diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 13e9c5c254c..f53e08bdaa8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,8 @@ # CODEOWNERS: https://help.github.com/articles/about-codeowners/ -* @colin-axner @AdityaSripal @crodriguezvega @seantking @charleenfei @damiannolan @chatton +* @colin-axner @AdityaSripal @crodriguezvega @charleenfei @damiannolan @chatton + +# Our appreciation and gratitude to past code owners: @fedekunze @seantking # Order is important; the last matching pattern takes the most # precedence. When someone opens a pull request that only @@ -9,34 +11,32 @@ # CODEOWNERS for the CODEOWNER file -/.github/CODEOWNERS @colin-axner @AdityaSripal @crodriguezvega +/.github/CODEOWNERS @colin-axner @AdityaSripal @crodriguezvega @damiannolan # CODEOWNERS for the core IBC module -/modules/core/ @colin-axner @AdityaSripal -/proto/ibc/core/ @colin-axner @AdityaSripal - -## CODEOWNERS for core/02-client - -/modules/core/02-client @colin-axner @AdityaSripal @seantking @damiannolan -/proto/ibc/core/client @colin-axner @AdityaSripal @seantking @damiannolan +/modules/core/ @colin-axner @AdityaSripal @damiannolan +/proto/ibc/core/ @colin-axner @AdityaSripal @damiannolan # CODEOWNERS for the light-clients -/modules/light-clients/ @colin-axner @AdityaSripal @seantking @damiannolan -/proto/ibc/lightclients/ @colin-axner @AdityaSripal @seantking @damiannolan +/modules/light-clients/ @colin-axner @AdityaSripal @damiannolan +/proto/ibc/lightclients/ @colin-axner @AdityaSripal @damiannolan # CODEOWNERS for ICS 20 -/modules/apps/transfer/ @colin-axner @AdityaSripal -/proto/ibc/applications/transfer/ @colin-axner @AdityaSripal +/modules/apps/transfer/ @colin-axner @AdityaSripal @damiannolan +/proto/ibc/applications/transfer/ @colin-axner @AdityaSripal @damiannolan # CODEOWNERS for interchain-accounts module -/modules/apps/27-interchain-accounts/ @seantking @colin-axner @AdityaSripal @damiannolan -/proto/ibc/applications/interchain_accounts/ @seantking @colin-axner @AdityaSripal @damiannolan +/modules/apps/27-interchain-accounts/ @colin-axner @AdityaSripal @damiannolan +/proto/ibc/applications/interchain_accounts/ @colin-axner @AdityaSripal @damiannolan # CODEOWNERS for fee module -/modules/apps/29-fee/ @AdityaSripal @seantking @charleenfei @colin-axner @damiannolan -/proto/ibc/applications/fee/ @AdityaSripal @seantking @charleenfei @colin-axner @damiannolan +/modules/apps/29-fee/ @AdityaSripal @charleenfei @colin-axner @damiannolan +/proto/ibc/applications/fee/ @AdityaSripal @charleenfei @colin-axner @damiannolan + +# CODEOWNERS for docs +/docs/ @colin-axner @AdityaSripal @crodriguezvega @charleenfei @damiannolan @chatton @tmsdkeys diff --git a/.github/ISSUE_TEMPLATE/release-tracker.md b/.github/ISSUE_TEMPLATE/release-tracker.md index 873f4e487ab..204c258609e 100644 --- a/.github/ISSUE_TEMPLATE/release-tracker.md +++ b/.github/ISSUE_TEMPLATE/release-tracker.md @@ -15,23 +15,24 @@ v without deliberation -### IBC spec compatibility +## IBC spec compatibility -### QA +## QA -#### Backwards compatibility +### Backwards compatibility -- [ ] Fungible token transfers over a non-incentivised channel works with a counterparty chain running each previous major version. -- [ ] Fungible token transfers over an incentivised channel works with a counterparty chain running each previous major version that supports ICS-29 Fee Middleware. -- [ ] Interchain Accounts over a non-incentivised channel works with a counterparty chain running each previous major version that supports ICS-27 Interchain Accounts over non-incentivised channels. -- [ ] Interchain Accounts over an incentivised channel works with a counterparty chain running each previous major version that supports ICS-27 Interchain Accounts over incentivised channels. +- [ ] [Compatibility tests](https://github.com/cosmos/ibc-go/actions/workflows/e2e-compatibility.yaml) pass for the release branch. +- [ ] [Upgrade tests](https://github.com/cosmos/ibc-go/actions/workflows/e2e-upgrade.yaml) pass. +- [ ] [Interchain Accounts inter-tx tests](https://github.com/cosmos/interchain-accounts-demo/actions/workflows/e2e-compatibility.yaml) pass. -### Migration +### Other testing + +## Migration @@ -41,7 +42,7 @@ versions of ibc-go to guarantee that no regression is introduced --> - [ ] Bump [go package version](https://github.com/cosmos/ibc-go/blob/main/go.mod#L3). - [ ] Change all imports starting with `github.com/cosmos/ibc-go/v{x}` to `github.com/cosmos/ibc-go/v{x+1}`. -- [ ] Branch off main to create release branch in the form of `release/vx.y.z`. +- [ ] Branch off main to create release branch in the form of `release/vx.y.z` and add branch protection rules. - [ ] Add branch protection rules to new release branch. - [ ] Add backport task to [`mergify.yml`](https://github.com/cosmos/ibc-go/blob/main/.github/mergify.yml) - [ ] Upgrade ibc-go version in [ibctest](https://github.com/strangelove-ventures/ibctest). @@ -50,12 +51,25 @@ versions of ibc-go to guarantee that no regression is introduced --> ## Post-release checklist - [ ] Update [`CHANGELOG.md`](https://github.com/cosmos/ibc-go/blob/main/CHANGELOG.md) -- [ ] Update the table of supported release lines (and End of Life dates) in [`RELEASES.md`](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md). -- [ ] Update [version matrix](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md#version-matrix) in `RELEASES.md`. +- [ ] Update the table of supported release lines (and End of Life dates) in [`RELEASES.md`](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md): + - Add the new release line. + - Remove any release lines that might have become discontinued. +- [ ] Update [version matrix](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md#version-matrix) in `RELEASES.md`: + - Add the new release. + - Remove any tags that might not be recommended anymore. +- [ ] Update the list of [supported release lines in README.md](https://github.com/cosmos/ibc-go#releases), if necessary. - [ ] Update docs site: - [ ] Add new release branch to [`docs/versions`](https://github.com/cosmos/ibc-go/blob/main/docs/versions) file. - - [ ] Add `label` and `key` to `versions` array in [`config.js`](https://github.com/cosmos/ibc-go/blob/main/docs/.vuepress/config.js#L33). + - [ ] Add `label` and `key` to `versions` array in [`config.js`](https://github.com/cosmos/ibc-go/blob/main/docs/.vuepress/config.js#L62). +- [ ] Bump ibc-go version in [cosmos/interchain-accounts-demo repository](https://github.com/cosmos/interchain-accounts-demo) and create a tag. +- [ ] Update the [compatibility test matrices](https://github.com/cosmos/ibc-go/tree/main/.github/compatibility-test-matrices): + - Add the new release. + - Remove any tags that might not be recommended anymore. +- [ ] Update the manual [e2e `simd`](https://github.com/cosmos/ibc-go/blob/main/.github/workflows/e2e-manual-simd.yaml) and [e2e `icad`](https://github.com/cosmos/ibc-go/blob/main/.github/workflows/e2e-manual-icad.yaml) test workflows: + - Add the new release and the new `icad` tag. + - Remove any tags that might not be recommended anymore. - [ ] After changes to docs site are deployed, check [ibc.cosmos.network](https://ibc.cosmos.network) is updated. +- [ ] Open issue in [SDK tutorials repo](https://github.com/cosmos/sdk-tutorials) to update tutorials to the released version of ibc-go. ____ diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 435e6a89ca8..bfbcfb6335f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,18 +12,41 @@ are the most critical to review. closes: #XXXX + +### Commit Message / Changelog Entry + +```bash +type: commit message +``` + +see the [guidelines](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) for commit messages. (view raw markdown for examples) + + + + --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. -- [ ] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#pr-targeting)) +- [ ] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#pull-request-targeting)). - [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. -- [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/structure.md). -- [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#testing) -- [ ] Updated relevant documentation (`docs/`) or specification (`x//spec/`) +- [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules/10-structure.md) and [Go style guide](../docs/dev/go-style-guide.md). +- [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/main/testing/README.md#ibc-testing-package). +- [ ] Updated relevant documentation (`docs/`) or specification (`x//spec/`). - [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). -- [ ] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md` -- [ ] Re-reviewed `Files changed` in the Github PR explorer -- [ ] Review `Codecov Report` in the comment section below once CI passes +- [ ] Provide a [commit message](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) to be used for the changelog entry in the PR description for review. +- [ ] Re-reviewed `Files changed` in the Github PR explorer. +- [ ] Review `Codecov Report` in the comment section below once CI passes. diff --git a/.github/compatibility-test-matrices/main/client-chain-a.json b/.github/compatibility-test-matrices/main/client-chain-a.json new file mode 100644 index 00000000000..23b1b5325d5 --- /dev/null +++ b/.github/compatibility-test-matrices/main/client-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["main"], + "chain-b": ["main", "v5.1.0", "v5.0.1", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestClientTestSuite"], + "test": [ + "TestClientUpdateProposal_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/client-chain-b.json b/.github/compatibility-test-matrices/main/client-chain-b.json new file mode 100644 index 00000000000..f97107801af --- /dev/null +++ b/.github/compatibility-test-matrices/main/client-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["main", "v5.1.0", "v5.0.1", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["main"], + "entrypoint": ["TestClientTestSuite"], + "test": [ + "TestClientUpdateProposal_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/connection-chain-a.json b/.github/compatibility-test-matrices/main/connection-chain-a.json new file mode 100644 index 00000000000..c41bca7f985 --- /dev/null +++ b/.github/compatibility-test-matrices/main/connection-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["main"], + "chain-b": ["main", "v5.1.0", "v5.0.1", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestConnectionTestSuite"], + "test": [ + "TestMaxExpectedTimePerBlockParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/connection-chain-b.json b/.github/compatibility-test-matrices/main/connection-chain-b.json new file mode 100644 index 00000000000..030e84d84fe --- /dev/null +++ b/.github/compatibility-test-matrices/main/connection-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["main", "v5.1.0", "v5.0.1", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["main"], + "entrypoint": ["TestConnectionTestSuite"], + "test": [ + "TestMaxExpectedTimePerBlockParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/ica-chain-a.json b/.github/compatibility-test-matrices/main/ica-chain-a.json new file mode 100644 index 00000000000..2b80c602c5a --- /dev/null +++ b/.github/compatibility-test-matrices/main/ica-chain-a.json @@ -0,0 +1,13 @@ +{ + "chain-a": ["main"], + "chain-b": ["main"], + "entrypoint": ["TestInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulTransfer", + "TestMsgSendTx_FailedTransfer_InsufficientFunds", + "TestMsgSubmitTx_SuccessfulTransfer_AfterReopeningICA" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/ica-gov-chain-a.json b/.github/compatibility-test-matrices/main/ica-gov-chain-a.json new file mode 100644 index 00000000000..7fa0e161267 --- /dev/null +++ b/.github/compatibility-test-matrices/main/ica-gov-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["main"], + "chain-b": ["main"], + "entrypoint": ["TestInterchainAccountsGovTestSuite"], + "test": [ + "TestInterchainAccountsGovIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/ica-groups-chain-a.json b/.github/compatibility-test-matrices/main/ica-groups-chain-a.json new file mode 100644 index 00000000000..1e8fff430b3 --- /dev/null +++ b/.github/compatibility-test-matrices/main/ica-groups-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["main"], + "chain-b": ["main"], + "entrypoint": ["TestInterchainAccountsGroupsTestSuite"], + "test": [ + "TestInterchainAccountsGroupsIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/incentivized-ica-chain-a.json b/.github/compatibility-test-matrices/main/incentivized-ica-chain-a.json new file mode 100644 index 00000000000..9330a274711 --- /dev/null +++ b/.github/compatibility-test-matrices/main/incentivized-ica-chain-a.json @@ -0,0 +1,12 @@ +{ + "chain-a": ["main"], + "chain-b": ["main"], + "entrypoint": ["TestIncentivizedInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulBankSend_Incentivized", + "TestMsgSendTx_FailedBankSend_Incentivized" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/incentivized-transfer-chain-a.json b/.github/compatibility-test-matrices/main/incentivized-transfer-chain-a.json new file mode 100644 index 00000000000..235b4558a5d --- /dev/null +++ b/.github/compatibility-test-matrices/main/incentivized-transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["main"], + "chain-b": ["main", "v5.1.0", "v5.0.1", "v4.2.0", "v4.1.1"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/incentivized-transfer-chain-b.json b/.github/compatibility-test-matrices/main/incentivized-transfer-chain-b.json new file mode 100644 index 00000000000..ad00897c137 --- /dev/null +++ b/.github/compatibility-test-matrices/main/incentivized-transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["main", "v5.1.0", "v5.0.1", "v4.2.0", "v4.1.1"], + "chain-b": ["main"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/transfer-chain-a.json b/.github/compatibility-test-matrices/main/transfer-chain-a.json new file mode 100644 index 00000000000..425b14fdfc1 --- /dev/null +++ b/.github/compatibility-test-matrices/main/transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["main"], + "chain-b": ["main", "v5.1.0", "v5.0.1", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/main/transfer-chain-b.json b/.github/compatibility-test-matrices/main/transfer-chain-b.json new file mode 100644 index 00000000000..916d1e58744 --- /dev/null +++ b/.github/compatibility-test-matrices/main/transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["main", "v5.1.0", "v5.0.1", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["main"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v3.4.x/transfer-chain-a.json b/.github/compatibility-test-matrices/release-v3.4.x/transfer-chain-a.json new file mode 100644 index 00000000000..407e9ebd616 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v3.4.x/transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v3.4.x"], + "chain-b": ["release-v3.4.x", "v6.1.0", "v5.2.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v3.4.x/transfer-chain-b.json b/.github/compatibility-test-matrices/release-v3.4.x/transfer-chain-b.json new file mode 100644 index 00000000000..ae95e67834a --- /dev/null +++ b/.github/compatibility-test-matrices/release-v3.4.x/transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v3.4.x", "v6.1.0", "v5.2.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v3.4.x"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v4.2.x/incentivized-transfer-chain-a.json b/.github/compatibility-test-matrices/release-v4.2.x/incentivized-transfer-chain-a.json new file mode 100644 index 00000000000..c2b4e20e0f9 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v4.2.x/incentivized-transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v4.2.x"], + "chain-b": ["release-v4.2.x", "v6.1.0", "v5.2.0", "v4.1.1"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v4.2.x/incentivized-transfer-chain-b.json b/.github/compatibility-test-matrices/release-v4.2.x/incentivized-transfer-chain-b.json new file mode 100644 index 00000000000..3acc5bf05f9 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v4.2.x/incentivized-transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v4.2.x", "v6.1.0", "v5.2.0", "v4.1.1"], + "chain-b": ["release-v4.2.x"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v4.2.x/transfer-chain-a.json b/.github/compatibility-test-matrices/release-v4.2.x/transfer-chain-a.json new file mode 100644 index 00000000000..191ca1e3d01 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v4.2.x/transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v4.2.x"], + "chain-b": ["release-v4.2.x", "v6.1.0", "v5.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v4.2.x/transfer-chain-b.json b/.github/compatibility-test-matrices/release-v4.2.x/transfer-chain-b.json new file mode 100644 index 00000000000..b7024615f69 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v4.2.x/transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v4.2.x", "v6.1.0", "v5.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v4.2.x"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v4.3.x/incentivized-transfer-chain-a.json b/.github/compatibility-test-matrices/release-v4.3.x/incentivized-transfer-chain-a.json new file mode 100644 index 00000000000..884575a8648 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v4.3.x/incentivized-transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v4.3.x"], + "chain-b": ["release-v4.3.x", "v6.1.0", "v5.2.0", "v4.3.0", "4.2.0", "v4.1.1"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v4.3.x/incentivized-transfer-chain-b.json b/.github/compatibility-test-matrices/release-v4.3.x/incentivized-transfer-chain-b.json new file mode 100644 index 00000000000..a3190d1da42 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v4.3.x/incentivized-transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v4.3.x", "v6.1.0", "v5.2.0", "v4.3.0", "4.2.0", "v4.1.1"], + "chain-b": ["release-v4.3.x"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v4.3.x/transfer-chain-a.json b/.github/compatibility-test-matrices/release-v4.3.x/transfer-chain-a.json new file mode 100644 index 00000000000..d4711252f4e --- /dev/null +++ b/.github/compatibility-test-matrices/release-v4.3.x/transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v4.3.x"], + "chain-b": ["release-v4.3.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v4.3.x/transfer-chain-b.json b/.github/compatibility-test-matrices/release-v4.3.x/transfer-chain-b.json new file mode 100644 index 00000000000..ad11eec6e39 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v4.3.x/transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v4.3.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v4.3.x"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v5.2.x/incentivized-transfer-chain-a.json b/.github/compatibility-test-matrices/release-v5.2.x/incentivized-transfer-chain-a.json new file mode 100644 index 00000000000..6ff10fdc4bd --- /dev/null +++ b/.github/compatibility-test-matrices/release-v5.2.x/incentivized-transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v5.2.x"], + "chain-b": ["release-v5.2.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v5.2.x/incentivized-transfer-chain-b.json b/.github/compatibility-test-matrices/release-v5.2.x/incentivized-transfer-chain-b.json new file mode 100644 index 00000000000..dba1d97b60f --- /dev/null +++ b/.github/compatibility-test-matrices/release-v5.2.x/incentivized-transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v5.2.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1"], + "chain-b": ["release-v5.2.x"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v5.2.x/transfer-chain-a.json b/.github/compatibility-test-matrices/release-v5.2.x/transfer-chain-a.json new file mode 100644 index 00000000000..7f18e5f202d --- /dev/null +++ b/.github/compatibility-test-matrices/release-v5.2.x/transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v5.2.x"], + "chain-b": ["release-v5.2.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v5.2.x/transfer-chain-b.json b/.github/compatibility-test-matrices/release-v5.2.x/transfer-chain-b.json new file mode 100644 index 00000000000..b4f20372860 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v5.2.x/transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v5.2.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v5.2.x"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/client-chain-a.json b/.github/compatibility-test-matrices/release-v6.1.x/client-chain-a.json new file mode 100644 index 00000000000..79bc3005ed1 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/client-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v6.1.x"], + "chain-b": ["release-v6.1.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestClientTestSuite"], + "test": [ + "TestClientUpdateProposal_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/client-chain-b.json b/.github/compatibility-test-matrices/release-v6.1.x/client-chain-b.json new file mode 100644 index 00000000000..53f70071854 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/client-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v6.1.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v6.1.x"], + "entrypoint": ["TestClientTestSuite"], + "test": [ + "TestClientUpdateProposal_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/connection-chain-a.json b/.github/compatibility-test-matrices/release-v6.1.x/connection-chain-a.json new file mode 100644 index 00000000000..a740b2701d0 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/connection-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v6.1.x"], + "chain-b": ["release-v6.1.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestConnectionTestSuite"], + "test": [ + "TestMaxExpectedTimePerBlockParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/connection-chain-b.json b/.github/compatibility-test-matrices/release-v6.1.x/connection-chain-b.json new file mode 100644 index 00000000000..eae5513e627 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/connection-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v6.1.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v6.1.x"], + "entrypoint": ["TestConnectionTestSuite"], + "test": [ + "TestMaxExpectedTimePerBlockParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/ica-chain-a.json b/.github/compatibility-test-matrices/release-v6.1.x/ica-chain-a.json new file mode 100644 index 00000000000..56bdb35c6f2 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/ica-chain-a.json @@ -0,0 +1,13 @@ +{ + "chain-a": ["release-v6.1.x"], + "chain-b": ["release-v6.1.x", "v6.1.0"], + "entrypoint": ["TestInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulTransfer", + "TestMsgSendTx_FailedTransfer_InsufficientFunds", + "TestMsgSubmitTx_SuccessfulTransfer_AfterReopeningICA" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/ica-chain-b.json b/.github/compatibility-test-matrices/release-v6.1.x/ica-chain-b.json new file mode 100644 index 00000000000..0d6c894d461 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/ica-chain-b.json @@ -0,0 +1,13 @@ +{ + "chain-a": ["release-v6.1.x", "v6.1.0"], + "chain-b": ["release-v6.1.x"], + "entrypoint": ["TestInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulTransfer", + "TestMsgSendTx_FailedTransfer_InsufficientFunds", + "TestMsgSubmitTx_SuccessfulTransfer_AfterReopeningICA" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/ica-gov-chain-a.json b/.github/compatibility-test-matrices/release-v6.1.x/ica-gov-chain-a.json new file mode 100644 index 00000000000..a5db177b6df --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/ica-gov-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v6.1.x", "v6.1.0"], + "chain-b": ["release-v6.1.x"], + "entrypoint": ["TestInterchainAccountsGovTestSuite"], + "test": [ + "TestInterchainAccountsGovIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/ica-gov-chain-b.json b/.github/compatibility-test-matrices/release-v6.1.x/ica-gov-chain-b.json new file mode 100644 index 00000000000..210a45a9d9f --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/ica-gov-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v6.1.x"], + "chain-b": ["release-v6.1.x", "v6.1.0"], + "entrypoint": ["TestInterchainAccountsGovTestSuite"], + "test": [ + "TestInterchainAccountsGovIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/ica-groups-chain-a.json b/.github/compatibility-test-matrices/release-v6.1.x/ica-groups-chain-a.json new file mode 100644 index 00000000000..bcf9da79a3f --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/ica-groups-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v6.1.x"], + "chain-b": ["release-v6.1.x", "v6.1.0"], + "entrypoint": ["TestInterchainAccountsGroupsTestSuite"], + "test": [ + "TestInterchainAccountsGroupsIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/ica-groups-chain-b.json b/.github/compatibility-test-matrices/release-v6.1.x/ica-groups-chain-b.json new file mode 100644 index 00000000000..33705ad8c9b --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/ica-groups-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v6.1.x", "v6.1.0"], + "chain-b": ["release-v6.1.x"], + "entrypoint": ["TestInterchainAccountsGroupsTestSuite"], + "test": [ + "TestInterchainAccountsGroupsIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/incentivized-ica-chain-a.json b/.github/compatibility-test-matrices/release-v6.1.x/incentivized-ica-chain-a.json new file mode 100644 index 00000000000..bcf9e42659d --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/incentivized-ica-chain-a.json @@ -0,0 +1,12 @@ +{ + "chain-a": ["release-v6.1.x"], + "chain-b": ["release-v6.1.x", "v6.1.0"], + "entrypoint": ["TestIncentivizedInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulBankSend_Incentivized", + "TestMsgSendTx_FailedBankSend_Incentivized" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/incentivized-ica-chain-b.json b/.github/compatibility-test-matrices/release-v6.1.x/incentivized-ica-chain-b.json new file mode 100644 index 00000000000..141eecac664 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/incentivized-ica-chain-b.json @@ -0,0 +1,12 @@ +{ + "chain-a": ["release-v6.1.x", "v6.1.0"], + "chain-b": ["release-v6.1.x"], + "entrypoint": ["TestIncentivizedInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulBankSend_Incentivized", + "TestMsgSendTx_FailedBankSend_Incentivized" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/incentivized-transfer-chain-a.json b/.github/compatibility-test-matrices/release-v6.1.x/incentivized-transfer-chain-a.json new file mode 100644 index 00000000000..004418020be --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/incentivized-transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v6.1.x"], + "chain-b": ["release-v6.1.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/incentivized-transfer-chain-b.json b/.github/compatibility-test-matrices/release-v6.1.x/incentivized-transfer-chain-b.json new file mode 100644 index 00000000000..4d0b6a7ee99 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/incentivized-transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v6.1.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1"], + "chain-b": ["release-v6.1.x"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/transfer-chain-a.json b/.github/compatibility-test-matrices/release-v6.1.x/transfer-chain-a.json new file mode 100644 index 00000000000..14d9ee98579 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v6.1.x"], + "chain-b": ["release-v6.1.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v6.1.x/transfer-chain-b.json b/.github/compatibility-test-matrices/release-v6.1.x/transfer-chain-b.json new file mode 100644 index 00000000000..468049cc707 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v6.1.x/transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v6.1.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v6.1.x"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/client-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/client-chain-a.json new file mode 100644 index 00000000000..ce0b032b90b --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/client-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestClientTestSuite"], + "test": [ + "TestClientUpdateProposal_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/client-chain-b.json b/.github/compatibility-test-matrices/release-v7.0.x/client-chain-b.json new file mode 100644 index 00000000000..5c49fbc7b9c --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/client-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestClientTestSuite"], + "test": [ + "TestClientUpdateProposal_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/connection-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/connection-chain-a.json new file mode 100644 index 00000000000..0cc16812e03 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/connection-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestConnectionTestSuite"], + "test": [ + "TestMaxExpectedTimePerBlockParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/connection-chain-b.json b/.github/compatibility-test-matrices/release-v7.0.x/connection-chain-b.json new file mode 100644 index 00000000000..c6aa5e28dbb --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/connection-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestConnectionTestSuite"], + "test": [ + "TestMaxExpectedTimePerBlockParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/ica-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/ica-chain-a.json new file mode 100644 index 00000000000..f6a63997f3d --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/ica-chain-a.json @@ -0,0 +1,13 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x", "v6.1.0"], + "entrypoint": ["TestInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulTransfer", + "TestMsgSendTx_FailedTransfer_InsufficientFunds", + "TestMsgSubmitTx_SuccessfulTransfer_AfterReopeningICA" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/ica-chain-b.json b/.github/compatibility-test-matrices/release-v7.0.x/ica-chain-b.json new file mode 100644 index 00000000000..452fbebe98b --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/ica-chain-b.json @@ -0,0 +1,13 @@ +{ + "chain-a": ["release-v7.0.x", "v6.1.0"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulTransfer", + "TestMsgSendTx_FailedTransfer_InsufficientFunds", + "TestMsgSubmitTx_SuccessfulTransfer_AfterReopeningICA" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/ica-gov-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/ica-gov-chain-a.json new file mode 100644 index 00000000000..c339471ea3d --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/ica-gov-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x", "v6.1.0"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestInterchainAccountsGovTestSuite"], + "test": [ + "TestInterchainAccountsGovIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/ica-gov-chain-b.json b/.github/compatibility-test-matrices/release-v7.0.x/ica-gov-chain-b.json new file mode 100644 index 00000000000..c8489613a48 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/ica-gov-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x", "v6.1.0"], + "entrypoint": ["TestInterchainAccountsGovTestSuite"], + "test": [ + "TestInterchainAccountsGovIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/ica-groups-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/ica-groups-chain-a.json new file mode 100644 index 00000000000..888f7e22e07 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/ica-groups-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x", "v6.1.0"], + "entrypoint": ["TestInterchainAccountsGroupsTestSuite"], + "test": [ + "TestInterchainAccountsGroupsIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/ica-groups-chain-b.json b/.github/compatibility-test-matrices/release-v7.0.x/ica-groups-chain-b.json new file mode 100644 index 00000000000..ff75181eb46 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/ica-groups-chain-b.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x", "v6.1.0"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestInterchainAccountsGroupsTestSuite"], + "test": [ + "TestInterchainAccountsGroupsIntegration" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/incentivized-ica-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/incentivized-ica-chain-a.json new file mode 100644 index 00000000000..bc937f1d6a5 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/incentivized-ica-chain-a.json @@ -0,0 +1,12 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x", "v6.1.0"], + "entrypoint": ["TestIncentivizedInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulBankSend_Incentivized", + "TestMsgSendTx_FailedBankSend_Incentivized" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/incentivized-ica-chain-b.json b/.github/compatibility-test-matrices/release-v7.0.x/incentivized-ica-chain-b.json new file mode 100644 index 00000000000..000e6fcf2be --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/incentivized-ica-chain-b.json @@ -0,0 +1,12 @@ +{ + "chain-a": ["release-v7.0.x", "v6.1.0"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestIncentivizedInterchainAccountsTestSuite"], + "test": [ + "TestMsgSendTx_SuccessfulBankSend_Incentivized", + "TestMsgSendTx_FailedBankSend_Incentivized" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/incentivized-transfer-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/incentivized-transfer-chain-a.json new file mode 100644 index 00000000000..54841e7e08c --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/incentivized-transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/incentivized-transfer-chain-b.json b/.github/compatibility-test-matrices/release-v7.0.x/incentivized-transfer-chain-b.json new file mode 100644 index 00000000000..f62e5040c05 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/incentivized-transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v7.0.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/transfer-authz-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/transfer-authz-chain-a.json new file mode 100644 index 00000000000..23ac0a9ed1b --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/transfer-authz-chain-a.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestAuthzTransferTestSuite"], + "test": [ + "TestAuthz_MsgTransfer_Succeeds", + "TestAuthz_InvalidTransferAuthorizations" + ], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/transfer-chain-a.json b/.github/compatibility-test-matrices/release-v7.0.x/transfer-chain-a.json new file mode 100644 index 00000000000..afc45db5d08 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/transfer-chain-a.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v7.0.x"], + "chain-b": ["release-v7.0.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/release-v7.0.x/transfer-chain-b.json b/.github/compatibility-test-matrices/release-v7.0.x/transfer-chain-b.json new file mode 100644 index 00000000000..d3cf643c553 --- /dev/null +++ b/.github/compatibility-test-matrices/release-v7.0.x/transfer-chain-b.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v7.0.x", "v6.1.0", "v5.2.0", "v4.3.0", "v4.2.0", "v4.1.1", "v3.4.0", "v3.3.1"], + "chain-b": ["release-v7.0.x"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/unreleased/client.json b/.github/compatibility-test-matrices/unreleased/client.json new file mode 100644 index 00000000000..48d0bab8140 --- /dev/null +++ b/.github/compatibility-test-matrices/unreleased/client.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x", "release-v6.1.x", "release-v5.2.x", "release-v4.3.x", "release-v4.2.x", "release-v3.4.x"], + "chain-b": ["release-v7.0.x", "release-v6.1.x", "release-v5.2.x", "release-v4.3.x", "release-v4.2.x", "release-v3.4.x"], + "entrypoint": ["TestClientTestSuite"], + "test": [ + "TestClientUpdateProposal_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/unreleased/connection.json b/.github/compatibility-test-matrices/unreleased/connection.json new file mode 100644 index 00000000000..f386a945054 --- /dev/null +++ b/.github/compatibility-test-matrices/unreleased/connection.json @@ -0,0 +1,11 @@ +{ + "chain-a": ["release-v7.0.x", "release-v6.1.x", "release-v5.2.x", "release-v4.3.x", "release-v4.2.x", "release-v3.4.x"], + "chain-b": ["release-v7.0.x", "release-v6.1.x", "release-v5.2.x", "release-v4.3.x", "release-v4.2.x", "release-v3.4.x"], + "entrypoint": ["TestConnectionTestSuite"], + "test": [ + "TestMaxExpectedTimePerBlockParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/unreleased/incentivized-transfer.json b/.github/compatibility-test-matrices/unreleased/incentivized-transfer.json new file mode 100644 index 00000000000..53637437077 --- /dev/null +++ b/.github/compatibility-test-matrices/unreleased/incentivized-transfer.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v7.0.x", "release-v6.1.x", "release-v5.2.x", "release-v4.3.x", "release-v4.2.x"], + "chain-b": ["release-v7.0.x", "release-v6.1.x", "release-v5.2.x", "release-v4.3.x", "release-v4.2.x"], + "entrypoint": ["TestIncentivizedTransferTestSuite"], + "test": [ + "TestMsgPayPacketFee_AsyncSingleSender_Succeeds", + "TestMsgPayPacketFee_InvalidReceiverAccount", + "TestMultiMsg_MsgPayPacketFeeSingleSender", + "TestMsgPayPacketFee_SingleSender_TimesOut", + "TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress", + "TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/compatibility-test-matrices/unreleased/transfer.json b/.github/compatibility-test-matrices/unreleased/transfer.json new file mode 100644 index 00000000000..dc93ca6f85b --- /dev/null +++ b/.github/compatibility-test-matrices/unreleased/transfer.json @@ -0,0 +1,16 @@ +{ + "chain-a": ["release-v7.0.x", "release-v6.1.x", "release-v5.2.x", "release-v4.2.x", "release-v3.4.x"], + "chain-b": ["release-v7.0.x", "release-v6.1.x", "release-v5.2.x", "release-v4.2.x", "release-v3.4.x"], + "entrypoint": ["TestTransferTestSuite"], + "test": [ + "TestMsgTransfer_Succeeds_Nonincentivized", + "TestMsgTransfer_Fails_InvalidAddress", + "TestMsgTransfer_Timeout_Nonincentivized", + "TestMsgTransfer_WithMemo", + "TestSendEnabledParam", + "TestReceiveEnabledParam" + ], + "relayer-type": ["rly"], + "chain-binary": ["simd"], + "chain-image": ["ghcr.io/cosmos/ibc-go-simd"] +} diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1fed7f0c1ac..a9b4e5309f9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,9 +10,5 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 - reviewers: - - colin-axner - - fedekunze - - AdityaSripal labels: - dependencies diff --git a/.github/mergify.yml b/.github/mergify.yml index 2dfc4653a7d..8ff9b606452 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -18,67 +18,67 @@ pull_request_rules: commit_message_template: | {{ title }} (#{{ number }}) {{ body }} - - name: backport patches to v2.1.x branch + - name: backport patches to v3.3.x branch conditions: - base=main - - label=backport-to-v2.1.x + - label=backport-to-v3.3.x actions: backport: branches: - - release/v2.1.x - - name: backport patches to v2.2.x branch + - release/v3.3.x + - name: backport patches to v3.4.x branch conditions: - base=main - - label=backport-to-v2.2.x + - label=backport-to-v3.4.x actions: backport: branches: - - release/v2.2.x - - name: backport patches to v2.3.x branch + - release/v3.4.x + - name: backport patches to v4.1.x branch conditions: - base=main - - label=backport-to-v2.3.x + - label=backport-to-v4.1.x actions: backport: branches: - - release/v2.3.x - - name: backport patches to v2.4.x branch + - release/v4.1.x + - name: backport patches to v4.2.x branch conditions: - base=main - - label=backport-to-v2.4.x + - label=backport-to-v4.2.x actions: backport: branches: - - release/v2.4.x - - name: backport patches to v3.0.x branch + - release/v4.2.x + - name: backport patches to v4.3.x branch conditions: - base=main - - label=backport-to-v3.0.x + - label=backport-to-v4.3.x actions: backport: branches: - - release/v3.0.x - - name: backport patches to v3.1.x branch + - release/v4.3.x + - name: backport patches to v5.2.x branch conditions: - base=main - - label=backport-to-v3.1.x + - label=backport-to-v5.2.x actions: backport: branches: - - release/v3.1.x - - name: backport patches to v3.2.x branch + - release/v5.2.x + - name: backport patches to v6.1.x branch conditions: - base=main - - label=backport-to-v3.2.x + - label=backport-to-v6.1.x actions: backport: branches: - - release/v3.2.x - - name: backport patches to v4.0.x branch + - release/v6.1.x + - name: backport patches to v7.0.x branch conditions: - base=main - - label=backport-to-v4.0.x + - label=backport-to-v7.0.x actions: backport: branches: - - release/v4.0.x + - release/v7.0.x diff --git a/.github/scripts/go-imports.sh b/.github/scripts/go-imports.sh deleted file mode 100755 index bc5e6db3f86..00000000000 --- a/.github/scripts/go-imports.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -formatted_files="$(docker run -v "$(pwd)":/ibc-go --rm -w "/ibc-go" --entrypoint="" cytopia/goimports goimports -l -local 'github.com/cosmos/ibc-go' /ibc-go)" - -exit_code=0 -for f in $formatted_files -do - # we don't care about formatting in pb.go files. - if [ "${f: -5}" == "pb.go" ]; then - continue - fi - exit_code=1 - echo "formatted file ${f}..." -done - -if [ "${exit_code}" == 1 ]; then - echo "not all files were correctly formated, run the following:" - echo "make goimports" -fi - -exit $exit_code diff --git a/.github/workflows/build-simd-image-from-tag.yml b/.github/workflows/build-simd-image-from-tag.yml new file mode 100644 index 00000000000..5ac105b9c88 --- /dev/null +++ b/.github/workflows/build-simd-image-from-tag.yml @@ -0,0 +1,39 @@ +name: Build Simd Image +on: + workflow_dispatch: + inputs: + tag: + description: 'The tag of the image to build' + required: true + type: string + ibc-go-version: + description: 'The ibc-go version to be added as a label' + required: true + type: string + +env: + REGISTRY: ghcr.io + ORG: cosmos + IMAGE_NAME: ibc-go-simd + GIT_TAG: "${{ inputs.tag }}" + +jobs: + build-image-at-tag: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: "${{ env.GIT_TAG }}" + fetch-depth: 0 + - name: Log in to the Container registry + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build image + run: | + # remove any `/` characters from the docker tag and replace them with a - + docker_tag="$(echo $GIT_TAG | sed 's/\//-/')" + docker build . -t "${REGISTRY}/${ORG}/${IMAGE_NAME}:${docker_tag}" --build-arg IBC_GO_VERSION=${{ inputs.ibc-go-version }} + docker push "${REGISTRY}/${ORG}/${IMAGE_NAME}:${docker_tag}" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f9a7c4a9230..9cdbe5618cf 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -40,7 +40,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - uses: technote-space/get-diff-action@v6.1.0 + - uses: technote-space/get-diff-action@v6.1.2 with: PATTERNS: | **/**.go diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 00000000000..eb9b6ef31ff --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,42 @@ +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. +on: + workflow_dispatch: + push: + branches: + - main + - "release/**" + paths: + - "docs/**" + - .github/workflows/deploy-docs.yml + +permissions: + contents: read + +jobs: + build-and-deploy: + permissions: + contents: write # for JamesIves/github-pages-deploy-action to push changes in repo + runs-on: ubuntu-latest + container: + image: ghcr.io/cosmos/website-deployment + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v3 + with: + persist-credentials: false + fetch-depth: 0 + path: "." + + - name: Build 🔧 + run: | + git config --global --add safe.directory /__w/ibc-go/ibc-go + make build-docs LEDGER_ENABLED=false + + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@v4.4.1 + with: + branch: gh-pages + folder: ~/output + single-commit: true diff --git a/.github/workflows/e2e-compatibility-unreleased.yaml b/.github/workflows/e2e-compatibility-unreleased.yaml new file mode 100644 index 00000000000..19be796dd9f --- /dev/null +++ b/.github/workflows/e2e-compatibility-unreleased.yaml @@ -0,0 +1,49 @@ +name: Compatibility E2E (Unreleased) +on: + workflow_dispatch: + inputs: + release-branch: + description: 'Select unreleased to run all release branches against each other' + required: true + type: choice + options: + - unreleased + +env: + REGISTRY: ghcr.io + ORG: cosmos + IMAGE_NAME: ibc-go-simd + RELEASE_BRANCH: '${{ inputs.release-branch }}' + +jobs: + transfer: + needs: + - build-release-images + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "unreleased" + test-suite: "transfer" + + connection: + needs: + - build-release-images + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "unreleased" + test-suite: "connection" + + client: + needs: + - build-release-images + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "unreleased" + test-suite: "client" + + incentivized-transfer: + needs: + - build-release-images + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "unreleased" + test-suite: "incentivized-transfer" \ No newline at end of file diff --git a/.github/workflows/e2e-compatibility-workflow-call.yaml b/.github/workflows/e2e-compatibility-workflow-call.yaml new file mode 100644 index 00000000000..58c5642a4f4 --- /dev/null +++ b/.github/workflows/e2e-compatibility-workflow-call.yaml @@ -0,0 +1,56 @@ +on: + workflow_call: + inputs: + test-file-directory: + description: 'Directory containing compatibility matrices' + required: true + type: string + test-suite: + description: "Test suite to run" + required: true + type: string + +jobs: + load-test-matrix: + outputs: + test-matrix: ${{ steps.set-test-matrix.outputs.test-matrix }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: andstor/file-existence-action@v2 + with: + files: ".github/compatibility-test-matrices/${{ inputs.test-file-directory }}/${{ inputs.test-suite }}.json" + - run: | + # use jq -c to put the full json contents on a single line. This is required when using the json body + # to create the matrix in the following job. + test_matrix="$(cat .github/compatibility-test-matrices/${{ inputs.test-file-directory }}/${{ inputs.test-suite }}.json | jq -c)" + echo $test_matrix + echo "test-matrix=$test_matrix" >> $GITHUB_OUTPUT + id: set-test-matrix + + e2e: + runs-on: ubuntu-latest + needs: load-test-matrix + if: needs.load-test-matrix.outputs.test-matrix + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.load-test-matrix.outputs.test-matrix) }} + steps: + - name: Checkout the ibc-go repo + uses: actions/checkout@v3 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v3 + with: + go-version: 1.19 + - name: Run e2e Test + run: | + cd e2e + make e2e-test entrypoint=${{ matrix.entrypoint }} test=${{ matrix.test }} + env: + # each test has its own set of variables to specify which images are used. + CHAIN_IMAGE: "${{ matrix.chain-image }}" + CHAIN_A_TAG: "${{ matrix.chain-a }}" + CHAIN_B_TAG: "${{ matrix.chain-b }}" + CHAIN_BINARY: "${{ matrix.chain-binary }}" + RELAYER_TYPE: "${{ matrix.relayer-type }}" diff --git a/.github/workflows/e2e-compatibility.yaml b/.github/workflows/e2e-compatibility.yaml new file mode 100644 index 00000000000..76c755a6265 --- /dev/null +++ b/.github/workflows/e2e-compatibility.yaml @@ -0,0 +1,194 @@ +name: Compatibility E2E +on: + workflow_dispatch: + inputs: + release-branch: + description: 'Release branch to test' + required: true + type: choice + options: + - release/v3.4.x + - release/v4.2.x + - release/v4.3.x + - release/v5.2.x + - release/v6.1.x + - release/v7.0.x + - main + ibc-go-version: + description: 'The version of ibc-go that is going to be released' + required: true + type: string + +env: + REGISTRY: ghcr.io + ORG: cosmos + IMAGE_NAME: ibc-go-simd + RELEASE_BRANCH: '${{ inputs.release-branch }}' + +jobs: + determine-test-directory: + runs-on: ubuntu-latest + outputs: + test-directory: ${{ steps.set-test-dir.outputs.test-directory }} + steps: + - run: | + test_dir="$(echo $RELEASE_BRANCH | sed 's/\//-/')" + echo $test_dir + echo "test-directory=$test_dir" >> $GITHUB_OUTPUT + id: set-test-dir + + # build-release-images builds all docker images that are relevant for the compatibility tests. If a single release + # branch is specified, only that image will be built, e.g. release-v6.0.x. + build-release-images: + runs-on: ubuntu-latest + strategy: + matrix: + release-branch: + - release/v3.4.x + - release/v4.2.x + - release/v4.3.x + - release/v5.2.x + - release/v6.1.x + - release/v7.0.x + - main + steps: + - uses: actions/checkout@v3 + if: env.RELEASE_BRANCH == matrix.release-branch + with: + ref: "${{ matrix.release-branch }}" + fetch-depth: 0 + - name: Log in to the Container registry + if: env.RELEASE_BRANCH == matrix.release-branch + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build image + if: env.RELEASE_BRANCH == matrix.release-branch + run: | + docker_tag="$(echo ${{ matrix.release-branch }} | sed 's/\//-/')" + docker build . -t "${REGISTRY}/${ORG}/${IMAGE_NAME}:$docker_tag" --build-arg IBC_GO_VERSION=${{ inputs.ibc-go-version }} + docker push "${REGISTRY}/${ORG}/${IMAGE_NAME}:$docker_tag" + - name: Display image details + if: env.RELEASE_BRANCH == matrix.release-branch + run: | + docker_tag="$(echo ${{ matrix.release-branch }} | sed 's/\//-/')" + docker inspect "${REGISTRY}/${ORG}/${IMAGE_NAME}:$docker_tag" + + transfer-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "transfer-chain-a" + + transfer-chain-b: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "transfer-chain-b" + + transfer-authz-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "transfer-authz-chain-a" + + connection-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "connection-chain-a" + + connection-chain-b: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "connection-chain-b" + + client-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "client-chain-a" + + client-chain-b: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "client-chain-b" + + incentivized-transfer-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "incentivized-transfer-chain-a" + + incentivized-transfer-chain-b: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "incentivized-transfer-chain-b" + + ica-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "ica-chain-a" + + incentivized-ica-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "incentivized-ica-chain-a" + + ica-groups-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "ica-groups-chain-a" + + ica-gov-chain-a: + needs: + - build-release-images + - determine-test-directory + uses: ./.github/workflows/e2e-compatibility-workflow-call.yaml + with: + test-file-directory: "${{ needs.determine-test-directory.outputs.test-directory }}" + test-suite: "ica-gov-chain-a" diff --git a/.github/workflows/e2e-fork.yml b/.github/workflows/e2e-fork.yml index d3717d2c35a..1f3f691c9ae 100644 --- a/.github/workflows/e2e-fork.yml +++ b/.github/workflows/e2e-fork.yml @@ -5,7 +5,9 @@ on: branches: - main paths-ignore: - - docs/** + - "docs/**" + - "**.md" + - "LICENSE" jobs: # dynamically build a matrix of test/test suite pairs to run @@ -18,14 +20,16 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - id: set-matrix - run: echo "::set-output name=matrix::$(go run cmd/build_test_matrix/main.go)" + run: echo "matrix=$(go run cmd/build_test_matrix/main.go)" >> $GITHUB_OUTPUT + env: + TEST_EXCLUSIONS: "TestInterTxTestSuite,TestIncentivizedInterTxTestSuite,TestUpgradeTestSuite" e2e: env: - SIMD_TAG: latest - SIMD_IMAGE: ibc-go-simd-e2e + CHAIN_A_TAG: latest + CHAIN_IMAGE: ibc-go-simd if: ${{ github.event.pull_request.head.repo.fork || github.actor == 'dependabot[bot]' || github.event_name == 'workflow_dispatch' }} needs: - build-test-matrix @@ -36,15 +40,12 @@ jobs: steps: - uses: actions/checkout@v3 - name: Docker Build - run: docker build . -t "${SIMD_IMAGE}:${SIMD_TAG}" + run: docker build . -t "${CHAIN_IMAGE}:${CHAIN_A_TAG}" --build-arg IBC_GO_VERSION=latest - name: Setup Go uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Run e2e Test - env: - # see images here https://github.com/cosmos/relayer/pkgs/container/relayer/versions - RLY_TAG: "v2.0.0-rc2" run: | cd e2e - make e2e-test suite=${{ matrix.suite }} test=${{ matrix.test }} + make e2e-test entrypoint=${{ matrix.entrypoint }} test=${{ matrix.test }} diff --git a/.github/workflows/e2e-manual-icad.yaml b/.github/workflows/e2e-manual-icad.yaml new file mode 100644 index 00000000000..4e01772ef75 --- /dev/null +++ b/.github/workflows/e2e-manual-icad.yaml @@ -0,0 +1,67 @@ +name: Manual E2E (Icad) +on: + # when https://github.com/community/community/discussions/11795 is resolved + # we will be able to dynamically build up the list of valid inputs. + # for now this needs to be manual. + workflow_dispatch: + inputs: + test-entry-point: + description: 'Test entry point' + required: true + type: choice + options: + - TestInterTxTestSuite + - TestIncentivizedInterTxTestSuite + - TestUpgradeTestSuite + chain-image: + description: 'The image to use for chain A' + required: true + type: string + default: "ghcr.io/cosmos/ibc-go-icad" + chain-a-tag: + description: 'The tag to use for chain A' + required: true + type: choice + default: master + options: + - master + - v0.4.3 + - v0.3.6 + - v0.2.6 + - v0.1.7 + chain-b-tag: + default: master + description: 'The tag to use for chain B' + required: true + type: choice + options: + - master + - v0.4.3 + - v0.3.6 + - v0.2.6 + - v0.1.7 + relayer-type: + default: rly + description: 'The relayer to use' + required: true + type: choice + options: + - rly + - hermes + relayer-tag: + description: 'The tag to use for the relayer' + required: true + default: "v2.1.2" + type: string + + +jobs: + e2e-manual: + uses: ./.github/workflows/e2e-test-workflow-call.yml + with: + chain-image: "${{ github.event.inputs.chain-image }}" + chain-a-tag: "${{ github.event.inputs.chain-a-tag }}" + chain-b-tag: "${{ github.event.inputs.chain-b-tag }}" + relayer-tag: "${{ github.event.inputs.relayer-tag }}" + test-entry-point: "${{ github.event.inputs.test-entry-point }}" + chain-binary: "icad" diff --git a/.github/workflows/e2e-manual-simd.yaml b/.github/workflows/e2e-manual-simd.yaml new file mode 100644 index 00000000000..3aea4fe4f6f --- /dev/null +++ b/.github/workflows/e2e-manual-simd.yaml @@ -0,0 +1,92 @@ +name: Manual E2E (Simd) +on: + # when https://github.com/community/community/discussions/11795 is resolved + # we will be able to dynamically build up the list of valid inputs. + # for now this needs to be manual. + workflow_dispatch: + inputs: + test-entry-point: + description: 'Test entry point' + required: true + type: choice + options: + - TestTransferTestSuite + - TestIncentivizedTransferTestSuite + - TestConnectionTestSuite + - TestInterchainAccountsTestSuite + - TestInterchainAccountsGroupsTestSuite + - TestInterchainAccountsGovTestSuite + - TestIncentivizedInterchainAccountsTestSuite + - TestAuthzTransferTestSuite + chain-image: + description: 'The image to use for chain A' + required: true + type: string + default: "ghcr.io/cosmos/ibc-go-simd" + chain-binary: + description: 'Specify the chain binary to be used' + required: true + type: string + default: "simd" + chain-a-tag: + description: 'The tag to use for chain A' + required: true + type: choice + default: main + options: + - main + - v6.1.0 + - v5.2.0 + - v4.3.0 + - v4.2.0 + - v4.1.1 + - v3.4.0 + - v3.3.1 + chain-a-tag-override: + description: 'Specify an arbitrary tag for chain A' + required: false + type: string + chain-b-tag: + default: v6.0.0 + description: 'The tag to use for chain B' + required: true + type: choice + options: + - main + - v6.1.0 + - v5.2.0 + - v4.3.0 + - v4.2.0 + - v4.1.1 + - v3.4.0 + - v3.3.1 + chain-b-tag-override: + description: 'Specify an arbitrary tag for chain B' + required: false + type: string + relayer-type: + default: rly + description: 'The relayer to use' + required: true + type: choice + options: + - rly + - hermes + relayer-tag: + description: 'The tag to use for the relayer' + required: true + default: "v2.1.2" + type: string + + +jobs: + e2e-manual: + uses: ./.github/workflows/e2e-test-workflow-call.yml + with: + chain-image: "${{ github.event.inputs.chain-image }}" + chain-a-tag: "${{ github.event.inputs.chain-a-tag-override || github.event.inputs.chain-a-tag }}" + chain-b-tag: "${{ github.event.inputs.chain-b-tag-override || github.event.inputs.chain-b-tag }}" + relayer-tag: "${{ github.event.inputs.relayer-tag }}" + relayer-type: "${{ github.event.inputs.relayer-type }}" + test-entry-point: "${{ github.event.inputs.test-entry-point }}" + chain-binary: "${{ github.event.inputs.chain-binary }}" diff --git a/.github/workflows/e2e-test-workflow-call.yml b/.github/workflows/e2e-test-workflow-call.yml new file mode 100644 index 00000000000..3ed7f572c11 --- /dev/null +++ b/.github/workflows/e2e-test-workflow-call.yml @@ -0,0 +1,165 @@ +on: + workflow_call: + inputs: + test-entry-point: + description: "Test entry point" + required: false + type: string + default: "" # empty string means run all tests + test: + description: "test name to run as standalone" + required: false + type: string + default: "" + test-exclusions: + description: "Comma separated list of tests to skip" + required: false + type: string + default: "" # empty string means don't skip any test. + chain-image: + description: "The image to use for chains" + required: true + type: string + default: "ghcr.io/cosmos/ibc-go-simd" + chain-a-tag: + description: "The tag to use for chain A" + required: true + type: string + default: main + chain-b-tag: + default: v4.0.0 + description: "The tag to use for chain B" + required: true + type: string + chain-binary: + default: "simd" + description: "The chain binary" + required: false + type: string + chain-upgrade-tag: + default: "" + description: "The image tag that the chain will be upgraded to" + required: false + type: string + upgrade-plan-name: + default: "" + description: "The upgrade plan name" + required: false + type: string + relayer-type: + description: "The type of relayer to use" + required: false + default: "rly" + type: string + relayer-tag: + description: "The tag to use for the relayer" + required: false + default: "" # the tests themselves will choose a sensible default when unset. + type: string + build-and-push-docker-image: + description: "Flag to specify if the docker image should be built and pushed beforehand" + required: false + type: boolean + default: false + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ibc-go-simd + +jobs: + test-details: + runs-on: ubuntu-latest + steps: + - name: Display Inputs + run: | + echo "Chain Image: ${{ inputs.chain-image }}" + echo "Chain A Tag: ${{ inputs.chain-a-tag }}" + echo "Chain B Tag: ${{ inputs.chain-b-tag }}" + echo "Chain Upgrade Tag: ${{ inputs.chain-upgrade-tag }}" + echo "Upgrade Plan Name: ${{ inputs.upgrade-plan-name }}" + echo "Relayer Type: ${{ inputs.relayer-type }}" + echo "Relayer Tag: ${{ inputs.relayer-tag }}" + echo "Test Entry Point: ${{ inputs.test-entry-point }}" + echo "Test: ${{ inputs.test }}" + echo "Github Ref Name: ${{ github.ref_name }}" + + # we skip individual steps rather than the full job as e2e-tests will not run if this task + # is skipped. But will run if every individual task is skipped. There is no current way of conditionally needing + # a job. + docker-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + if: ${{ inputs.build-and-push-docker-image }} + - name: Log in to the Container registry + if: ${{ inputs.build-and-push-docker-image }} + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + if: ${{ inputs.build-and-push-docker-image }} + id: meta + uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 + with: + images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + if: ${{ inputs.build-and-push-docker-image }} + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + build-args: | + IBC_GO_VERSION=${{ github.ref_name }} + + # dynamically build a matrix of test/test suite pairs to run + build-test-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v3 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v3 + with: + go-version: 1.19 + - id: set-matrix + run: echo "matrix=$(go run cmd/build_test_matrix/main.go)" >> $GITHUB_OUTPUT + env: + TEST_ENTRYPOINT: "${{ inputs.test-entry-point }}" + TEST_EXCLUSIONS: "${{ inputs.test-exclusions }}" + TEST_NAME: "${{ inputs.test }}" + + e2e-tests: + runs-on: ubuntu-latest + needs: + - build-test-matrix + - docker-build + env: + CHAIN_IMAGE: "${{ inputs.chain-image }}" + CHAIN_A_TAG: "${{ inputs.chain-a-tag }}" + CHAIN_B_TAG: "${{ inputs.chain-b-tag }}" + RELAYER_TAG: "${{ inputs.relayer-tag }}" + RELAYER_TYPE: "${{ inputs.relayer-type }}" + CHAIN_BINARY: "${{ inputs.chain-binary }}" + CHAIN_UPGRADE_TAG: "${{ inputs.chain-upgrade-tag }}" + CHAIN_UPGRADE_PLAN: "${{ inputs.upgrade-plan-name }}" + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.build-test-matrix.outputs.matrix) }} + steps: + - uses: actions/checkout@v3 + with: + repository: cosmos/ibc-go + - uses: actions/setup-go@v3 + with: + go-version: 1.19 + - name: Run e2e Test + run: | + cd e2e + make e2e-test entrypoint=${{ matrix.entrypoint }} test=${{ matrix.test }} diff --git a/.github/workflows/e2e-upgrade.yaml b/.github/workflows/e2e-upgrade.yaml new file mode 100644 index 00000000000..b596f22a9ce --- /dev/null +++ b/.github/workflows/e2e-upgrade.yaml @@ -0,0 +1,43 @@ +name: Tests / E2E Upgrade +on: + workflow_dispatch: + + schedule: + - cron: '0 0 * * *' + +jobs: + upgrade-v5: + uses: cosmos/ibc-go/.github/workflows/e2e-test-workflow-call.yml@main + with: + chain-image: ghcr.io/cosmos/ibc-go-simd + chain-binary: simd + chain-a-tag: v4.3.0 + chain-b-tag: v4.3.0 + chain-upgrade-tag: v5.1.0 + upgrade-plan-name: "normal upgrade" + test-entry-point: "TestUpgradeTestSuite" + test: "TestIBCChainUpgrade" + + upgrade-v6: + uses: cosmos/ibc-go/.github/workflows/e2e-test-workflow-call.yml@main + with: + chain-image: ghcr.io/cosmos/ibc-go-icad + chain-binary: icad + chain-a-tag: v0.3.5 + chain-b-tag: v0.3.5 + chain-upgrade-tag: v0.4.1 + upgrade-plan-name: "ibc-go/v6" + test-entry-point: "TestUpgradeTestSuite" + test: "TestV5ToV6ChainUpgrade" + + upgrade-v7: + uses: cosmos/ibc-go/.github/workflows/e2e-test-workflow-call.yml@main + with: + chain-image: ghcr.io/cosmos/ibc-go-simd + chain-binary: simd + chain-a-tag: v6.1.0 + chain-b-tag: v6.1.0 + chain-upgrade-tag: v7.0.0-rc0 # TODO: needs v7.0.0-rc1 when cut + upgrade-plan-name: "v7" + test-entry-point: "TestUpgradeTestSuite" + test: "TestV6ToV7ChainUpgrade" diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index ae4d29e7b51..9fe4b02cefd 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -2,104 +2,69 @@ name: Tests / E2E on: workflow_dispatch: pull_request: + paths-ignore: + - "docs/**" + - "**.md" + - "LICENSE" push: branches: - main paths-ignore: - - docs/** - -env: - REGISTRY: ghcr.io - IMAGE_NAME: ibc-go-simd-e2e + - "docs/**" + - "**.md" + - "LICENSE" jobs: - docker-build: - if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Log in to the Container registry - uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@69f6fc9d46f2f8bf0d5491e4aabe0bb8c6a4678a - with: - images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }} - - - name: Build and push Docker image - uses: docker/build-push-action@1cb9d22b932e4832bb29793b7777ec860fc1cde0 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - # dynamically build a matrix of test/test suite pairs to run - build-test-matrix: - if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: 1.18 - - id: set-matrix - run: echo "::set-output name=matrix::$(go run cmd/build_test_matrix/main.go)" - - - # the tag of the image will differ if this is a PR or the branch is being merged into main. - # we store the tag as an environment variable and use it in the E2E tests to determine the tag. - determine-image-tag: - if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} - runs-on: ubuntu-latest - outputs: - simd-tag: ${{ steps.get-tag.outputs.simd-tag }} - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: 1.18 - - id: get-tag - run: | - tag=$(go run cmd/determine_simd_tag/main.go -pr "${{ github.event.pull_request.number }}" ) - echo "Using tag $tag" - echo "::set-output name=simd-tag::$tag" + determine-image-tag: + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} + runs-on: ubuntu-latest + outputs: + simd-tag: ${{ steps.get-tag.outputs.simd-tag }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.18 + - id: get-tag + run: | + if [ -z "${{ github.event.pull_request.number }}" ] + then + echo "simd-tag=main" >> $GITHUB_OUTPUT + else + tag="pr-${{ github.event.pull_request.number }}" + echo "Using tag $tag" + echo "simd-tag=$tag" >> $GITHUB_OUTPUT + fi + build-e2e: + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 1.19 + - name: Build e2e + run: | + cd e2e + test_dirs="$(ls -A tests)" + for td in $test_dirs + do + go test -c "./tests/${td}" + done - e2e: - if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} - runs-on: ubuntu-latest - needs: - - build-test-matrix - - determine-image-tag - - docker-build - env: - SIMD_TAG: ${{ needs.determine-image-tag.outputs.simd-tag }} - SIMD_IMAGE: ghcr.io/cosmos/ibc-go-simd-e2e - # see images here https://github.com/cosmos/relayer/pkgs/container/relayer/versions - RLY_TAG: "v2.0.0-rc2" - strategy: - fail-fast: false - matrix: ${{ fromJSON(needs.build-test-matrix.outputs.matrix) }} - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: 1.18 - - name: Log in to the Container registry - uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Run e2e Test - run: | - cd e2e - make e2e-test suite=${{ matrix.suite }} test=${{ matrix.test }} + e2e: + if: ${{ !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} + needs: + - determine-image-tag + - build-e2e # don't attempt any tests unless the e2e code compiles successfully. + uses: ./.github/workflows/e2e-test-workflow-call.yml + secrets: inherit + with: + build-and-push-docker-image: true + chain-image: ghcr.io/cosmos/ibc-go-simd + chain-a-tag: "${{ needs.determine-image-tag.outputs.simd-tag }}" + chain-b-tag: "${{ needs.determine-image-tag.outputs.simd-tag }}" + chain-binary: "simd" + # on regular PRs we won't run interchain account or upgrade tests. + test-exclusions: "TestInterTxTestSuite,TestIncentivizedInterTxTestSuite,TestUpgradeTestSuite" diff --git a/.github/workflows/goimports.yaml b/.github/workflows/goimports.yaml deleted file mode 100644 index b951b17aa1d..00000000000 --- a/.github/workflows/goimports.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: Goimports -on: pull_request -jobs: - goimports: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: "Go Imports" - run: .github/scripts/go-imports.sh diff --git a/.github/workflows/golangci.yml b/.github/workflows/golangci.yml new file mode 100644 index 00000000000..30d745b89e5 --- /dev/null +++ b/.github/workflows/golangci.yml @@ -0,0 +1,26 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - main + pull_request: +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + # pull-requests: read +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.19 + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3.4.0 + with: + version: latest + args: --timeout 5m diff --git a/.github/workflows/link-check.yml b/.github/workflows/link-check.yml index fdf8b184259..6f237e14b79 100644 --- a/.github/workflows/link-check.yml +++ b/.github/workflows/link-check.yml @@ -1,5 +1,5 @@ name: Check Markdown links -on: [push, pull_request] +on: pull_request jobs: markdown-link-check: runs-on: ubuntu-latest @@ -7,4 +7,4 @@ jobs: - uses: actions/checkout@v3 - uses: gaurav-nelson/github-action-markdown-link-check@v1 with: - config-file: '.github/workflows/link-check-config.json' \ No newline at end of file + config-file: '.github/workflows/link-check-config.json' diff --git a/.github/workflows/proto-registry.yml b/.github/workflows/proto-registry.yml new file mode 100644 index 00000000000..dd9e685af42 --- /dev/null +++ b/.github/workflows/proto-registry.yml @@ -0,0 +1,20 @@ +name: Buf-Push +# Protobuf runs buf (https://buf.build/) push updated proto files to https://buf.build/cosmos/ibc +# This workflow is only run when a .proto file has been changed +on: + push: + branches: + - main + paths: + - "proto/**" + +jobs: + push: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: bufbuild/buf-setup-action@v1.14.0 + - uses: bufbuild/buf-push-action@v1 + with: + input: "proto" + buf_token: ${{ secrets.BUF_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 06b11e26d46..f775032c128 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,10 +21,10 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: '1.18' + go-version: '1.19' - name: Release - uses: goreleaser/goreleaser-action@v3 + uses: goreleaser/goreleaser-action@v4 if: startsWith(github.ref, 'refs/tags/') with: version: latest @@ -32,23 +32,30 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Log in to the Container registry - uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + publish-docker-image: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@69f6fc9d46f2f8bf0d5491e4aabe0bb8c6a4678a - with: - images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }} + - name: Log in to the Container registry + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker image - uses: docker/build-push-action@1cb9d22b932e4832bb29793b7777ec860fc1cde0 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 + with: + images: ${{ env.REGISTRY }}/cosmos/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + build-args: | + IBC_GO_VERSION=${{ github.ref_name }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 09add80b02b..16f7fb5a421 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Display go version run: go version - name: install tparse @@ -41,23 +41,31 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 - - uses: technote-space/get-diff-action@v6.1.0 + go-version: 1.19 + - uses: technote-space/get-diff-action@v6.1.2 id: git_diff with: PATTERNS: | **/**.go go.mod go.sum - - name: Build + - name: Build ibc-go run: GOARCH=${{ matrix.go-arch }} LEDGER_ENABLED=false make build + - name: Build e2e + run: | + cd e2e + test_dirs="$(ls -A tests)" + for td in $test_dirs + do + GOARCH=${{ matrix.go-arch }} go test -c "./tests/${td}" + done split-test-files: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Create a file with all the pkgs - run: go list ./... > pkgs.txt + run: go list ./... | grep -v e2e > pkgs.txt - name: Split pkgs into 4 files run: split -d -n l/4 pkgs.txt pkgs.txt.part. # cache multiple @@ -89,8 +97,8 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: 1.18 - - uses: technote-space/get-diff-action@v6.1.0 + go-version: 1.19 + - uses: technote-space/get-diff-action@v6.1.2 with: PATTERNS: | **/**.go @@ -102,7 +110,7 @@ jobs: if: env.GIT_DIFF - name: test & coverage report creation run: | - cat pkgs.txt.part.${{ matrix.part }} | xargs go test $(go list ./... | grep -v e2e) -race -mod=readonly -timeout 30m -coverprofile=${{ matrix.part }}profile.out -covermode=atomic -tags='ledger test_ledger_mock' + cat pkgs.txt.part.${{ matrix.part }} | xargs go test -mod=readonly -timeout 30m -coverprofile=${{ matrix.part }}profile.out -covermode=atomic -tags='ledger test_ledger_mock' if: env.GIT_DIFF - uses: actions/upload-artifact@v3 with: @@ -114,7 +122,7 @@ jobs: needs: tests steps: - uses: actions/checkout@v3 - - uses: technote-space/get-diff-action@v6.1.0 + - uses: technote-space/get-diff-action@v6.1.2 with: PATTERNS: | **/**.go diff --git a/.gitignore b/.gitignore index e821f35d7e7..1844a2347f6 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,6 @@ dependency-graph.png *.history +# Go +go.work +go.work.sum \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 34738ccf7e6..76204d5471c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,53 +1,40 @@ run: - tests: false -# # timeout for analysis, e.g. 30s, 5m, default is 1m -# timeout: 5m + tests: true + # # timeout for analysis, e.g. 30s, 5m, default is 1m + timeout: 5m linters: disable-all: true enable: - - bodyclose - - deadcode - depguard - dogsled - # - errcheck + - exportloopref + - errcheck - goconst - gocritic - - gofmt - - goimports - - golint + - gofumpt - gosec - gosimple - govet - ineffassign - - interfacer - - maligned - misspell - nakedret - - prealloc - - scopelint - staticcheck - - structcheck - stylecheck + - revive - typecheck - unconvert - unused - - unparam - misspell - # - wsl - - nolintlint issues: exclude-rules: + - text: "SA1019:" + linters: + - staticcheck - text: "Use of weak random number generator" linters: - gosec - - text: "comment on exported var" - linters: - - golint - - text: "don't use an underscore in package name" - linters: - - golint - text: "ST1003:" linters: - stylecheck diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 00000000000..e91db0f891d --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,10 @@ +{ + "default": true, + "MD013": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md013---line-length + "MD024": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md024---multiple-headings-with-the-same-content + "MD025": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md025---multiple-top-level-headings-in-the-same-document + "MD029": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix + "MD033": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md033---inline-html + "MD036": false, // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md036---emphasis-used-instead-of-a-heading + "MD041": false // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md041---first-line-in-a-file-should-be-a-top-level-heading +} \ No newline at end of file diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 00000000000..ad7b2bba0be --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,3 @@ +vendor +e2e/vendor +docs/node_modules diff --git a/CHANGELOG.md b/CHANGELOG.md index 41c31d738fa..8009b66362c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ Types of changes (Stanzas): "Bug Fixes" for any bug fixes. "Client Breaking" for breaking CLI commands and REST routes used by end-users. "API Breaking" for breaking exported APIs used by developers building on SDK. -"State Machine Breaking" for any changes that result in a different AppState given same genesisState and txList. +"State Machine Breaking" for any changes that result in a different AppState given the same genesisState and txList. Ref: https://keepachangelog.com/en/1.0.0/ --> @@ -38,11 +38,263 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Dependencies -* [\#1615](https://github.com/cosmos/ibc-go/pull/1615) Bump SDK version to v0.45.6 +* [\#2999](https://github.com/cosmos/ibc-go/pull/2999) Bump Cosmos SDK to v0.46.7 and Tendermint to v0.34.24. + +### API Breaking + +* (core) [\#2897](https://github.com/cosmos/ibc-go/pull/2897) Remove legacy migrations required for upgrading from Stargate release line to ibc-go >= v1.x.x. +* (core/02-client) [\#2856](https://github.com/cosmos/ibc-go/pull/2856) Rename `IterateClients` to `IterateClientStates`. The function now takes a prefix argument which may be used for prefix iteration over the client store. +* (light-clients/tendermint)[\#1768](https://github.com/cosmos/ibc-go/pull/1768) Removed `AllowUpdateAfterExpiry`, `AllowUpdateAfterMisbehaviour` booleans as they are deprecated (see ADR026) +* (06-solomachine) [\#1679](https://github.com/cosmos/ibc-go/pull/1679) Remove `types` sub-package from `06-solomachine` lightclient directory. +* (07-tendermint) [\#1677](https://github.com/cosmos/ibc-go/pull/1677) Remove `types` sub-package from `07-tendermint` lightclient directory. +* (06-solomachine) [\#1687](https://github.com/cosmos/ibc-go/pull/1687) Bump `06-solomachine` protobuf version from `v2` to `v3`. +* (06-solomachine) [\#1687](https://github.com/cosmos/ibc-go/pull/1687) Removed `DataType` enum and associated message types from `06-solomachine`. `DataType` has been removed from `SignBytes` and `SignatureAndData` in favour of `path`. +* (02-client) [\#598](https://github.com/cosmos/ibc-go/pull/598) The client state and consensus state return value has been removed from `VerifyUpgradeAndUpdateState`. Light client implementations must update the client state and consensus state after verifying a valid client upgrade. +* (06-solomachine) [\#1100](https://github.com/cosmos/ibc-go/pull/1100) Remove `GetClientID` function from 06-solomachine `Misbehaviour` type. +* (06-solomachine) [\#1100](https://github.com/cosmos/ibc-go/pull/1100) Deprecate `ClientId` field in 06-solomachine `Misbehaviour` type. +* (07-tendermint) [\#1097](https://github.com/cosmos/ibc-go/pull/1097) Remove `GetClientID` function from 07-tendermint `Misbehaviour` type. +* (07-tendermint) [\#1097](https://github.com/cosmos/ibc-go/pull/1097) Deprecate `ClientId` field in 07-tendermint `Misbehaviour` type. +* (modules/core/exported) [\#1107](https://github.com/cosmos/ibc-go/pull/1107) Merging the `Header` and `Misbehaviour` interfaces into a single `ClientMessage` type. +* (06-solomachine)[\#1906](https://github.com/cosmos/ibc-go/pull/1906/files) Removed `AllowUpdateAfterProposal` boolean as it has been deprecated (see 01_concepts of the solo machine spec for more details). +* (07-tendermint) [\#1896](https://github.com/cosmos/ibc-go/pull/1896) Remove error return from `IterateConsensusStateAscending` in `07-tendermint`. +* (apps/27-interchain-accounts) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Interchain accounts host and controller Keepers now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (06-solomachine) [\#2761](https://github.com/cosmos/ibc-go/pull/2761) Removed deprecated `ClientId` field from `Misbehaviour` and `allow_update_after_proposal` field from `ClientState`. +* (apps) [\#3154](https://github.com/cosmos/ibc-go/pull/3154) Remove unused `ProposalContents` function. +* (apps) [#3149](https://github.com/cosmos/ibc-go/pull/3149) Remove legacy interface function `RandomizedParams`, which is no longer used. + +### State Machine Breaking + +* (06-solomachine) [\#2744](https://github.com/cosmos/ibc-go/pull/2744) `Misbehaviour.ValidateBasic()` now only enforces that signature data does not match when the signature paths are different. +* (06-solomachine) [\#2748](https://github.com/cosmos/ibc-go/pull/2748) Adding sentinel value for header path in 06-solomachine. +* (apps/29-fee) [\#2942](https://github.com/cosmos/ibc-go/pull/2942) Check `x/bank` send enabled before escrowing fees. + +### Improvements + +* (tests) [\#3138](https://github.com/cosmos/ibc-go/pull/3138) Support benchmarks and fuzz tests through `testing.TB`. +* (core) [\#3082](https://github.com/cosmos/ibc-go/pull/3082) Add `HasConnection` and `HasChannel` methods. +* (tests) [\#2926](https://github.com/cosmos/ibc-go/pull/2926) Lint tests +* (apps/transfer) [\#2643](https://github.com/cosmos/ibc-go/pull/2643) Add amount, denom, and memo to transfer event emission. +* (core) [\#2746](https://github.com/cosmos/ibc-go/pull/2746) Allow proof height to be zero for all core IBC `sdk.Msg` types that contain proofs. +* (light-clients/06-solomachine) [\#2746](https://github.com/cosmos/ibc-go/pull/2746) Discard proofHeight for solo machines and use the solo machine sequence instead. +* (modules/light-clients/07-tendermint) [\#1713](https://github.com/cosmos/ibc-go/pull/1713) Allow client upgrade proposals to update `TrustingPeriod`. See ADR-026 for context. +* (modules/core/02-client) [\#1188](https://github.com/cosmos/ibc-go/pull/1188/files) Routing `MsgSubmitMisbehaviour` to `UpdateClient` keeper function. Deprecating `SubmitMisbehaviour` endpoint. +* (modules/core/02-client) [\#1208](https://github.com/cosmos/ibc-go/pull/1208) Replace `CheckHeaderAndUpdateState` usage in 02-client with calls to `VerifyClientMessage`, `CheckForMisbehaviour`, `UpdateStateOnMisbehaviour` and `UpdateState`. +* (modules/light-clients/09-localhost) [\#1187](https://github.com/cosmos/ibc-go/pull/1187/) Removing localhost light client implementation as it is not functional. An upgrade handler is provided in `modules/migrations/v5` to prune `09-localhost` clients and consensus states from the store. +* [\#1186](https://github.com/cosmos/ibc-go/pull/1186/files) Removing `GetRoot` function from ConsensusState interface in `02-client`. `GetRoot` is unused by core IBC. +* (modules/core/02-client) [\#1196](https://github.com/cosmos/ibc-go/pull/1196) Adding VerifyClientMessage to ClientState interface. +* (modules/core/02-client) [\#1198](https://github.com/cosmos/ibc-go/pull/1198) Adding UpdateStateOnMisbehaviour to ClientState interface. +* (modules/core/02-client) [\#1170](https://github.com/cosmos/ibc-go/pull/1170) Updating `ClientUpdateProposal` to set client state in lightclient implementations `CheckSubstituteAndUpdateState` methods. +* (modules/core/02-client) [\#1197](https://github.com/cosmos/ibc-go/pull/1197) Adding `CheckForMisbehaviour` to `ClientState` interface. +* (modules/core/02-client) [\#1195](https://github.com/cosmos/ibc-go/pull/1210) Removing `CheckHeaderAndUpdateState` from `ClientState` interface & associated light client implementations. +* (modules/core/02-client) [\#1189](https://github.com/cosmos/ibc-go/pull/1212) Removing `CheckMisbehaviourAndUpdateState` from `ClientState` interface & associated light client implementations. +* (modules/core/exported) [\#1206](https://github.com/cosmos/ibc-go/pull/1206) Adding new method `UpdateState` to `ClientState` interface. +* (modules/core/02-client) [\#1741](https://github.com/cosmos/ibc-go/pull/1741) Emitting a new `upgrade_chain` event upon setting upgrade consensus state. +* (client) [\#724](https://github.com/cosmos/ibc-go/pull/724) `IsRevisionFormat` and `IsClientIDFormat` have been updated to disallow newlines before the dash used to separate the chainID and revision number, and the client type and client sequence. +* (02-client/cli) [\#897](https://github.com/cosmos/ibc-go/pull/897) Remove `GetClientID()` from `Misbehaviour` interface. Submit client misbehaviour cli command requires an explicit client id now. +* (06-solomachine) [\#1972](https://github.com/cosmos/ibc-go/pull/1972) Solo machine implementation of `ZeroCustomFields` fn now panics as the fn is only used for upgrades which solo machine does not support. +* (light-clients/06-solomachine) Moving `verifyMisbehaviour` function from update.go to misbehaviour_handle.go. +* [\#2434](https://github.com/cosmos/ibc-go/pull/2478) Removed all `TypeMsg` constants +* (modules/core/exported) [#1689](https://github.com/cosmos/ibc-go/pull/2539) Removing `GetVersions` from `ConnectionI` interface. +* (core/02-connection) [#2419](https://github.com/cosmos/ibc-go/pull/2419) Add optional proof data to proto definitions of `MsgConnectionOpenTry` and `MsgConnectionOpenAck` for host state machines that are unable to introspect their own consensus state. +* (modules/light-clients/07-tendermint) [#2007](https://github.com/cosmos/ibc-go/pull/3046) Moved non-verification misbehaviour checks to `CheckForMisbehaviour` + +### Features + +* (core/02-client) [\#2824](https://github.com/cosmos/ibc-go/pull/2824) Add genesis migrations for v6 to v7. The migration migrates the solo machine client state definition, removes all solo machine consensus states and removes the localhost client. +* (core/24-host) [\#2856](https://github.com/cosmos/ibc-go/pull/2856) Add `PrefixedClientStorePath` and `PrefixedClientStoreKey` functions to 24-host +* (core/02-client) [\#2819](https://github.com/cosmos/ibc-go/pull/2819) Add automatic in-place store migrations to remove the localhost client and migrate existing solo machine definitions. +* (light-clients/06-solomachine) [\#2826](https://github.com/cosmos/ibc-go/pull/2826) Add `AppModuleBasic` for the 06-solomachine client and remove solo machine type registration from core IBC. Chains must register the `AppModuleBasic` of light clients. +* (light-clients/07-tendermint) [\#2825](https://github.com/cosmos/ibc-go/pull/2825) Add `AppModuleBasic` for the 07-tendermint client and remove tendermint type registration from core IBC. Chains must register the `AppModuleBasic` of light clients. +* (light-clients/07-tendermint) [\#2800](https://github.com/cosmos/ibc-go/pull/2800) Add optional in-place store migration function to prune all expired tendermint consensus states. +* (core/24-host) [\#2820](https://github.com/cosmos/ibc-go/pull/2820) Add `MustParseClientStatePath` which parses the clientID from a client state key path. +* (testing/simapp) [\#2842](https://github.com/cosmos/ibc-go/pull/2842) Adding the new upgrade handler for v6 -> v7 to simapp which prunes expired Tendermint consensus states. +* (testing) [\#2829](https://github.com/cosmos/ibc-go/pull/2829) Add `AssertEvents` which asserts events against expected event map. + +### Bug Fixes + +* (light-clients/solomachine) [#1839](https://github.com/cosmos/ibc-go/issues/1839) Fixed usage of the new diversifier in validation of changing diversifiers for the solo machine. The current diversifier must sign over the new diversifier. +* (light-clients/07-tendermint) [\#1674](https://github.com/cosmos/ibc-go/pull/1674) Submitted ClientState is zeroed out before checking the proof in order to prevent the proposal from containing information governance is not actually voting on. +* (modules/core/02-client)[\#1676](https://github.com/cosmos/ibc-go/pull/1676) ClientState must be zeroed out for `UpgradeProposals` to pass validation. This prevents a proposal containing information governance is not actually voting on. +* (core/02-client) [\#2510](https://github.com/cosmos/ibc-go/pull/2510) Fix client ID validation regex to conform closer to spec. + +## [v6.0.0](https://github.com/cosmos/ibc-go/releases/tag/v4.0.0) - 2022-12-09 + +### Dependencies + +* [\#2868](https://github.com/cosmos/ibc-go/pull/2868) Bump ICS 23 to v0.9.0. +* [\#2458](https://github.com/cosmos/ibc-go/pull/2458) Bump Cosmos SDK to v0.46.2 +* [\#2784](https://github.com/cosmos/ibc-go/pull/2784) Bump Cosmos SDK to v0.46.6 and Tendermint to v0.34.23. + +### API Breaking + +* (apps/27-interchain-accounts) [\#2607](https://github.com/cosmos/ibc-go/pull/2607) `SerializeCosmosTx` now takes in a `[]proto.Message` instead of `[]sdk.Msg`. +* (apps/transfer) [\#2446](https://github.com/cosmos/ibc-go/pull/2446) Remove `SendTransfer` function in favor of a private `sendTransfer` function. All IBC transfers must be initiated with `MsgTransfer`. +* (apps/29-fee) [\#2395](https://github.com/cosmos/ibc-go/pull/2395) Remove param space from ics29 NewKeeper function. The field was unused. +* (apps/27-interchain-accounts) [\#2133](https://github.com/cosmos/ibc-go/pull/2133) Generates genesis protos in a separate directory to avoid circular import errors. The protobuf package name has changed for the genesis types. +* (apps/27-interchain-accounts) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Interchain accounts host and controller Keepers now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (transfer) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Transfer Keeper now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (05-port) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Port Keeper now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (04-channel) [\#2638](https://github.com/cosmos/ibc-go/pull/2638) Channel Keeper now expects a keeper which fulfills the expected `exported.ScopedKeeper` interface for the capability keeper. +* (core/04-channel)[\#1703](https://github.com/cosmos/ibc-go/pull/1703) Update `SendPacket` API to take in necessary arguments and construct rest of packet rather than taking in entire packet. The generated packet sequence is returned by the `SendPacket` function. +* (modules/apps/27-interchain-accounts) [\#2433](https://github.com/cosmos/ibc-go/pull/2450) Renamed icatypes.PortPrefix to icatypes.ControllerPortPrefix & icatypes.PortID to icatypes.HostPortID +* (testing) [\#2567](https://github.com/cosmos/ibc-go/pull/2567) Modify `SendPacket` API of `Endpoint` to match the API of `SendPacket` in 04-channel. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (27-interchain-accounts) [\#2580](https://github.com/cosmos/ibc-go/issues/2580) Removing port prefix requirement from the ICA host channel handshake +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. +* (light-clients/07-tendermint) [\#2555](https://github.com/cosmos/ibc-go/pull/2555) Forbid negative values for `TrustingPeriod`, `UnbondingPeriod` and `MaxClockDrift` (as specified in ICS-07). + +### Improvements + +* (apps/27-interchain-accounts) [\#2134](https://github.com/cosmos/ibc-go/pull/2134) Adding upgrade handler to ICS27 `controller` submodule for migration of channel capabilities. This upgrade handler migrates ownership of channel capabilities from the underlying application to the ICS27 `controller` submodule. +* (apps/27-interchain-accounts) [\#2102](https://github.com/cosmos/ibc-go/pull/2102) ICS27 controller middleware now supports a nil underlying application. This allows chains to make use of interchain accounts with existing auth mechanisms such as x/group and x/gov. +* (apps/27-interchain-accounts) [\#2157](https://github.com/cosmos/ibc-go/pull/2157) Adding `IsMiddlewareEnabled` functionality to enforce calls to ICS27 msg server to *not* route to the underlying application. +* (apps/27-interchain-accounts) [\#2146](https://github.com/cosmos/ibc-go/pull/2146) ICS27 controller now claims the channel capability passed via ibc core, and passes `nil` to the underlying app callback. The channel capability arg in `SendTx` is now ignored and looked up internally. +* (apps/27-interchain-accounts) [\#2177](https://github.com/cosmos/ibc-go/pull/2177) Adding `IsMiddlewareEnabled` flag to interchain accounts `ActiveChannel` genesis type. +* (apps/27-interchain-accounts) [\#2140](https://github.com/cosmos/ibc-go/pull/2140) Adding migration handler to ICS27 `controller` submodule to assert ownership of channel capabilities and set middleware enabled flag for existing channels. The ICS27 module consensus version has been bumped from 1 to 2. +* (core/04-channel) [\#2304](https://github.com/cosmos/ibc-go/pull/2304) Adding `GetAllChannelsWithPortPrefix` function which filters channels based on a provided port prefix. +* (apps/27-interchain-accounts) [\#2248](https://github.com/cosmos/ibc-go/pull/2248) Adding call to underlying app in `OnChanCloseConfirm` callback of the controller submodule and adding relevant unit tests. +* (apps/27-interchain-accounts) [\#2251](https://github.com/cosmos/ibc-go/pull/2251) Adding `msgServer` struct to controller submodule that embeds the `Keeper` struct. +* (apps/27-interchain-accounts) [\#2290](https://github.com/cosmos/ibc-go/pull/2290) Changed `DefaultParams` function in `host` submodule to allow all messages by default. Defined a constant named `AllowAllHostMsgs` for `host` module to keep wildcard "*" string which allows all messages. +* (apps/27-interchain-accounts) [\#2297](https://github.com/cosmos/ibc-go/pull/2297) Adding cli command to generate ICS27 packet data. +* (modules/core/keeper) [\#1728](https://github.com/cosmos/ibc-go/pull/2399) Updated channel callback errors to include portID & channelID for better identification of errors. +* (testing) [\#2657](https://github.com/cosmos/ibc-go/pull/2657) Carry `ProposerAddress` through commited blocks. Allow `DefaultGenTxGas` to be modified. +* (core/03-connection) [\#2745](https://github.com/cosmos/ibc-go/pull/2745) Adding `ConnectionParams` grpc query and CLI to 03-connection. +* (apps/29-fee) [\#2786](https://github.com/cosmos/ibc-go/pull/2786) Save gas by checking key existence with `KVStore`'s `Has` method. + +### Features + +* (apps/27-interchain-accounts) [\#2147](https://github.com/cosmos/ibc-go/pull/2147) Adding a `SubmitTx` gRPC endpoint for the ICS27 Controller module which allows owners of interchain accounts to submit transactions. This replaces the previously existing need for authentication modules to implement this standard functionality. +* (testing/simapp) [\#2190](https://github.com/cosmos/ibc-go/pull/2190) Adding the new `x/group` cosmos-sdk module to simapp. +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (modules/core/keeper) [\#2403](https://github.com/cosmos/ibc-go/pull/2403) Added a function in keeper to cater for blank pointers. +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. +* (modules/core/keeper) [\#2745](https://github.com/cosmos/ibc-go/pull/2745) Fix request wiring for `UpgradedConsensusState` in core query server. + +## [v5.1.0](https://github.com/cosmos/ibc-go/releases/tag/v5.1.0) - 2022-11-09 + +### Dependencies + +* [\#2647](https://github.com/cosmos/ibc-go/pull/2647) Bump Cosmos SDK to v0.46.4 and Tendermint to v0.34.22. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (27-interchain-accounts) [\#2580](https://github.com/cosmos/ibc-go/issues/2580) Removing port prefix requirement from the ICA host channel handshake +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. + +### Improvements + +* (testing) [\#2657](https://github.com/cosmos/ibc-go/pull/2657) Carry `ProposerAddress` through committed blocks. Allow `DefaultGenTxGas` to be modified. + +### Features + +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. + +## [v5.0.1](https://github.com/cosmos/ibc-go/releases/tag/v5.0.1) - 2022-10-27 + +### Dependencies + +* [\#2623](https://github.com/cosmos/ibc-go/pull/2623) Bump SDK version to v0.46.3 and Tendermint version to v0.34.22. + +## [v5.0.0](https://github.com/cosmos/ibc-go/releases/tag/v5.0.0) - 2022-09-28 + +### Dependencies + +* [\#1653](https://github.com/cosmos/ibc-go/pull/1653) Bump SDK version to v0.46 +* [\#2124](https://github.com/cosmos/ibc-go/pull/2124) Bump SDK version to v0.46.1 + +### API Breaking + +* (testing)[\#2028](https://github.com/cosmos/ibc-go/pull/2028) New interface `ibctestingtypes.StakingKeeper` added and set for the testing app `StakingKeeper` setup. +* (core/04-channel) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) `NewPacketId` has been renamed to `NewPacketID` to comply with go linting rules. +* (core/ante) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) `AnteDecorator` has been renamed to `RedundancyDecorator` to comply with go linting rules and to give more clarity to the purpose of the Decorator. +* (core/ante) [\#1820](https://github.com/cosmos/ibc-go/pull/1418) `RedundancyDecorator` has been renamed to `RedundantRelayDecorator` to make the name for explicit. +* (testing) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) `MockIBCApp` has been renamed to `IBCApp` and `MockEmptyAcknowledgement` has been renamed to `EmptyAcknowledgement` to comply with go linting rules +* (apps/27-interchain-accounts) [\#2058](https://github.com/cosmos/ibc-go/pull/2058) Added `MessageRouter` interface and replaced `*baseapp.MsgServiceRouter` with it. The controller and host keepers of apps/27-interchain-accounts have been updated to use it. +* (apps/27-interchain-accounts)[\#2302](https://github.com/cosmos/ibc-go/pull/2302) Handle unwrapping of channel version in interchain accounts channel reopening handshake flow. The `host` submodule `Keeper` now requires an `ICS4Wrapper` similarly to the `controller` submodule. + +### Improvements + +* (27-interchain-accounts) [\#1352](https://github.com/cosmos/ibc-go/issues/1352) Add support for Cosmos-SDK simulation to ics27 module. +* (linting) [\#1418](https://github.com/cosmos/ibc-go/pull/1418) Fix linting errors, resulting compatiblity with go1.18 linting style, golangci-lint 1.46.2 and the revivie linter. This caused breaking changes in core/04-channel, core/ante, and the testing library. + +### Features + +* (apps/27-interchain-accounts) [\#2193](https://github.com/cosmos/ibc-go/pull/2193) Adding `InterchainAccount` gRPC query endpont to ICS27 `controller` submodule to allow users to retrieve registered interchain account addresses. + +### Bug Fixes + +* (27-interchain-accounts) [\#2308](https://github.com/cosmos/ibc-go/pull/2308) Nil checks have been added to ensure services are not registered for nil host or controller keepers. +* (makefile) [\#1785](https://github.com/cosmos/ibc-go/pull/1785) Fetch the correct versions of protocol buffers dependencies from tendermint, cosmos-sdk, and ics23. +* (modules/core/04-channel)[\#1919](https://github.com/cosmos/ibc-go/pull/1919) Fixed formatting of sequence for packet "acknowledgement written" logs. + +## [v4.2.0](https://github.com/cosmos/ibc-go/releases/tag/v4.2.0) - 2022-11-07 + +### Dependencies + +* [\#2588](https://github.com/cosmos/ibc-go/pull/2588) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (27-interchain-accounts) [\#2580](https://github.com/cosmos/ibc-go/issues/2580) Removing port prefix requirement from the ICA host channel handshake +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. + +### Features + +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. + +## [v4.1.1](https://github.com/cosmos/ibc-go/releases/tag/v4.1.1) - 2022-10-27 + +### Dependencies + +* [\#2624](https://github.com/cosmos/ibc-go/pull/2624) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +## [v4.1.0](https://github.com/cosmos/ibc-go/releases/tag/v4.1.0) - 2022-09-20 + +### Dependencies + +* [\#2288](https://github.com/cosmos/ibc-go/pull/2288) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +### Features + +* (apps/27-interchain-accounts) [\#2193](https://github.com/cosmos/ibc-go/pull/2193) Adding `InterchainAccount` gRPC query endpont to ICS27 `controller` submodule to allow users to retrieve registered interchain account addresses. + +### Bug Fixes + +* (27-interchain-accounts) [\#2308](https://github.com/cosmos/ibc-go/pull/2308) Nil checks have been added to ensure services are not registered for nil host or controller keepers. + +## [v4.0.1](https://github.com/cosmos/ibc-go/releases/tag/v4.0.1) - 2022-09-15 + +### Dependencies + +* [\#2287](https://github.com/cosmos/ibc-go/pull/2287) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +## [v4.0.0](https://github.com/cosmos/ibc-go/releases/tag/v4.0.0) - 2022-08-12 + +### Dependencies + * [\#1627](https://github.com/cosmos/ibc-go/pull/1627) Bump Go version to 1.18 +* [\#1905](https://github.com/cosmos/ibc-go/pull/1905) Bump SDK version to v0.45.7 ### API Breaking +* (core/04-channel) [\#1792](https://github.com/cosmos/ibc-go/pull/1792) Remove `PreviousChannelID` from `NewMsgChannelOpenTry` arguments. `MsgChannelOpenTry.ValidateBasic()` returns error if the deprecated `PreviousChannelID` is not empty. +* (core/03-connection) [\#1797](https://github.com/cosmos/ibc-go/pull/1797) Remove `PreviousConnectionID` from `NewMsgConnectionOpenTry` arguments. `MsgConnectionOpenTry.ValidateBasic()` returns error if the deprecated `PreviousConnectionID` is not empty. * (modules/core/03-connection) [\#1672](https://github.com/cosmos/ibc-go/pull/1672) Remove crossing hellos from connection handshakes. The `PreviousConnectionId` in `MsgConnectionOpenTry` has been deprecated. * (modules/core/04-channel) [\#1317](https://github.com/cosmos/ibc-go/pull/1317) Remove crossing hellos from channel handshakes. The `PreviousChannelId` in `MsgChannelOpenTry` has been deprecated. * (transfer) [\#1250](https://github.com/cosmos/ibc-go/pull/1250) Deprecate `GetTransferAccount` since the `transfer` module account is never used. @@ -57,42 +309,125 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### State Machine Breaking +* (apps/transfer) [\#1907](https://github.com/cosmos/ibc-go/pull/1907) Blocked module account addresses are no longer allowed to send IBC transfers. +* (apps/27-interchain-accounts) [\#1882](https://github.com/cosmos/ibc-go/pull/1882) Explicitly check length of interchain account packet data in favour of nil check. + ### Improvements * (app/20-transfer) [\#1680](https://github.com/cosmos/ibc-go/pull/1680) Adds migration to correct any malformed trace path information of tokens with denoms that contains slashes. The transfer module consensus version has been bumped to 2. * (app/20-transfer) [\#1730](https://github.com/cosmos/ibc-go/pull/1730) parse the ics20 denomination provided via a packet using the channel identifier format specified by ibc-go. * (cleanup) [\#1335](https://github.com/cosmos/ibc-go/pull/1335/) `gofumpt -w -l .` to standardize the code layout more strictly than `go fmt ./...` -* (middleware) [\#1022](https://github.com/cosmos/ibc-go/pull/1022) Add `GetAppVersion` to the ICS4Wrapper interface. This function should be used by IBC applications to obtain their own version since the version set in the channel structure may be wrapped many times by middleware. +* (middleware) [\#1022](https://github.com/cosmos/ibc-go/pull/1022) Add `GetAppVersion` to the ICS4Wrapper interface. This function should be used by IBC applications to obtain their own version since the version set in the channel structure may be wrapped many times by middleware. * (modules/core/04-channel) [\#1232](https://github.com/cosmos/ibc-go/pull/1232) Updating params on `NewPacketId` and moving to bottom of file. * (app/29-fee) [\#1305](https://github.com/cosmos/ibc-go/pull/1305) Change version string for fee module to `ics29-1` * (app/29-fee) [\#1341](https://github.com/cosmos/ibc-go/pull/1341) Check if the fee module is locked and if the fee module is enabled before refunding all fees * (transfer) [\#1414](https://github.com/cosmos/ibc-go/pull/1414) Emitting Sender address from `fungible_token_packet` events in `OnRecvPacket` and `OnAcknowledgementPacket`. -* (testing/simapp) [\#1397](https://github.com/cosmos/ibc-go/pull/1397) Adding mock module to maccperms and adding check to ensure mock module is not a blocked account address. +* (testing/simapp) [\#1397](https://github.com/cosmos/ibc-go/pull/1397) Adding mock module to maccperms and adding check to ensure mock module is not a blocked account address. * (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. * (modules/light-clients/07-tendermint) [\#1713](https://github.com/cosmos/ibc-go/pull/1713) Allow client upgrade proposals to update `TrustingPeriod`. See ADR-026 for context. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types ### Features * [\#276](https://github.com/cosmos/ibc-go/pull/276) Adding the Fee Middleware module v1 -* (apps/29-fee) [\#1229](https://github.com/cosmos/ibc-go/pull/1229) Adding CLI commands for getting all unrelayed incentivized packets and packet by packet-id. +* (apps/29-fee) [\#1229](https://github.com/cosmos/ibc-go/pull/1229) Adding CLI commands for getting all unrelayed incentivized packets and packet by packet-id. * (apps/29-fee) [\#1224](https://github.com/cosmos/ibc-go/pull/1224) Adding Query/CounterpartyAddress and CLI to ICS29 fee middleware * (apps/29-fee) [\#1225](https://github.com/cosmos/ibc-go/pull/1225) Adding Query/FeeEnabledChannel and Query/FeeEnabledChannels with CLIs to ICS29 fee middleware. -* (modules/apps/29-fee) [\#1230](https://github.com/cosmos/ibc-go/pull/1230) Adding CLI command for getting incentivized packets for a specific channel-id. +* (modules/apps/29-fee) [\#1230](https://github.com/cosmos/ibc-go/pull/1230) Adding CLI command for getting incentivized packets for a specific channel-id. ### Bug Fixes +* (apps/29-fee) [\#1774](https://github.com/cosmos/ibc-go/pull/1774) Change non nil relayer assertion to non empty to avoid import/export issues for genesis upgrades. * (apps/29-fee) [\#1278](https://github.com/cosmos/ibc-go/pull/1278) The URI path for the query to get all incentivized packets for a specific channel did not follow the same format as the rest of queries. +* (modules/core/04-channel)[\#1919](https://github.com/cosmos/ibc-go/pull/1919) Fixed formatting of sequence for packet "acknowledgement written" logs. -## [v3.1.0](https://github.com/cosmos/ibc-go/releases/tag/v3.1.0) - 2022-04-16 +## [v3.4.0](https://github.com/cosmos/ibc-go/releases/tag/v3.4.0) - 2022-11-07 ### Dependencies -* [\#1300](https://github.com/cosmos/ibc-go/pull/1300) Bump SDK version to v0.45.4 +* [\#2589](https://github.com/cosmos/ibc-go/pull/2589) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. -### API Breaking +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (27-interchain-accounts) [\#2580](https://github.com/cosmos/ibc-go/issues/2580) Removing port prefix requirement from the ICA host channel handshake +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. + +### Features + +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. + +## [v3.3.1](https://github.com/cosmos/ibc-go/releases/tag/v3.3.1) - 2022-10-27 + +### Dependencies + +* [\#2621](https://github.com/cosmos/ibc-go/pull/2621) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +## [v3.3.0](https://github.com/cosmos/ibc-go/releases/tag/v3.3.0) - 2022-09-20 + +### Dependencies + +* [\#2286](https://github.com/cosmos/ibc-go/pull/2286) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +### Features + +* (apps/27-interchain-accounts) [\#2193](https://github.com/cosmos/ibc-go/pull/2193) Adding `InterchainAccount` gRPC query endpont to ICS27 `controller` submodule to allow users to retrieve registered interchain account addresses. + +### Bug Fixes + +* (27-interchain-accounts) [\#2308](https://github.com/cosmos/ibc-go/pull/2308) Nil checks have been added to ensure services are not registered for nil host or controller keepers. + +## [v3.2.1](https://github.com/cosmos/ibc-go/releases/tag/v3.2.1) - 2022-09-15 + +### Dependencies + +* [\#2285](https://github.com/cosmos/ibc-go/pull/2285) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +## [v3.2.0](https://github.com/cosmos/ibc-go/releases/tag/v3.2.0) - 2022-08-12 + +### Dependencies + +* [\#1627](https://github.com/cosmos/ibc-go/pull/1627) Bump Go version to 1.18 +* [\#1905](https://github.com/cosmos/ibc-go/pull/1905) Bump SDK version to v0.45.7 ### State Machine Breaking +* (apps/transfer) [\#1907](https://github.com/cosmos/ibc-go/pull/1907) Blocked module account addresses are no longer allowed to send IBC transfers. +* (apps/27-interchain-accounts) [\#1882](https://github.com/cosmos/ibc-go/pull/1882) Explicitly check length of interchain account packet data in favour of nil check. + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (modules/light-clients/07-tendermint) [\#1713](https://github.com/cosmos/ibc-go/pull/1713) Allow client upgrade proposals to update `TrustingPeriod`. See ADR-026 for context. +* (app/20-transfer) [\#1680](https://github.com/cosmos/ibc-go/pull/1680) Adds migration to correct any malformed trace path information of tokens with denoms that contains slashes. The transfer module consensus version has been bumped to 2. +* (app/20-transfer) [\#1730](https://github.com/cosmos/ibc-go/pull/1730) parse the ics20 denomination provided via a packet using the channel identifier format specified by ibc-go. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +### Bug Fixes + +* (modules/core/04-channel)[\#1919](https://github.com/cosmos/ibc-go/pull/1919) Fixed formatting of sequence for packet "acknowledgement written" logs. + +## [v3.1.1](https://github.com/cosmos/ibc-go/releases/tag/v3.1.1) - 2022-08-02 + +### Dependencies + +* [\#1525](https://github.com/cosmos/ibc-go/pull/1525) Bump SDK version to v0.45.5 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v3.1.0](https://github.com/cosmos/ibc-go/releases/tag/v3.1.0) - 2022-06-14 + +### Dependencies + +* [\#1300](https://github.com/cosmos/ibc-go/pull/1300) Bump SDK version to v0.45.4 + ### Improvements * (transfer) [\#1342](https://github.com/cosmos/ibc-go/pull/1342) `DenomTrace` grpc now takes in either an `ibc denom` or a `hash` instead of only accepting a `hash`. @@ -106,7 +441,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features * (modules/core/02-client) [\#1336](https://github.com/cosmos/ibc-go/pull/1336) Adding Query/ConsensusStateHeights gRPC for fetching the height of every consensus state associated with a client. -* (modules/apps/transfer) [\#1416](https://github.com/cosmos/ibc-go/pull/1416) Adding gRPC endpoint for getting an escrow account for a given port-id and channel-id. +* (modules/apps/transfer) [\#1416](https://github.com/cosmos/ibc-go/pull/1416) Adding gRPC endpoint for getting an escrow account for a given port-id and channel-id. * (modules/apps/27-interchain-accounts) [\#1512](https://github.com/cosmos/ibc-go/pull/1512) Allowing ICA modules to handle all message types with "*". ### Bug Fixes @@ -114,7 +449,14 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output * (apps/transfer) [\#1451](https://github.com/cosmos/ibc-go/pull/1451) Fixing the support for base denoms that contain slashes. -## [v3.0.1](https://github.com/cosmos/ibc-go/releases/tag/v3.0.1) - 2022-04-16 +## [v3.0.2](https://github.com/cosmos/ibc-go/releases/tag/v3.0.2) - 2022-08-02 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v3.0.1](https://github.com/cosmos/ibc-go/releases/tag/v3.0.1) - 2022-06-14 ### Dependencies @@ -154,7 +496,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (transfer) [\#517](https://github.com/cosmos/ibc-go/pull/517) Separates the ICS 26 callback functions from `AppModule` into a new type `IBCModule` for ICS 20 transfer. * (modules/core/02-client) [\#536](https://github.com/cosmos/ibc-go/pull/536) `GetSelfConsensusState` return type changed from bool to error. * (channel) [\#644](https://github.com/cosmos/ibc-go/pull/644) Removes `CounterpartyHops` function from the ChannelKeeper. -* (testing) [\#776](https://github.com/cosmos/ibc-go/pull/776) Adding helper fn to generate capability name for testing callbacks +* (testing) [\#776](https://github.com/cosmos/ibc-go/pull/776) Adding helper fn to generate capability name for testing callbacks * (testing) [\#892](https://github.com/cosmos/ibc-go/pull/892) IBC Mock modules store the scoped keeper and portID within the IBCMockApp. They also maintain reference to the AppModule to update the AppModule's list of IBC applications it references. Allows for the mock module to be reused as a base application in middleware stacks. * (channel) [\#882](https://github.com/cosmos/ibc-go/pull/882) The `WriteAcknowledgement` API now takes `exported.Acknowledgement` instead of a byte array * (modules/core/ante) [\#950](https://github.com/cosmos/ibc-go/pull/950) Replaces the channel keeper with the IBC keeper in the IBC `AnteDecorator` in order to execute the entire message and be able to reject redundant messages that are in the same block as the non-redundant messages. @@ -165,6 +507,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* (client) [\#888](https://github.com/cosmos/ibc-go/pull/888) Add `GetTimestampAtHeight` to `ClientState` * (interchain-accounts) [\#1037](https://github.com/cosmos/ibc-go/pull/1037) Add a function `InitModule` to the interchain accounts `AppModule`. This function should be called within the upgrade handler when adding the interchain accounts module to a chain. It should be called in place of InitGenesis (set the consensus version in the version map). * (testing) [\#942](https://github.com/cosmos/ibc-go/pull/942) `NewTestChain` will create 4 validators in validator set by default. A new constructor function `NewTestChainWithValSet` is provided for test writers who want custom control over the validator set of test chains. * (testing) [\#904](https://github.com/cosmos/ibc-go/pull/904) Add `ParsePacketFromEvents` function to the testing package. Useful when sending/relaying packets via the testing package. @@ -174,14 +517,14 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (channel) [\#692](https://github.com/cosmos/ibc-go/pull/692) Minimize channel logging by only emitting the packet sequence, source port/channel, destination port/channel upon packet receives, acknowledgements and timeouts. * [\#383](https://github.com/cosmos/ibc-go/pull/383) Adds helper functions for merging and splitting middleware versions from the underlying app version. * (modules/core/05-port) [\#288](https://github.com/cosmos/ibc-go/issues/288) Making the 05-port keeper function IsBound public. The IsBound function checks if the provided portID is already binded to a module. -* (channel) [\#644](https://github.com/cosmos/ibc-go/pull/644) Adds `GetChannelConnection` to the ChannelKeeper. This function returns the connectionID and connection state associated with a channel. -* (channel) [\647](https://github.com/cosmos/ibc-go/pull/647) Reorganizes channel handshake handling to set channel state after IBC application callbacks. -* (client) [\#724](https://github.com/cosmos/ibc-go/pull/724) `IsRevisionFormat` and `IsClientIDFormat` have been updated to disallow newlines before the dash used to separate the chainID and revision number, and the client type and client sequence. +* (client) [\#724](https://github.com/cosmos/ibc-go/pull/724) `IsRevisionFormat` and `IsClientIDFormat` have been updated to disallow newlines before the dash used to separate the chainID and revision number, and the client type and client sequence. +* (channel) [\#644](https://github.com/cosmos/ibc-go/pull/644) Adds `GetChannelConnection` to the ChannelKeeper. This function returns the connectionID and connection state associated with a channel. +* (channel) [\647](https://github.com/cosmos/ibc-go/pull/647) Reorganizes channel handshake handling to set channel state after IBC application callbacks. * (interchain-accounts) [\#1466](https://github.com/cosmos/ibc-go/pull/1466) Emit event when there is an acknowledgement during `OnRecvPacket`. ### Features -* [\#432](https://github.com/cosmos/ibc-go/pull/432) Introduce `MockIBCApp` struct to the mock module. Allows the mock module to be reused to perform custom logic on each IBC App interface function. This might be useful when testing out IBC applications written as middleware. +* [\#432](https://github.com/cosmos/ibc-go/pull/432) Introduce `MockIBCApp` struct to the mock module. Allows the mock module to be reused to perform custom logic on each IBC App interface function. This might be useful when testing out IBC applications written as middleware. * [\#380](https://github.com/cosmos/ibc-go/pull/380) Adding the Interchain Accounts module v1 * [\#679](https://github.com/cosmos/ibc-go/pull/679) New CLI command `query ibc-transfer denom-hash ` to get the denom hash for a denom trace; this might be useful for debug @@ -192,7 +535,72 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (client) [\#941](https://github.com/cosmos/ibc-go/pull/941) Classify client states without consensus states as expired * (channel) [\#995](https://github.com/cosmos/ibc-go/pull/995) Call `packet.GetSequence()` rather than passing func in `AcknowledgePacket` log output -## [v2.3.0](https://github.com/cosmos/ibc-go/releases/tag/v2.3.0) - 2022-04-16 +## [v2.5.0](https://github.com/cosmos/ibc-go/releases/tag/v2.5.0) - 2022-11-07 + +### Dependencies + +* [\#2578](https://github.com/cosmos/ibc-go/pull/2578) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +### State Machine Breaking + +* (apps/transfer) [\#2651](https://github.com/cosmos/ibc-go/pull/2651) Introduce `mustProtoMarshalJSON` for ics20 packet data marshalling which will skip emission (marshalling) of the memo field if unpopulated (empty). +* (transfer) [\#2377](https://github.com/cosmos/ibc-go/pull/2377) Adding `sequence` to `MsgTransferResponse`. + +### Features + +* (apps/transfer) [\#2595](https://github.com/cosmos/ibc-go/pull/2595) Adding optional memo field to `FungibleTokenPacketData` and `MsgTransfer`. + +### Bug Fixes + +* (apps/transfer) [\#2679](https://github.com/cosmos/ibc-go/pull/2679) Check `x/bank` send enabled. + +## [v2.4.2](https://github.com/cosmos/ibc-go/releases/tag/v2.4.2) - 2022-10-27 + +### Dependencies + +* [\#2622](https://github.com/cosmos/ibc-go/pull/2622) Bump SDK version to v0.45.10 and Tendermint to v0.34.22. + +## [v2.4.1](https://github.com/cosmos/ibc-go/releases/tag/v2.4.1) - 2022-09-15 + +### Dependencies + +* [\#2284](https://github.com/cosmos/ibc-go/pull/2284) Bump SDK version to v0.45.8 and Tendermint to v0.34.21. + +## [v2.4.0](https://github.com/cosmos/ibc-go/releases/tag/v2.4.0) - 2022-08-12 + +### Dependencies + +* [\#1627](https://github.com/cosmos/ibc-go/pull/1627) Bump Go version to 1.18 +* [\#1905](https://github.com/cosmos/ibc-go/pull/1905) Bump SDK version to v0.45.7 + +### State Machine Breaking + +* (apps/transfer) [\#1907](https://github.com/cosmos/ibc-go/pull/1907) Blocked module account addresses are no longer allowed to send IBC transfers. + +### Improvements + +* (modules/light-clients/07-tendermint) [\#1713](https://github.com/cosmos/ibc-go/pull/1713) Allow client upgrade proposals to update `TrustingPeriod`. See ADR-026 for context. +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (app/20-transfer) [\#1680](https://github.com/cosmos/ibc-go/pull/1680) Adds migration to correct any malformed trace path information of tokens with denoms that contains slashes. The transfer module consensus version has been bumped to 2. +* (app/20-transfer) [\#1730](https://github.com/cosmos/ibc-go/pull/1730) parse the ics20 denomination provided via a packet using the channel identifier format specified by ibc-go. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +### Bug Fixes + +* (modules/core/04-channel)[\#1919](https://github.com/cosmos/ibc-go/pull/1919) Fixed formatting of sequence for packet "acknowledgement written" logs. + +## [v2.3.1](https://github.com/cosmos/ibc-go/releases/tag/v2.3.1) - 2022-08-02 + +### Dependencies + +* [\#1525](https://github.com/cosmos/ibc-go/pull/1525) Bump SDK version to v0.45.5 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v2.3.0](https://github.com/cosmos/ibc-go/releases/tag/v2.3.0) - 2022-06-14 ### Dependencies @@ -218,7 +626,14 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (modules/core/04-channel) [\#1130](https://github.com/cosmos/ibc-go/pull/1130) Call `packet.GetSequence()` rather than passing func in `WriteAcknowledgement` log output * (apps/transfer) [\#1451](https://github.com/cosmos/ibc-go/pull/1451) Fixing the support for base denoms that contain slashes. -## [v2.2.1](https://github.com/cosmos/ibc-go/releases/tag/v2.2.1) - 2022-04-16 +## [v2.2.2](https://github.com/cosmos/ibc-go/releases/tag/v2.2.2) - 2022-08-02 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v2.2.1](https://github.com/cosmos/ibc-go/releases/tag/v2.2.1) - 2022-06-14 ### Improvements @@ -238,7 +653,14 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#851](https://github.com/cosmos/ibc-go/pull/851) Bump SDK version to v0.45.1 -## [v2.1.1](https://github.com/cosmos/ibc-go/releases/tag/v2.1.1) - 2022-04-16 +## [v2.1.2](https://github.com/cosmos/ibc-go/releases/tag/v2.1.2) - 2022-08-02 + +### Improvements + +* (core/02-client) [\#1570](https://github.com/cosmos/ibc-go/pull/1570) Emitting an event when handling an upgrade client proposal. +* (core/client) [\#1740](https://github.com/cosmos/ibc-go/pull/1740) Add `cosmos_proto.implements_interface` to adhere to guidelines in [Cosmos SDK ADR 019](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-019-protobuf-state-encoding.md#safe-usage-of-any) for annotating `google.protobuf.Any` types + +## [v2.1.1](https://github.com/cosmos/ibc-go/releases/tag/v2.1.1) - 2022-06-14 ### Dependencies @@ -317,7 +739,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking * (core) [\#227](https://github.com/cosmos/ibc-go/pull/227) Remove sdk.Result from application callbacks -* (transfer) [\#350](https://github.com/cosmos/ibc-go/pull/350) Change FungibleTokenPacketData to use a string for the Amount field. This enables token transfers with amounts previously restricted by uint64. Up to the maximum uint256 value is supported. +* (transfer) [\#350](https://github.com/cosmos/ibc-go/pull/350) Change FungibleTokenPacketData to use a string for the Amount field. This enables token transfers with amounts previously restricted by uint64. Up to the maximum uint256 value is supported. ### Features @@ -342,7 +764,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features * (modules/core/02-client) [\#1336](https://github.com/cosmos/ibc-go/pull/1336) Adding Query/ConsensusStateHeights gRPC for fetching the height of every consensus state associated with a client. -* (modules/apps/transfer) [\#1416](https://github.com/cosmos/ibc-go/pull/1416) Adding gRPC endpoint for getting an escrow account for a given port-id and channel-id. +* (modules/apps/transfer) [\#1416](https://github.com/cosmos/ibc-go/pull/1416) Adding gRPC endpoint for getting an escrow account for a given port-id and channel-id. ### Bug Fixes @@ -507,7 +929,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [v1.1.2](https://github.com/cosmos/ibc-go/releases/tag/v1.1.2) - 2021-10-15 * [\#485](https://github.com/cosmos/ibc-go/pull/485) Bump SDK version to v0.44.2 - + ## [v1.1.1](https://github.com/cosmos/ibc-go/releases/tag/v1.1.1) - 2021-10-04 ### Dependencies @@ -538,8 +960,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (core) [\#200](https://github.com/cosmos/ibc-go/pull/200) Fixes incorrect export of IBC identifier sequences. Previously, the next identifier sequence for clients/connections/channels was not set during genesis export. This resulted in the next identifiers being generated on the new chain to reuse old identifiers (the sequences began again from 0). * (02-client) [\#192](https://github.com/cosmos/ibc-go/pull/192) Fix IBC `query ibc client header` cli command. Support historical queries for query header/node-state commands. * (modules/light-clients/06-solomachine) [\#153](https://github.com/cosmos/ibc-go/pull/153) Fix solo machine proof height sequence mismatch bug. -* (modules/light-clients/06-solomachine) [\#122](https://github.com/cosmos/ibc-go/pull/122) Fix solo machine merkle prefix casting bug. -* (modules/light-clients/06-solomachine) [\#120](https://github.com/cosmos/ibc-go/pull/120) Fix solo machine handshake verification bug. +* (modules/light-clients/06-solomachine) [\#122](https://github.com/cosmos/ibc-go/pull/122) Fix solo machine merkle prefix casting bug. +* (modules/light-clients/06-solomachine) [\#120](https://github.com/cosmos/ibc-go/pull/120) Fix solo machine handshake verification bug. * (modules/light-clients/06-solomachine) [\#153](https://github.com/cosmos/ibc-go/pull/153) fix solo machine connection handshake failure at `ConnectionOpenAck`. ### API Breaking @@ -548,19 +970,19 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (modules) [\#206](https://github.com/cosmos/ibc-go/pull/206) Expose `relayer sdk.AccAddress` on `OnRecvPacket`, `OnAcknowledgementPacket`, `OnTimeoutPacket` module callbacks to enable incentivization. * (02-client) [\#181](https://github.com/cosmos/ibc-go/pull/181) Remove 'InitialHeight' from UpdateClient Proposal. Only copy over latest consensus state from substitute client. * (06-solomachine) [\#169](https://github.com/cosmos/ibc-go/pull/169) Change FrozenSequence to boolean in solomachine ClientState. The solo machine proto package has been bumped from `v1` to `v2`. -* (module/core/02-client) [\#165](https://github.com/cosmos/ibc-go/pull/165) Remove GetFrozenHeight from the ClientState interface. +* (module/core/02-client) [\#165](https://github.com/cosmos/ibc-go/pull/165) Remove GetFrozenHeight from the ClientState interface. * (modules) [\#166](https://github.com/cosmos/ibc-go/pull/166) Remove GetHeight from the misbehaviour interface. The `consensus_height` attribute has been removed from Misbehaviour events. -* (modules) [\#162](https://github.com/cosmos/ibc-go/pull/162) Remove deprecated Handler types in core IBC and the ICS 20 transfer module. +* (modules) [\#162](https://github.com/cosmos/ibc-go/pull/162) Remove deprecated Handler types in core IBC and the ICS 20 transfer module. * (modules/core) [\#161](https://github.com/cosmos/ibc-go/pull/161) Remove Type(), Route(), GetSignBytes() from 02-client, 03-connection, and 04-channel messages. * (modules) [\#140](https://github.com/cosmos/ibc-go/pull/140) IsFrozen() client state interface changed to Status(). gRPC `ClientStatus` route added. * (modules/core) [\#109](https://github.com/cosmos/ibc-go/pull/109) Remove connection and channel handshake CLI commands. -* (modules) [\#107](https://github.com/cosmos/ibc-go/pull/107) Modify OnRecvPacket callback to return an acknowledgement which indicates if it is successful or not. Callback state changes are discarded for unsuccessful acknowledgements only. +* (modules) [\#107](https://github.com/cosmos/ibc-go/pull/107) Modify OnRecvPacket callback to return an acknowledgement which indicates if it is successful or not. Callback state changes are discarded for unsuccessful acknowledgements only. * (modules) [\#108](https://github.com/cosmos/ibc-go/pull/108) All message constructors take the signer as a string to prevent upstream bugs. The `String()` function for an SDK Acc Address relies on external context. * (transfer) [\#275](https://github.com/cosmos/ibc-go/pull/275) Remove 'ChanCloseInit' function from transfer keeper. ICS20 does not close channels. ### State Machine Breaking -* (modules/light-clients/07-tendermint) [\#99](https://github.com/cosmos/ibc-go/pull/99) Enforce maximum chain-id length for tendermint client. +* (modules/light-clients/07-tendermint) [\#99](https://github.com/cosmos/ibc-go/pull/99) Enforce maximum chain-id length for tendermint client. * (modules/light-clients/07-tendermint) [\#141](https://github.com/cosmos/ibc-go/pull/141) Allow a new form of misbehaviour that proves counterparty chain breaks time monotonicity, automatically enforce monotonicity in UpdateClient and freeze client if monotonicity is broken. * (modules/light-clients/07-tendermint) [\#141](https://github.com/cosmos/ibc-go/pull/141) Freeze the client if there's a conflicting header submitted for an existing consensus state. * (modules/core/02-client) [\#8405](https://github.com/cosmos/cosmos-sdk/pull/8405) Refactor IBC client update governance proposals to use a substitute client to update a frozen or expired client. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b1111fc6d10..c471c6cb339 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,252 +1,65 @@ -# Contributing - -- [Contributing](#contributing) - - [Architecture Decision Records (ADR)](#architecture-decision-records-adr) - - [Pull Requests](#pull-requests) - - [Process for reviewing PRs](#process-for-reviewing-prs) - - [Updating Documentation](#updating-documentation) - - [Forking](#forking) - - [Dependencies](#dependencies) - - [Protobuf](#protobuf) - - [Testing](#testing) - - [Branching Model and Release](#branching-model-and-release) - - [PR Targeting](#pr-targeting) - - [Development Procedure](#development-procedure) - - [Pull Merge Procedure](#pull-merge-procedure) - - [Release Procedure](#release-procedure) - - [Point Release Procedure](#point-release-procedure) - -Thank you for considering making contributions to ibc-go! - -Contributing to this repo can mean many things such as participating in -discussion or proposing code changes. To ensure a smooth workflow for all -contributors, the general procedure for contributing has been established: - -1. Either [open](https://github.com/cosmos/ibc-go/issues/new/choose) or - [find](https://github.com/cosmos/ibc-go/issues) an issue you'd like to help with -2. Participate in thoughtful discussion on that issue -3. If you would like to contribute: - 1. If the issue is a proposal, ensure that the proposal has been accepted - 2. Ensure that nobody else has already begun working on this issue. If they have, - make sure to contact them to collaborate - 3. If nobody has been assigned for the issue and you would like to work on it, - make a comment on the issue to inform the community of your intentions - to begin work - 4. Follow standard Github best practices: fork the repo, branch from the - HEAD of `main`, make some commits, and submit a PR to `main` - - For core developers working within the ibc-go repo, to ensure a clear - ownership of branches, branches must be named with the convention - `{moniker}/{issue#}-branch-name` - 5. Be sure to submit the PR in `Draft` mode submit your PR early, even if - it's incomplete as this indicates to the community you're working on - something and allows them to provide comments early in the development process - 6. When the code is complete it can be marked `Ready for Review` - 7. Be sure to include a relevant change log entry in the `Unreleased` section - of `CHANGELOG.md` (see file for log format) +# Contributing to ibc-go -Note that for very small or blatantly obvious problems (such as typos) it is -not required to an open issue to submit a PR, but be aware that for more complex -problems/features, if a PR is opened before an adequate design discussion has -taken place in a github issue, that PR runs a high likelihood of being rejected. +Thank you for considering making contributions to ibc-go! 🎉👍 -Other notes: +## Code of conduct -- Looking for a good place to start contributing? How about checking out some - [good first issues](https://github.com/cosmos/ibc-go/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) -- Please make sure to run `make format` before every commit - the easiest way - to do this is have your editor run it for you upon saving a file. Additionally - please ensure that your code is lint compliant by running `golangci-lint run`. +This project and everyone participating in it is governed by ibc-go's [code of conduct](./CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code -## Architecture Decision Records (ADR) +## How can I contribute? -When proposing an architecture decision for the ibc-go, please create an [ADR](./docs/architecture/README.md) -so further discussions can be made. We are following this process so all involved parties are in -agreement before any party begins coding the proposed implementation. If you would like to see some examples -of how these are written refer to [Cosmos SDK ADRs](https://github.com/cosmos/cosmos-sdk/tree/master/docs/architecture) +Contributing to this repository can mean many things such as participating in discussions or proposing code changes. To ensure a smooth workflow for all contributors, the general procedure for contributing has been established: -## Pull Requests +### Reporting bugs -To accommodate review process we suggest that PRs are categorically broken up. -Ideally each PR addresses only a single issue. Additionally, as much as possible -code refactoring and cleanup should be submitted as a separate PRs from bugfixes/feature-additions. +If you find that something is not working as expected, please open an issue using the [bug report template](https://github.com/cosmos/ibc-go/blob/main/.github/ISSUE_TEMPLATE/bug-report.md) and provide as much information possible: how can the bug be reproduced? What's the expected behavior? What version is affected? -### Process for reviewing PRs +### Proposing improvements or new features -All PRs require an approval from at least one CODEOWNER before merge. PRs which cause signficant changes require two approvals from CODEOWNERS. When reviewing PRs please use the following review explanations: +New features or improvements should be written in an issue using the [new feature template](https://github.com/cosmos/ibc-go/blob/main/.github/ISSUE_TEMPLATE/feature-request.md). Please include in the issue as many details as possible: what use case(s) would this new feature or improvement enable? Why are those use cases important or helpful? what user group would benefit? The team will evaluate and engage with you in a discussion of the proposal, which could have different outcomes: -- `LGTM` without an explicit approval means that the changes look good, but you haven't pulled down the code, run tests locally and thoroughly reviewed it. -- `Approval` through the GH UI means that you understand the code, documentation/spec is updated in the right places, you have pulled down and tested the code locally. In addition: - - You must also think through anything which ought to be included but is not - - You must think through whether any added code could be partially combined (DRYed) with existing code - - You must think through any potential security issues or incentive-compatibility flaws introduced by the changes - - Naming must be consistent with conventions and the rest of the codebase - - Code must live in a reasonable location, considering dependency structures (e.g. not importing testing modules in production code, or including example code modules in production code). - - if you approve of the PR, you are responsible for fixing any of the issues mentioned here and more -- If you sat down with the PR submitter and did a pairing review please note that in the `Approval`, or your PR comments. -- If you are only making "surface level" reviews, submit any notes as `Comments` without adding a review. +- the core ibc-go team deciding to implement this feature and adding it to their planning, +- agreeing to support external contributors to implement it with the goal of merging it eventually in ibc-go, +- discarding the suggestion if deemed not aligned with the objectives of ibc-go; +- or proposing (in the case of applications or light clients) to be developed and maintained in a separate repository. -### Updating Documentation +Please check out also our [Request For Maintainership](./MAINTAINERSHIP.md) process, which contains information relevant to this. -If you open a PR on ibc-go, it is mandatory to update the relevant documentation in /docs. +### Architecture Decision Records (ADR) -## Forking +When proposing an architecture decision for the ibc-go, please create an [ADR](./docs/architecture/README.md) so further discussions can be made. We are following this process so all involved parties are in agreement before any party begins coding the proposed implementation. Please use the [ADR template](./docs/architecture/adr-template.md) to scaffold any new ADR. If you would like to see some examples of how these are written refer to ibc-go's [ADRs](./docs/architecture/). Solidified designs that will be implemented in ibc-go (and do not have a spec). They should document the architecture that will be built. Most design feedback should be gathered before the initial draft of the ADR. ADR's can/should be written for any design decisions we make which may be changed at some point in the future. -Please note that Go requires code to live under absolute paths, which complicates forking. -While my fork lives at `https://github.com/colin-axner/ibc-go`, -the code should never exist at `$GOPATH/src/github.com/colin-axner/ibc-go`. -Instead, we use `git remote` to add the fork as a new remote for the original repo, -`$GOPATH/src/github.com/cosmos/ibc-go`, and do all the work there. +### Participating in discussions -For instance, to create a fork and work on a branch of it, I would: +New features or improvements are sometimes also debated in [discussions](https://github.com/cosmos/ibc-go/discussions). Sharing feedback or ideas there is very helpful for us. high level discussions that may get a lot of comments on a variety of different aspects, design aspects still being considered. -- Create the fork on github, using the fork button. -- Go to the original repo checked out locally (i.e. `$GOPATH/src/github.com/cosmos/ibc-go`) -- `git remote add fork git@github.com:colin-axner/ibc-go.git` +### Submitting pull requests -Now `fork` refers to my fork and `origin` refers to the ibc-go version. -So I can `git push -u fork main` to update my fork, and make pull requests to ibc-go from there. -Of course, replace `colin-axner` with your git handle. +Unless you feel confident your change will be accepted (trivial bug fixes, code cleanup, etc) you should first create an issue to discuss your change with us. This lets us all discuss the design and proposed implementation of your change, which helps ensure your time is well spent and that your contribution will be accepted. -To pull in updates from the origin repo, run +Looking for a good place to start contributing? The issue tracker is always the first place to go. Issues are triaged to categorize them: -- `git fetch origin` -- `git rebase origin/main` (or whatever branch you want) +- Check out some [`good first issue`s](https://github.com/cosmos/ibc-go/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). These are issues whose scope of work should be pretty clearly specified and they are best suited for developers new to ibc-go (i.e. no deep knowledge of Cosmos SDK or ibc-go is required). For example, some of these issues may involve improving the logging, emitting new events or removing unused code. +- Or pick up a [`help wanted`](https://github.com/cosmos/ibc-go/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issue. These issues should be a bit more involved than the good first issues and the developer working on them would benefit from some familiarity already with the codebase. These types of issues may involve adding new (or extending the functionality of existing) gRPC endpoints, bumping the version of Cosmos SDK or Tendermint or fixing bugs. -Please don't make Pull Requests from `main`. +If you would like to contribute, follow this process: -## Dependencies +1. If the issue is a proposal, ensure that the proposal has been accepted. +2. Ensure that nobody else has already begun working on this issue. If they have, make sure to contact them to collaborate. +3. If nobody has been assigned for the issue and you would like to work on it, comment on the issue to inform the community of your intentions to begin work. Then we will be able to assign the issue to you, making it visible for others that this issue is being tackled. If you end up not creating a pull request for this issue, please comment on the issue as well, so that it can be assigned to somebody else. +4. Follow standard GitHub best practices: fork the repo, branch from the HEAD of `main`, make some commits, and submit a PR to `main`. For core developers working within the ibc-go repo, branches must be named with the convention `{moniker}/{issue#}-branch-name` to ensure a clear ownership of branches. +5. Feel free to submit the pull request in `Draft` mode, even if the work is not complete, as this indicates to the community you are working on something and allows them to provide comments early in the development process. +6. When the code is complete it can be marked `Ready for Review`. +7. Be sure to include a relevant changelog entry in the [Commit Message / Changelog Entry section of pull request description](https://github.com/cosmos/ibc-go/blob/main/.github/PULL_REQUEST_TEMPLATE.md#commit-message--changelog-entry) so that we can add changelog entry when merging the pull request. Please follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and use one of the commit types mentioned in the [Commit messages section of the pull request guidelines](./docs/dev/pull-requests.md#commit-messages). -We use [Go 1.14 Modules](https://github.com/golang/go/wiki/Modules) to manage -dependency versions. +Please make sure to check out our [Pull request guidelines](./docs/dev/pull-requests.md) for more information. -The main branch of every Cosmos repository should just build with `go get`, -which means they should be kept up-to-date with their dependencies, so we can -get away with telling people they can just `go get` our software. +## Relevant development docs -Since some dependencies are not under our control, a third party may break our -build, in which case we can fall back on `go mod tidy -v`. - -## Protobuf - -We use [Protocol Buffers](https://developers.google.com/protocol-buffers) along with [gogoproto](https://github.com/gogo/protobuf) to generate code for use in ibc-go. - -For determinstic behavior around Protobuf tooling, everything is containerized using Docker. Make sure to have Docker installed on your machine, or head to [Docker's website](https://docs.docker.com/get-docker/) to install it. - -For formatting code in `.proto` files, you can run `make proto-format` command. - -For linting and checking breaking changes, we use [buf](https://buf.build/). You can use the commands `make proto-lint` and `make proto-check-breaking` to respectively lint your proto files and check for breaking changes. - -To generate the protobuf stubs, you can run `make proto-gen`. - -We also added the `make proto-all` command to run all the above commands sequentially. - -In order for imports to properly compile in your IDE, you may need to manually set your protobuf path in your IDE's workspace settings/config. - -For example, in vscode your `.vscode/settings.json` should look like: - -``` -{ - "protoc": { - "options": [ - "--proto_path=${workspaceRoot}/proto", - "--proto_path=${workspaceRoot}/third_party/proto" - ] - } -} -``` - -## Testing - -All go tests in ibc-go can be ran by running `make test`. - -When testing a function under a variety of different inputs, we prefer to use -[table driven tests](https://github.com/golang/go/wiki/TableDrivenTests). - -All tests should use the testing package. Please see the testing package [README](./testing/README.md) for more information. - - -## Branching Model and Release - -User-facing repos should adhere to the trunk based development branching model: https://trunkbaseddevelopment.com/. - -ibc-go utilizes [semantic versioning](https://semver.org/). - -### PR Targeting - -Ensure that you base and target your PR on the `main` branch. - -All development should be targeted against `main`. Bug fixes which are required for outstanding releases should be backported if the CODEOWNERS decide it is applicable. - -### Development Procedure - -- the latest state of development is on `main` -- `main` must never fail `make test` -- no `--force` onto `main` (except when reverting a broken commit, which should seldom happen) -- create a development branch either on github.com/cosmos/ibc-go, or your fork (using `git remote add fork`) -- before submitting a pull request, begin `git rebase` on top of `main` - -### Pull Merge Procedure - -- ensure all github requirements pass -- squash and merge pull request - -### Release Procedure - -- Start on `main` -- Create the release candidate branch `rc/v*` (going forward known as **RC**) - and ensure it's protected against pushing from anyone except the release - manager/coordinator - - **no PRs targeting this branch should be merged unless exceptional circumstances arise** -- On the `RC` branch, prepare a new version section in the `CHANGELOG.md` - - All links must be link-ified: `$ python ./scripts/linkify_changelog.py CHANGELOG.md` -- Run external relayer tests against the prepared RC -- If errors are found during the relayer testing, commit the fixes to `main` - and create a new `RC` branch (making sure to increment the `rcN`) -- After relayer testing has successfully completed, create the release branch - (`release/vX.XX.X`) from the `RC` branch -- Create a PR to `main` to incorporate the `CHANGELOG.md` updates -- Tag the release (use `git tag -a`) and create a release in Github -- Delete the `RC` branches - -### Point Release Procedure - -At the moment, only a single major release will be supported, so all point releases will be based -off of that release. - -In order to alleviate the burden for a single person to have to cherry-pick and handle merge conflicts -of all desired backporting PRs to a point release, we instead maintain a living backport branch, where -all desired features and bug fixes are merged into as separate PRs. - -Example: - -Current release is `v1.0.2`. We then maintain a (living) branch `release/v1.0.x`, given x as -the next patch release number (currently `1.0.3`) for the `1.0` release series. As bugs are fixed -and PRs are merged into `main`, if a contributor wishes the PR to be released into the -`v1.0.x` point release, the contributor must: - -1. Add `1.0.x-backport` label -2. Pull latest changes on the desired `release/v1.0.x` branch -3. Create a 2nd PR merging the respective PR into `release/v1.0.x` -4. Update the PR's description and ensure it contains the following information: - - **[Impact]** Explanation of how the bug affects users or developers. - - **[Test Case]** section with detailed instructions on how to reproduce the bug. - - **[Regression Potential]** section with a discussion how regressions are most likely to manifest, or might - manifest even if it's unlikely, as a result of the change. **It is assumed that any backport PR is - well-tested before it is merged in and has an overall low risk of regression**. This section should discuss - the potential for state breaking changes to occur such as through out-of-gas errors. - -It is the PR's author's responsibility to fix merge conflicts, update changelog entries, and -ensure CI passes. If a PR originates from an external contributor, it may be a core team member's -responsibility to perform this process instead of the original author. -Lastly, it is core team's responsibility to ensure that the PR meets all the backport criteria. - -Finally, when a point release is ready to be made: - -1. Checkout `release/v1.0.x` branch -2. Ensure changelog entries are verified -3. Add release version date to the changelog -4. Push release branch along with the annotated tag: **git tag -a** -5. Create a PR into `main` containing ONLY `CHANGELOG.md` updates - -Note, although we aim to support only a single release at a time, the process stated above could be -used for multiple previous versions. +- [Project structure](./docs/dev/project-structure.md) +- [Develoment setup](./docs/dev/development-setup.md) +- [Go style guide](./docs/dev/go-style-guide.md) +- [Documentation guidelines](./docs/DOCS_GUIDELINES.md) +- [Writing tests](./testing/README.md) +- [Pull request guidelines](./docs/dev/pull-requests.md) +- [Release process](./docs/dev/release-management.md) diff --git a/Dockerfile b/Dockerfile index a193f54906e..64f76ec298a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,35 @@ -FROM golang:1.18 as builder +FROM golang:1.19 as builder + +ARG IBC_GO_VERSION ENV GOPATH="" ENV GOMODULE="on" +# ensure the ibc go version is being specified for this image. +RUN test -n "${IBC_GO_VERSION}" + COPY go.mod . COPY go.sum . RUN go mod download +ADD internal internal ADD testing testing ADD modules modules ADD LICENSE LICENSE +COPY contrib/devtools/Makefile contrib/devtools/Makefile COPY Makefile . + RUN make build FROM ubuntu:20.04 +ARG IBC_GO_VERSION + +LABEL "org.cosmos.ibc-go" "${IBC_GO_VERSION}" + COPY --from=builder /go/build/simd /bin/simd ENTRYPOINT ["simd"] diff --git a/MAINTAINERSHIP.md b/MAINTAINERSHIP.md new file mode 100644 index 00000000000..f3247c1b225 --- /dev/null +++ b/MAINTAINERSHIP.md @@ -0,0 +1,62 @@ +# Request For Maintainership + +This document details the acceptance process for requests from external contributors who require for the ibc-go core team to take over **maintainership** of a complex block of code (ie: an application module or a light client implementation). It is the process we also follow internally for features that we develop which will go into the `ibc-go` codebase. + +For projects who have created a custom IBC application and want us to list this application on the registry, please break out your module into its own repo for ease of import into chains! + +- Create a repo with the custom module in a folder `x/` or `modules/`. +- Please include an app that contains the custom module along with end-to-end tests that spins up the blockchain and runs the custom module. +- See [cosmos/interchain-security](https://github.com/cosmos/interchain-security) for an example of this setup. + +For contributors wishing to submit contributions to the codebase, please check our [Contributor Guidelines](https://github.com/cosmos/ibc-go/blob/main/CONTRIBUTING.md) :) + +

+ maintainership +

+ +## Step 1: Product check + +Reach out to the IBC product team through susannah@interchain.io to coordinate use-case walkthrough. + +Answer these questions in a requirements doc: + +- What problem does this feature solve? +- What are the current solutions or workarounds? +- Are there other versions or implementations? +- If there are other versions of this feature, why is this solution better? +- What are the use cases? +- Which users have confirmed they will use this? +- How urgent is it to implement this feature? +- How soon after being developed would this be adopted? +- What is the impact of this feature being adopted? +- Is there a specific need for this feature to be included in the `ibc-go` codebase, rather than in its own module repo? + +Answers to these questions should also be detailed in a **discussion** in the `ibc-go` repo to open up the discussion to a wider audience, this can be done before or after the walkthrough. + +The acceptance criteria is based on the answers to these questions and the results of this product check, as well as of course an acceptable spec should the module be deemed to need one. Please see Step #2 below for the spec considerations. + +In summary, the feature must solve a genuine problem, have users that would greatly benefit from the solution and be generic enough to benefit many users of the `ibc-go` implementation. + +## Step 2: Submit spec to the IBC protocol repo + +A detailed review of the specification can be expected **within 2 weeks** of submission of the specification to the repo. Please notify the specification team if this does not occur, so it can be corrected as soon as possible. Please note that this timeline may be subject to amendment based on complexity of the spec and team capacity considering other ongoing reviews, but we will strive to ensure a 2 week turnaround. + +Any IBC code that is expected to be implemented across different chains in order to function correctly must be specified in the IBC repo to be accepted unless exempted by the specification team. + +Unilateral software (ie. code that only needs to run on a single chain to be functional) need not be submitted. In these cases however, some sort of design document such as [ADR-008](https://github.com/cosmos/ibc-go/pull/1976/files) should be submitted. + +If the associated module to be developed is expected to be submitted to the `ibc-go` team for maintainership, this should already be flagged at this step so that we can start thinking about/preparing our own capacity for the engineering team. + +## Step 3: Prepare code for handover + +*(this step can be initiated in parallel w/ spec submission, subject to feature complexity)* + +Once the spec has been given initial approval, `ibc-go` engineering will coordinate a code walkthrough in preparation for taking the module into the repo. Any requested changes from the `ibc-go` engineering team after the code walkthrough should be discussed and/or addressed in a timely manner. + +The code that is presented should adhere to our [code contributor guidelines](https://github.com/cosmos/ibc-go/blob/main/CONTRIBUTING.md). + +More details on what code walkthrough should cover will be provided by the `ibc-go` engineering team on a case by case basis. However, the code should be sufficiently unit and [E2E tested](https://github.com/cosmos/ibc-go/blob/main/e2e/README.md). Think about preparing for this process similarly to submitting a codebase for audit :) + +Please indicate the expected contribution of your team maintainership, if any. This contribution should also include ideas about devrels support and support for product on social media. + +ETA for the actual handover will be subject to amendment based on feedback resulting from the code walkthrough. diff --git a/Makefile b/Makefile index eba4b5c2de2..73c89cb236b 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ SIMAPP = ./testing/simapp MOCKS_DIR = $(CURDIR)/tests/mocks HTTPS_GIT := https://github.com/cosmos/ibc-go.git DOCKER := $(shell which docker) -DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf:1.0.0-rc8 +PROJECT_NAME = $(shell git remote get-url origin | xargs basename -s .git) export GO111MODULE = on @@ -96,7 +96,7 @@ endif all: build lint test # The below include contains the tools and runsim targets. -#include contrib/devtools/Makefile +include contrib/devtools/Makefile ############################################################################### ### Build ### @@ -114,47 +114,7 @@ $(BUILD_TARGETS): go.sum $(BUILDDIR)/ $(BUILDDIR)/: mkdir -p $(BUILDDIR)/ -build-simd-all: go.sum - $(DOCKER) rm latest-build || true - $(DOCKER) run --volume=$(CURDIR):/sources:ro \ - --env TARGET_PLATFORMS='linux/amd64 darwin/amd64 linux/arm64 windows/amd64' \ - --env APP=simd \ - --env VERSION=$(VERSION) \ - --env COMMIT=$(COMMIT) \ - --env LEDGER_ENABLED=$(LEDGER_ENABLED) \ - --name latest-build cosmossdk/rbuilder:latest - $(DOCKER) cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ - -build-simd-linux: go.sum $(BUILDDIR)/ - $(DOCKER) rm latest-build || true - $(DOCKER) run --volume=$(CURDIR):/sources:ro \ - --env TARGET_PLATFORMS='linux/amd64' \ - --env APP=simd \ - --env VERSION=$(VERSION) \ - --env COMMIT=$(COMMIT) \ - --env LEDGER_ENABLED=false \ - --name latest-build cosmossdk/rbuilder:latest - $(DOCKER) cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ - cp artifacts/simd-*-linux-amd64 $(BUILDDIR)/simd - -cosmovisor: - $(MAKE) -C cosmovisor cosmovisor - -.PHONY: build build-linux build-simd-all build-simd-linux cosmovisor - -mocks: $(MOCKS_DIR) - mockgen -source=client/account_retriever.go -package mocks -destination tests/mocks/account_retriever.go - mockgen -package mocks -destination tests/mocks/tendermint_tm_db_DB.go github.com/tendermint/tm-db DB - mockgen -source=types/module/module.go -package mocks -destination tests/mocks/types_module_module.go - mockgen -source=types/invariant.go -package mocks -destination tests/mocks/types_invariant.go - mockgen -source=types/router.go -package mocks -destination tests/mocks/types_router.go - mockgen -source=types/handler.go -package mocks -destination tests/mocks/types_handler.go - mockgen -package mocks -destination tests/mocks/grpc_server.go github.com/gogo/protobuf/grpc Server - mockgen -package mocks -destination tests/mocks/tendermint_tendermint_libs_log_DB.go github.com/tendermint/tendermint/libs/log Logger -.PHONY: mocks - -$(MOCKS_DIR): - mkdir -p $(MOCKS_DIR) +.PHONY: build build-linux distclean: clean clean: @@ -179,7 +139,7 @@ go.sum: go.mod ############################################################################### update-swagger-docs: statik - $(BINDIR)/statik -src=client/docs/swagger-ui -dest=client/docs -f -m + $(BINDIR)/statik -src=docs/client/swagger-ui -dest=docs/client -f -m @if [ -n "$(git status --porcelain)" ]; then \ echo "\033[91mSwagger docs are out of sync!!!\033[0m";\ exit 1;\ @@ -203,12 +163,17 @@ build-docs: mkdir -p ~/output/$${path_prefix} ; \ cp -r .vuepress/dist/* ~/output/$${path_prefix}/ ; \ cp ~/output/$${path_prefix}/index.html ~/output ; \ + cp ~/output/$${path_prefix}/404.html ~/output ; \ done < versions ; view-docs: @cd docs && \ npm install && npm run serve + +changelog: + docker run --rm -v "$$(pwd)"/.git:/app/ -v "$$(pwd)/cliff.toml":/app/cliff.toml orhunp/git-cliff:latest --unreleased --tag $(tag) + .PHONY: build-docs ############################################################################### @@ -317,11 +282,6 @@ test-cover: @export VERSION=$(VERSION); bash -x contrib/test_cover.sh .PHONY: test-cover -test-rosetta: - docker build -t rosetta-ci:latest -f contrib/rosetta/node/Dockerfile . - docker-compose -f contrib/rosetta/docker-compose.yaml up --abort-on-container-exit --exit-code-from test_rosetta --build -.PHONY: test-rosetta - benchmark: @go test -mod=readonly -bench=. $(PACKAGES_NOSIMULATION) .PHONY: benchmark @@ -335,166 +295,52 @@ lint: lint-fix: golangci-lint run --fix --out-format=tab --issues-exit-code=0 -.PHONY: lint lint-fix - -format: goimports - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs gofmt -w -s - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' | xargs misspell -w -.PHONY: format - -goimports: - $(DOCKER) run -v $(CURDIR):/ibc-go --rm -w "/ibc-go" cytopia/goimports -w -local 'github.com/cosmos/ibc-go' "$(CHANGED_GO_FILES)" &> /dev/null || echo "No changed go files to format" - -goimports-all: - $(DOCKER) run -v $(CURDIR):/ibc-go --rm -w "/ibc-go" cytopia/goimports -w -local 'github.com/cosmos/ibc-go' "$(ALL_GO_FILES)" - -############################################################################### -### Devdoc ### -############################################################################### -DEVDOC_SAVE = docker commit `docker ps -a -n 1 -q` devdoc:local +lint-fix-changed: + ./scripts/linting/lint-changed-go-files.sh -devdoc-init: - $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/cosmos/cosmos-sdk" -w "/go/src/github.com/cosmos/cosmos-sdk" tendermint/devdoc echo - # TODO make this safer - $(call DEVDOC_SAVE) - -devdoc: - $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/cosmos/cosmos-sdk" -w "/go/src/github.com/cosmos/cosmos-sdk" devdoc:local bash - -devdoc-save: - # TODO make this safer - $(call DEVDOC_SAVE) +format: + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./docs/client/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' -not -name '*.pb.gw.go' | xargs gofumpt -w + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./docs/client/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' -not -name '*.pb.gw.go' | xargs misspell -w +.PHONY: format -devdoc-clean: - docker rmi -f $$(docker images -f "dangling=true" -q) +docs-lint: + markdownlint . --fix -devdoc-update: - docker pull tendermint/devdoc +docs-lint-changed: + ./scripts/linting/lint-changed-md-files.sh -.PHONY: devdoc devdoc-clean devdoc-init devdoc-save devdoc-update +.PHONY: lint lint-fix lint-fix-changed docs-lint docs-lint-changed ############################################################################### ### Protobuf ### ############################################################################### -containerProtoVer=v0.2 -containerProtoImage=tendermintdev/sdk-proto-gen:$(containerProtoVer) -containerProtoGen=cosmos-sdk-proto-gen-$(containerProtoVer) -containerProtoGenSwagger=cosmos-sdk-proto-gen-swagger-$(containerProtoVer) -containerProtoFmt=cosmos-sdk-proto-fmt-$(containerProtoVer) +protoVer=0.11.5 +protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer) +protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) 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 - -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) sh ./scripts/protocgen.sh 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/protoc-swagger-gen.sh + +proto-format: + @$(protoImage) find ./ -name "*.proto" -exec clang-format -i {} \; 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 - -TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.0-rc6/proto/tendermint -GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos -CONFIO_URL = https://raw.githubusercontent.com/confio/ics23/v0.6.3 -SDK_PROTO_URL = https://raw.githubusercontent.com/cosmos/cosmos-sdk/v0.41.0/proto/cosmos - -TM_CRYPTO_TYPES = third_party/proto/tendermint/crypto -TM_ABCI_TYPES = third_party/proto/tendermint/abci -TM_TYPES = third_party/proto/tendermint/types -TM_VERSION = third_party/proto/tendermint/version -TM_LIBS = third_party/proto/tendermint/libs/bits -TM_P2P = third_party/proto/tendermint/p2p - -SDK_QUERY = third_party/proto/cosmos/base/query/v1beta1 -SDK_BASE = third_party/proto/cosmos/base/v1beta1 -SDK_UPGRADE = third_party/proto/cosmos/upgrade - -GOGO_PROTO_TYPES = third_party/proto/gogoproto -CONFIO_TYPES = third_party/proto/confio + @$(protoImage) buf breaking --against $(HTTPS_GIT)#branch=main proto-update-deps: - @mkdir -p $(GOGO_PROTO_TYPES) - @curl -sSL $(GOGO_PROTO_URL)/gogoproto/gogo.proto > $(GOGO_PROTO_TYPES)/gogo.proto - - @mkdir -p $(SDK_QUERY) - @curl -sSL $(SDK_PROTO_URL)/base/query/v1beta1/pagination.proto > $(SDK_QUERY)/pagination.proto - - @mkdir -p $(SDK_BASE) - @curl -sSL $(SDK_PROTO_URL)/base/v1beta1/coin.proto > $(SDK_BASE)/coin.proto - - @mkdir -p $(SDK_UPGRADE) - @curl -sSL $(SDK_PROTO_URL)/upgrade/v1beta1/upgrade.proto > $(SDK_UPGRADE)/v1beta1/upgrade.proto - -## Importing of tendermint protobuf definitions currently requires the -## use of `sed` in order to build properly with cosmos-sdk's proto file layout -## (which is the standard Buf.build FILE_LAYOUT) -## Issue link: https://github.com/tendermint/tendermint/issues/5021 - @mkdir -p $(TM_TYPES) - @curl -sSL $(TM_URL)/types/types.proto > $(TM_TYPES)/types.proto - @curl -sSL $(TM_URL)/types/validator.proto > $(TM_TYPES)/validator.proto - - @mkdir -p $(TM_VERSION) - @curl -sSL $(TM_URL)/version/types.proto > $(TM_VERSION)/types.proto - - @mkdir -p $(TM_LIBS) - @curl -sSL $(TM_URL)/libs/bits/types.proto > $(TM_LIBS)/types.proto - - @mkdir -p $(TM_CRYPTO_TYPES) - @curl -sSL $(TM_URL)/crypto/proof.proto > $(TM_CRYPTO_TYPES)/proof.proto - @curl -sSL $(TM_URL)/crypto/keys.proto > $(TM_CRYPTO_TYPES)/keys.proto - - @mkdir -p $(CONFIO_TYPES) - @curl -sSL $(CONFIO_URL)/proofs.proto > $(CONFIO_TYPES)/proofs.proto - -## insert go package option into proofs.proto file -## Issue link: https://github.com/confio/ics23/issues/32 - @sed -i '4ioption go_package = "github.com/confio/ics23/go";' $(CONFIO_TYPES)/proofs.proto + @echo "Updating Protobuf dependencies" + $(DOCKER) run --rm -v $(CURDIR)/proto:/workspace --workdir /workspace $(protoImageName) buf mod update .PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps - -############################################################################### -### Localnet ### -############################################################################### - -# Run a 4-node testnet locally -localnet-start: build-linux localnet-stop - $(if $(shell $(DOCKER) inspect -f '{{ .Id }}' cosmossdk/simd-env 2>/dev/null),$(info found image cosmossdk/simd-env),$(MAKE) -C contrib/images simd-env) - if ! [ -f build/node0/simd/config/genesis.json ]; then $(DOCKER) run --rm \ - --user $(shell id -u):$(shell id -g) \ - -v $(BUILDDIR):/simd:Z \ - -v /etc/group:/etc/group:ro \ - -v /etc/passwd:/etc/passwd:ro \ - -v /etc/shadow:/etc/shadow:ro \ - cosmossdk/simd-env testnet --v 4 -o . --starting-ip-address 192.168.10.2 --keyring-backend=test ; fi - docker-compose up -d - -localnet-stop: - docker-compose down - -.PHONY: localnet-start localnet-stop - -############################################################################### -### rosetta ### -############################################################################### -# builds rosetta test data dir -rosetta-data: - -docker container rm data_dir_build - docker build -t rosetta-ci:latest -f contrib/rosetta/node/Dockerfile . - docker run --name data_dir_build -t rosetta-ci:latest sh /rosetta/data.sh - docker cp data_dir_build:/tmp/data.tar.gz "$(CURDIR)/contrib/rosetta/node/data.tar.gz" - docker container rm data_dir_build -.PHONY: rosetta-data diff --git a/README.md b/README.md index f4a830c5149..1469fcd021d 100644 --- a/README.md +++ b/README.md @@ -31,12 +31,88 @@ Imported by - Lint Status + Tests / Code Coverage Status + E2E Status -The Inter-Blockchain Communication protocol (IBC) allows blockchains to talk to each other. IBC handles transport across different sovereign blockchains. This end-to-end, connection-oriented, stateful protocol provides reliable, ordered, and authenticated communication between heterogeneous blockchains. This IBC implementation in Golang is built as a Cosmos SDK module. +The [Inter-Blockchain Communication protocol (IBC)](https://ibcprotocol.dev/) allows blockchains to talk to each other. This end-to-end, connection-oriented, stateful protocol provides reliable, ordered, and authenticated communication between heterogeneous blockchains. -## Contents +This IBC implementation in Golang is built as a Cosmos SDK module. To understand more about how to use the `ibc-go` module as well as about the IBC protocol, please check out the Interchain Developer Academy [section on IBC](https://tutorials.cosmos.network/academy/3-ibc/), or [our docs](https://ibc.cosmos.network/main/ibc/overview.html). + +## Roadmap + +For an overview of upcoming changes to ibc-go take a look at the [roadmap](./docs/roadmap/roadmap.md). + +This roadmap is also available as a [project board](https://github.com/orgs/cosmos/projects/7/views/25). + +For the latest expected release timelines, please check [here](https://github.com/cosmos/ibc-go/wiki/Release-timeline). + +For the latest information on the progress of the work or the decisions made that might influence the roadmap, please follow our [engineering updates](https://github.com/cosmos/ibc-go/wiki/Engineering-updates). + +## Releases + +The release lines currently supported are v3, v4, v5 and v6. + +Please refer to the [Stable Release Policy section of RELEASES.md](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md#stable-release-policy) for more details. + +Please refer to our [versioning guide](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md) for more information on how to understand our release versioning. + +## Ecosystem + +Discover the applications, middleware and light clients developed by other awesome teams in the ecosystem: + +In the table below +`app` refers to IBC application modules for custom use cases and +`middleware` refers to modules that wrap an IBC application enabling custom logic to be executed. + +|Description|Repository|Type| +|----------|----------|----| +|An application that enables on chain querying of another IBC enabled chain utilizing `baseapp.Query`. Both chains must have implemented the query application and ICA (for queries requiring consensus).|[async-icq](https://github.com/strangelove-ventures/async-icq)|`app`| +|An application that enables on chain querying of another IBC enabled chains state without the need for the chain being queried to implement the application.|[interchain-queries](https://github.com/ingenuity-build/interchain-queries)|`app`| +|An application that enables on chain querying of another IBC enabled chains state without the need for the chain being queried to implement the application. Similar to the interchain-queries application in the row above but without callbacks.|[query](https://github.com/defund-labs/defund/tree/main/x/query)|`app`| +|An application that enables cross chain NFT transfer.|[NFT Transfer (ICS 721)](https://github.com/bianjieai/nft-transfer)|`app`| +|Middleware enabling a packet to be sent to a destination chain via an intermediate chain, e.g. going from Juno to Osmosis via the Hub.|[packet-forward-middleware](https://github.com/strangelove-ventures/packet-forward-middleware)|`middleware`| +|Middleware enabling the recovery of tokens sent to unsupported addresses.|[recovery](https://github.com/evmos/evmos/tree/main/x/recovery)|`middleware`| +|Middleware that limits the in or out flow of an asset in a certain time period to minimise the risks of cross chain token transfers. This is implemented as a middleware wrapping ICS20 with the rate limiting logic implemented by cosmwasm contracts|[ibc-rate-limit](https://github.com/osmosis-labs/osmosis/tree/main/x/ibc-rate-limit)|`middleware`| + +## Support + +We have active, helpful communities on Discord and Telegram. + +For questions and support please use the `developers` channel in the [Cosmos Network Discord server](https://discord.com/channels/669268347736686612/1019978171367559208) or join the [IBC Gang Discord server](https://discord.gg/RdpdkaXKpZ). The issue list of this repo is exclusively for bug reports and feature requests. + +To receive announcements of new releases or other technical updates, please join the [Telegram group that we administer](https://t.me/ibc_is_expansive). + +## Contributing + +If you're interested in contributing to ibc-go, please take a look at the [contributing guidelines](./CONTRIBUTING.md). We welcome and appreciate community contributions! + +This project adheres to ibc-go's [code of conduct](./CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. + +To help contributors understand which issues are good to pick up, we have the following two categories: + +- Issues with the label [`good first issue`](https://github.com/cosmos/ibc-go/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) should be pretty well defined and are best suited for developers new to ibc-go. +- Issues with the label [`help wanted`](https://github.com/cosmos/ibc-go/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) are a bit more involved and they usually require some familiarity already with the codebase. + +If you are interested in working on an issue, please comment on it; then we will be able to assign it to you. We will be happy to answer any questions you may have and help you out while you work on the issue. + +If you have any general questions or feedback, please reach out to us in the [IBC Gang Discord server](https://discord.com/channels/955868717269516318/955883113484013578). + +## Request for maintainership + +We have a document that describes the process for [submitting a feature for maintainership](./MAINTAINERSHIP.md) in the ibc-go codebase. + +## Security + +To report a security vulnerability, see our [bug bounty program](https://hackerone.com/cosmos). + +## Audits + +The following audits have been performed on the `ibc-go` source code: + +- [ICS27 Interchain Accounts](https://github.com/cosmos/ibc-go/tree/main/docs/apps/interchain-accounts/audits) by Trail of Bits + +## Quick Navigation 1. **[Core IBC Implementation](https://github.com/cosmos/ibc-go/tree/main/modules/core)** @@ -58,20 +134,21 @@ The Inter-Blockchain Communication protocol (IBC) allows blockchains to talk to 2.2 [ICS 27 Interchain Accounts](https://github.com/cosmos/ibc-go/tree/main/modules/apps/27-interchain-accounts) -3. **Light Clients** +3. **Middleware** - 3.1 [ICS 07 Tendermint](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/07-tendermint) + 3.1 [ICS 29 Fee Middleware](https://github.com/cosmos/ibc-go/tree/main/modules/apps/29-fee) - 3.2 [ICS 06 Solo Machine](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/06-solomachine) +4. **Light Clients** -Note: The localhost client is currently non-functional. + 4.1 [ICS 07 Tendermint](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/07-tendermint) -## Roadmap + 4.2 [ICS 06 Solo Machine](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/06-solomachine) -For an overview of upcoming changes to ibc-go take a look at the [roadmap](./docs/roadmap/roadmap.md). +5. **[E2E Integration Tests](https://github.com/cosmos/ibc-go/tree/main/e2e)** -## Resources +## Documentation and Resources -- [IBC Website](https://ibcprotocol.org/) -- [IBC Specification](https://github.com/cosmos/ibc) +- [IBC Website](https://ibcprotocol.dev/) +- [IBC Protocol Specification](https://github.com/cosmos/ibc) - [Documentation](https://ibc.cosmos.network/main/ibc/overview.html) +- [Interchain Developer Academy](https://tutorials.cosmos.network/academy/3-ibc/) diff --git a/RELEASES.md b/RELEASES.md index 9adabdc61f9..4c9cff29313 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -17,85 +17,86 @@ When bumping the dependencies of [Cosmos SDK](https://github.com/cosmos/cosmos-s [ibc-go](https://github.com/cosmos/ibc-go) and the [IBC protocol specification](https://github.com/cosmos/ibc) maintain different versions. Furthermore, ibc-go serves several different user groups (chains, IBC app developers, relayers, IBC light client developers). Each of these groups has different expectations of what *backwards compatible* means. It simply isn't possible to categorize a change as backwards or non backwards compatible for all user groups. We are primarily interested in when our API breaks and when changes are state machine breaking (thus requiring a coordinated upgrade). This is scoping the meaning of ibc-go to that of those interacting with the code (IBC app developers, relayers, IBC light client developers), not chains using IBC to communicate (that should be encapsulated by the IBC protocol specification versioning). -To summarize: **All our ibc-go releases allow chains to communicate successfully with any chain running any version of our code**. That is to say, we are still using IBC protocol specification v1.0. +To summarize: **All our ibc-go releases allow chains to communicate successfully with any chain running any version of our code**. That is to say, we are still using IBC protocol specification v1.0. We ensure all major releases are supported by relayers ([hermes](https://github.com/informalsystems/ibc-rs), [rly](https://github.com/strangelove-ventures/relayer) and [ts-relayer](https://github.com/confio/ts-relayer) at the moment) which can relay between the new major release and older releases. We have no plans of upgrading to an IBC protocol specification v2.0, as this would be very disruptive to the ecosystem. ## Release cycle -IBC-Go follows a traditional release cycle involving an alpha, beta, and rc (release candidate) releases before finalizing a new version. As ibc-go works in a non-traditional area, we apply our own interpretation to each release type. We reserve the right to make both go API breaking changes and state machine breaking changes throughout the entire release cycle. The stable release guarentees do not go into affect until a final release is performed. +IBC-Go follows a traditional release cycle involving an alpha, beta, and rc (release candidate) releases before finalizing a new version. As ibc-go works in a non-traditional area, we apply our own interpretation to each release type. We reserve the right to make both go API breaking changes and state machine breaking changes throughout the entire release cycle. The stable release guarantees do not go into affect until a final release is performed. -It is never advisable to use a non-final release in production. +It is never advisable to use a non-final release in production. ### Alpha -Alpha releases are intended to make available new features as soon as they are functional. No correctness guarentees are made and alpha releases **may** contain serious security vulnerabilities, bugs, and lack of user tooling, so long as they don't affect the core functionality. +Alpha releases are intended to make available new features as soon as they are functional. No correctness guarantees are made and alpha releases **may** contain serious security vulnerabilities, bugs, and lack of user tooling, so long as they don't affect the core functionality. Initial users of alpha releases are expected to be advanced, patient, and capable of handling unusual errors. Very basic integration testing will be performed by the ibc-go development team before alpha releases. -An internal audit is typically performed before the alpha release allowing the development team to guage the maturity and stability of changes included in the next release. +An internal audit is typically performed before the alpha release allowing the development team to guage the maturity and stability of changes included in the next release. ### Beta -Beta releases are intended to signal design stability. While the go API is still subject to change, the core design of the new features should not be. Developers integrating the new features should expect to handle breaking changes when upgrading to RC's. +Beta releases are intended to signal design stability. While the go API is still subject to change, the core design of the new features should not be. Developers integrating the new features should expect to handle breaking changes when upgrading to RC's. -Beta releases should not be made with known bugs or security vulnerabilities. Beta releases should focus on ironing out remaining bugs and filling out the UX functionality required by a final release. Beta releases should have a clearly defined scope of the features that will be included in the release. Only highly requested feature additions should be acted upon in this phase. +Beta releases should not be made with known bugs or security vulnerabilities. Beta releases should focus on ironing out remaining bugs and filling out the UX functionality required by a final release. Beta releases should have a clearly defined scope of the features that will be included in the release. Only highly requested feature additions should be acted upon in this phase. -When the development team has determined a release is ready to enter the RC phase, a final security audit should be performed. The security audit should be limited to looking for bugs and security vulnerabilities. Code improvements may be noted, but they should not be acted upon unless highly desirable. +When the development team has determined a release is ready to enter the RC phase, a final security audit should be performed. The security audit should be limited to looking for bugs and security vulnerabilities. Code improvements may be noted, but they should not be acted upon unless highly desirable. -### RC +### RC RC's are release candidates. Final releases should contain little to no changes in comparison to the latest RC. Changes included in between RC releases should be limited to: + - Improved testing - UX additions - Bug fixes - Highly requested changes by the community -A release should not be finalized until the development team and the external community have done sufficient integration tests on the targeted release. +A release should not be finalized until the development team and the external community have done sufficient integration tests on the targeted release. ## Stable Release Policy The beginning of a new major release series is marked by the release of a new major version. A major release series is comprised of all minor and patch releases made under the same major version number. The series continues to receive bug fixes (released as minor or patch releases) until it reaches end of life. The date when a major release series reaches end of life is determined by one of the two following methods: -- If the next major release is made within the first 6 months, then the end of life date of the major release series is 1 year after its initial release. + +- If the next major release is made within the first 6 months, then the end of life date of the major release series is 1 year after its initial release. - If the next major release is made 6 months after the initial release, then the end of life date of the major release series is 6 months after the release date of the next major release. -For example, if the current major release series is v1 and was released on January 1st, 2022, then v1 will be supported at least until January 1st, 2023. If v2 is published on August 1st 2022, then v1's end of life will be March 1st, 2023. +For example, if the current major release series is v1 and was released on January 1st, 2022, then v1 will be supported at least until January 1st, 2023. If v2 is published on August 1st 2022, then v1's end of life will be March 1st, 2023. Only the following major release series have a stable release status: |Release|End of Life Date| |-------|----------------| -|`v1.3.x`|July 01, 2022| -|`v1.4.x`|July 01, 2022| -|`v1.5.x`|July 01, 2022| -|`v2.1.x`|February 01, 2023| -|`v2.2.x`|February 01, 2023| -|`v2.3.x`|February 01, 2023| -|`v3.0.x`|March 15, 2023| -|`v3.1.x`|March 15, 2023| +|`v3.3.x`|March 15, 2023| +|`v3.4.x`|March 15, 2023| +|`v4.1.x`|August 12, 2023| +|`v4.2.x`|August 12, 2023| +|`v4.3.x`|August 12, 2023| +|`v5.2.x`|September 28, 2023| +|`v6.1.x`|December 09, 2023| -**Note**: The v1 major release series will reach end of life 6 months after merging this policy. v2 will reach end of life one year after merging this policy. +All missing minor release versions have been discontinued. ### What pull requests will be included in stable patch-releases? Pull requests that fix bugs and add features that fall in the following categories: -* **Severe regressions**. -* Bugs that may cause **client applications** to be **largely unusable**. -* Bugs that may cause **state corruption or data loss**. -* Bugs that may directly or indirectly cause a **security vulnerability**. -* Non-breaking features that are strongly requested by the community. -* Non-breaking CLI improvements that are strongly requested by the community. +- **Severe regressions**. +- Bugs that may cause **client applications** to be **largely unusable**. +- Bugs that may cause **state corruption or data loss**. +- Bugs that may directly or indirectly cause a **security vulnerability**. +- Non-breaking features that are strongly requested by the community. +- Non-breaking CLI improvements that are strongly requested by the community. ### What pull requests will NOT be automatically included in stable patch-releases? As rule of thumb, the following changes will **NOT** be automatically accepted into stable point-releases: -* **State machine changes**, unless the previous behaviour would result in a consensus halt. -* **Protobuf-breaking changes**. -* **Client-breaking changes**, i.e. changes that prevent gRPC, HTTP and RPC clients to continue interacting with the node without any change. -* **API-breaking changes**, i.e. changes that prevent client applications to *build without modifications* to the client application's source code. -* **CLI-breaking changes**, i.e. changes that require usage changes for CLI users. +- **State machine changes**, unless the previous behaviour would result in a consensus halt. +- **Protobuf-breaking changes**. +- **Client-breaking changes**, i.e. changes that prevent gRPC, HTTP and RPC clients to continue interacting with the node without any change. +- **API-breaking changes**, i.e. changes that prevent client applications to *build without modifications* to the client application's source code. +- **CLI-breaking changes**, i.e. changes that require usage changes for CLI users. ## Version matrix @@ -103,33 +104,32 @@ Versions of Golang, Cosmos SDK and Tendermint used by ibc-go in the currently ac | Go | ibc-go | Cosmos SDK | Tendermint | |----|--------|------------|------------| -| 1.15 | v2.1.0 | v0.44.6 | v0.34.14 | -| 1.15 | v2.1.1 | v0.44.8 | v0.34.19 | -| 1.15 | v2.2.0 | v0.45.1 | v0.34.14 | -| 1.15 | v2.2.1 | v0.45.1 | v0.34.14 | -| 1.17 | v2.3.0 | v0.45.4 | v0.34.19 | -| 1.17 | v3.0.0 | v0.45.1 | v0.34.14 | -| 1.17 | v3.0.1 | v0.45.4 | v0.34.19 | -| 1.17 | v3.1.0 | v0.45.4 | v0.34.19 | +| 1.18 | v3.3.1 | v0.45.10 | v0.34.22 | +| 1.18 | v3.4.0 | v0.45.10 | v0.34.22 | +| 1.18 | v4.1.1 | v0.45.10 | v0.34.22 | +| 1.18 | v4.2.0 | v0.45.10 | v0.34.22 | +| 1.18 | v4.3.0 | v0.45.12 | v0.34.24 | +| 1.18 | v5.2.0 | v0.46.7 | v0.34.24 | +| 1.18 | v6.1.0 | v0.46.7 | v0.34.24 | ## Graphics The decision tree above was generated with the following code: -``` +```text %%{init: - {'theme': 'default', - 'themeVariables': - {'fontFamily': 'verdana', 'fontSize': '13px'} - } + {'theme': 'default', + 'themeVariables': + {'fontFamily': 'verdana', 'fontSize': '13px'} + } }%% flowchart TD - A(Change):::c --> B{API breaking?} - B:::c --> |Yes| C(Increase major version):::c - B:::c --> |No| D{state-machine breaking?} - D:::c --> |Yes| G(Increase minor version):::c - D:::c --> |No| H(Increase patch version):::c - classDef c fill:#eee,stroke:#aaa + A(Change):::c --> B{API breaking?} + B:::c --> |Yes| C(Increase major version):::c + B:::c --> |No| D{state-machine breaking?} + D:::c --> |Yes| G(Increase minor version):::c + D:::c --> |No| H(Increase patch version):::c + classDef c fill:#eee,stroke:#aaa ``` using [Mermaid](https://mermaid-js.github.io)'s [live editor](https://mermaid.live). diff --git a/buf.work.yaml b/buf.work.yaml index 98094695ffe..1b4a0d95c29 100644 --- a/buf.work.yaml +++ b/buf.work.yaml @@ -6,4 +6,3 @@ version: v1 directories: - proto - - third_party/proto diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 00000000000..c29518f5bbf --- /dev/null +++ b/cliff.toml @@ -0,0 +1,119 @@ +# configuration file for git-cliff (0.1.0) + +[changelog] +# changelog header +header = """ + + +# Changelog +All notable changes to this project will be documented in this file. +""" +# template for the changelog body +# https://tera.netlify.app/docs/#introduction +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | striptags | trim | upper_first }} + {% for commit in commits %} + * {{ commit.message | upper_first }}\ + {% endfor %} +{% endfor %}\n +""" +# remove the leading and trailing whitespace from the template +trim = true +# changelog footer +footer = """ + +""" + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = true +# process each line of a commit as an individual commit +split_commits = true +# regex for preprocessing the commit messages +commit_preprocessors = [ + # A reference to an issue is appened to commits that looks like "(#1234)", this will be replaced + # with a link to that issue, e.g. "[#$1234](https://github.com/cosmos/ibc-go/issues/1234)". + { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/cosmos/ibc-go/issues/${2}))" }, + # any reference to a pr like "pr-1234" will be replaced with a link to the PR. + { pattern = '\(pr-([0-9]+)\)', replace = "([#${1}](https://github.com/cosmos/ibc-go/pulls/${1}))" }, + + # the following patterns only exist because "split_commits" is set to true, and we are processesing + # each line of the commit as a separate message. + # these exist to filter out common messages that appear in commit messages that are technically + # conventional, but we do not way to include in the changelog. + { pattern = '^Signed-off-by:.*', replace='' }, + { pattern = '^Co-authored-by:.*', replace='' }, + # don't include references to issues as changelog entries. + { pattern = '^ref:.*', replace='' }, + # exclude CVSS format, CVE can still be included in regular conventinal commits. + { pattern = 'CVSS:.*', replace='' }, + # don't include dependabot auto merge entries. + { pattern = '.*dependabot-automerge-.*', replace='' }, + # don't include statements saying which issue is closed. + { pattern = '^closes:.*', replace='' }, + # remove standalone links in the commit messages. + { pattern = '^https://.*', replace='' }, + # remove lines with html. + { pattern = '^<.*', replace='' }, +] + +# regex for parsing and grouping commits +commit_parsers = [ + # specifying the number in a comment is a workaround to enable ordering of groups. + # these comments are stripped out of the markdown with the filter "{{ group | striptags | trim | upper_first }}" + # above in the body template. + { message = "^((?i)deps|(?i)dep|(?i)build)", group = "Dependencies" }, + { message = '^.*\(api\)!', group = "API Breaking" }, + { message = '^.*\(statemachine\)!', group = "State Machine Breaking" }, + { message = "^((?i)improvements|(?i)imp)", group = "Improvements" }, + { message = "^((?i)feature|(?i)feat)", group = "Features" }, + { message = "^((?i)fix|(?i)bug)", group = "Bug Fixes" }, + { message = "^((?i)doc|(?i)docs|(?i)documentation)", group = "Documentation" }, + { message = "^((?i)test|(?i)e2e)", group = "Testing" }, + { message = "^((?i)deprecated)", group = "Deprecated" }, + { message = "^((?i)chore|(?i)misc|(?i)nit)", group = "Miscellaneous Tasks" }, +] +# filter out the commits that are not matched by commit parsers +filter_commits = false +# glob pattern for matching git tags +tag_pattern = "v[0-9]*" +# regex for skipping tags +skip_tags = "" +# regex for ignoring tags +ignore_tags = "" +# sort the tags chronologically +date_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "oldest" diff --git a/cmd/build_test_matrix/main.go b/cmd/build_test_matrix/main.go index c86324b31f8..a59e57d9e27 100644 --- a/cmd/build_test_matrix/main.go +++ b/cmd/build_test_matrix/main.go @@ -16,6 +16,13 @@ const ( testNamePrefix = "Test" testFileNameSuffix = "_test.go" e2eTestDirectory = "e2e" + // testEntryPointEnv specifes a single test function to run if provided. + testEntryPointEnv = "TEST_ENTRYPOINT" + // testExclusionsEnv is a comma separated list of test function names that will not be included + // in the results of this script. + testExclusionsEnv = "TEST_EXCLUSIONS" + // testNameEnv if provided returns a single test entry so that only one test is actually run. + testNameEnv = "TEST_NAME" ) // GithubActionTestMatrix represents @@ -24,12 +31,12 @@ type GithubActionTestMatrix struct { } type TestSuitePair struct { - Test string `json:"test"` - Suite string `json:"suite"` + Test string `json:"test"` + EntryPoint string `json:"entrypoint"` } func main() { - githubActionMatrix, err := getGithubActionMatrixForTests(e2eTestDirectory) + githubActionMatrix, err := getGithubActionMatrixForTests(e2eTestDirectory, getTestToRun(), getTestEntrypointToRun(), getExcludedTestFunctions()) if err != nil { fmt.Printf("error generating github action json: %s", err) os.Exit(1) @@ -43,13 +50,55 @@ func main() { fmt.Println(string(ghBytes)) } +// getTestEntrypointToRun returns the specified test function to run if present, otherwise +// it returns an empty string which will result in running all test suites. +func getTestEntrypointToRun() string { + testSuite, ok := os.LookupEnv(testEntryPointEnv) + if !ok { + return "" + } + return testSuite +} + +// getTestToRun returns the specified test function to run if present. +// If specified, only this test will be run. +func getTestToRun() string { + testName, ok := os.LookupEnv(testNameEnv) + if !ok { + return "" + } + return testName +} + +// getExcludedTestFunctions returns a list of test functions that we don't want to run. +func getExcludedTestFunctions() []string { + exclusions, ok := os.LookupEnv(testExclusionsEnv) + if !ok { + return nil + } + return strings.Split(exclusions, ",") +} + +func contains(s string, items []string) bool { + for _, elem := range items { + if elem == s { + return true + } + } + return false +} + // getGithubActionMatrixForTests returns a json string representing the contents that should go in the matrix // field in a github action workflow. This string can be used with `fromJSON(str)` to dynamically build // the workflow matrix to include all E2E tests under the e2eRootDirectory directory. -func getGithubActionMatrixForTests(e2eRootDirectory string) (GithubActionTestMatrix, error) { +func getGithubActionMatrixForTests(e2eRootDirectory, testName string, suite string, excludedItems []string) (GithubActionTestMatrix, error) { testSuiteMapping := map[string][]string{} fset := token.NewFileSet() err := filepath.Walk(e2eRootDirectory, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return fmt.Errorf("error walking e2e directory: %s", err) + } + // only look at test files if !strings.HasSuffix(path, testFileNameSuffix) { return nil @@ -65,11 +114,20 @@ func getGithubActionMatrixForTests(e2eRootDirectory string) (GithubActionTestMat return fmt.Errorf("failed extracting test suite name and test cases: %s", err) } - testSuiteMapping[suiteNameForFile] = testCases + if testName != "" && contains(testName, testCases) { + testCases = []string{testName} + } + + if contains(suiteNameForFile, excludedItems) { + return nil + } + + if suite == "" || suiteNameForFile == suite { + testSuiteMapping[suiteNameForFile] = testCases + } return nil }) - if err != nil { return GithubActionTestMatrix{}, err } @@ -81,12 +139,16 @@ func getGithubActionMatrixForTests(e2eRootDirectory string) (GithubActionTestMat for testSuiteName, testCases := range testSuiteMapping { for _, testCaseName := range testCases { gh.Include = append(gh.Include, TestSuitePair{ - Test: testCaseName, - Suite: testSuiteName, + Test: testCaseName, + EntryPoint: testSuiteName, }) } } + if testName != "" && len(gh.Include) != 1 { + return GithubActionTestMatrix{}, fmt.Errorf("expected exactly 1 test in the output matrix but got %d", len(gh.Include)) + } + return gh, nil } diff --git a/cmd/build_test_matrix/main_test.go b/cmd/build_test_matrix/main_test.go index 47de4d981c2..732973efe0e 100644 --- a/cmd/build_test_matrix/main_test.go +++ b/cmd/build_test_matrix/main_test.go @@ -19,7 +19,7 @@ const ( func TestGetGithubActionMatrixForTests(t *testing.T) { t.Run("empty dir does not fail", func(t *testing.T) { testingDir := t.TempDir() - _, err := getGithubActionMatrixForTests(testingDir) + _, err := getGithubActionMatrixForTests(testingDir, "", "", nil) assert.NoError(t, err) }) @@ -27,18 +27,18 @@ func TestGetGithubActionMatrixForTests(t *testing.T) { testingDir := t.TempDir() createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) - gh, err := getGithubActionMatrixForTests(testingDir) + gh, err := getGithubActionMatrixForTests(testingDir, "", "", nil) assert.NoError(t, err) expected := GithubActionTestMatrix{ Include: []TestSuitePair{ { - Suite: "TestFeeMiddlewareTestSuite", - Test: "TestA", + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestA", }, { - Suite: "TestFeeMiddlewareTestSuite", - Test: "TestB", + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestB", }, }, } @@ -50,26 +50,26 @@ func TestGetGithubActionMatrixForTests(t *testing.T) { createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) createFileWithTestSuiteAndTests(t, "TransferTestSuite", "TestC", "TestD", testingDir, goTestFileNameTwo) - gh, err := getGithubActionMatrixForTests(testingDir) + gh, err := getGithubActionMatrixForTests(testingDir, "", "", nil) assert.NoError(t, err) expected := GithubActionTestMatrix{ Include: []TestSuitePair{ { - Suite: "TestTransferTestSuite", - Test: "TestC", + EntryPoint: "TestTransferTestSuite", + Test: "TestC", }, { - Suite: "TestFeeMiddlewareTestSuite", - Test: "TestA", + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestA", }, { - Suite: "TestFeeMiddlewareTestSuite", - Test: "TestB", + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestB", }, { - Suite: "TestTransferTestSuite", - Test: "TestD", + EntryPoint: "TestTransferTestSuite", + Test: "TestD", }, }, } @@ -77,11 +77,39 @@ func TestGetGithubActionMatrixForTests(t *testing.T) { assertGithubActionTestMatricesEqual(t, expected, gh) }) + t.Run("single test can be specified", func(t *testing.T) { + testingDir := t.TempDir() + createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) + createFileWithTestSuiteAndTests(t, "TransferTestSuite", "TestC", "TestD", testingDir, goTestFileNameTwo) + + gh, err := getGithubActionMatrixForTests(testingDir, "TestA", "TestFeeMiddlewareTestSuite", nil) + assert.NoError(t, err) + + expected := GithubActionTestMatrix{ + Include: []TestSuitePair{ + { + EntryPoint: "TestFeeMiddlewareTestSuite", + Test: "TestA", + }, + }, + } + + assertGithubActionTestMatricesEqual(t, expected, gh) + }) + + t.Run("error if single test doesn't exist", func(t *testing.T) { + testingDir := t.TempDir() + createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, goTestFileNameOne) + + _, err := getGithubActionMatrixForTests(testingDir, "TestThatDoesntExist", "TestFeeMiddlewareTestSuite", nil) + assert.Error(t, err) + }) + t.Run("non test files are not picked up", func(t *testing.T) { testingDir := t.TempDir() createFileWithTestSuiteAndTests(t, "FeeMiddlewareTestSuite", "TestA", "TestB", testingDir, nonTestFile) - gh, err := getGithubActionMatrixForTests(testingDir) + gh, err := getGithubActionMatrixForTests(testingDir, "", "", nil) assert.NoError(t, err) assert.Empty(t, gh.Include) }) @@ -102,10 +130,10 @@ func SuiteTwo(t *testing.T) { type FeeMiddlewareTestSuite struct {} ` - err := os.WriteFile(path.Join(testingDir, goTestFileNameOne), []byte(fileWithTwoSuites), os.FileMode(777)) + err := os.WriteFile(path.Join(testingDir, goTestFileNameOne), []byte(fileWithTwoSuites), os.FileMode(0o777)) assert.NoError(t, err) - _, err = getGithubActionMatrixForTests(testingDir) + _, err = getGithubActionMatrixForTests(testingDir, "", "", nil) assert.Error(t, err) }) } @@ -116,25 +144,24 @@ func assertGithubActionTestMatricesEqual(t *testing.T, expected, actual GithubAc sort.SliceStable(expected.Include, func(i, j int) bool { memberI := expected.Include[i] memberJ := expected.Include[j] - if memberI.Suite == memberJ.Suite { + if memberI.EntryPoint == memberJ.EntryPoint { return memberI.Test < memberJ.Test } - return memberI.Suite < memberJ.Suite + return memberI.EntryPoint < memberJ.EntryPoint }) sort.SliceStable(actual.Include, func(i, j int) bool { memberI := actual.Include[i] memberJ := actual.Include[j] - if memberI.Suite == memberJ.Suite { + if memberI.EntryPoint == memberJ.EntryPoint { return memberI.Test < memberJ.Test } - return memberI.Suite < memberJ.Suite + return memberI.EntryPoint < memberJ.EntryPoint }) assert.Equal(t, expected.Include, actual.Include) } func goTestFileContents(suiteName, fnName1, fnName2 string) string { - replacedSuiteName := strings.ReplaceAll(`package foo func TestSuiteName(t *testing.T) { @@ -157,6 +184,6 @@ func helper() {} func createFileWithTestSuiteAndTests(t *testing.T, suiteName, fn1Name, fn2Name, dir, filename string) { goFileContents := goTestFileContents(suiteName, fn1Name, fn2Name) - err := os.WriteFile(path.Join(dir, filename), []byte(goFileContents), os.FileMode(777)) + err := os.WriteFile(path.Join(dir, filename), []byte(goFileContents), os.FileMode(0o777)) assert.NoError(t, err) } diff --git a/cmd/determine_simd_tag/main.go b/cmd/determine_simd_tag/main.go deleted file mode 100644 index af3a6281268..00000000000 --- a/cmd/determine_simd_tag/main.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "flag" - "fmt" -) - -var prNum string - -func init() { - flag.StringVar(&prNum, "pr", "", "the number of the pr") - flag.Parse() -} - -// in the context of a GithubAction workflow, the PR is non empty if it is a pr. When -// code is merged to main, it will be empty. In this case we just use the "main" tag. -func main() { - fmt.Printf(getSimdTag(prNum)) -} - -func getSimdTag(prNum string) string { - if prNum == "" { - return "main" - } - return fmt.Sprintf("pr-%s", prNum) -} diff --git a/contrib/devtools/Makefile b/contrib/devtools/Makefile new file mode 100644 index 00000000000..dc9eb0c8e3b --- /dev/null +++ b/contrib/devtools/Makefile @@ -0,0 +1,76 @@ +### +# Find OS and Go environment +# GO contains the Go binary +# FS contains the OS file separator +### +ifeq ($(OS),Windows_NT) + GO := $(shell where go.exe 2> NUL) + FS := "\\" +else + GO := $(shell command -v go 2> /dev/null) + FS := "/" +endif + +ifeq ($(GO),) + $(error could not find go. Is it in PATH? $(GO)) +endif + +############################################################################### +### Functions ### +############################################################################### + +go_get = $(if $(findstring Windows_NT,$(OS)),\ +IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS) ( mkdir $(GITHUBDIR)$(FS)$(1) ) else (cd .) &\ +IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS)$(2)$(FS) ( cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2) ) else (cd .) &\ +,\ +mkdir -p $(GITHUBDIR)$(FS)$(1) &&\ +(test ! -d $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2)) || true &&\ +)\ +cd $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && git fetch origin && git checkout -q $(3) + +mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +mkfile_dir := $(shell cd $(shell dirname $(mkfile_path)); pwd) + + +############################################################################### +### Tools ### +############################################################################### + +PREFIX ?= /usr/local +BIN ?= $(PREFIX)/bin +UNAME_S ?= $(shell uname -s) +UNAME_M ?= $(shell uname -m) + +GOPATH ?= $(shell $(GO) env GOPATH) +GITHUBDIR := $(GOPATH)$(FS)src$(FS)github.com + +BUF_VERSION ?= 0.11.0 + +TOOLS_DESTDIR ?= $(GOPATH)/bin +STATIK = $(TOOLS_DESTDIR)/statik +RUNSIM = $(TOOLS_DESTDIR)/runsim + +tools: tools-stamp +tools-stamp: statik runsim + # Create dummy file to satisfy dependency and avoid + # rebuilding when this Makefile target is hit twice + # in a row. + touch $@ + +# Install the runsim binary +statik: $(STATIK) +$(STATIK): + @echo "Installing statik..." + @go install github.com/rakyll/statik@v0.1.6 + +# Install the runsim binary +runsim: $(RUNSIM) +$(RUNSIM): + @echo "Installing runsim..." + @go install github.com/cosmos/tools/cmd/runsim@v1.0.0 + +tools-clean: + rm -f $(STATIK) $(GOLANGCI_LINT) $(RUNSIM) + rm -f tools-stamp + +.PHONY: tools-clean statik runsim diff --git a/contrib/test_cover.sh b/contrib/test_cover.sh new file mode 100644 index 00000000000..24f7804b516 --- /dev/null +++ b/contrib/test_cover.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -e + +PKGS=$(go list ./... | grep -v '/simapp') + +set -e +echo "mode: atomic" > coverage.txt +for pkg in ${PKGS[@]}; do + go test -v -timeout 30m -race -coverprofile=profile.out -covermode=atomic -tags='ledger test_ledger_mock' "$pkg" + if [ -f profile.out ]; then + tail -n +2 profile.out >> coverage.txt; + rm profile.out + fi +done diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index f459a997da6..ba11c556e9e 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -100,6 +100,14 @@ module.exports = { label: "v2.3.0", key: "v2.3.0", }, + { + label: "v2.4.0", + key: "v2.4.0", + }, + { + label: "v2.5.0", + key: "v2.5.0", + }, { label: "v3.0.0", key: "v3.0.0", @@ -108,6 +116,50 @@ module.exports = { label: "v3.1.0", key: "v3.1.0", }, + { + label: "v3.2.0", + key: "v3.2.0", + }, + { + label: "v3.3.0", + key: "v3.3.0", + }, + { + label: "v3.4.0", + key: "v3.4.0", + }, + { + label: "v4.0.0", + key: "v4.0.0", + }, + { + label: "v4.1.0", + key: "v4.1.0", + }, + { + label: "v4.2.0", + key: "v4.2.0", + }, + { + label: "v4.3.0", + key: "v4.3.0", + }, + { + label: "v5.0.0", + key: "v5.0.0", + }, + { + label: "v5.1.0", + key: "v5.1.0", + }, + { + label: "v5.2.0", + key: "v5.2.0", + }, + { + label: "v6.1.0", + key: "v6.1.0", + }, ], topbar: { banner: true, @@ -179,29 +231,61 @@ module.exports = { path: "/apps/interchain-accounts/overview.html", }, { - title: "Authentication Modules", + title: "Development Use Cases", directory: false, - path: "/apps/interchain-accounts/auth-modules.html", + path: "/apps/interchain-accounts/development.html", }, { - title: "Active Channels", + title: "Authentication Modules", directory: false, - path: "/apps/interchain-accounts/active-channels.html", + path: "/apps/interchain-accounts/auth-modules.html", }, { title: "Integration", directory: false, path: "/apps/interchain-accounts/integration.html", }, + { + title: "Messages", + directory: false, + path: "/apps/interchain-accounts/messages.html", + }, { title: "Parameters", directory: false, path: "/apps/interchain-accounts/parameters.html", }, { - title: "Transactions", + title: "Client", directory: false, - path: "/apps/interchain-accounts/transactions.html", + path: "/apps/interchain-accounts/client.html", + }, + { + title: "Active Channels", + directory: false, + path: "/apps/interchain-accounts/active-channels.html", + }, + { + title: "Legacy", + directory: true, + path: "/apps/interchain-accounts", + children: [ + { + title: "Authentication Modules", + directory: false, + path: "/apps/interchain-accounts/legacy/auth-modules.html", + }, + { + title: "Integration", + directory: false, + path: "/apps/interchain-accounts/legacy/integration.html", + }, + { + title: "Keeper API", + directory: false, + path: "/apps/interchain-accounts/legacy/keeper-api.html", + }, + ] }, ], }, @@ -245,6 +329,95 @@ module.exports = { directory: false, path: "/apps/transfer/params.html", }, + { + title: "Authorizations", + directory: false, + path: "/apps/transfer/authorizations.html", + }, + ], + }, + ], + }, + { + title: "IBC Light Clients", + children: [ + { + title: "Developer Guide", + directory: true, + path: "/ibc/light-clients", + children: [ + { + title: "Overview", + directory: false, + path: "/ibc/light-clients/overview.html", + }, + { + title: "Client State interface", + directory: false, + path: "/ibc/light-clients/client-state.html", + }, + { + title: "Consensus State interface", + directory: false, + path: "/ibc/light-clients/consensus-state.html", + }, + { + title: "Handling Updates and Misbehaviour", + directory: false, + path: "/ibc/light-clients/updates-and-misbehaviour.html", + }, + { + title: "Handling Upgrades", + directory: false, + path: "/ibc/light-clients/upgrades.html", + }, + { + title: "Existence/Non-Existence Proofs", + directory: false, + path: "/ibc/light-clients/proofs.html", + }, + { + title: "Handling Proposals", + directory: false, + path: "/ibc/light-clients/proposals.html", + }, + { + title: "Handling Genesis", + directory: false, + path: "/ibc/light-clients/genesis.html", + }, + { + title: "Setup", + directory: false, + path: "/ibc/light-clients/setup.html", + }, + ] + }, + { + title: "Solomachine", + directory: true, + path: "/ibc/light-clients/solomachine", + children: [ + { + title: "Solomachine", + directory: false, + path: "/ibc/light-clients/solomachine/solomachine.html", + }, + { + title: "Concepts", + directory: false, + path: "/ibc/light-clients/solomachine/concepts.html", + }, + { + title: "State", + directory: false, + path: "/ibc/light-clients/solomachine/state.html", + }, + { + title: "State Transitions", + directory: false, + path: "/ibc/light-clients/solomachine/state_transitions.html", + }, ], }, ], @@ -320,6 +493,21 @@ module.exports = { directory: false, path: "/migrations/v3-to-v4.html", }, + { + title: "IBC-Go v4 to v5", + directory: false, + path: "/migrations/v4-to-v5.html", + }, + { + title: "IBC-Go v5 to v6", + directory: false, + path: "/migrations/v5-to-v6.html", + }, + { + title: "IBC-Go v6 to v7", + directory: false, + path: "/migrations/v6-to-v7.html", + }, ], }, { @@ -352,8 +540,8 @@ module.exports = { text: "Chat with IBC developers in Discord.", }, textLink: { - text: "ibcprotocol.org", - url: "https://ibcprotocol.org", + text: "ibcprotocol.dev", + url: "https://ibcprotocol.dev", }, services: [ { diff --git a/docs/DOCS_GUIDELINES.md b/docs/DOCS_GUIDELINES.md new file mode 100644 index 00000000000..3539d3e13aa --- /dev/null +++ b/docs/DOCS_GUIDELINES.md @@ -0,0 +1,41 @@ +# Documentation guidelines + +## Best practices + +- Check the spelling and grammar, even if you have to copy and paste from an external source. +- Use simple sentences. Easy-to-read sentences mean the reader can quickly use the guidance you share. +- Try to express your thoughts in a concise and clean way. +- Either Leave a space or use a `-` between the acronyms ADR and ICS and the corresponding number (e.g. ADR 008 or ADR-008, and ICS 27 or ICS-27). +- Don't overuse `code` format when writing in plain English. +- Follow Google developer documentation [style guide](https://developers.google.com/style). +- Check the meaning of words in Microsoft's [A-Z word list and term collections](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/accessibility-terms) (use the search input!). +- We recommend using RFC keywords in user documentation (lowercase). The RFC keywords are: "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL. They are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119). +- Lint the markdown files for documentation with [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli). Run `make docs-lint` (you will need to have `markdownlint-cli` installed, so please follow the [installation instructions](https://github.com/igorshubovych/markdownlint-cli#installation)). + +### Links + +**NOTE:** Strongly consider the existing links (both within this directory and to the website docs) when moving or deleting files. + +Relative links should be used nearly everywhere, due to versioning. Note that in case of page reshuffling, you must update all links references. + +### Code snippets + +Code snippets can be included in the documentation using normal Markdown code blocks. For example: + +```md + ```go + func() {} + ``` +``` + +It is also possible to include code snippets from GitHub files by referencing the files directly (and the line numbers if needed). For example: + +```md + ```go reference + https://github.com/cosmos/ibc-go/blob/v5.0.0/modules/core/04-channel/keeper/handshake.go#L18-L65 + ``` +``` + +## Technical writing course + +Google provides a free [course](https://developers.google.com/tech-writing/overview) for technical writing. diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md index fb6e4f2acc3..00a117f71b7 100644 --- a/docs/DOCS_README.md +++ b/docs/DOCS_README.md @@ -10,7 +10,7 @@ If you want to update the documentation please open a pr on ibc-go. ## Docs Build Workflow -The documentation for IBC-Go is hosted at https://ibc.cosmos.network. +The documentation for IBC-Go is hosted at . built from the files in this (`/docs`) directory for [main](https://github.com/cosmos/ibc-go/tree/main/docs). @@ -83,7 +83,7 @@ Install the theme and all dependencies. npm run serve ``` -Run `pre` and `post` hooks and start a hot-reloading web-server. See output of this command for the URL (it is often https://localhost:8080). +Run `pre` and `post` hooks and start a hot-reloading web-server. See output of this command for the URL (it is often ). To build documentation as a static website run `npm run build`. You will find the website in `.vuepress/dist` directory. @@ -96,19 +96,22 @@ We are using [Algolia](https://www.algolia.com) to power full-text search. This ## Consistency Because the build processes are identical (as is the information contained herein), this file should be kept in sync as -much as possible with its [counterpart in the Cosmos SDK repo](https://github.com/cosmos/cosmos-sdk/tree/master/docs/DOCS_README.md). +much as possible with its [counterpart in the Cosmos SDK repo](https://github.com/cosmos/cosmos-sdk/blob/main/docs/README.md). ### Update and Build the RPC docs 1. Execute the following command at the root directory to install the swagger-ui generate tool. + ```bash make tools ``` + 2. Edit API docs 1. Directly Edit API docs manually: `client/lcd/swagger-ui/swagger.yaml`. 2. Edit API docs within the [Swagger Editor](https://editor.swagger.io/). Please refer to this [document](https://swagger.io/docs/specification/2-0/basic-structure/) for the correct structure in `.yaml`. 3. Download `swagger.yaml` and replace the old `swagger.yaml` under fold `client/lcd/swagger-ui`. 4. Compile simd + ```bash make install ``` diff --git a/docs/OLD_README.md b/docs/OLD_README.md deleted file mode 100644 index 47bb2547732..00000000000 --- a/docs/OLD_README.md +++ /dev/null @@ -1,117 +0,0 @@ - - - -# `ibc` - -## Abstract - -This specification defines the implementation of the IBC protocol on the Cosmos SDK, the -changes made to the specification and where to find each specific ICS spec within -the module. - -For the general specification please refer to the [Interchain Standards](https://github.com/cosmos/ics). - -## Contents - -1. **Applications** - - 1.1. [Transfer](./../applications/transfer/spec/README.md) -2. **[Core](./../core/spec/README.md)** -3. **Light Clients** - - 3.1 [Solo Machine Client](./../light-clients/06-solomachine/spec/README.md) - - 3.2 [Tendermint Client](./../light-clients/07-tendermint/spec/README.md) - - 3.3 [Localhost Client](./../light-clients/09-localhost/spec/README.md) - -## Implementation Details - -As stated above, the IBC implementation on the Cosmos SDK introduces some changes -to the general specification, in order to avoid code duplication and to take -advantage of the SDK architectural components such as the transaction routing -through `Handlers`. - -### Interchain Standards reference - -The following list is a mapping from each Interchain Standard to their implementation -in the SDK's `x/ibc` module: - -* [ICS 002 - Client Semantics](https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics): Implemented in [`x/ibc/core/02-client`](https://github.com/cosmos/tree/master/ibc/core/02-client) -* [ICS 003 - Connection Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-003-connection-semantics): Implemented in [`x/ibc/core/03-connection`](https://github.com/cosmos/tree/master/ibc/core/03-connection) -* [ICS 004 - Channel and Packet Semantics](https://github.com/cosmos/ics/blob/master/spec/ics-004-channel-and-packet-semantics): Implemented in [`x/ibc/core/04-channel`](https://github.com/cosmos/tree/master/ibc/core/04-channel) -* [ICS 005 - Port Allocation](https://github.com/cosmos/ics/blob/master/spec/ics-005-port-allocation): Implemented in [`x/ibc/core/05-port`](https://github.com/cosmos/tree/master/ibc/core/05-port) -* [ICS 006 - Solo Machine Client](https://github.com/cosmos/ics/blob/master/spec/ics-006-solo-machine-client): Implemented in [`x/ibc/light-clients/06-solomachine`](https://github.com/cosmos/tree/master/ibc/solomachine) -* [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client): Implemented in [`x/ibc/light-clients/07-tendermint`](https://github.com/cosmos/tree/master/ibc/light-clients/07-tendermint) -* [ICS 009 - Loopback Client](https://github.com/cosmos/ics/blob/master/spec/ics-009-loopback-client): Implemented in [`x/ibc/light-clients/09-localhost`](https://github.com/cosmos/tree/master/ibc/light-clients/09-localhost) -* [ICS 018- Relayer Algorithms](https://github.com/cosmos/ics/tree/master/spec/ics-018-relayer-algorithms): Implemented in it's own [relayer repository](https://github.com/cosmos/relayer) -* [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer): Implemented in [`x/ibc/applications/transfer`](https://github.com/cosmos/tree/master/ibc/applications/transfer) -* [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments): Implemented in [`x/ibc/core/23-commitment`](https://github.com/cosmos/tree/master/ibc/core/23-commitment) -* [ICS 024 - Host Requirements](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements): Implemented in [`x/ibc/core/24-host`](https://github.com/cosmos/tree/master/ibc/core/24-host) -* [ICS 025 - Handler Interface](https://github.com/cosmos/ics/tree/master/spec/ics-025-handler-interface): `Handler` interfaces are implemented at the top level in `x/ibc/handler.go`, -which call each ICS submodule's handlers (i.e `x/ibc/*/{XX-ICS}/handler.go`). -* [ICS 026 - Routing Module](https://github.com/cosmos/ics/blob/master/spec/ics-026-routing-module): Replaced by [ADR 15 - IBC Packet Receiver](../../../docs/architecture/adr-015-ibc-packet-receiver.md). - -### Architecture Decision Records (ADR) - -The following ADR provide the design and architecture decision of IBC-related components. - -* [ADR 001 - Coin Source Tracing](../../../docs/architecture/adr-001-coin-source-tracing.md): standard to hash the ICS20's fungible token -denomination trace path in order to support special characters and limit the maximum denomination length. -* [ADR 17 - Historical Header Module](../../../docs/architecture/adr-017-historical-header-module.md): Introduces the ability to introspect past -consensus states in order to verify their membership in the counterparty clients. -* [ADR 19 - Protobuf State Encoding](../../../docs/architecture/adr-019-protobuf-state-encoding.md): Migration from Amino to Protobuf for state encoding. -* [ADR 020 - Protocol Buffer Transaction Encoding](./../../docs/architecture/adr-020-protobuf-transaction-encoding.md): Client side migration to Protobuf. -* [ADR 021 - Protocol Buffer Query Encoding](../../../docs/architecture/adr-020-protobuf-query-encoding.md): Queries migration to Protobuf. -* [ADR 026 - IBC Client Recovery Mechanisms](../../../docs/architecture/adr-026-ibc-client-recovery-mechanisms.md): Allows IBC Clients to be recovered after freezing or expiry. -* [ADR 027 - IBC WASM Client](../../../docs/architecture/adr-027-ibc-wasm.md) - -### SDK Modules - -* [`x/capability`](https://github.com/cosmos/tree/master/x/capability): The capability module provides object-capability keys support through scoped keepers in order to authenticate usage of ports or channels. Check [ADR 3 - Dynamic Capability Store](../../../docs/architecture/adr-003-dynamic-capability-store.md) for more details. - -## IBC module architecture - -> **NOTE for auditors**: If you're not familiar with the overall module structure from -the SDK modules, please check this [document](../../../docs/building-modules/structure.md) as -prerequisite reading. - -For ease of auditing, every Interchain Standard has been developed in its own -package. The development team separated the IBC TAO (Transport, Authentication, Ordering) ICS specifications from the IBC application level -specification. The following tree describes the architecture of the directories that -the `ibc` (TAO) and `ibc-transfer` ([ICS20](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer)) modules: - -```shell -x/ibc -├── applications/ -│ └──transfer/ -├── core/ -│   ├── 02-client/ -│   ├── 03-connection/ -│   ├── 04-channel/ -│   ├── 05-port/ -│   ├── 23-commitment/ -│   ├── 24-host/ -│  ├── client -│  │   └── cli -│ │       └── cli.go -│  ├── keeper -│  │ ├── keeper.go -│   │ └── querier.go -│ ├── types -│ │ ├── errors.go -│ │ └── keys.go -│ ├── handler.go -│ └── module.go -├── light-clients/ -│   ├── 06-solomachine/ -│   ├── 07-tendermint/ -│   └── 09-localhost/ -└── testing/ -``` - \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index b1c4855520f..23f5ac5f341 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,11 +8,10 @@ footer: Welcome to the IBC-Go documentation! -The Inter-Blockchain Communication protocol (IBC) is an end-to-end, connection-oriented, stateful protocol for reliable, ordered, and authenticated communication between heterogeneous blockchains arranged in an unknown and dynamic topology. +The Inter-Blockchain Communication protocol (IBC) is an end-to-end, connection-oriented, stateful protocol for reliable, ordered, and authenticated communication between heterogeneous blockchains arranged in an unknown and dynamic topology. IBC is a protocol that allows blockchains to talk to each other. The protocol realizes this interoperability by specifying a set of data structures, abstractions, and semantics that can be implemented by any distributed ledger that satisfies a small set of requirements. IBC can be used to build a wide range of cross-chain applications that include token transfers, atomic swaps, multi-chain smart contracts (with or without mutually comprehensible VMs), and data and code sharding of various kinds. - diff --git a/docs/apps/interchain-accounts/active-channels.md b/docs/apps/interchain-accounts/active-channels.md index d387bdea038..f9d457f1a85 100644 --- a/docs/apps/interchain-accounts/active-channels.md +++ b/docs/apps/interchain-accounts/active-channels.md @@ -1,25 +1,36 @@ -# Understanding Active Channels +# Understanding Active Channels -The Interchain Accounts module uses [ORDERED channels](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#ordering) to maintain the order of transactions when sending packets from a controller to a host chain. A limitation when using ORDERED channels is that when a packet times out the channel will be closed. +The Interchain Accounts module uses [ORDERED channels](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#ordering) to maintain the order of transactions when sending packets from a controller to a host chain. A limitation when using ORDERED channels is that when a packet times out the channel will be closed. -In the case of a channel closing, a controller chain needs to be able to regain access to the interchain account registered on this channel. `Active Channels` enable this functionality. Future versions of the ICS-27 protocol and the Interchain Accounts module will likely use a new -channel type that provides ordering of packets without the channel closing on timing out, thus removing the need for `Active Channels` entirely. +In the case of a channel closing, a controller chain needs to be able to regain access to the interchain account registered on this channel. `Active Channels` enable this functionality. -When an Interchain Account is registered using the `RegisterInterchainAccount` API, a new channel is created on a particular port. During the `OnChanOpenAck` and `OnChanOpenConfirm` steps (controller & host chain) the `Active Channel` for this interchain account -is stored in state. +When an Interchain Account is registered using `MsgRegisterInterchainAccount`, a new channel is created on a particular port. During the `OnChanOpenAck` and `OnChanOpenConfirm` steps (on controller & host chain respectively) the `Active Channel` for this interchain account is stored in state. It is possible to create a new channel using the same controller chain portID if the previously set `Active Channel` is now in a `CLOSED` state. This channel creation can be initialized programatically by sending a new `MsgChannelOpenInit` message like so: ```go -msg := channeltypes.NewMsgChannelOpenInit(portID, string(versionBytes), channeltypes.ORDERED, []string{connectionID}, icatypes.PortID, icatypes.ModuleName) -handler := k.msgRouter.Handler(msg) +msg := channeltypes.NewMsgChannelOpenInit(portID, string(versionBytes), channeltypes.ORDERED, []string{connectionID}, icatypes.HostPortID, authtypes.NewModuleAddress(icatypes.ModuleName).String()) +handler := keeper.msgRouter.Handler(msg) +res, err := handler(ctx, msg) +if err != nil { + return err +} ``` Alternatively, any relayer operator may initiate a new channel handshake for this interchain account once the previously set `Active Channel` is in a `CLOSED` state. This is done by initiating the channel handshake on the controller chain using the same portID associated with the interchain account in question. -It is important to note that once a channel has been opened for a given Interchain Account, new channels can not be opened for this account until the currently set `Active Channel` is set to `CLOSED`. +It is important to note that once a channel has been opened for a given interchain account, new channels can not be opened for this account until the currently set `Active Channel` is set to `CLOSED`. +## Future improvements + +Future versions of the ICS-27 protocol and the Interchain Accounts module will likely use a new channel type that provides ordering of packets without the channel closing in the event of a packet timing out, thus removing the need for `Active Channels` entirely. +The following is a list of issues which will provide the infrastructure to make this possible: + +- [IBC Channel Upgrades](https://github.com/cosmos/ibc-go/issues/1599) +- [Implement ORDERED_ALLOW_TIMEOUT logic in 04-channel](https://github.com/cosmos/ibc-go/issues/1661) +- [Add ORDERED_ALLOW_TIMEOUT as supported ordering in 03-connection](https://github.com/cosmos/ibc-go/issues/1662) +- [Allow ICA channels to be opened as ORDERED_ALLOW_TIMEOUT](https://github.com/cosmos/ibc-go/issues/1663) diff --git a/docs/apps/interchain-accounts/auth-modules.md b/docs/apps/interchain-accounts/auth-modules.md index 5d75409b3c4..c53230f69d8 100644 --- a/docs/apps/interchain-accounts/auth-modules.md +++ b/docs/apps/interchain-accounts/auth-modules.md @@ -1,393 +1,21 @@ # Building an authentication module -Authentication modules play the role of the `Base Application` as described in [ICS30 IBC Middleware](https://github.com/cosmos/ibc/tree/master/spec/app/ics-030-middleware), and enable application developers to perform custom logic when working with the Interchain Accounts controller API. {synopsis} +Authentication modules enable application developers to perform custom logic when interacting with the Interchain Accounts controller sumbmodule's `MsgServer`. {synopsis} -The controller submodule is used for account registration and packet sending. -It executes only logic required of all controllers of interchain accounts. -The type of authentication used to manage the interchain accounts remains unspecified. -There may exist many different types of authentication which are desirable for different use cases. -Thus the purpose of the authentication module is to wrap the controller module with custom authentication logic. +The controller submodule is used for account registration and packet sending. It executes only logic required of all controllers of interchain accounts. The type of authentication used to manage the interchain accounts remains unspecified. There may exist many different types of authentication which are desirable for different use cases. Thus the purpose of the authentication module is to wrap the controller submodule with custom authentication logic. -In ibc-go, authentication modules are connected to the controller chain via a middleware stack. -The controller module is implemented as [middleware](https://github.com/cosmos/ibc/tree/master/spec/app/ics-030-middleware) and the authentication module is connected to the controller module as the base application of the middleware stack. -To implement an authentication module, the `IBCModule` interface must be fulfilled. -By implementing the controller module as middleware, any amount of authentication modules can be created and connected to the controller module without writing redundant code. +In ibc-go, authentication modules can communicate with the controller submodule by passing messages through `baseapp`'s `MsgServiceRouter`. To implement an authentication module, the `IBCModule` interface need not be fulfilled; it is only required to fulfill Cosmos SDK's `AppModuleBasic` interface, just like any regular Cosmos SDK application module. The authentication module must: -- Authenticate interchain account owners -- Track the associated interchain account address for an owner -- Claim the channel capability in `OnChanOpenInit` -- Send packets on behalf of an owner (after authentication) -### IBCModule implementation +- Authenticate interchain account owners. +- Track the associated interchain account address for an owner. +- Send packets on behalf of an owner (after authentication). -The following `IBCModule` callbacks must be implemented with appropriate custom logic: +## Integration into `app.go` file -```go -// OnChanOpenInit implements the IBCModule interface -func (im IBCModule) OnChanOpenInit( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, -) (string, error) { - // the authentication module *must* claim the channel capability on OnChanOpenInit - if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return version, err - } - - // perform custom logic - - return version, nil -} - -// OnChanOpenAck implements the IBCModule interface -func (im IBCModule) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyVersion string, -) error { - // perform custom logic - - return nil -} - -// OnChanCloseConfirm implements the IBCModule interface -func (im IBCModule) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // perform custom logic - - return nil -} - -// OnAcknowledgementPacket implements the IBCModule interface -func (im IBCModule) OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, - relayer sdk.AccAddress, -) error { - // perform custom logic - - return nil -} - -// OnTimeoutPacket implements the IBCModule interface. -func (im IBCModule) OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) error { - // perform custom logic - - return nil -} -``` - -**Note**: The channel capability must be claimed by the authentication module in `OnChanOpenInit` otherwise the authentication module will not be able to send packets on the channel created for the associated interchain account. - -The following functions must be defined to fulfill the `IBCModule` interface, but they will never be called by the controller module so they may error or panic. - -```go -// OnChanOpenTry implements the IBCModule interface -func (im IBCModule) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, -) (string, error) { - panic("UNIMPLEMENTED") -} - -// OnChanOpenConfirm implements the IBCModule interface -func (im IBCModule) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - panic("UNIMPLEMENTED") -} - -// OnChanCloseInit implements the IBCModule interface -func (im IBCModule) OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, -) error { - panic("UNIMPLEMENTED") -} - -// OnRecvPacket implements the IBCModule interface. A successful acknowledgement -// is returned if the packet data is succesfully decoded and the receive application -// logic returns without error. -func (im IBCModule) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) ibcexported.Acknowledgement { - panic("UNIMPLEMENTED") -} -``` - -## `RegisterInterchainAccount` - -The authentication module can begin registering interchain accounts by calling `RegisterInterchainAccount`: - -```go -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID, owner.String(), version); err != nil { - return err -} - -return nil -``` - -The `version` argument is used to support ICS29 fee middleware for relayer incentivization of ICS27 packets. Consumers of the `RegisterInterchainAccount` are expected to build the appropriate JSON encoded version string themselves and pass it accordingly. If an empty string is passed in the `version` argument, then the version will be initialized to a default value in the `OnChanOpenInit` callback of the controller's handler, so that channel handshake can proceed. - -The following code snippet illustrates how to construct an appropriate interchain accounts `Metadata` and encode it as a JSON bytestring: - -```go -icaMetadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: controllerConnectionID, - HostConnectionId: hostConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, -} - -appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) -if err != nil { - return err -} - -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(appVersion)); err != nil { - return err -} -``` - -Similarly, if the application stack is configured to route through ICS29 fee middleware and a fee enabled channel is desired, construct the appropriate ICS29 `Metadata` type: - -```go -icaMetadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: controllerConnectionID, - HostConnectionId: hostConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, -} - -appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) -if err != nil { - return err -} - -feeMetadata := feetypes.Metadata{ - AppVersion: string(appVersion), - FeeVersion: feetypes.Version, -} - -feeEnabledVersion, err := feetypes.ModuleCdc.MarshalJSON(&feeMetadata) -if err != nil { - return err -} - -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(feeEnabledVersion)); err != nil { - return err -} -``` - -## `SendTx` - -The authentication module can attempt to send a packet by calling `SendTx`: -```go - -// Authenticate owner -// perform custom logic - -// Construct controller portID based on interchain account owner address -portID, err := icatypes.NewControllerPortID(owner.String()) -if err != nil { - return err -} - -channelID, found := keeper.icaControllerKeeper.GetActiveChannelID(ctx, portID) -if !found { - return sdkerrors.Wrapf(icatypes.ErrActiveChannelNotFound, "failed to retrieve active channel for port %s", portID) -} - -// Obtain the channel capability, claimed in OnChanOpenInit -chanCap, found := keeper.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) -if !found { - return sdkerrors.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") -} - -// Obtain data to be sent to the host chain. -// In this example, the owner of the interchain account would like to send a bank MsgSend to the host chain. -// The appropriate serialization function should be called. The host chain must be able to deserialize the transaction. -// If the host chain is using the ibc-go host module, `SerializeCosmosTx` should be used. -msg := &banktypes.MsgSend{FromAddress: fromAddr, ToAddress: toAddr, Amount: amt} -data, err := icatypes.SerializeCosmosTx(keeper.cdc, []sdk.Msg{msg}) -if err != nil { - return err -} - -// Construct packet data -packetData := icatypes.InterchainAccountPacketData{ - Type: icatypes.EXECUTE_TX, - Data: data, -} - -// Obtain timeout timestamp -// An appropriate timeout timestamp must be determined based on the usage of the interchain account. -// If the packet times out, the channel will be closed requiring a new channel to be created -timeoutTimestamp := obtainTimeoutTimestamp() - -// Send the interchain accounts packet, returning the packet sequence -seq, err = keeper.icaControllerKeeper.SendTx(ctx, chanCap, portID, packetData, timeoutTimestamp) -``` - -The data within an `InterchainAccountPacketData` must be serialized using a format supported by the host chain. -If the host chain is using the ibc-go host chain submodule, `SerializeCosmosTx` should be used. If the `InterchainAccountPacketData.Data` is serialized using a format not support by the host chain, the packet will not be successfully received. - -## `OnAcknowledgementPacket` - -Controller chains will be able to access the acknowledgement written into the host chain state once a relayer relays the acknowledgement. -The acknowledgement bytes will be passed to the auth module via the `OnAcknowledgementPacket` callback. -Auth modules are expected to know how to decode the acknowledgement. - -If the controller chain is connected to a host chain using the host module on ibc-go, it may interpret the acknowledgement bytes as follows: - -Begin by unmarshaling the acknowledgement into sdk.TxMsgData: -```go -var ack channeltypes.Acknowledgement -if err := channeltypes.SubModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return err -} - -txMsgData := &sdk.TxMsgData{} -if err := proto.Unmarshal(ack.GetResult(), txMsgData); err != nil { - return err -} -``` - -If the txMsgData.Data field is non nil, the host chain is using SDK version <= v0.45. -The auth module should interpret the txMsgData.Data as follows: - -```go -switch len(txMsgData.Data) { -case 0: - // see documentation below for SDK 0.46.x or greater -default: - for _, msgData := range txMsgData.Data { - if err := handler(msgData); err != nil { - return err - } - } -... -} -``` - -A handler will be needed to interpret what actions to perform based on the message type sent. -A router could be used, or more simply a switch statement. - -```go -func handler(msgData sdk.MsgData) error { -switch msgData.MsgType { -case sdk.MsgTypeURL(&banktypes.MsgSend{}): - msgResponse := &banktypes.MsgSendResponse{} - if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { - return err - } - - handleBankSendMsg(msgResponse) - -case sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}): - msgResponse := &stakingtypes.MsgDelegateResponse{} - if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { - return err - } - - handleStakingDelegateMsg(msgResponse) - -case sdk.MsgTypeURL(&transfertypes.MsgTransfer{}): - msgResponse := &transfertypes.MsgTransferResponse{} - if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { - return err - } - - handleIBCTransferMsg(msgResponse) - -default: - return -} -``` - -If the txMsgData.Data is empty, the host chain is using SDK version > v0.45. -The auth module should interpret the txMsgData.Responses as follows: - -```go -... -// switch statement from above -case 0: - for _, any := range txMsgData.MsgResponses { - if err := handleAny(any); err != nil { - return err - } - } -} -``` - -A handler will be needed to interpret what actions to perform based on the type url of the Any. -A router could be used, or more simply a switch statement. -It may be possible to deduplicate logic between `handler` and `handleAny`. - -```go -func handleAny(any *codectypes.Any) error { -switch any.TypeURL { -case banktypes.MsgSend: - msgResponse, err := unpackBankMsgSendResponse(any) - if err != nil { - return err - } - - handleBankSendMsg(msgResponse) - -case stakingtypes.MsgDelegate: - msgResponse, err := unpackStakingDelegateResponse(any) - if err != nil { - return err - } - - handleStakingDelegateMsg(msgResponse) - - case transfertypes.MsgTransfer: - msgResponse, err := unpackIBCTransferMsgResponse(any) - if err != nil { - return err - } - - handleIBCTransferMsg(msgResponse) - -default: - return -} -``` - -### Integration into `app.go` file - -To integrate the authentication module into your chain, please follow the steps outlined above in [app.go integration](./integration.md#example-integration). +To integrate the authentication module into your chain, please follow the steps outlined in [`app.go` integration](./integration.md#example-integration). diff --git a/docs/apps/interchain-accounts/client.md b/docs/apps/interchain-accounts/client.md new file mode 100644 index 00000000000..c35d28f0df0 --- /dev/null +++ b/docs/apps/interchain-accounts/client.md @@ -0,0 +1,180 @@ + + +# Client + +## CLI + +A user can query and interact with the Interchain Accounts module using the CLI. Use the `--help` flag to discover the available commands: + +```shell +simd query interchain-accounts --help +``` + +> Please not that this section does not document all the available commands, but only the ones that deserved extra documentation that was not possible to fit in the command line documentation. + +### Controller + +A user can query and interact with the controller submodule. + +#### Query + +The `query` commands allow users to query the controller submodule. + +```shell +simd query interchain-accounts controller --help +``` + +#### Transactions + +The `tx` commands allow users to interact with the controller submodule. + +```shell +simd tx interchain-accounts controller --help +``` + +#### `send-tx` + +The `send-tx` command allows users to send a transaction on the provided connection to be executed using an interchain account on the host chain. + +```shell +simd tx interchain-accounts controller send-tx [connection-id] [path/to/packet_msg.json] +``` + +Example: + +```shell +simd tx interchain-accounts controller send-tx connection-0 packet-data.json --from cosmos1.. +``` + +See below for example contents of `packet-data.json`. The CLI handler will unmarshal the following into `InterchainAccountPacketData` appropriately. + +```json +{ + "type":"TYPE_EXECUTE_TX", + "data":"CqIBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEoEBCkFjb3Ntb3MxNWNjc2hobXAwZ3N4MjlxcHFxNmc0em1sdG5udmdteXU5dWV1YWRoOXkybmM1emowc3psczVndGRkehItY29zbW9zMTBoOXN0YzV2Nm50Z2V5Z2Y1eGY5NDVuanFxNWgzMnI1M3VxdXZ3Gg0KBXN0YWtlEgQxMDAw", + "memo":"" +} +``` + +Note the `data` field is a base64 encoded byte string as per the [proto3 JSON encoding specification](https://developers.google.com/protocol-buffers/docs/proto3#json). + +A helper CLI is provided in the host submodule which can be used to generate the packet data JSON using the counterparty chain's binary. See the [`generate-packet-data` command](#generate-packet-data) for an example. + +### Host + +A user can query and interact with the host submodule. + +#### Query + +The `query` commands allow users to query the host submodule. + +```shell +simd query interchain-accounts host --help +``` + +#### Transactions + +The `tx` commands allow users to interact with the controller submodule. + +```shell +simd tx interchain-accounts host --help +``` + +##### `generate-packet-data` + +The `generate-packet-data` command allows users to generate interchain accounts packet data for input message(s). The packet data can then be used with the controller submodule's [`send-tx` command](#send-tx). + +```shell +simd tx interchain-accounts host generate-packet-data [message] +``` + +Example: + +```shell +simd tx interchain-accounts host generate-packet-data '[{ + "@type":"/cosmos.bank.v1beta1.MsgSend", + "from_address":"cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", + "to_address":"cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw", + "amount": [ + { + "denom": "stake", + "amount": "1000" + } + ] +}]' --memo memo +``` + +The command accepts a single `sdk.Msg` or a list of `sdk.Msg`s that will be encoded into the outputs `data` field. + +Example output: + +```json +{ + "type":"TYPE_EXECUTE_TX", + "data":"CqIBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEoEBCkFjb3Ntb3MxNWNjc2hobXAwZ3N4MjlxcHFxNmc0em1sdG5udmdteXU5dWV1YWRoOXkybmM1emowc3psczVndGRkehItY29zbW9zMTBoOXN0YzV2Nm50Z2V5Z2Y1eGY5NDVuanFxNWgzMnI1M3VxdXZ3Gg0KBXN0YWtlEgQxMDAw", + "memo":"memo" +} +``` + +## gRPC + +A user can query the interchain account module using gRPC endpoints. + +### Controller + +A user can query the controller submodule using gRPC endpoints. + +#### `InterchainAccount` + +The `InterchainAccount` endpoint allows users to query the controller submodule for the interchain account address for a given owner on a particular connection. + +```shell +ibc.applications.interchain_accounts.controller.v1.Query/InterchainAccount +``` + +Example: + +```shell +grpcurl -plaintext \ + -d '{"owner":"cosmos1..","connection_id":"connection-0"}' \ + localhost:9090 \ + ibc.applications.interchain_accounts.controller.v1.Query/InterchainAccount +``` + +#### `Params` + +The `Params` endpoint users to query the current controller submodule parameters. + +```shell +ibc.applications.interchain_accounts.controller.v1.Query/Params +``` + +Example: + +```shell +grpcurl -plaintext \ + localhost:9090 \ + ibc.applications.interchain_accounts.controller.v1.Query/Params +``` + +### Host + +A user can query the host submodule using gRPC endpoints. + +#### `Params` + +The `Params` endpoint users to query the current host submodule parameters. + +```shell +ibc.applications.interchain_accounts.host.v1.Query/Params +``` + +Example: + +```shell +grpcurl -plaintext \ + localhost:9090 \ + ibc.applications.interchain_accounts.host.v1.Query/Params +``` diff --git a/docs/apps/interchain-accounts/development.md b/docs/apps/interchain-accounts/development.md new file mode 100644 index 00000000000..f2a463868a5 --- /dev/null +++ b/docs/apps/interchain-accounts/development.md @@ -0,0 +1,36 @@ + + +# Development use cases + +The initial version of Interchain Accounts allowed for the controller submodule to be extended by providing it with an underlying application which would handle all packet callbacks. +That functionality is now being deprecated in favor of alternative approaches. +This document will outline potential use cases and redirect each use case to the appropriate documentation. + +## Custom authentication + +Interchain accounts may be associated with alternative types of authentication relative to the traditional public/private key signing. +If you wish to develop or use Interchain Accounts with a custom authentication module and do not need to execute custom logic on the packet callbacks, we recommend you use ibc-go v6 or greater and that your custom authentication module interacts with the controller submodule via the [`MsgServer`](./messages.md). + +If you wish to consume and execute custom logic in the packet callbacks, then please read the section [Packet callbacks](#packet-callbacks) below. + +## Redirection to a smart contract + +It may be desirable to allow smart contracts to control an interchain account. +To faciliate such an action, the controller submodule may be provided an underlying application which redirects to smart contract callers. +An improved design has been suggested in [ADR 008](https://github.com/cosmos/ibc-go/pull/1976) which performs this action via middleware. + +Implementors of this use case are recommended to follow the ADR 008 approach. +The underlying application may continue to be used as a short term solution for ADR 008 and the [legacy API](./auth-modules.md#registerinterchainaccount) should continue to be utilized in such situations. + +## Packet callbacks + +If a developer requires access to packet callbacks for their use case, then they have the following options: + +1. Write a smart contract which is connected via an ADR 008 or equivalent IBC application (recommended). +2. Use the controller's underlying application to implement packet callback logic. + +In the first case, the smart contract should use the [`MsgServer`](./messages.md). + +In the second case, the underlying application should use the [legacy API](./legacy/keeper-api.md). diff --git a/docs/apps/interchain-accounts/integration.md b/docs/apps/interchain-accounts/integration.md index 14757ccca3c..4d56e3c1106 100644 --- a/docs/apps/interchain-accounts/integration.md +++ b/docs/apps/interchain-accounts/integration.md @@ -1,19 +1,20 @@ # Integration Learn how to integrate Interchain Accounts host and controller functionality to your chain. The following document only applies for Cosmos SDK chains. {synopsis} -The Interchain Accounts module contains two submodules. Each submodule has its own IBC application. The Interchain Accounts module should be registered as an `AppModule` in the same way all SDK modules are registered on a chain, but each submodule should create its own `IBCModule` as necessary. A route should be added to the IBC router for each submodule which will be used. +The Interchain Accounts module contains two submodules. Each submodule has its own IBC application. The Interchain Accounts module should be registered as an `AppModule` in the same way all SDK modules are registered on a chain, but each submodule should create its own `IBCModule` as necessary. A route should be added to the IBC router for each submodule which will be used. -Chains who wish to support ICS27 may elect to act as a host chain, a controller chain or both. Disabling host or controller functionality may be done statically by excluding the host or controller module entirely from the `app.go` file or it may be done dynamically by taking advantage of the on-chain parameters which enable or disable the host or controller submodules. +Chains who wish to support ICS-27 may elect to act as a host chain, a controller chain or both. Disabling host or controller functionality may be done statically by excluding the host or controller submodule entirely from the `app.go` file or it may be done dynamically by taking advantage of the on-chain parameters which enable or disable the host or controller submodules. -Interchain Account authentication modules are the base application of a middleware stack. The controller submodule is the middleware in this stack. +Interchain Account authentication modules (both custom or generic, such as the `x/gov`, `x/group` or `x/auth` Cosmos SDK modules) can send messages to the controller submodule's [`MsgServer`](./messages.md) to register interchain accounts and send packets to the interchain account. To accomplish this, the authentication module needs to be composed with `baseapp`'s `MsgServiceRouter`. +![ICAv6](../../assets/ica/ica-v6.png) -### Example integration +## Example integration ```go // app.go @@ -21,10 +22,10 @@ Interchain Account authentication modules are the base application of a middlewa // Register the AppModule for the Interchain Accounts module and the authentication module // Note: No `icaauth` exists, this must be substituted with an actual Interchain Accounts authentication module ModuleBasics = module.NewBasicManager( - ... - ica.AppModuleBasic{}, - icaauth.AppModuleBasic{}, - ... + ... + ica.AppModuleBasic{}, + icaauth.AppModuleBasic{}, + ... ) ... @@ -33,8 +34,8 @@ ModuleBasics = module.NewBasicManager( // Only necessary for host chain functionality // Each Interchain Account created on the host chain is derived from the module account created maccPerms = map[string][]string{ - ... - icatypes.ModuleName: nil, + ... + icatypes.ModuleName: nil, } ... @@ -42,24 +43,24 @@ maccPerms = map[string][]string{ // Add Interchain Accounts Keepers for each submodule used and the authentication module // If a submodule is being statically disabled, the associated Keeper does not need to be added. type App struct { - ... + ... - ICAControllerKeeper icacontrollerkeeper.Keeper - ICAHostKeeper icahostkeeper.Keeper - ICAAuthKeeper icaauthkeeper.Keeper + ICAControllerKeeper icacontrollerkeeper.Keeper + ICAHostKeeper icahostkeeper.Keeper + ICAAuthKeeper icaauthkeeper.Keeper - ... + ... } ... // Create store keys for each submodule Keeper and the authentication module keys := sdk.NewKVStoreKeys( - ... - icacontrollertypes.StoreKey, - icahosttypes.StoreKey, - icaauthtypes.StoreKey, - ... + ... + icacontrollertypes.StoreKey, + icahosttypes.StoreKey, + icaauthtypes.StoreKey, + ... ) ... @@ -73,55 +74,84 @@ scopedICAAuthKeeper := app.CapabilityKeeper.ScopeToModule(icaauthtypes.ModuleNam // Create the Keeper for each submodule app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper( - appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName), - app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, scopedICAControllerKeeper, app.MsgServiceRouter(), + appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName), + app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee + app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, + scopedICAControllerKeeper, app.MsgServiceRouter(), ) app.ICAHostKeeper = icahostkeeper.NewKeeper( - appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName), - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(), + appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName), + app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee + app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, + app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(), ) // Create Interchain Accounts AppModule icaModule := ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper) // Create your Interchain Accounts authentication module -app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.ICAControllerKeeper, scopedICAAuthKeeper) +app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.MsgServiceRouter()) // ICA auth AppModule icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) -// ICA auth IBC Module -icaAuthIBCModule := icaauth.NewIBCModule(app.ICAAuthKeeper) - -// Create host and controller IBC Modules as desired -icaControllerIBCModule := icacontroller.NewIBCModule(app.ICAControllerKeeper, icaAuthIBCModule) +// Create controller IBC application stack and host IBC module as desired +icaControllerStack := icacontroller.NewIBCMiddleware(nil, app.ICAControllerKeeper) icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) // Register host and authentication routes -ibcRouter.AddRoute(icacontrollertypes.SubModuleName, icaControllerIBCModule). - AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). - AddRoute(icaauthtypes.ModuleName, icaControllerIBCModule) // Note, the authentication module is routed to the top level of the middleware stack - +ibcRouter. + AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). + AddRoute(icahosttypes.SubModuleName, icaHostIBCModule) ... // Register Interchain Accounts and authentication module AppModule's app.moduleManager = module.NewManager( - ... - icaModule, - icaAuthModule, + ... + icaModule, + icaAuthModule, ) ... +// Add Interchain Accounts to begin blocker logic +app.moduleManager.SetOrderBeginBlockers( + ... + icatypes.ModuleName, + ... +) + +// Add Interchain Accounts to end blocker logic +app.moduleManager.SetOrderEndBlockers( + ... + icatypes.ModuleName, + ... +) + // Add Interchain Accounts module InitGenesis logic -app.mm.SetOrderInitGenesis( - ... - icatypes.ModuleName, - ... +app.moduleManager.SetOrderInitGenesis( + ... + icatypes.ModuleName, + ... ) + +// initParamsKeeper init params keeper and its subspaces +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper { + ... + paramsKeeper.Subspace(icahosttypes.SubModuleName) + paramsKeeper.Subspace(icacontrollertypes.SubModuleName) + ... +} +``` + +If no custom athentication module is needed and a generic Cosmos SDK authentication module can be used, then from the sample integration code above all references to `ICAAuthKeeper` and `icaAuthModule` can be removed. That's it, the following code would not be needed: + +```go +// Create your Interchain Accounts authentication module +app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.MsgServiceRouter()) + +// ICA auth AppModule +icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) ``` ### Using submodules exclusively @@ -151,15 +181,13 @@ ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostIBCModule) // Create Interchain Accounts AppModule omitting the host keeper icaModule := ica.NewAppModule(&app.ICAControllerKeeper, nil) -// Create your Interchain Accounts authentication module, setting up the Keeper, AppModule and IBCModule appropriately -app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.ICAControllerKeeper, scopedICAAuthKeeper) -icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) -icaAuthIBCModule := icaauth.NewIBCModule(app.ICAAuthKeeper) -// Create controller IBC Module -icaControllerIBCModule := icacontroller.NewIBCModule(app.ICAControllerKeeper, icaAuthIBCModule) +// Optionally instantiate your custom authentication module if needed, or not otherwise +... + +// Create controller IBC application stack +icaControllerStack := icacontroller.NewIBCMiddleware(nil, app.ICAControllerKeeper) -// Register controller and authentication routes -ibcRouter.AddRoute(icacontrollertypes.SubModuleName, icaControllerIBCModule) -ibcRouter.AddRoute(icaauthtypes.ModuleName, icaControllerIBCModule) // Note, the authentication module is routed to the top level of the middleware stack +// Register controller route +ibcRouter.AddRoute(icacontrollertypes.SubModuleName, icaControllerStack) ``` diff --git a/docs/apps/interchain-accounts/legacy/auth-modules.md b/docs/apps/interchain-accounts/legacy/auth-modules.md new file mode 100644 index 00000000000..3a2db58cfa0 --- /dev/null +++ b/docs/apps/interchain-accounts/legacy/auth-modules.md @@ -0,0 +1,268 @@ + + +# Building an authentication module + +## Deprecation Notice + +**This document is deprecated and will be removed in future releases**. + +Authentication modules play the role of the `Base Application` as described in [ICS-30 IBC Middleware](https://github.com/cosmos/ibc/tree/master/spec/app/ics-030-middleware), and enable application developers to perform custom logic when working with the Interchain Accounts controller API. {synopsis} + +The controller submodule is used for account registration and packet sending. It executes only logic required of all controllers of interchain accounts. The type of authentication used to manage the interchain accounts remains unspecified. There may exist many different types of authentication which are desirable for different use cases. Thus the purpose of the authentication module is to wrap the controller submodule with custom authentication logic. + +In ibc-go, authentication modules are connected to the controller chain via a middleware stack. The controller submodule is implemented as [middleware](https://github.com/cosmos/ibc/tree/master/spec/app/ics-030-middleware) and the authentication module is connected to the controller submodule as the base application of the middleware stack. To implement an authentication module, the `IBCModule` interface must be fulfilled. By implementing the controller submodule as middleware, any amount of authentication modules can be created and connected to the controller submodule without writing redundant code. + +The authentication module must: + +- Authenticate interchain account owners. +- Track the associated interchain account address for an owner. +- Send packets on behalf of an owner (after authentication). + +> Please note that since ibc-go v6 the channel capability is claimed by the controller submodule and therefore it is not required for authentication modules to claim the capability in the `OnChanOpenInit` callback. When the authentication module sends packets on the channel created for the associated interchain account it can pass a `nil` capability to the legacy function `SendTx` of the controller keeper (see section [`SendTx`](./keeper-api.md#sendtx) for more information). + +## `IBCModule` implementation + +The following `IBCModule` callbacks must be implemented with appropriate custom logic: + +```go +// OnChanOpenInit implements the IBCModule interface +func (im IBCModule) OnChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, +) (string, error) { + // since ibc-go v6 the authentication module *must not* claim the channel capability on OnChanOpenInit + + // perform custom logic + + return version, nil +} + +// OnChanOpenAck implements the IBCModule interface +func (im IBCModule) OnChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + counterpartyVersion string, +) error { + // perform custom logic + + return nil +} + +// OnChanCloseConfirm implements the IBCModule interface +func (im IBCModule) OnChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + // perform custom logic + + return nil +} + +// OnAcknowledgementPacket implements the IBCModule interface +func (im IBCModule) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + // perform custom logic + + return nil +} + +// OnTimeoutPacket implements the IBCModule interface. +func (im IBCModule) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) error { + // perform custom logic + + return nil +} +``` + +The following functions must be defined to fulfill the `IBCModule` interface, but they will never be called by the controller submodule so they may error or panic. That is because in Interchain Accounts, the channel handshake is always initiated on the controller chain and packets are always sent to the host chain and never to the controller chain. + +```go +// OnChanOpenTry implements the IBCModule interface +func (im IBCModule) OnChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, +) (string, error) { + panic("UNIMPLEMENTED") +} + +// OnChanOpenConfirm implements the IBCModule interface +func (im IBCModule) OnChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + panic("UNIMPLEMENTED") +} + +// OnChanCloseInit implements the IBCModule interface +func (im IBCModule) OnChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + panic("UNIMPLEMENTED") +} + +// OnRecvPacket implements the IBCModule interface. A successful acknowledgement +// is returned if the packet data is succesfully decoded and the receive application +// logic returns without error. +func (im IBCModule) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) ibcexported.Acknowledgement { + panic("UNIMPLEMENTED") +} +``` + +## `OnAcknowledgementPacket` + +Controller chains will be able to access the acknowledgement written into the host chain state once a relayer relays the acknowledgement. +The acknowledgement bytes contain either the response of the execution of the message(s) on the host chain or an error. They will be passed to the auth module via the `OnAcknowledgementPacket` callback. Auth modules are expected to know how to decode the acknowledgement. + +If the controller chain is connected to a host chain using the host module on ibc-go, it may interpret the acknowledgement bytes as follows: + +Begin by unmarshaling the acknowledgement into `sdk.TxMsgData`: + +```go +var ack channeltypes.Acknowledgement +if err := channeltypes.SubModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { + return err +} + +txMsgData := &sdk.TxMsgData{} +if err := proto.Unmarshal(ack.GetResult(), txMsgData); err != nil { + return err +} +``` + +If the `txMsgData.Data` field is non nil, the host chain is using SDK version <= v0.45. +The auth module should interpret the `txMsgData.Data` as follows: + +```go +switch len(txMsgData.Data) { +case 0: + // see documentation below for SDK 0.46.x or greater +default: + for _, msgData := range txMsgData.Data { + if err := handler(msgData); err != nil { + return err + } + } +... +} +``` + +A handler will be needed to interpret what actions to perform based on the message type sent. +A router could be used, or more simply a switch statement. + +```go +func handler(msgData sdk.MsgData) error { +switch msgData.MsgType { +case sdk.MsgTypeURL(&banktypes.MsgSend{}): + msgResponse := &banktypes.MsgSendResponse{} + if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { + return err + } + + handleBankSendMsg(msgResponse) + +case sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}): + msgResponse := &stakingtypes.MsgDelegateResponse{} + if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { + return err + } + + handleStakingDelegateMsg(msgResponse) + +case sdk.MsgTypeURL(&transfertypes.MsgTransfer{}): + msgResponse := &transfertypes.MsgTransferResponse{} + if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { + return err + } + + handleIBCTransferMsg(msgResponse) + +default: + return +} +``` + +If the `txMsgData.Data` is empty, the host chain is using SDK version > v0.45. +The auth module should interpret the `txMsgData.Responses` as follows: + +```go +... +// switch statement from above +case 0: + for _, any := range txMsgData.MsgResponses { + if err := handleAny(any); err != nil { + return err + } + } +} +``` + +A handler will be needed to interpret what actions to perform based on the type URL of the Any. +A router could be used, or more simply a switch statement. +It may be possible to deduplicate logic between `handler` and `handleAny`. + +```go +func handleAny(any *codectypes.Any) error { +switch any.TypeURL { +case banktypes.MsgSend: + msgResponse, err := unpackBankMsgSendResponse(any) + if err != nil { + return err + } + + handleBankSendMsg(msgResponse) + +case stakingtypes.MsgDelegate: + msgResponse, err := unpackStakingDelegateResponse(any) + if err != nil { + return err + } + + handleStakingDelegateMsg(msgResponse) + + case transfertypes.MsgTransfer: + msgResponse, err := unpackIBCTransferMsgResponse(any) + if err != nil { + return err + } + + handleIBCTransferMsg(msgResponse) + +default: + return +} +``` + +## Integration into `app.go` file + +To integrate the authentication module into your chain, please follow the steps outlined in [`app.go` integration](./integration.md#example-integration). diff --git a/docs/apps/interchain-accounts/legacy/integration.md b/docs/apps/interchain-accounts/legacy/integration.md new file mode 100644 index 00000000000..5b683b801a6 --- /dev/null +++ b/docs/apps/interchain-accounts/legacy/integration.md @@ -0,0 +1,195 @@ + + +# Integration + +## Deprecation Notice + +**This document is deprecated and will be removed in future releases**. + +Learn how to integrate Interchain Accounts host and controller functionality to your chain. The following document only applies for Cosmos SDK chains. {synopsis} + +The Interchain Accounts module contains two submodules. Each submodule has its own IBC application. The Interchain Accounts module should be registered as an `AppModule` in the same way all SDK modules are registered on a chain, but each submodule should create its own `IBCModule` as necessary. A route should be added to the IBC router for each submodule which will be used. + +Chains who wish to support ICS-27 may elect to act as a host chain, a controller chain or both. Disabling host or controller functionality may be done statically by excluding the host or controller module entirely from the `app.go` file or it may be done dynamically by taking advantage of the on-chain parameters which enable or disable the host or controller submodules. + +Interchain Account authentication modules are the base application of a middleware stack. The controller submodule is the middleware in this stack. + +![ICApreV6](../../../assets/ica/ica-pre-v6.png) + +> Please note that since ibc-go v6 the channel capability is claimed by the controller submodule and therefore it is not required for authentication modules to claim the capability in the `OnChanOpenInit` callback. Therefore the custom authentication module does not need a scoped keeper anymore. + +## Example integration + +```go +// app.go + +// Register the AppModule for the Interchain Accounts module and the authentication module +// Note: No `icaauth` exists, this must be substituted with an actual Interchain Accounts authentication module +ModuleBasics = module.NewBasicManager( + ... + ica.AppModuleBasic{}, + icaauth.AppModuleBasic{}, + ... +) + +... + +// Add module account permissions for the Interchain Accounts module +// Only necessary for host chain functionality +// Each Interchain Account created on the host chain is derived from the module account created +maccPerms = map[string][]string{ + ... + icatypes.ModuleName: nil, +} + +... + +// Add Interchain Accounts Keepers for each submodule used and the authentication module +// If a submodule is being statically disabled, the associated Keeper does not need to be added. +type App struct { + ... + + ICAControllerKeeper icacontrollerkeeper.Keeper + ICAHostKeeper icahostkeeper.Keeper + ICAAuthKeeper icaauthkeeper.Keeper + + ... +} + +... + +// Create store keys for each submodule Keeper and the authentication module +keys := sdk.NewKVStoreKeys( + ... + icacontrollertypes.StoreKey, + icahosttypes.StoreKey, + icaauthtypes.StoreKey, + ... +) + +... + +// Create the scoped keepers for each submodule keeper and authentication keeper +scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) +scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) + +... + +// Create the Keeper for each submodule +app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper( + appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName), + app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee + app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, + scopedICAControllerKeeper, app.MsgServiceRouter(), +) +app.ICAHostKeeper = icahostkeeper.NewKeeper( + appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName), + app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee + app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, + app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(), +) + +// Create Interchain Accounts AppModule +icaModule := ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper) + +// Create your Interchain Accounts authentication module +app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.ICAControllerKeeper) + +// ICA auth AppModule +icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) + +// ICA auth IBC Module +icaAuthIBCModule := icaauth.NewIBCModule(app.ICAAuthKeeper) + +// Create controller IBC application stack and host IBC module as desired +icaControllerStack := icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) +icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) + +// Register host and authentication routes +ibcRouter. + AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). + AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). + AddRoute(icaauthtypes.ModuleName, icaControllerStack) // Note, the authentication module is routed to the top level of the middleware stack + +... + +// Register Interchain Accounts and authentication module AppModule's +app.moduleManager = module.NewManager( + ... + icaModule, + icaAuthModule, +) + +... + +// Add fee middleware to begin blocker logic +app.moduleManager.SetOrderBeginBlockers( + ... + icatypes.ModuleName, + ... +) + +// Add fee middleware to end blocker logic +app.moduleManager.SetOrderEndBlockers( + ... + icatypes.ModuleName, + ... +) + +// Add Interchain Accounts module InitGenesis logic +app.moduleManager.SetOrderInitGenesis( + ... + icatypes.ModuleName, + ... +) + +// initParamsKeeper init params keeper and its subspaces +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper { + ... + paramsKeeper.Subspace(icahosttypes.SubModuleName) + paramsKeeper.Subspace(icacontrollertypes.SubModuleName) + ... +``` + +## Using submodules exclusively + +As described above, the Interchain Accounts application module is structured to support the ability of exclusively enabling controller or host functionality. +This can be achieved by simply omitting either controller or host `Keeper` from the Interchain Accounts `NewAppModule` constructor function, and mounting only the desired submodule via the `IBCRouter`. +Alternatively, submodules can be enabled and disabled dynamically using [on-chain parameters](../parameters.md). + +The following snippets show basic examples of statically disabling submodules using `app.go`. + +### Disabling controller chain functionality + +```go +// Create Interchain Accounts AppModule omitting the controller keeper +icaModule := ica.NewAppModule(nil, &app.ICAHostKeeper) + +// Create host IBC Module +icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) + +// Register host route +ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostIBCModule) +``` + +### Disabling host chain functionality + +```go +// Create Interchain Accounts AppModule omitting the host keeper +icaModule := ica.NewAppModule(&app.ICAControllerKeeper, nil) + +// Create your Interchain Accounts authentication module, setting up the Keeper, AppModule and IBCModule appropriately +app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.ICAControllerKeeper) +icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) +icaAuthIBCModule := icaauth.NewIBCModule(app.ICAAuthKeeper) + +// Create controller IBC application stack +icaControllerStack := icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) + +// Register controller and authentication routes +ibcRouter. + AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). + AddRoute(icaauthtypes.ModuleName, icaControllerStack) // Note, the authentication module is routed to the top level of the middleware stack +``` diff --git a/docs/apps/interchain-accounts/legacy/keeper-api.md b/docs/apps/interchain-accounts/legacy/keeper-api.md new file mode 100644 index 00000000000..670879d02df --- /dev/null +++ b/docs/apps/interchain-accounts/legacy/keeper-api.md @@ -0,0 +1,121 @@ + + +# Keeper API + +## Deprecation Notice + +**This document is deprecated and will be removed in future releases**. + +The controller submodule keeper exposes two legacy functions that allow respectively for custom authentication modules to register interchain accounts and send packets to the interchain account. + +## `RegisterInterchainAccount` + +The authentication module can begin registering interchain accounts by calling `RegisterInterchainAccount`: + +```go +if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID, owner.String(), version); err != nil { + return err +} + +return nil +``` + +The `version` argument is used to support ICS-29 fee middleware for relayer incentivization of ICS-27 packets. Consumers of the `RegisterInterchainAccount` are expected to build the appropriate JSON encoded version string themselves and pass it accordingly. If an empty string is passed in the `version` argument, then the version will be initialized to a default value in the `OnChanOpenInit` callback of the controller's handler, so that channel handshake can proceed. + +The following code snippet illustrates how to construct an appropriate interchain accounts `Metadata` and encode it as a JSON bytestring: + +```go +icaMetadata := icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: controllerConnectionID, + HostConnectionId: hostConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, +} + +appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) +if err != nil { + return err +} + +if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(appVersion)); err != nil { + return err +} +``` + +Similarly, if the application stack is configured to route through ICS-29 fee middleware and a fee enabled channel is desired, construct the appropriate ICS-29 `Metadata` type: + +```go +icaMetadata := icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: controllerConnectionID, + HostConnectionId: hostConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, +} + +appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) +if err != nil { + return err +} + +feeMetadata := feetypes.Metadata{ + AppVersion: string(appVersion), + FeeVersion: feetypes.Version, +} + +feeEnabledVersion, err := feetypes.ModuleCdc.MarshalJSON(&feeMetadata) +if err != nil { + return err +} + +if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(feeEnabledVersion)); err != nil { + return err +} +``` + +## `SendTx` + +The authentication module can attempt to send a packet by calling `SendTx`: + +```go +// Authenticate owner +// perform custom logic + +// Construct controller portID based on interchain account owner address +portID, err := icatypes.NewControllerPortID(owner.String()) +if err != nil { + return err +} + +// Obtain data to be sent to the host chain. +// In this example, the owner of the interchain account would like to send a bank MsgSend to the host chain. +// The appropriate serialization function should be called. The host chain must be able to deserialize the transaction. +// If the host chain is using the ibc-go host module, `SerializeCosmosTx` should be used. +msg := &banktypes.MsgSend{FromAddress: fromAddr, ToAddress: toAddr, Amount: amt} +data, err := icatypes.SerializeCosmosTx(keeper.cdc, []proto.Message{msg}) +if err != nil { + return err +} + +// Construct packet data +packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, +} + +// Obtain timeout timestamp +// An appropriate timeout timestamp must be determined based on the usage of the interchain account. +// If the packet times out, the channel will be closed requiring a new channel to be created. +timeoutTimestamp := obtainTimeoutTimestamp() + +// Send the interchain accounts packet, returning the packet sequence +// A nil channel capability can be passed, since the controller submodule (and not the authentication module) +// claims the channel capability since ibc-go v6. +seq, err = keeper.icaControllerKeeper.SendTx(ctx, nil, portID, packetData, timeoutTimestamp) +``` + +The data within an `InterchainAccountPacketData` must be serialized using a format supported by the host chain. +If the host chain is using the ibc-go host chain submodule, `SerializeCosmosTx` should be used. If the `InterchainAccountPacketData.Data` is serialized using a format not supported by the host chain, the packet will not be successfully received. diff --git a/docs/apps/interchain-accounts/messages.md b/docs/apps/interchain-accounts/messages.md new file mode 100644 index 00000000000..0f4475818fe --- /dev/null +++ b/docs/apps/interchain-accounts/messages.md @@ -0,0 +1,74 @@ + + +# Messages + +## `MsgRegisterInterchainAccount` + +An Interchain Accounts channel handshake can be initated using `MsgRegisterInterchainAccount`: + +```go +type MsgRegisterInterchainAccount struct { + Owner string + ConnectionID string + Version string +} +``` + +This message is expected to fail if: + +- `Owner` is an empty string. +- `ConnectionID` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). + +This message will construct a new `MsgChannelOpenInit` on chain and route it to the core IBC message server to initiate the opening step of the channel handshake. + +The controller submodule will generate a new port identifier and claim the associated port capability. The caller is expected to provide an appropriate application version string. For example, this may be an ICS-27 JSON encoded [`Metadata`](https://github.com/cosmos/ibc-go/blob/v6.0.0/proto/ibc/applications/interchain_accounts/v1/metadata.proto#L11) type or an ICS-29 JSON encoded [`Metadata`](https://github.com/cosmos/ibc-go/blob/v6.0.0/proto/ibc/applications/fee/v1/metadata.proto#L11) type with a nested application version. +If the `Version` string is omitted, the controller submodule will construct a default version string in the `OnChanOpenInit` handshake callback. + +```go +type MsgRegisterInterchainAccountResponse struct { + ChannelID string + PortId string +} +``` + +The `ChannelID` and `PortID` are returned in the message response. + +## `MsgSendTx` + +An Interchain Accounts transaction can be executed on a remote host chain by sending a `MsgSendTx` from the corresponding controller chain: + +```go +type MsgSendTx struct { + Owner string + ConnectionID string + PacketData InterchainAccountPacketData + RelativeTimeout uint64 +} +``` + +This message is expected to fail if: + +- `Owner` is an empty string. +- `ConnectionID` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). +- `PacketData` contains an `UNSPECIFIED` type enum, the length of `Data` bytes is zero or the `Memo` field exceeds 256 characters in length. +- `RelativeTimeout` is zero. + +This message will create a new IBC packet with the provided `PacketData` and send it via the channel associated with the `Owner` and `ConnectionID`. +The `PacketData` is expected to contain a list of serialized `[]sdk.Msg` in the form of `CosmosTx`. Please note the signer field of each `sdk.Msg` must be the interchain account address. +When the packet is relayed to the host chain, the `PacketData` is unmarshalled and the messages are authenticated and executed. + +```go +type MsgSendTxResponse struct { + Sequence uint64 +} +``` + +The packet `Sequence` is returned in the message response. + +## Atomicity + +As the Interchain Accounts module supports the execution of multiple transactions using the Cosmos SDK `Msg` interface, it provides the same atomicity guarantees as Cosmos SDK-based applications, leveraging the [`CacheMultiStore`](https://docs.cosmos.network/main/core/store.html#cachemultistore) architecture provided by the [`Context`](https://docs.cosmos.network/main/core/context.html) type. + +This provides atomic execution of transactions when using Interchain Accounts, where state changes are only committed if all `Msg`s succeed. diff --git a/docs/apps/interchain-accounts/overview.md b/docs/apps/interchain-accounts/overview.md index dc015aaf1e3..f892ae31775 100644 --- a/docs/apps/interchain-accounts/overview.md +++ b/docs/apps/interchain-accounts/overview.md @@ -4,35 +4,30 @@ order: 1 # Overview -Learn about what the Interchain Accounts module is, and how to build custom modules that utilize Interchain Accounts functionality {synopsis} - +Learn about what the Interchain Accounts module is {synopsis} ## What is the Interchain Accounts module? -Interchain Accounts is the Cosmos SDK implementation of the ICS-27 protocol, which enables cross-chain account management built upon IBC. Chains using the Interchain Accounts module can programmatically create accounts on other chains and control these accounts via IBC transactions. - -Interchain Accounts exposes a simple-to-use API which means IBC application developers do not require an in-depth knowledge of the underlying low-level details of IBC or the ICS-27 protocol. +Interchain Accounts is the Cosmos SDK implementation of the ICS-27 protocol, which enables cross-chain account management built upon IBC. -Developers looking to build upon Interchain Accounts must write custom logic in their own IBC application module, called authentication modules. +- How does an interchain account differ from a regular account? -- How is an interchain account different than a regular account? +Regular accounts use a private key to sign transactions. Interchain Accounts are instead controlled programmatically by counterparty chains via IBC packets. -Regular accounts use a private key to sign transactions on-chain. Interchain Accounts are instead controlled programmatically by separate chains via IBC transactions. Interchain Accounts are implemented as sub-accounts of the interchain accounts module account. +## Concepts -## Concepts +`Host Chain`: The chain where the interchain account is registered. The host chain listens for IBC packets from a controller chain which should contain instructions (e.g. Cosmos SDK messages) for which the interchain account will execute. -`Host Chain`: The chain where the interchain account is registered. The host chain listens for IBC packets from a controller chain which should contain instructions (e.g. cosmos SDK messages) for which the interchain account will execute. +`Controller Chain`: The chain registering and controlling an account on a host chain. The controller chain sends IBC packets to the host chain to control the account. -`Controller Chain`: The chain registering and controlling an account on a host chain. The controller chain sends IBC packets to the host chain to control the account. A controller chain must have at least one interchain accounts authentication module in order to act as a controller chain. +`Interchain Account`: An account on a host chain created using the ICS-27 protocol. An interchain account has all the capabilities of a normal account. However, rather than signing transactions with a private key, a controller chain will send IBC packets to the host chain which signals what transactions the interchain account should execute. -`Authentication Module`: A custom IBC application module on the controller chain that uses the Interchain Accounts module API to build custom logic for the creation & management of interchain accounts. For a controller chain to utilize the interchain accounts module functionality, an authentication module is required. +`Authentication Module`: A custom application module on the controller chain that uses the Interchain Accounts module to build custom logic for the creation & management of interchain accounts. It can be either an IBC application module using the [legacy API](./legacy/keeper-api.md), or a regular Cosmos SDK application module sending messages to the controller submodule's `MsgServer` (this is the recommended approach from ibc-go v6 if access to packet callbacks is not needed). Please note that the legacy API will eventually be removed and IBC applications will not be able to use them in later releases. -`Interchain Account`: An account on a host chain. An interchain account has all the capabilities of a normal account. However, rather than signing transactions with a private key, a controller chain's authentication module will send IBC packets to the host chain which signals what transactions the interchain account should execute. - -## SDK Security Model +## SDK security model -SDK modules on a chain are assumed to be trustworthy. For example, there are no checks to prevent an untrustworthy module from accessing the bank keeper. +SDK modules on a chain are assumed to be trustworthy. For example, there are no checks to prevent an untrustworthy module from accessing the bank keeper. -The implementation of ICS27 on ibc-go uses this assumption in its security considerations. The implementation assumes the authentication module will not try to open channels on owner addresses it does not control. +The implementation of ICS-27 in ibc-go uses this assumption in its security considerations. -The implementation assumes other IBC application modules will not bind to ports within the ICS27 namespace. +The implementation assumes other IBC application modules will not bind to ports within the ICS-27 namespace. diff --git a/docs/apps/interchain-accounts/parameters.md b/docs/apps/interchain-accounts/parameters.md index 8f985b9293e..2d87927cc11 100644 --- a/docs/apps/interchain-accounts/parameters.md +++ b/docs/apps/interchain-accounts/parameters.md @@ -1,58 +1,61 @@ # Parameters The Interchain Accounts module contains the following on-chain parameters, logically separated for each distinct submodule: -### Controller Submodule Parameters +## Controller Submodule Parameters | Key | Type | Default Value | |------------------------|------|---------------| | `ControllerEnabled` | bool | `true` | -#### ControllerEnabled +### ControllerEnabled The `ControllerEnabled` parameter controls a chains ability to service ICS-27 controller specific logic. This includes the sending of Interchain Accounts packet data as well as the following ICS-26 callback handlers: + - `OnChanOpenInit` - `OnChanOpenAck` - `OnChanCloseConfirm` - `OnAcknowledgementPacket` - `OnTimeoutPacket` -### Host Submodule Parameters +## Host Submodule Parameters | Key | Type | Default Value | |------------------------|----------|---------------| | `HostEnabled` | bool | `true` | -| `AllowMessages` | []string | `[]` | +| `AllowMessages` | []string | `["*"]` | + +### HostEnabled -#### HostEnabled +The `HostEnabled` parameter controls a chains ability to service ICS-27 host specific logic. This includes the following ICS-26 callback handlers: -The `HostEnabled` parameter controls a chains ability to service ICS27 host specific logic. This includes the following ICS-26 callback handlers: - `OnChanOpenTry` - `OnChanOpenConfirm` - `OnChanCloseConfirm` - `OnRecvPacket` -#### AllowMessages +### AllowMessages -The `AllowMessages` parameter provides the ability for a chain to limit the types of messages or transactions that hosted interchain accounts are authorized to execute by defining an allowlist using the Protobuf message TypeURL format. +The `AllowMessages` parameter provides the ability for a chain to limit the types of messages or transactions that hosted interchain accounts are authorized to execute by defining an allowlist using the Protobuf message type URL format. -For example, a Cosmos SDK based chain that elects to provide hosted Interchain Accounts with the ability of governance voting and staking delegations will define its parameters as follows: +For example, a Cosmos SDK-based chain that elects to provide hosted Interchain Accounts with the ability of governance voting and staking delegations will define its parameters as follows: -``` +```json "params": { - "host_enabled": true, - "allow_messages": ["/cosmos.staking.v1beta1.MsgDelegate", "/cosmos.gov.v1beta1.MsgVote"] + "host_enabled": true, + "allow_messages": ["/cosmos.staking.v1beta1.MsgDelegate", "/cosmos.gov.v1beta1.MsgVote"] } ``` -There is also a special wildcard `"*"` message type which allows any type of message to be executed by the interchain account. This must be the only message in the `allow_messages` array. -``` +There is also a special wildcard `"*"` value which allows any type of message to be executed by the interchain account. This must be the only value in the `allow_messages` array. + +```json "params": { - "host_enabled": true, - "allow_messages": ["*"] + "host_enabled": true, + "allow_messages": ["*"] } -``` \ No newline at end of file +``` diff --git a/docs/apps/interchain-accounts/transactions.md b/docs/apps/interchain-accounts/transactions.md deleted file mode 100644 index e17571a6e00..00000000000 --- a/docs/apps/interchain-accounts/transactions.md +++ /dev/null @@ -1,21 +0,0 @@ - - -# Transactions - -Learn about Interchain Accounts transaction execution {synopsis} - -## Executing a transaction - -As described in [Authentication Modules](./auth-modules.md#trysendtx) transactions are executed using the interchain accounts controller API and require a `Base Application` as outlined in [ICS30 IBC Middleware](https://github.com/cosmos/ibc/tree/master/spec/app/ics-030-middleware) to facilitate authentication. The method of authentication remains unspecified to provide flexibility for the authentication module developer. - -Transactions are executed via the ICS27 [`SendTx` API](./auth-modules.md#trysendtx). This must be invoked through an Interchain Accounts authentication module and follows the outlined path of execution below. Packet relaying semantics provided by the IBC core transport, authentication, and ordering (IBC/TAO) layer are omitted for brevity. - -![send-tx-flow](../../assets/send-interchain-tx.png "Transaction Execution") - -## Atomicity - -As the Interchain Accounts module supports the execution of multiple transactions using the Cosmos SDK `Msg` interface, it provides the same atomicity guarantees as Cosmos SDK-based applications, leveraging the [`CacheMultiStore`](https://docs.cosmos.network/main/core/store.html#cachemultistore) architecture provided by the [`Context`](https://docs.cosmos.network/main/core/context.html) type. - -This provides atomic execution of transactions when using Interchain Accounts, where state changes are only committed if all `Msg`s succeed. diff --git a/docs/apps/transfer/authorizations.md b/docs/apps/transfer/authorizations.md new file mode 100644 index 00000000000..8835e3d807c --- /dev/null +++ b/docs/apps/transfer/authorizations.md @@ -0,0 +1,47 @@ +# `TransferAuthorization` + +`TransferAuthorization` implements the `Authorization` interface for `ibc.applications.transfer.v1.MsgTransfer`. It allows a granter to grant a grantee the privilege to submit MsgTransfer on its behalf. Please see the [Cosmos SDK docs](https://docs.cosmos.network/v0.47/modules/authz) for more details on granting privileges via the `x/authz` module. + +More specifically, the granter allows the grantee to transfer funds that belong to the granter over a specified channel. + +For the specified channel, the granter must be able to specify a spend limit of a specific denomination they wish to allow the grantee to be able to transfer. + +The granter may be able to specify the list of addresses that they allow to receive funds. If empty, then all addresses are allowed. + +It takes: + +- a `SourcePort` and a `SourceChannel` which together comprise the unique transfer channel identifier over which authorized funds can be transferred. + +- a `SpendLimit` that specifies the maximum amount of tokens the grantee can spend. The `SpendLimit` is updated as the tokens are spent. This `SpendLimit` may also be updated to increase or decrease the limit as the granter wishes. + +- an `AllowList` list that specifies the list of addresses that are allowed to receive funds. If this list is empty, then all addresses are allowed to receive funds from the `TransferAuthorization`. + +Setting a `TransferAuthorization` is expected to fail if: + +- the spend limit is nil +- the denomination of the spend limit is an invalid coin type +- the source port ID is invalid +- the source channel ID is invalid +- there are duplicate entries in the `AllowList` + +Below is the `TransferAuthorization` message: + +```go +func NewTransferAuthorization(allocations ...Allocation) *TransferAuthorization { + return &TransferAuthorization{ + Allocations: allocations, + } +} + +type Allocation struct { + // the port on which the packet will be sent + SourcePort string + // the channel by which the packet will be sent + SourceChannel string + // spend limitation on the channel + SpendLimit sdk.Coins + // allow list of receivers, an empty allow list permits any receiver address + AllowList []string +} + +``` diff --git a/docs/apps/transfer/events.md b/docs/apps/transfer/events.md index a538d07d068..52605fd7cfb 100644 --- a/docs/apps/transfer/events.md +++ b/docs/apps/transfer/events.md @@ -23,6 +23,7 @@ order: 5 | fungible_token_packet | denom | {denom} | | fungible_token_packet | amount | {amount} | | fungible_token_packet | success | {ackSuccess} | +| fungible_token_packet | memo | {memo} | | denomination_trace | trace_hash | {hex_hash} | ## `OnAcknowledgePacket` callback @@ -34,6 +35,7 @@ order: 5 | fungible_token_packet | receiver | {receiver} | | fungible_token_packet | denom | {denom} | | fungible_token_packet | amount | {amount} | +| fungible_token_packet | memo | {memo} | | fungible_token_packet | acknowledgement | {ack.String()} | | fungible_token_packet | success | error | {ack.Response} | @@ -45,3 +47,4 @@ order: 5 | fungible_token_packet | refund_receiver | {receiver} | | fungible_token_packet | denom | {denom} | | fungible_token_packet | amount | {amount} | +| fungible_token_packet | memo | {memo} | diff --git a/docs/apps/transfer/messages.md b/docs/apps/transfer/messages.md index 7cb61402e04..26a636de8d2 100644 --- a/docs/apps/transfer/messages.md +++ b/docs/apps/transfer/messages.md @@ -17,6 +17,7 @@ type MsgTransfer struct { Receiver string TimeoutHeight ibcexported.Height TimeoutTimestamp uint64 + Memo string } ``` diff --git a/docs/apps/transfer/metrics.md b/docs/apps/transfer/metrics.md index e9e3086ba1d..7d83b08eb13 100644 --- a/docs/apps/transfer/metrics.md +++ b/docs/apps/transfer/metrics.md @@ -4,7 +4,7 @@ order: 6 # Metrics -The IBC transfer application module exposes the following set of [metrics](https://github.com/cosmos/cosmos-sdk/blob/main/docs/core/telemetry.md). +The IBC transfer application module exposes the following set of [metrics](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/core/09-telemetry.md). | Metric | Description | Unit | Type | |:--------------------------------|:------------------------------------------------------------------------------------------|:----------------|:--------| diff --git a/docs/apps/transfer/params.md b/docs/apps/transfer/params.md index e2e74305311..a04f3d42021 100644 --- a/docs/apps/transfer/params.md +++ b/docs/apps/transfer/params.md @@ -15,10 +15,16 @@ The IBC transfer application module contains the following parameters: The transfers enabled parameter controls send cross-chain transfer capabilities for all fungible tokens. -To prevent a single token from being transferred from the chain, set the `SendEnabled` parameter to `true` and then set the bank module's [`SendEnabled` parameter](https://github.com/cosmos/cosmos-sdk/blob/main/x/bank/spec/05_params.md#sendenabled) for the denomination to `false`. +To prevent a single token from being transferred from the chain, set the `SendEnabled` parameter to `true` and then, depending on the Cosmos SDK version, do one of the following: + +- For Cosmos SDK v0.46.x or earlier, set the bank module's [`SendEnabled` parameter](https://github.com/cosmos/cosmos-sdk/blob/release/v0.46.x/x/bank/spec/05_params.md#sendenabled) for the denomination to `false`. +- For Cosmos SDK versions above v0.46.x, set the bank module's `SendEnabled` entry for the denomination to `false` using `MsgSetSendEnabled` as a governance proposal. ## `ReceiveEnabled` The transfers enabled parameter controls receive cross-chain transfer capabilities for all fungible tokens. -To prevent a single token from being transferred to the chain, set the `ReceiveEnabled` parameter to `true` and then set the bank module's [`SendEnabled` parameter](https://github.com/cosmos/cosmos-sdk/blob/main/x/bank/spec/05_params.md#sendenabled) for the denomination to `false`. +To prevent a single token from being transferred to the chain, set the `ReceiveEnabled` parameter to `true` and then, depending on the Cosmos SDK version, do one of the following: + +- For Cosmos SDK v0.46.x or earlier, set the bank module's [`SendEnabled` parameter](https://github.com/cosmos/cosmos-sdk/blob/release/v0.46.x/x/bank/spec/05_params.md#sendenabled) for the denomination to `false`. +- For Cosmos SDK versions above v0.46.x, set the bank module's `SendEnabled` entry for the denomination to `false` using `MsgSetSendEnabled` as a governance proposal. diff --git a/docs/architecture/README.md b/docs/architecture/README.md index edfbea4f0c8..213cbc138b2 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -35,5 +35,3 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov | [025](./adr-025-ibc-passive-channels.md) | IBC passive channels | Deprecated | | [026](./adr-026-ibc-client-recovery-mechanisms.md) | IBC client recovery mechansisms | Accepted | | [027](./adr-027-ibc-wasm.md) | Wasm based light clients | Accepted | - - diff --git a/docs/architecture/adr-001-coin-source-tracing.md b/docs/architecture/adr-001-coin-source-tracing.md index 4aeb59aecab..bc0c42efd2a 100644 --- a/docs/architecture/adr-001-coin-source-tracing.md +++ b/docs/architecture/adr-001-coin-source-tracing.md @@ -114,7 +114,7 @@ trace the token back to the originating chain, as specified on ICS20. The new proposed format will be the following: -```golang +```go ibcDenom = "ibc/" + hash(trace path + "/" + base denom) ``` @@ -133,7 +133,7 @@ message DenomTrace { The `IBCDenom` function constructs the `Coin` denomination used when creating the ICS20 fungible token packet data: -```golang +```go // Hash returns the hex bytes of the SHA256 hash of the DenomTrace fields using the following formula: // // hash = sha256(tracePath + "/" + baseDenom) @@ -157,7 +157,7 @@ In order to retrieve the trace information from an IBC denomination, a lookup ta added to the `ibc-transfer` module. These values need to also be persisted between upgrades, meaning that a new `[]DenomTrace` `GenesisState` field state needs to be added to the module: -```golang +```go // GetDenomTrace retrieves the full identifiers trace and base denomination from the store. func (k Keeper) GetDenomTrace(ctx Context, denomTraceHash []byte) (DenomTrace, bool) { store := ctx.KVStore(k.storeKey) @@ -188,14 +188,14 @@ func (k Keeper) SetDenomTrace(ctx Context, denomTrace DenomTrace) { The `MsgTransfer` will validate that the `Coin` denomination from the `Token` field contains a valid hash, if the trace info is provided, or that the base denominations matches: -```golang +```go func (msg MsgTransfer) ValidateBasic() error { // ... return ValidateIBCDenom(msg.Token.Denom) } ``` -```golang +```go // ValidateIBCDenom validates that the given denomination is either: // // - A valid base denomination (eg: 'uatom') @@ -226,7 +226,7 @@ The denomination trace info only needs to be updated when token is received: - Receiver is **source** chain: The receiver created the token and must have the trace lookup already stored (if necessary _ie_ native token case wouldn't need a lookup). - Receiver is **not source** chain: Store the received info. For example, during step 1, when chain `B` receives `transfer/channelToA/denom`. -```golang +```go // SendTransfer // ... @@ -245,7 +245,7 @@ if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) { //... ``` -```golang +```go // DenomPathFromHash returns the full denomination path prefix from an ibc denom with a hash // component. func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error) { @@ -265,8 +265,7 @@ func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error) } ``` - -```golang +```go // OnRecvPacket // ... @@ -322,7 +321,7 @@ return k.bankKeeper.SendCoinsFromModuleToAccount( ) ``` -```golang +```go func NewDenomTraceFromRawDenom(denom string) DenomTrace{ denomSplit := strings.Split(denom, "/") trace := "" diff --git a/docs/architecture/adr-002-go-module-versioning.md b/docs/architecture/adr-002-go-module-versioning.md index a046792b142..aa2c74f1ad4 100644 --- a/docs/architecture/adr-002-go-module-versioning.md +++ b/docs/architecture/adr-002-go-module-versioning.md @@ -1,6 +1,7 @@ # ADR 002: Go module versioning ## Changelog + * 05/01/2022: initial draft ## Status @@ -11,18 +12,19 @@ Accepted The IBC module was originally developed in the Cosmos SDK and released during with the Stargate release series (v0.42). It was subsequently migrated to its own repository, ibc-go. -The first official release on ibc-go was v1.0.0. +The first official release on ibc-go was v1.0.0. v1.0.0 was decided to be used instead of v0.1.0 primarily for the following reasons: -- Maintaining compatibility with the IBC specification v1 requires stronger support/guarantees. -- Using the major, minor, and patch numbers allows for easier communication of what breaking changes are included in a release. -- The IBC module is being used by numerous high value projects which require stability. + +* Maintaining compatibility with the IBC specification v1 requires stronger support/guarantees. +* Using the major, minor, and patch numbers allows for easier communication of what breaking changes are included in a release. +* The IBC module is being used by numerous high value projects which require stability. ### Problems #### Go module version must be incremented When a Go module is released under v1.0.0, all following releases must follow Go semantic versioning. -Thus when the go API is broken, the Go module major version **must** be incremented. +Thus when the go API is broken, the Go module major version **must** be incremented. For example, changing the go package version from `v2` to `v3` bumps the import from `github.com/cosmos/ibc-go/v2` to `github.com/cosmos/ibc-go/v3`. If the Go module version is not incremented then attempting to go get a module @v3.0.0 without the suffix results in: @@ -33,15 +35,15 @@ Not including a go.mod in our release is not a viable option. #### Attempting to import multiple go module versions for ibc-go -Attempting to import two versions of ibc-go, such as `github.com/cosmos/ibc-go/v2` and `github.com/cosmos/ibc-go/v3`, will result in multiple issues. +Attempting to import two versions of ibc-go, such as `github.com/cosmos/ibc-go/v2` and `github.com/cosmos/ibc-go/v3`, will result in multiple issues. -The Cosmos SDK does global registration of error and governance proposal types. +The Cosmos SDK does global registration of error and governance proposal types. The errors and proposals used in ibc-go would need to now register their naming based on the go module version. The more concerning problem is that protobuf definitions will also reach a namespace collision. ibc-go and the Cosmos SDK in general rely heavily on using extended functions for go structs generated from protobuf definitions. -This requires the go structs to be defined in the same package as the extended functions. -Thus, bumping the import versioning causes the protobuf definitions to be generated in two places (in v2 and v3). +This requires the go structs to be defined in the same package as the extended functions. +Thus, bumping the import versioning causes the protobuf definitions to be generated in two places (in v2 and v3). When registering these types at compile time, the go compiler will panic. The generated types need to be registered against the proto codec, but there exist two definitions for the same name. @@ -52,11 +54,11 @@ More information [here](https://developers.google.com/protocol-buffers/docs/refe #### Changing the protobuf definition version -The protobuf definitions all have a type URL containing the protobuf version for this type. -Changing the protobuf version would solve the namespace collision which arise from importing multiple versions of ibc-go, but it leads to new issues. +The protobuf definitions all have a type URL containing the protobuf version for this type. +Changing the protobuf version would solve the namespace collision which arise from importing multiple versions of ibc-go, but it leads to new issues. In the Cosmos SDK, `Any`s are unpacked and decoded using the type URL. -Changing the type URL thus is creating a distinctly different type. +Changing the type URL thus is creating a distinctly different type. The same registration on the proto codec cannot be used to unpack the new type. For example: @@ -85,12 +87,12 @@ For example, lets say this solution is implemented in v3. Then ## Decision Supporting importing multiple versions of ibc-go requires a non-trivial amount of complexity. -It is unclear when a user of the ibc-go code would need multiple versions of ibc-go. +It is unclear when a user of the ibc-go code would need multiple versions of ibc-go. Until there is an overwhelming reason to support importing multiple versions of ibc-go: **Major releases cannot be imported simultaneously**. -Releases should focus on keeping backwards compatibility for go code clients, within reason. -Old functionality should be marked as deprecated and there should exist upgrade paths between major versions. +Releases should focus on keeping backwards compatibility for go code clients, within reason. +Old functionality should be marked as deprecated and there should exist upgrade paths between major versions. Deprecated functionality may be removed when no clients rely on that functionality. How this is determined is to be decided. @@ -99,7 +101,7 @@ This explicitly stops external clients from trying to import two major versions ## Consequences -This only affects clients relying directly on the go code. +This only affects clients relying directly on the go code. ### Positive @@ -108,4 +110,3 @@ This only affects clients relying directly on the go code. Multiple ibc-go versions cannot be imported. ### Neutral - diff --git a/docs/architecture/adr-003-ics27-acknowledgement.md b/docs/architecture/adr-003-ics27-acknowledgement.md index dc2e3256ba6..5704af0d98c 100644 --- a/docs/architecture/adr-003-ics27-acknowledgement.md +++ b/docs/architecture/adr-003-ics27-acknowledgement.md @@ -1,6 +1,7 @@ # ADR 003: ICS27 Acknowledgement Format ## Changelog + * January 28th, 2022: Initial Draft ## Status @@ -9,92 +10,94 @@ Accepted ## Context -Upon receiving an IBC packet, an IBC application can optionally return an acknowledgement. -This acknowledgement will be hashed and written into state. Thus any changes to the information included in an acknowledgement are state machine breaking. +Upon receiving an IBC packet, an IBC application can optionally return an acknowledgement. +This acknowledgement will be hashed and written into state. Thus any changes to the information included in an acknowledgement are state machine breaking. -ICS27 executes transactions on behalf of a controller chain. Information such as the message result or message error may be returned from other SDK modules outside the control of the ICS27 module. -It might be very valuable to return message execution information inside the ICS27 acknowledgement so that controller chain interchain account auth modules can act upon this information. -Only determinstic information returned from the message execution is allowed to be returned in the packet acknowledgement otherwise the network will halt due to a fork in the expected app hash. +ICS27 executes transactions on behalf of a controller chain. Information such as the message result or message error may be returned from other SDK modules outside the control of the ICS27 module. +It might be very valuable to return message execution information inside the ICS27 acknowledgement so that controller chain interchain account auth modules can act upon this information. +Only determinstic information returned from the message execution is allowed to be returned in the packet acknowledgement otherwise the network will halt due to a fork in the expected app hash. ## Decision At the time of this writing, Tendermint includes the following information in the [ABCI.ResponseDeliverTx](https://github.com/tendermint/tendermint/blob/release/v0.34.13/types/results.go#L47-#L53): + ```go // deterministicResponseDeliverTx strips non-deterministic fields from // ResponseDeliverTx and returns another ResponseDeliverTx. func deterministicResponseDeliverTx(response *abci.ResponseDeliverTx) *abci.ResponseDeliverTx { - return &abci.ResponseDeliverTx{ - Code: response.Code, - Data: response.Data, - GasWanted: response.GasWanted, - GasUsed: response.GasUsed, - } + return &abci.ResponseDeliverTx{ + Code: response.Code, + Data: response.Data, + GasWanted: response.GasWanted, + GasUsed: response.GasUsed, + } } ``` ### Successful acknowledgements -Successful acknowledgements should return information about the transaction execution. -Given the determinstic fields in the `abci.ResponseDeliverTx`, the transaction `Data` can be used to indicate information about the transaction execution. +Successful acknowledgements should return information about the transaction execution. +Given the determinstic fields in the `abci.ResponseDeliverTx`, the transaction `Data` can be used to indicate information about the transaction execution. The `abci.ResponseDeliverTx.Data` will be set in the ICS27 packet acknowledgement upon successful transaction execution. -The format for the `abci.ResponseDeliverTx.Data` is constructed by the SDK. +The format for the `abci.ResponseDeliverTx.Data` is constructed by the SDK. -At the time of this writing, the next major release of the SDK will change the format for constructing the transaction response data. +At the time of this writing, the next major release of the SDK will change the format for constructing the transaction response data. #### v0.45 format The current version, v0.45 constructs the transaction response as follows: + ```go - proto.Marshal(&sdk.TxMsgData{ - Data: []*sdk.MsgData{msgResponses...}, - } +proto.Marshal(&sdk.TxMsgData{ + Data: []*sdk.MsgData{msgResponses...}, +} ``` -Where `msgResponses` is a slice of `*sdk.MsgData`. +Where `msgResponses` is a slice of `*sdk.MsgData`. The `MsgData.MsgType` contains the `sdk.MsgTypeURL` of the `sdk.Msg` being executed. -The `MsgData.Data` contains the proto marshaled `MsgResponse` for the associated message executed. +The `MsgData.Data` contains the proto marshaled `MsgResponse` for the associated message executed. #### Next major version format The next major version will construct the transaction response as follows: -```go - proto.Marshal(&sdk.TxMsgData{ - MsgResponses: []*codectypes.Any{msgResponses...}, - } + +```go +proto.Marshal(&sdk.TxMsgData{ + MsgResponses: []*codectypes.Any{msgResponses...}, +} ``` Where `msgResponses` is a slice of the `MsgResponse`s packed into `Any`s. #### Forwards compatible approach -A forwards compatible approach was deemed infeasible. -The `handler` provided by the `MsgServiceRouter` will only include the `*sdk.Result` and an error (if one occurred). -In v0.45 of the SDK, the `*sdk.Result.Data` will contain the MsgResponse marshaled data. -However, the MsgResponse is not packed and marshaled as a `*codectypes.Any`, thus making it impossible from a generalized point of view to unmarshal the bytes. -If the bytes could be unmarshaled, then they could be packed into an `*codectypes.Any` in antcipation of the upcoming format. +A forwards compatible approach was deemed infeasible. +The `handler` provided by the `MsgServiceRouter` will only include the `*sdk.Result` and an error (if one occurred). +In v0.45 of the SDK, the `*sdk.Result.Data` will contain the MsgResponse marshaled data. +However, the MsgResponse is not packed and marshaled as a `*codectypes.Any`, thus making it impossible from a generalized point of view to unmarshal the bytes. +If the bytes could be unmarshaled, then they could be packed into an `*codectypes.Any` in anticipation of the upcoming format. -Intercepting the MsgResponse before it becomes marshaled requires replicating this [code](https://github.com/cosmos/cosmos-sdk/blob/dfd47f5b449f558a855da284a9a7eabbfbad435d/baseapp/msg_service_router.go#L109-#L128). +Intercepting the MsgResponse before it becomes marshaled requires replicating this [code](https://github.com/cosmos/cosmos-sdk/blob/dfd47f5b449f558a855da284a9a7eabbfbad435d/baseapp/msg_service_router.go#L109-#L128). It may not even be possible to replicate the linked code. The method handler would need to be accessed somehow. -For these reasons it is deemed infeasible to attempt a fowards compatible approach. +For these reasons it is deemed infeasible to attempt a fowards compatible approach. -ICA auth developers can interpret which format was used when constructing the transaction response by checking if the `sdk.TxMsgData.Data` field is non-empty. +ICA auth developers can interpret which format was used when constructing the transaction response by checking if the `sdk.TxMsgData.Data` field is non-empty. If the `sdk.TxMsgData.Data` field is not empty then the format for v0.45 was used, otherwise ICA auth developers can assume the transaction response uses the newer format. - #### Decision -Replicate the transaction response format as provided by the current SDK verison. -When the SDK version changes, adjust the transaction response format to use the updated transaction response format. -Include the transaction response bytes in the result channel acknowledgement. +Replicate the transaction response format as provided by the current SDK verison. +When the SDK version changes, adjust the transaction response format to use the updated transaction response format. +Include the transaction response bytes in the result channel acknowledgement. A test has been [written](https://github.com/cosmos/ibc-go/blob/v3.0.0-beta1/modules/apps/27-interchain-accounts/host/ibc_module_test.go#L716-#L774) to fail if the `MsgResponse` is no longer included in consensus. ### Error acknowledgements -As indicated above, the `abci.ResponseDeliverTx.Code` is determinstic. -Upon transaction execution errors, an error acknowledgement should be returned including the abci code. +As indicated above, the `abci.ResponseDeliverTx.Code` is determinstic. +Upon transaction execution errors, an error acknowledgement should be returned including the abci code. A test has been [written](https://github.com/cosmos/ibc-go/blob/v3.0.0-beta1/modules/apps/27-interchain-accounts/host/types/ack_test.go#L41-#L82) to fail if the ABCI code is no longer determinstic. @@ -104,15 +107,14 @@ A test has been [written](https://github.com/cosmos/ibc-go/blob/v3.0.0-beta1/mod ### Positive -- interchain account auth modules can act upon transaction results without requiring a query module -- transaction results align with those returned by execution of a normal SDK message. +* interchain account auth modules can act upon transaction results without requiring a query module +* transaction results align with those returned by execution of a normal SDK message. ### Negative -- the security assumptions of this decision rest on the inclusion of the ABCI error code and the Msg response in the ResponseDeliverTx hash created by Tendermint -- events are non-determinstic and cannot be included in the packet acknowledgement +* the security assumptions of this decision rest on the inclusion of the ABCI error code and the Msg response in the ResponseDeliverTx hash created by Tendermint +* events are non-determinstic and cannot be included in the packet acknowledgement ### Neutral No neutral consequences. - diff --git a/docs/architecture/adr-004-ics29-lock-fee-module.md b/docs/architecture/adr-004-ics29-lock-fee-module.md index 5b17717e669..27fc2319637 100644 --- a/docs/architecture/adr-004-ics29-lock-fee-module.md +++ b/docs/architecture/adr-004-ics29-lock-fee-module.md @@ -1,6 +1,7 @@ # ADR 004: Lock fee module upon escrow out of balance ## Changelog + * 03/03/2022: initial draft ## Status @@ -9,27 +10,27 @@ Accepted ## Context -The fee module maintains an escrow account for all fees escrowed to incentivize packet relays. -It also tracks each packet fee escrowed separately from the escrow account. This is because the escrow account only maintains a total balance. It has no reference for which coins belonged to which packet fee. +The fee module maintains an escrow account for all fees escrowed to incentivize packet relays. +It also tracks each packet fee escrowed separately from the escrow account. This is because the escrow account only maintains a total balance. It has no reference for which coins belonged to which packet fee. In the presence of a severe bug, it is possible the escrow balance will become out of sync with the packet fees marked as escrowed. The ICS29 module should be capable of elegantly handling such a scenario. ## Decision -We will allow for the ICS29 module to become "locked" if the escrow balance is determined to be out of sync with the packet fees marked as escrowed. -A "locked" fee module will not allow for packet escrows to occur nor will it distribute fees. All IBC callbacks will skip performing fee logic, similar to fee disabled channels. +We will allow for the ICS29 module to become "locked" if the escrow balance is determined to be out of sync with the packet fees marked as escrowed. +A "locked" fee module will not allow for packet escrows to occur nor will it distribute fees. All IBC callbacks will skip performing fee logic, similar to fee disabled channels. -Manual intervention will be needed to unlock the fee module. +Manual intervention will be needed to unlock the fee module. ### Sending side -Special behaviour will have to be accounted for in `OnAcknowledgementPacket`. Since the counterparty will continue to send incentivized acknowledgements for fee enabled channels, the acknowledgement will still need to be unmarshalled into an incentivized acknowledgement before calling the underlying application `OnAcknowledgePacket` callback. +Special behaviour will have to be accounted for in `OnAcknowledgementPacket`. Since the counterparty will continue to send incentivized acknowledgements for fee enabled channels, the acknowledgement will still need to be unmarshalled into an incentivized acknowledgement before calling the underlying application `OnAcknowledgePacket` callback. When distributing fees, a cached context should be used. If the escrow account balance would become negative, the current state changes should be discarded and the fee module should be locked using the uncached context. This prevents fees from being partially distributed for a given packetID. ### Receiving side -`OnRecvPacket` should remain unaffected by the fee module becoming locked since escrow accounts only affect the sending side. +`OnRecvPacket` should remain unaffected by the fee module becoming locked since escrow accounts only affect the sending side. ## Consequences @@ -39,17 +40,19 @@ The fee module can be elegantly disabled in the presence of severe bugs. ### Negative -Extra logic is added to account for edge cases which are only possible in the presence of bugs. +Extra logic is added to account for edge cases which are only possible in the presence of bugs. ### Neutral ## References Issues: -- [#821](https://github.com/cosmos/ibc-go/issues/821) -- [#860](https://github.com/cosmos/ibc-go/issues/860) + +* [#821](https://github.com/cosmos/ibc-go/issues/821) +* [#860](https://github.com/cosmos/ibc-go/issues/860) PR's: -- [#1031](https://github.com/cosmos/ibc-go/pull/1031) -- [#1029](https://github.com/cosmos/ibc-go/pull/1029) -- [#1056](https://github.com/cosmos/ibc-go/pull/1056) + +* [#1031](https://github.com/cosmos/ibc-go/pull/1031) +* [#1029](https://github.com/cosmos/ibc-go/pull/1029) +* [#1056](https://github.com/cosmos/ibc-go/pull/1056) diff --git a/docs/architecture/adr-005-consensus-height-events.md b/docs/architecture/adr-005-consensus-height-events.md new file mode 100644 index 00000000000..5df21dac7cd --- /dev/null +++ b/docs/architecture/adr-005-consensus-height-events.md @@ -0,0 +1,92 @@ +# ADR 005: UpdateClient Events - ClientState Consensus Heights + +## Changelog + +* 25/04/2022: initial draft + +## Status + +Accepted + +## Context + +The `ibc-go` implementation leverages the [Cosmos-SDK's EventManager](https://github.com/cosmos/cosmos-sdk/blob/v0.45.4/docs/core/events.md#EventManager) to provide subscribers a method of reacting to application specific events. +Some IBC relayers depend on the [`consensus_height`](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/core/02-client/keeper/events.go#L33) attribute emitted as part of `UpdateClient` events in order to run `07-tendermint` misbehaviour detection by cross-checking the details of the *Header* emitted at a given consensus height against those of the *Header* from the originating chain. This includes such details as: + +* The `SignedHeader` containing the commitment root. +* The `ValidatorSet` that signed the *Header*. +* The `TrustedHeight` seen by the client at less than or equal to the height of *Header*. +* The last `TrustedValidatorSet` at the trusted height. + +Following the refactor of the `02-client` submodule and associated `ClientState` interfaces, it will now be possible for +light client implementations to perform such actions as batch updates, inserting `N` number of `ConsensusState`s into the application state tree with a single `UpdateClient` message. This flexibility is provided in `ibc-go` by the usage of the [Protobuf `Any`](https://developers.google.com/protocol-buffers/docs/proto3#any) field contained within the [`UpdateClient`](https://github.com/cosmos/ibc-go/blob/v3.0.0/proto/ibc/core/client/v1/tx.proto#L44) message. +For example, a batched client update message serialized as a Protobuf `Any` type for the `07-tendermint` lightclient implementation could be defined as follows: + +```protobuf +message BatchedHeaders { + repeated Header headers = 1; +} +``` + +To complement this flexibility, the `UpdateClient` handler will now support the submission of [client misbehaviour](https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics#misbehaviour) by consolidating the `Header` and `Misbehaviour` interfaces into a single `ClientMessage` interface type: + +```go +// ClientMessage is an interface used to update an IBC client. +// The update may be done by a single header, a batch of headers, misbehaviour, or any type which when verified produces +// a change to state of the IBC client +type ClientMessage interface { + proto.Message + + ClientType() string + ValidateBasic() error +} +``` + +To support this functionality the `GetHeight()` method has been omitted from the new `ClientMessage` interface. +Emission of standardised events from the `02-client` submodule now becomes problematic and is two-fold: + +1. The `02-client` submodule previously depended upon the `GetHeight()` method of `Header` types in order to [retrieve the updated consensus height](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/core/02-client/keeper/client.go#L90). +2. Emitting a single `consensus_height` event attribute is not sufficient in the case of a batched client update containing multiple *Headers*. + +## Decision + +The following decisions have been made in order to provide flexibility to consumers of `UpdateClient` events in a non-breaking fashion: + +1. Return a list of updated consensus heights `[]exported.Height` from the new `UpdateState` method of the `ClientState` interface. + +```go +// UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. +// Upon successful update, a list of consensus heights is returned. It assumes the ClientMessage has already been verified. +UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) []Height +``` + +2. Maintain the `consensus_height` event attribute emitted from the `02-client` update handler, but mark as deprecated for future removal. For example, with tendermint lightclients this will simply be `consensusHeights[0]` following a successful update using a single *Header*. + +3. Add an additional `consensus_heights` event attribute, containing a comma separated list of updated heights. This provides flexibility for emitting a single consensus height or multiple consensus heights in the example use-case of batched header updates. + +## Consequences + +### Positive + +* Subscribers of IBC core events can act upon `UpdateClient` events containing one or more consensus heights. +* Deprecation of the existing `consensus_height` attribute allows consumers to continue to process `UpdateClient` events as normal, with a path to upgrade to using the `consensus_heights` attribute moving forward. + +### Negative + +* Consumers of IBC core `UpdateClient` events are forced to make future code changes. + +### Neutral + +## References + +Discussions: + +* [#1208](https://github.com/cosmos/ibc-go/pull/1208#discussion_r839691927) + +Issues: + +* [#594](https://github.com/cosmos/ibc-go/issues/594) + +PRs: + +* [#1285](https://github.com/cosmos/ibc-go/pull/1285) diff --git a/docs/architecture/adr-006-02-client-refactor.md b/docs/architecture/adr-006-02-client-refactor.md new file mode 100644 index 00000000000..4f955672f31 --- /dev/null +++ b/docs/architecture/adr-006-02-client-refactor.md @@ -0,0 +1,203 @@ +# ADR 006: ICS-02 client refactor + +## Changelog + +* 2022-08-01: Initial Draft + +## Status + +Accepted and applied in v7 of ibc-go + +## Context + +During the initial development of the 02-client submodule, each light client supported (06-solomachine, 07-tendermint, 09-localhost) was referenced through hardcoding. +Here is an example of the [code](https://github.com/cosmos/cosmos-sdk/commit/b93300288e3a04faef9c0774b75c13b24450ba1c#diff-c5f6b956947375f28d611f18d0e670cf28f8f305300a89c5a9b239b0eeec5064R83) that existed in the 02-client submodule: + +```go +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) (exported.ClientState, error) { + ... + + switch clientType { + case exported.Tendermint: + clientState, consensusState, err = tendermint.CheckValidityAndUpdateState( + clientState, header, ctx.BlockTime(), + ) + case exported.Localhost: + // override client state and update the block height + clientState = localhosttypes.NewClientState( + ctx.ChainID(), // use the chain ID from context since the client is from the running chain (i.e self). + ctx.BlockHeight(), + ) + default: + err = types.ErrInvalidClientType + } +``` + +To add additional light clients, code would need to be added directly to the 02-client submodule. +Evidently, this would likely become problematic as IBC scaled to many chains using consensus mechanisms beyond the initial supported light clients. +Issue [#6064](https://github.com/cosmos/cosmos-sdk/issues/6064) on the SDK addressed this problem by creating a more modular 02-client submodule. +The 02-client submodule would now interact with each light client via an interface. +While, this change was positive in development, increasing the flexibility and adoptability of IBC, it also opened the door to new problems. + +The difficulty of generalizing light clients became apparent once changes to those light clients were required. +Each light client represents a different consensus algorithm which may contain a host of complexity and nuances. +Here are some examples of issues which arose for light clients that are not applicable to all the light clients supported (06-solomachine, 07-tendermint, 09-localhost): + +### Tendermint non-zero height upgrades + +Before the launch of IBC, it was determined that the golang implementation of [tendermint](https://github.com/tendermint/tendermint) would not be capable of supporting non-zero height upgrades. +This implies that any upgrade would require changing of the chain ID and resetting the height to 0. +A chain is uniquely identified by its chain-id and validator set. +Two different chain ID's can be viewed as different chains and thus a normal update produced by a validator set cannot change the chain ID. +To work around the lack of support for non-zero height upgrades, an abstract height type was created along with an upgrade mechanism. +This type would indicate the revision number (the number of times the chain ID has been changed) and revision height (the current height of the blockchain). + +Refs: + +* Issue [#439](https://github.com/cosmos/ibc/issues/439) on IBC specification repository. +* Specification changes in [#447](https://github.com/cosmos/ibc/pull/447) +* Implementation changes for the abstract height type, [SDK#7211](https://github.com/cosmos/cosmos-sdk/pull/7211) + +### Tendermint requires misbehaviour detection during updates + +The initial release of the IBC module and the 07-tendermint light client implementation did not support misbehaviour detection during update nor did it prevent overwriting of previous updates. +Despite the fact that we designed the `ClientState` interface and developed the 07-tendermint client, we failed to detect even a duplicate update that constituted misbehaviour and thus should freeze the client. +This was fixed in PR [#141](https://github.com/cosmos/ibc-go/pull/141) which required light client implementations to be aware that they must handle duplicate updates and misbehaviour detection. +Misbehaviour detection during updates is not applicable to the solomachine nor localhost. +It is also not obvious that `CheckHeaderAndUpdateState` should be performing this functionality. + +### Localhost requires access to the entire client store + +The localhost has been broken since the initial version of the IBC module. +The localhost tried to be developed underneath the 02-client interfaces without special exception, but this proved to be impossible. +The issues were outlined in [#27](https://github.com/cosmos/ibc-go/issues/27) and further discussed in the attempted ADR in [#75](https://github.com/cosmos/ibc-go/pull/75). +Unlike all other clients, the localhost requires access to the entire IBC store and not just the prefixed client store. + +### Solomachine doesn't set consensus states + +The 06-solomachine does not set the consensus states within the prefixed client store. +It has a single consensus state that is stored within the client state. +This causes setting of the consensus state at the 02-client level to use unnecessary storage. +It also causes timeouts to fail with solo machines. +Previously, the timeout logic within IBC would obtain the consensus state at the height a timeout is being proved. +This is problematic for the solo machine as no consensus state is set. +See issue [#562](https://github.com/cosmos/ibc/issues/562) on the IBC specification repo. + +### New clients may want to do batch updates + +New light clients may not function in a similar fashion to 06-solomachine and 07-tendermint. +They may require setting many consensus states in a single update. +As @seunlanlege [states](https://github.com/cosmos/ibc-go/issues/284#issuecomment-1005583679): + +> I'm in support of these changes for 2 reasons: +> +> * This would allow light clients handle batch header updates in CheckHeaderAndUpdateState, for the special case of 11-beefy proving the finality for a batch of headers is much more space and time efficient than the space/time complexity of proving each individual headers in that batch, combined. +> +> * This also allows for a single light client instance of 11-beefy be used to prove finality for every parachain connected to the relay chain (Polkadot/Kusama). We achieve this by setting the appropriate ConsensusState for individual parachain headers in CheckHeaderAndUpdateState + +## Decision + +### Require light clients to set client and consensus states + +The IBC specification states: + +> If the provided header was valid, the client MUST also mutate internal state to store now-finalised consensus roots and update any necessary signature authority tracking (e.g. changes to the validator set) for future calls to the validity predicate. + +The initial version of the IBC go SDK based module did not fulfill this requirement. +Instead, the 02-client submodule required each light client to return the client and consensus state which should be updated in the client prefixed store. +This decision lead to the issues "Solomachine doesn't set consensus states" and "New clients may want to do batch updates". + +Each light client should be required to set its own client and consensus states on any update necessary. +The go implementation should be changed to match the specification requirements. +This will allow more flexibility for light clients to manage their own internal storage and do batch updates. + +### Merge `Header`/`Misbehaviour` interface and rename to `ClientMessage` + +Remove `GetHeight()` from the header interface (as light clients now set the client/consensus states). +This results in the `Header`/`Misbehaviour` interfaces being the same. +To reduce complexity of the codebase, the `Header`/`Misbehaviour` interfaces should be merged into `ClientMessage`. +`ClientMessage` will provide the client with some authenticated information which may result in regular updates, misbehaviour detection, batch updates, or other custom functionality a light client requires. + +### Split `CheckHeaderAndUpdateState` into 4 functions + +See [#668](https://github.com/cosmos/ibc-go/issues/668). + +Split `CheckHeaderAndUpdateState` into 4 functions: + +* `VerifyClientMessage` +* `CheckForMisbehaviour` +* `UpdateStateOnMisbehaviour` +* `UpdateState` + +`VerifyClientMessage` checks the that the structure of a `ClientMessage` is correct and that all authentication data provided is valid. + +`CheckForMisbehaviour` checks to see if a `ClientMessage` is evidence of misbehaviour. + +`UpdateStateOnMisbehaviour` freezes the client and updates its state accordingly. + +`UpdateState` performs a regular update or a no-op on duplicate updates. + +The code roughly looks like: + +```go +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { + ... + + if err := clientState.VerifyClientMessage(clientMessage); err != nil { + return err + } + + foundMisbehaviour := clientState.CheckForMisbehaviour(clientMessage) + if foundMisbehaviour { + clientState.UpdateStateOnMisbehaviour(header) + // emit misbehaviour event + return + } + + clientState.UpdateState(clientMessage) // expects no-op on duplicate header + // emit update event + return +} +``` + +### Add `GetTimestampAtHeight` to the client state interface + +By adding `GetTimestampAtHeight` to the ClientState interface, we allow light clients which do non-traditional consensus state/timestamp storage to process timeouts correctly. +This fixes the issues outlined for the solo machine client. + +### Add generic verification functions + +As the complexity and the functionality grows, new verification functions will be required for additional paths. +This was explained in [#684](https://github.com/cosmos/ibc/issues/684) on the specification repo. +These generic verification functions would be immediately useful for the new paths added in connection/channel upgradability as well as for custom paths defined by IBC applications such as Interchain Queries. +The old verification functions (`VerifyClientState`, `VerifyConnection`, etc) should be removed in favor of the generic verification functions. + +## Consequences + +### Positive + +* Flexibility for light client implementations +* Well defined interfaces and their required functionality +* Generic verification functions +* Applies changes necessary for future client/connection/channel upgrabability features +* Timeout processing for solo machines +* Reduced code complexity + +### Negative + +* The refactor touches on sensitive areas of the ibc-go codebase +* Changing of established naming (`Header`/`Misbehaviour` to `ClientMessage`) + +### Neutral + +No notable consequences + +## References + +Issues: + +* [#284](https://github.com/cosmos/ibc-go/issues/284) + +PRs: + +* [#1871](https://github.com/cosmos/ibc-go/pull/1871) diff --git a/docs/architecture/adr-007-solomachine-signbytes.md b/docs/architecture/adr-007-solomachine-signbytes.md new file mode 100644 index 00000000000..23be1322e2e --- /dev/null +++ b/docs/architecture/adr-007-solomachine-signbytes.md @@ -0,0 +1,52 @@ +# ADR 007: Solo machine sign bytes + +## Changelog + +* 2022-08-02: Initial draft + +## Status + +Accepted, applied in v7 + +## Context + +The `06-solomachine` implemention up until ibc-go v7 constructed sign bytes using a `DataType` which described what type of data was being signed. +This design decision arose from a misunderstanding of the security implications. +It was noted that the proto definitions do not [provide uniqueness](https://github.com/cosmos/cosmos-sdk/pull/7237#discussion_r484264573) which is a necessity for ensuring two signatures over different data types can never be the same. +What was missed is that the uniqueness is not provided by the proto definition, but by the usage of the proto definition. +The path provided by core IBC will be unique and is already encoded into the signature data. +Thus two different paths with the same data values will encode differently which provides signature uniqueness. + +Furthermore, the current construction does not support the proposed changes in the spec repo to support [Generic Verification functions](https://github.com/cosmos/ibc/issues/684). +This is because in order to verify a new path, a new `DataType` must be added for that path. + +## Decision + +Remove `DataType` and change the `DataType` in the `SignBytes` and `SignatureAndData` to be `Path`. +The new `Path` field should be bytes. +Remove all `...Data` proto definitions except for `HeaderData` +These `...Data` definitions were created previously for each `DataType`. +The proto version of the solo machine proto definitions should be bumped to `v3`. + +This removes an extra layer of complexity from signature construction and allows for support of generic verification. + +## Consequences + +### Positive + +* Simplification of solo machine signature construction +* Support for generic verification + +### Negative + +* Breaks existing signature construction in a non-backwards compatible way +* Solo machines must update to handle the new format +* Migration required for solo machine client and consensus states + +### Neutral + +No notable consequences + +## References + +* [#1141](https://github.com/cosmos/ibc-go/issues/1141) diff --git a/docs/architecture/adr-009-v6-ics27-msgserver.md b/docs/architecture/adr-009-v6-ics27-msgserver.md new file mode 100644 index 00000000000..9fe6708a4b1 --- /dev/null +++ b/docs/architecture/adr-009-v6-ics27-msgserver.md @@ -0,0 +1,115 @@ +# ADR 009: ICS27 message server addition + +## Changelog + +* 2022/09/07: Initial draft + +## Status + +Accepted, implemented in v6 of ibc-go + +## Context + +ICS 27 (Interchain Accounts) brought a cross-chain account management protocol built upon IBC. +It enabled chains to programatically create accounts on behalf of counterparty chains which may enable a variety of authentication methods for this interchain account. +The initial release of ICS 27 focused on enabling authentication schemes which may not require signing with a private key, such as via on-chain mechanisms like governance. + +Following the initial release of ICS 27 it became evident that: + +* a default authentication module would enable more usage of ICS 27 +* generic authentication modules should be capable of authenticating an interchain account registration +* application logic which wraps ICS 27 packet sends do not need to be associated with the authentication logic + +## Decision + +The controller module should be simplified to remove the correlation between the authentication logic for an interchain account and the application logic for an interchain account. +To minimize disruption to developers working on the original design of the ICS 27 controller module, all changes will be made in a backwards compatible fashion. + +### Msg server + +To acheive this, as stated by [@damiannolan](https://github.com/cosmos/ibc-go/issues/2026#issue-1341640594), it was proposed to: + +> Add a new `MsgServer` to `27-interchain-accounts` which exposes two distinct rpc endpoints: +> +> * `RegisterInterchainAccount` +> * `SendTx` + +This will enable any SDK (authentication) module to register interchain accounts and send transactions on their behalf. +Examples of existing SDK modules which would benefit from this change include: + +* x/auth +* x/gov +* x/group + +The existing go functions: `RegisterInterchainAccount()` and `SendTx()` will remain to operate as they did in previous release versions. + +This will be possible for SDK v0.46.x and above. + +### Allow `nil` underlying applications + +Authentication modules should interact with the controller module via the message server and should not be associated with application logic. +For now, it will be allowed to set a `nil` underlying application. +A future version may remove the underlying application entirely. + +See issue [#2040](https://github.com/cosmos/ibc-go/issues/2040) + +### Channel capability claiming + +The controller module will now claim the channel capability in `OnChanOpenInit`. +Underlying applications will be passed a `nil` capability in `OnChanOpenInit`. + +Channel capability migrations will be added in two steps: + +* Upgrade handler migration which modifies the channel capability owner from the underlying app to the controller module +* ICS 27 module automatic migration which asserts the upgrade handler channel capability migration has been performed successfully + +See issue [#2033](https://github.com/cosmos/ibc-go/issues/2033) + +### Middleware enabled channels + +In order to maintain backwards compatibility and avoid requiring underlying application developers to account for interchain accounts they did not register, a boolean mapping has been added to track the behaviour of how an account was created. + +If the account was created via the legacy API, then the underlying application callbacks will be executed. + +If the account was created with the new API (message server), then the underlying application callbacks will not be executed. + +See issue [#2145](https://github.com/cosmos/ibc-go/issues/2145) + +### Future considerations + +[ADR 008](https://github.com/cosmos/ibc-go/pull/1976) proposes the creation of a middleware which enables callers of an IBC packet send to perform application logic in conjunction with the IBC application. +The underlying application can be removed at the availablity of such a middleware as that will be the preferred method for executing application logic upon a ICS 27 packet send. + +### Miscellanous + +In order to avoid import cycles, the genesis types have been moved to their own directory. +A new protobuf package has been created for the genesis types. + +See PR [#2133](https://github.com/cosmos/ibc-go/pull/2133) + +An additional field has been added to the `ActiveChannel` type to store the `IsMiddlewareEnabled` field upon genesis import/export. + +See issue [#2165](https://github.com/cosmos/ibc-go/issues/2165) + +## Consequences + +### Positive + +* default authentication modules are provided (x/auth, x/group, x/gov) +* any SDK authentication module may now be used with ICS 27 +* separation of authentication from application logic in relation to ICS 27 +* minimized disruption to existing development around ICS 27 controller module +* underlying applications no longer have to handle capabilities +* removal of the underlying application upon the creation of ADR 008 may be done in a minimally disruptive fashion +* only underlying applications which registered the interchain account will perform application logic for that account (underlying applications do not need to be aware of accounts they did not register) + +### Negative + +* the security model has been reduced to that of the SDK. SDK modules may send packets for any interchain account. +* additional maintenance of the messages added and the middleware enabled flag +* underlying applications which will become ADR 008 modules are not required to be aware of accounts they did not register +* calling legacy API vs the new API results in different behaviour for ICS 27 application stacks which have an underlying application + +### Neutral + +* A major release is required diff --git a/docs/architecture/adr-010-light-clients-as-sdk-modules.md b/docs/architecture/adr-010-light-clients-as-sdk-modules.md new file mode 100644 index 00000000000..62186debaf3 --- /dev/null +++ b/docs/architecture/adr-010-light-clients-as-sdk-modules.md @@ -0,0 +1,100 @@ +# ADR 010: IBC light clients as SDK modules + +## Changelog +* 12/12/2022: initial draft + +## Status + +Proposed + +## Context + +ibc-go has 3 main consumers: +- IBC light clients +- IBC applications +- relayers + +Relayers listen and respond to events emitted by ibc-go while IBC light clients and applications are invoked by core IBC. +Currently there exists two different approaches to callbacks being invoked by core IBC. + +IBC light clients currently are invoked by a `ClientState` and `ConsensusState` interface as defined by [core IBC](https://github.com/cosmos/ibc-go/blob/fb9dedd706e5835cdd607392320df79fcea7ca7f/modules/core/exported/client.go#L36). +The 02-client submodule will retrieve the `ClientState` or `ConsensusState` from the IBC store in order to perform callbacks to the light client. +This design requires all required information for the light client to function to be stored in the `ClientState` or `ConsensusState` or potentially under metadata keys for a specific client instance. +Additional information may be provided by core IBC via the defined interface arguments if that information is generic enough to be useful to all IBC light clients. +This constraint has proved problematic as pass through clients (such as wasm) cannot maintain easy access to a VM instance. +In addition, without increasing the size of the defined `ClientState` interface, light clients are unable to take advantage of basic built-in SDK functionality such as genesis import/export and migrations. + +The other approach used to perform callback logic is via registered SDK modules. +This approach is used by core IBC to interact with IBC applications. +IBC applications will register their callbacks on the IBC router at compile time. +When a packet comes in, core IBC will use the IBC router to lookup the registered callback functions for the provided packet. +The benefit of registered callbacks opposed to interface functions is that additional information may be accessed via external keepers. +Because the IBC applications are also SDK modules, they additionally get access to a host of functionality provided by the SDK. +This includes: genesis import/export, migrations, query/transaction CLI commands, type registration, gRPC query registration, and message server registration. + +As described in [ADR 006](./adr-006-02-client-refactor.md), generalizing light client behaviour is difficult. +IBC light clients will obtain greater flexibility and control via the registered SDK module approach. + +## Decision + +Instead of using two different approaches to invoking callbacks, IBC light clients should be invoked as SDK modules. +Over time and as necessary, core IBC should adjust its interactions with light clients such that they are SDK modules as opposed to interfaces. + +One immediate decision that has already been applied is to formalize light client type registration via the inclusion of an `AppModuleBasic` within the `ModuleManager` for a chain. +The [tendermint](https://github.com/cosmos/ibc-go/pull/2825) and [solo machine](https://github.com/cosmos/ibc-go/pull/2826) clients were refactored to include this `AppModuleBasic` implementation and core IBC will no longer include either type as registered by default. + +Longer term solutions include using internal module communication as described in [ADR 033](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-033-protobuf-inter-module-comm.md) on the SDK. +The following functions should become callbacks invoked via intermodule communication: +- `Status` +- `GetTimestampAtHeight` +- `VerifyMembership` +- `VerifyNonMembership` +- `Initialize` +- `VerifyClientMessage` +- `CheckForMisbehaviour` +- `UpdateStateOnMisbehaviour` +- `UpdateState` +- `CheckSubstituteAndUpdateState` +- `VerifyUpgradeAndUpdateState` + +The ClientState interface should eventually be trimmed down to something along the lines of: +```go +type ClientState interface { + proto.Message + + ClientType() string + GetLatestHeight() Height + Validate() error + + ZeroCustomFields() ClientState + + // ADDITION + Route() string // route used for intermodule communication +} +``` + +For the most part, any functions which require access to the client store should likely not be an interface function of the `ClientState`. + +`ExportMetadata` should eventually be replaced by a light client's ability to import/export it's own genesis information. + +### Intermodule communication + +To keep the transition from interface callbacks to SDK module callbacks as simple as possible, intermodule communication (when available) should be used to route to light client modules. +Without intermodule communication, a routing system would need to be developed/maintained to register callbacks. +This functionality of routing to another SDK module should and will be provided by the SDK. +Once it is possible to route to SDK modules, a `ClientState` type could expose the function `Route` which returns the callback route used to call the light client module. + +## Consequences + +### Positive +- use a single approach for interacting with callbacks +- greater flexibilty and control for IBC light clients +- does not require developing another routing system + +### Negative +- requires breaking changes +- requires waiting for intermodule communication + +### Neutral +N/A + diff --git a/docs/architecture/adr-015-ibc-packet-receiver.md b/docs/architecture/adr-015-ibc-packet-receiver.md index 26f9bdecc88..08264c6d2ee 100644 --- a/docs/architecture/adr-015-ibc-packet-receiver.md +++ b/docs/architecture/adr-015-ibc-packet-receiver.md @@ -5,7 +5,7 @@ - 2019 Oct 22: Initial Draft ## Context - + [ICS 26 - Routing Module](https://github.com/cosmos/ibc/tree/master/spec/core/ics-026-routing-module) defines a function [`handlePacketRecv`](https://github.com/cosmos/ibc/tree/master/spec/core/ics-026-routing-module#packet-relay). In ICS 26, the routing module is defined as a layer above each application module @@ -154,16 +154,16 @@ func (keeper ChannelKeeper) DeleteCommitmentTimeout(ctx Context, packet Packet) Each application handler should call respective finalization methods on the `PortKeeper` in order to increase sequence (in case of packet) or remove the commitment (in case of acknowledgement and timeout). -Calling those functions implies that the application logic has successfully executed. +Calling those functions implies that the application logic has successfully executed. However, the handlers can return `Result` with `CodeTxBreak` after calling those methods -which will persist the state changes that has been already done but prevent any further +which will persist the state changes that has been already done but prevent any further messages to be executed in case of semantically invalid packet. This will keep the sequence -increased in the previous IBC packets(thus preventing double execution) without +increased in the previous IBC packets(thus preventing double execution) without proceeding to the following messages. -In any case the application modules should never return state reverting result, +In any case the application modules should never return state reverting result, which will make the channel unable to proceed. -`ChannelKeeper.CheckOpen` method will be introduced. This will replace `onChanOpen*` defined +`ChannelKeeper.CheckOpen` method will be introduced. This will replace `onChanOpen*` defined under the routing module specification. Instead of define each channel handshake callback functions, application modules can provide `ChannelChecker` function with the `AppModule` which will be injected to `ChannelKeeper.Port()` at the top level application. diff --git a/docs/architecture/adr-025-ibc-passive-channels.md b/docs/architecture/adr-025-ibc-passive-channels.md index 9b39da98152..35449185a1b 100644 --- a/docs/architecture/adr-025-ibc-passive-channels.md +++ b/docs/architecture/adr-025-ibc-passive-channels.md @@ -34,26 +34,26 @@ const ( AttributeKeyDstVersion = "dst_version" ) // ... - // Emit Event with Channel metadata for the relayer to pick up and - // relay to the other chain - // This appears immediately before the successful return statement. - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - types.EventTypeChannelMeta, - sdk.NewAttribute(types.AttributeKeyAction, "open_init"), - sdk.NewAttribute(types.AttributeKeySrcConnection, connectionHops[0]), - sdk.NewAttribute(types.AttributeKeyHops, strings.Join(connectionHops, ",")), - sdk.NewAttribute(types.AttributeKeyOrder, order.String()), - sdk.NewAttribute(types.AttributeKeySrcPort, portID), - sdk.NewAttribute(types.AttributeKeySrcChannel, chanenlID), - sdk.NewAttribute(types.AttributeKeySrcVersion, version), - sdk.NewAttribute(types.AttributeKeyDstPort, counterparty.GetPortID()), - sdk.NewAttribute(types.AttributeKeyDstChannel, counterparty.GetChannelID()), - // The destination version is not yet known, but a value is necessary to pad - // the event attribute offsets - sdk.NewAttribute(types.AttributeKeyDstVersion, ""), - ), - }) +// Emit Event with Channel metadata for the relayer to pick up and +// relay to the other chain +// This appears immediately before the successful return statement. +ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelMeta, + sdk.NewAttribute(types.AttributeKeyAction, "open_init"), + sdk.NewAttribute(types.AttributeKeySrcConnection, connectionHops[0]), + sdk.NewAttribute(types.AttributeKeyHops, strings.Join(connectionHops, ",")), + sdk.NewAttribute(types.AttributeKeyOrder, order.String()), + sdk.NewAttribute(types.AttributeKeySrcPort, portID), + sdk.NewAttribute(types.AttributeKeySrcChannel, chanenlID), + sdk.NewAttribute(types.AttributeKeySrcVersion, version), + sdk.NewAttribute(types.AttributeKeyDstPort, counterparty.GetPortID()), + sdk.NewAttribute(types.AttributeKeyDstChannel, counterparty.GetChannelID()), + // The destination version is not yet known, but a value is necessary to pad + // the event attribute offsets + sdk.NewAttribute(types.AttributeKeyDstVersion, ""), + ), +}) ``` These metadata events capture all the "header" information needed to route IBC channel handshake transactions without requiring the client to query any data except that of the connection ID that it is willing to relay. It is intended that `channel_meta.src_connection` is the only event key that needs to be indexed for a passive relayer to function. @@ -95,19 +95,19 @@ Here is how this callback would be used, in the implementation of `x/ibc/handler ```go // ... - case channel.MsgChannelOpenTry: - // Lookup module by port capability - module, portCap, err := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID) - if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") - } - // Retrieve callbacks from router - cbs, ok := k.Router.GetRoute(module) - if !ok { - return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) - } - // Delegate to the module's OnAttemptChanOpenTry. - return cbs.OnAttemptChanOpenTry(ctx, k.ChannelKeeper, portCap, msg) +case channel.MsgChannelOpenTry: + // Lookup module by port capability + module, portCap, err := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID) + if err != nil { + return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + // Delegate to the module's OnAttemptChanOpenTry. + return cbs.OnAttemptChanOpenTry(ctx, k.ChannelKeeper, portCap, msg) ``` The reason we do not have a more structured interaction between `x/ibc/handler.go` and the port's module (to explicitly negotiate versions, etc) is that we do not wish to constrain the app module to have to finish handling the `MsgChannelOpenTry` during this transaction or even this block. diff --git a/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md b/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md index bec25a3aad9..e34244f1d6b 100644 --- a/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md +++ b/docs/architecture/adr-026-ibc-client-recovery-mechanisms.md @@ -45,18 +45,18 @@ We elect not to deal with chains which have actually halted, which is necessaril 1. Require Tendermint light clients (ICS 07) to expose the following additional state mutation functions 1. `Unfreeze()`, which unfreezes a light client after misbehaviour and clears any frozen height previously set 1. Add a new governance proposal type, `ClientUpdateProposal`, in the `x/ibc` module - 1. Extend the base `Proposal` with two client identifiers (`string`). + 1. Extend the base `Proposal` with two client identifiers (`string`). 1. The first client identifier is the proposed client to be updated. This client must be either frozen or expired. - 1. The second client is a substitute client. It carries all the state for the client which may be updated. It must have identitical client and chain parameters to the client which may be updated (except for latest height, frozen height, and chain-id). It should be continually updated during the voting period. + 1. The second client is a substitute client. It carries all the state for the client which may be updated. It must have identitical client and chain parameters to the client which may be updated (except for latest height, frozen height, and chain-id). It should be continually updated during the voting period. 1. If this governance proposal passes, the client on trial will be updated to the latest state of the substitute. Previously, `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehaviour` were used to signal the recovery options for an expired or frozen client, and governance proposals were not allowed to overwrite the client if these parameters were set to false. However, this has now been deprecated because a code migration can overwrite the client and consensus states regardless of the value of these parameters. If governance would vote to overwrite a client or consensus state, it is likely that governance would also be willing to perform a code migration to do the same. - In addition, `TrustingPeriod` was initally not allowed to be updated by a client upgrade proposal. However, due to the number of situations experienced in production where the `TrustingPeriod` of a client should be allowed to be updated because of ie: initial misconfiguration for a canonical channel, governance should be allowed to update this client parameter. - + In addition, `TrustingPeriod` was initally not allowed to be updated by a client upgrade proposal. However, due to the number of situations experienced in production where the `TrustingPeriod` of a client should be allowed to be updated because of ie: initial misconfiguration for a canonical channel, governance should be allowed to update this client parameter. + Note that this should NOT be lightly updated, as there may be a gap in time between when misbehaviour has occured and when the evidence of misbehaviour is submitted. For example, if the `UnbondingPeriod` is 2 weeks and the `TrustingPeriod` has also been set to two weeks, a validator could wait until right before `UnbondingPeriod` finishes, submit false information, then unbond and exit without being slashed for misbehaviour. Therefore, we recommend that the trusting period for the 07-tendermint client be set to 2/3 of the `UnbondingPeriod`. -Note that clients frozen due to misbehaviour must wait for the evidence to expire to avoid becoming refrozen. +Note that clients frozen due to misbehaviour must wait for the evidence to expire to avoid becoming refrozen. This ADR does not address planned upgrades, which are handled separately as per the [specification](https://github.com/cosmos/ibc/tree/master/spec/client/ics-007-tendermint-client#upgrades). diff --git a/docs/architecture/adr-027-ibc-wasm.md b/docs/architecture/adr-027-ibc-wasm.md index d105c9854b4..3e1f155f3b6 100644 --- a/docs/architecture/adr-027-ibc-wasm.md +++ b/docs/architecture/adr-027-ibc-wasm.md @@ -6,7 +6,7 @@ ## Status -*Draft* +*Draft, needs updates* ## Abstract @@ -18,6 +18,7 @@ existing IBC light clients as well as adding support for new IBC light clients w hard-fork event. ## Context + Currently in the SDK, light clients are defined as part of the codebase and are implemented as submodules under `ibc-go/core/modules/light-clients/`. @@ -48,7 +49,6 @@ With WASM light client module, anybody can add new IBC light client in the form as well as instantiate clients using any created client type. This allows any chain to update its own light client in other chains without going through steps outlined above. - ## Decision We decided to use WASM light client module as a light client proxy which will interface with the actual light client @@ -58,17 +58,17 @@ has prefix of `wasm/`. ```go // IsAllowedClient checks if the given client type is registered on the allowlist. func (p Params) IsAllowedClient(clientType string) bool { - if p.AreWASMClientsAllowed && isWASMClient(clientType) { - return true - } - - for _, allowedClient := range p.AllowedClients { - if allowedClient == clientType { - return true - } - } - - return false + if p.AreWASMClientsAllowed && isWASMClient(clientType) { + return true + } + + for _, allowedClient := range p.AllowedClients { + if allowedClient == clientType { + return true + } + } + + return false } ``` @@ -77,10 +77,10 @@ processed by IBC Wasm module. ```go func (k Keeper) UploadLightClient (wasmCode: []byte, description: String) { - wasmRegistry = getWASMRegistry() - id := hex.EncodeToString(sha256.Sum256(wasmCode)) - assert(!wasmRegistry.Exists(id)) - assert(wasmRegistry.ValidateAndStoreCode(id, description, wasmCode, false)) + wasmRegistry = getWASMRegistry() + id := hex.EncodeToString(sha256.Sum256(wasmCode)) + assert(!wasmRegistry.Exists(id)) + assert(wasmRegistry.ValidateAndStoreCode(id, description, wasmCode, false)) } ``` @@ -100,48 +100,50 @@ packaged inside a payload which is json serialized and passed to `callContract` array of bytes returned by the smart contract. This data is deserialized and passed as return argument. ```go -func (c *ClientState) CheckProposedHeaderAndUpdateState(context sdk.Context, marshaler codec.BinaryMarshaler, store sdk.KVStore, header exported.Header) (exported.ClientState, exported.ConsensusState, error) { - // get consensus state corresponding to client state to check if the client is expired - consensusState, err := GetConsensusState(store, marshaler, c.LatestHeight) - if err != nil { - return nil, nil, sdkerrors.Wrapf( - err, "could not get consensus state from clientstore at height: %d", c.LatestHeight, - ) - } - - payload := make(map[string]map[string]interface{}) - payload[CheckProposedHeaderAndUpdateState] = make(map[string]interface{}) - inner := payload[CheckProposedHeaderAndUpdateState] - inner["me"] = c - inner["header"] = header - inner["consensus_state"] = consensusState - - encodedData, err := json.Marshal(payload) - if err != nil { - return nil, nil, sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) - } - out, err := callContract(c.CodeId, context, store, encodedData) - if err != nil { - return nil, nil, sdkerrors.Wrapf(ErrUnableToCall, fmt.Sprintf("underlying error: %s", err.Error())) - } - output := clientStateCallResponse{} - if err := json.Unmarshal(out.Data, &output); err != nil { - return nil, nil, sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) - } - if !output.Result.IsValid { - return nil, nil, fmt.Errorf("%s error ocurred while updating client state", output.Result.ErrorMsg) - } - output.resetImmutables(c) - return output.NewClientState, output.NewConsensusState, nil +func (c *ClientState) CheckProposedHeaderAndUpdateState(context sdk.Context, marshaler codec.BinaryMarshaler, store sdk.KVStore, header exported.ClientMessage) (exported.ClientState, exported.ConsensusState, error) { + // get consensus state corresponding to client state to check if the client is expired + consensusState, err := GetConsensusState(store, marshaler, c.LatestHeight) + if err != nil { + return nil, nil, sdkerrors.Wrapf( + err, "could not get consensus state from clientstore at height: %d", c.LatestHeight, + ) + } + + payload := make(map[string]map[string]interface{}) + payload[CheckProposedHeaderAndUpdateState] = make(map[string]interface{}) + inner := payload[CheckProposedHeaderAndUpdateState] + inner["me"] = c + inner["header"] = header + inner["consensus_state"] = consensusState + + encodedData, err := json.Marshal(payload) + if err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToMarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + out, err := callContract(c.CodeId, context, store, encodedData) + if err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToCall, fmt.Sprintf("underlying error: %s", err.Error())) + } + output := clientStateCallResponse{} + if err := json.Unmarshal(out.Data, &output); err != nil { + return nil, nil, sdkerrors.Wrapf(ErrUnableToUnmarshalPayload, fmt.Sprintf("underlying error: %s", err.Error())) + } + if !output.Result.IsValid { + return nil, nil, fmt.Errorf("%s error ocurred while updating client state", output.Result.ErrorMsg) + } + output.resetImmutables(c) + return output.NewClientState, output.NewConsensusState, nil } ``` ## Consequences ### Positive + - Adding support for new light client or upgrading existing light client is way easier than before and only requires single transaction. - Improves maintainability of Cosmos SDK, since no change in codebase is required to support new client or upgrade it. ### Negative + - Light clients need to be written in subset of rust which could compile in Wasm. - Introspecting light client code is difficult as only compiled bytecode exists in the blockchain. diff --git a/docs/architecture/adr-template.md b/docs/architecture/adr-template.md index 129ddfa8f94..95ef45037de 100644 --- a/docs/architecture/adr-template.md +++ b/docs/architecture/adr-template.md @@ -1,6 +1,7 @@ # ADR {ADR-NUMBER}: {TITLE} ## Changelog + * {date}: {changelog} ## Status @@ -11,7 +12,7 @@ ## Context -> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution. +> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution. ## Decision diff --git a/docs/assets/auth-module-decision-tree.png b/docs/assets/auth-module-decision-tree.png new file mode 100644 index 00000000000..dc2c98e6618 Binary files /dev/null and b/docs/assets/auth-module-decision-tree.png differ diff --git a/docs/assets/ica/ica-pre-v6.png b/docs/assets/ica/ica-pre-v6.png new file mode 100644 index 00000000000..acd00d1294b Binary files /dev/null and b/docs/assets/ica/ica-pre-v6.png differ diff --git a/docs/assets/ica/ica-v6.png b/docs/assets/ica/ica-v6.png new file mode 100644 index 00000000000..0ffa707c981 Binary files /dev/null and b/docs/assets/ica/ica-v6.png differ diff --git a/docs/client/swagger-ui/swagger.yaml b/docs/client/swagger-ui/swagger.yaml index ca13125f6fa..e4159acdf8a 100644 --- a/docs/client/swagger-ui/swagger.yaml +++ b/docs/client/swagger-ui/swagger.yaml @@ -4,7 +4,7 @@ info: description: A REST interface for state queries version: 1.0.0 paths: - '/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address': + /ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address: get: summary: >- EscrowAddress returns the escrow address for a particular port and @@ -23,7 +23,7 @@ paths: QueryEscrowAddressResponse is the response type of the EscrowAddress RPC method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -57,7 +57,7 @@ paths: type: string tags: - Query - '/ibc/apps/transfer/v1/denom_hashes/{trace}': + /ibc/apps/transfer/v1/denom_hashes/{trace}: get: summary: DenomHash queries a denomination hash information. operationId: DenomHash @@ -76,7 +76,7 @@ paths: method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -99,7 +99,7 @@ paths: format: byte parameters: - name: trace - description: 'The denomination trace ([port_id]/[channel_id])+/[denom]' + description: The denomination trace ([port_id]/[channel_id])+/[denom] in: path required: true type: string @@ -143,9 +143,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -160,7 +161,7 @@ paths: method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -228,10 +229,19 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean tags: - Query - '/ibc/apps/transfer/v1/denom_traces/{hash}': + /ibc/apps/transfer/v1/denom_traces/{hash}: get: summary: DenomTrace queries a denomination trace information. operationId: DenomTrace @@ -265,7 +275,7 @@ paths: method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -312,7 +322,6 @@ paths: properties: send_enabled: type: boolean - format: boolean description: >- send_enabled enables or disables all cross-chain token transfers from this @@ -320,7 +329,6 @@ paths: chain. receive_enabled: type: boolean - format: boolean description: >- receive_enabled enables or disables all cross-chain token transfers to this @@ -330,7 +338,48 @@ paths: QueryParamsResponse is the response type for the Query/Params RPC method. default: - description: An unexpected error response + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + tags: + - Query + /ibc/apps/interchain_accounts/controller/v1/owners/{owner}/connections/{connection_id}: + get: + summary: >- + InterchainAccount returns the interchain account address for a given + owner address on a given connection + operationId: InterchainAccount + responses: + '200': + description: A successful response. + schema: + type: object + properties: + address: + type: string + description: >- + QueryInterchainAccountResponse the response type for the + Query/InterchainAccount RPC method. + default: + description: An unexpected error response. schema: type: object properties: @@ -351,6 +400,15 @@ paths: value: type: string format: byte + parameters: + - name: owner + in: path + required: true + type: string + - name: connection_id + in: path + required: true + type: string tags: - Query /ibc/apps/interchain_accounts/controller/v1/params: @@ -369,7 +427,6 @@ paths: properties: controller_enabled: type: boolean - format: boolean description: >- controller_enabled enables or disables the controller submodule. @@ -377,7 +434,7 @@ paths: QueryParamsResponse is the response type for the Query/Params RPC method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -416,7 +473,6 @@ paths: properties: host_enabled: type: boolean - format: boolean description: host_enabled enables or disables the host submodule. allow_messages: type: array @@ -429,7 +485,7 @@ paths: QueryParamsResponse is the response type for the Query/Params RPC method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -452,7 +508,7 @@ paths: format: byte tags: - Query - '/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/fee_enabled': + /ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/fee_enabled: get: summary: >- FeeEnabledChannel returns true if the provided port and channel @@ -466,13 +522,12 @@ paths: properties: fee_enabled: type: boolean - format: boolean title: boolean flag representing the fee enabled channel status title: >- QueryFeeEnabledChannelResponse defines the response type for the FeeEnabledChannel rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -598,10 +653,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -673,7 +731,7 @@ paths: type: string tags: - Query - '/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/incentivized_packets': + /ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/incentivized_packets: get: summary: Gets all incentivized packets for a specific channel operationId: IncentivizedPacketsForChannel @@ -794,7 +852,7 @@ paths: QueryIncentivizedPacketsResponse defines the response type for the incentivized packets RPC default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -920,10 +978,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -1037,7 +1098,16 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean - name: query_height description: Height to query at. in: query @@ -1046,7 +1116,7 @@ paths: format: uint64 tags: - Query - '/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/counterparty_payee': + /ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/counterparty_payee: get: summary: >- CounterpartyPayee returns the registered counterparty payee for forward @@ -1067,7 +1137,7 @@ paths: QueryCounterpartyPayeeResponse defines the response type for the CounterpartyPayee rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -1193,10 +1263,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -1268,7 +1341,7 @@ paths: type: string tags: - Query - '/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/payee': + /ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/payee: get: summary: >- Payee returns the registered payee address for a specific channel given @@ -1285,7 +1358,7 @@ paths: title: the payee address to which packet fees are paid out title: QueryPayeeResponse defines the response type for the Payee rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -1411,10 +1484,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -1486,7 +1562,7 @@ paths: type: string tags: - Query - '/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/incentivized_packet': + /ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/incentivized_packet: get: summary: >- IncentivizedPacket returns all packet fees for a packet given its @@ -1604,7 +1680,7 @@ paths: QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPacket rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -1730,10 +1806,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -1817,7 +1896,7 @@ paths: format: uint64 tags: - Query - '/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_ack_fees': + /ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_ack_fees: get: summary: >- TotalAckFees returns the total acknowledgement fees for a packet given @@ -1851,7 +1930,7 @@ paths: QueryTotalAckFeesResponse defines the response type for the TotalAckFees rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -1977,10 +2056,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -2058,7 +2140,7 @@ paths: format: uint64 tags: - Query - '/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_recv_fees': + /ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_recv_fees: get: summary: >- TotalRecvFees returns the total receive fees for a packet given its @@ -2092,7 +2174,7 @@ paths: QueryTotalRecvFeesResponse defines the response type for the TotalRecvFees rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -2218,10 +2300,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -2299,7 +2384,7 @@ paths: format: uint64 tags: - Query - '/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_timeout_fees': + /ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_timeout_fees: get: summary: >- TotalTimeoutFees returns the total timeout fees for a packet given its @@ -2333,7 +2418,7 @@ paths: QueryTotalTimeoutFeesResponse defines the response type for the TotalTimeoutFees rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -2459,10 +2544,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -2569,7 +2657,7 @@ paths: QueryFeeEnabledChannelsResponse defines the response type for the FeeEnabledChannels rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -2695,10 +2783,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -2804,7 +2895,16 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean - name: query_height description: block height at which to query. in: query @@ -2936,7 +3036,7 @@ paths: QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPackets rpc default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -3062,10 +3162,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -3171,7 +3274,16 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean - name: query_height description: block height at which to query. in: query @@ -3180,333 +3292,117 @@ paths: format: uint64 tags: - Query - /ibc/client/v1/params: + /ibc/core/client/v1/client_states: get: - summary: ClientParams queries all parameters of the ibc client. - operationId: ClientParams + summary: ClientStates queries all the IBC light clients of a chain. + operationId: ClientStates responses: '200': description: A successful response. schema: type: object properties: - params: - description: params defines the parameters of the module. - type: object - properties: - allowed_clients: - type: array - items: - type: string - description: >- - allowed_clients defines the list of allowed client state - types. - description: >- - QueryClientParamsResponse is the response type for the - Query/ClientParams RPC - - method. - default: - description: An unexpected error response - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: - type: string - details: + client_states: type: array items: type: object properties: - type_url: + client_id: type: string - description: >- - A URL/resource name that uniquely identifies the type of - the serialized + title: client identifier + client_state: + title: client state + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the + type of the serialized - protocol buffer message. This string must contain at - least + protocol buffer message. This string must contain at + least - one "/" character. The last segment of the URL's path - must represent + one "/" character. The last segment of the URL's + path must represent - the fully qualified name of the type (as in + the fully qualified name of the type (as in - `path/google.protobuf.Duration`). The name should be in - a canonical form + `path/google.protobuf.Duration`). The name should be + in a canonical form - (e.g., leading "." is not accepted). + (e.g., leading "." is not accepted). - In practice, teams usually precompile into the binary - all types that they + In practice, teams usually precompile into the + binary all types that they - expect it to use in the context of Any. However, for - URLs which use the + expect it to use in the context of Any. However, for + URLs which use the - scheme `http`, `https`, or no scheme, one can optionally - set up a type + scheme `http`, `https`, or no scheme, one can + optionally set up a type - server that maps type URLs to message definitions as - follows: + server that maps type URLs to message definitions as + follows: - * If no scheme is provided, `https` is assumed. + * If no scheme is provided, `https` is assumed. - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based - on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results + based on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) - Note: this functionality is not currently available in - the official + Note: this functionality is not currently available + in the official - protobuf release, and it is not used for type URLs - beginning with + protobuf release, and it is not used for type URLs + beginning with - type.googleapis.com. + type.googleapis.com. - Schemes other than `http`, `https` (or the empty scheme) - might be + Schemes other than `http`, `https` (or the empty + scheme) might be - used with implementation specific semantics. - value: - type: string - format: byte + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the + above specified type. description: >- - Must be a valid serialized protocol buffer of the above - specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer - message along with a - - URL that describes the type of the serialized message. - + `Any` contains an arbitrary serialized protocol buffer + message along with a - Protobuf library provides support to pack/unpack Any values - in the form + URL that describes the type of the serialized message. - of utility functions or additional generated methods of the - Any type. + Protobuf library provides support to pack/unpack Any + values in the form - Example 1: Pack and unpack a message in C++. + of utility functions or additional generated methods of + the Any type. - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - Example 2: Pack and unpack a message in Java. + Example 1: Pack and unpack a message in C++. - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) - ... - foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by - default use - - 'type.googleapis.com/full.type.name' as the type URL and the - unpack - - methods only use the fully qualified type name after the - last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield - type - - name "y.z". - - - - JSON - - ==== - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with - an - - additional field `@type` which contains the type URL. - Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom - JSON - - representation, that representation will be embedded adding - a field - - `value` which holds the custom JSON in addition to the - `@type` - - field. Example (for message [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - tags: - - Query - /ibc/core/client/v1/client_states: - get: - summary: ClientStates queries all the IBC light clients of a chain. - operationId: ClientStates - responses: - '200': - description: A successful response. - schema: - type: object - properties: - client_states: - type: array - items: - type: object - properties: - client_id: - type: string - title: client identifier - client_state: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the - type of the serialized - - protocol buffer message. This string must contain at - least - - one "/" character. The last segment of the URL's - path must represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be - in a canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the - binary all types that they - - expect it to use in the context of Any. However, for - URLs which use the - - scheme `http`, `https`, or no scheme, one can - optionally set up a type - - server that maps type URLs to message definitions as - follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results - based on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently available - in the official - - protobuf release, and it is not used for type URLs - beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty - scheme) might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the - above specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer - message along with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any - values in the form - - of utility functions or additional generated methods of - the Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. + Example 2: Pack and unpack a message in Java. Foo foo = ...; Any any = Any.pack(foo); @@ -3528,10 +3424,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -3592,7 +3491,6 @@ paths: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } - title: client state description: >- IdentifiedClientState defines a client state with an additional client @@ -3606,9 +3504,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -3633,7 +3532,7 @@ paths: method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -3759,10 +3658,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -3868,10 +3770,19 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean tags: - Query - '/ibc/core/client/v1/client_states/{client_id}': + /ibc/core/client/v1/client_states/{client_id}: get: summary: ClientState queries an IBC light client. operationId: ClientState @@ -3993,10 +3904,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -4095,7 +4009,7 @@ paths: which the proof was retrieved. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -4221,10 +4135,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -4291,7 +4208,7 @@ paths: type: string tags: - Query - '/ibc/core/client/v1/client_status/{client_id}': + /ibc/core/client/v1/client_status/{client_id}: get: summary: Status queries the status of an IBC client. operationId: ClientStatus @@ -4309,7 +4226,7 @@ paths: method. It returns the current status of the IBC client. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -4435,10 +4352,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -4505,7 +4425,7 @@ paths: type: string tags: - Query - '/ibc/core/client/v1/consensus_states/{client_id}': + /ibc/core/client/v1/consensus_states/{client_id}: get: summary: |- ConsensusStates queries all the consensus state associated with a given @@ -4664,10 +4584,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -4742,9 +4665,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -4767,7 +4691,7 @@ paths: QueryConsensusStatesResponse is the response type for the Query/ConsensusStates RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -4893,10 +4817,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -5007,10 +4934,19 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean tags: - Query - '/ibc/core/client/v1/consensus_states/{client_id}/heights': + /ibc/core/client/v1/consensus_states/{client_id}/heights: get: summary: >- ConsensusStateHeights queries the height of every consensus states @@ -5067,9 +5003,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -5092,7 +5029,7 @@ paths: QueryConsensusStateHeightsResponse is the response type for the Query/ConsensusStateHeights RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -5218,10 +5155,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -5332,10 +5272,19 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean tags: - Query - '/ibc/core/client/v1/consensus_states/{client_id}/revision/{revision_number}/height/{revision_height}': + /ibc/core/client/v1/consensus_states/{client_id}/revision/{revision_number}/height/{revision_height}: get: summary: >- ConsensusState queries a consensus state associated with a client state @@ -5461,10 +5410,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -5568,7 +5520,7 @@ paths: RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -5694,10 +5646,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -5779,11 +5734,230 @@ paths: latest_height overrrides the height field and queries the latest stored - ConsensusState. - in: query - required: false - type: boolean - format: boolean + ConsensusState. + in: query + required: false + type: boolean + tags: + - Query + /ibc/core/client/v1/params: + get: + summary: ClientParams queries all parameters of the ibc client submodule. + operationId: ClientParams + responses: + '200': + description: A successful response. + schema: + type: object + properties: + params: + description: params defines the parameters of the module. + type: object + properties: + allowed_clients: + type: array + items: + type: string + description: >- + allowed_clients defines the list of allowed client state + types. + description: >- + QueryClientParamsResponse is the response type for the + Query/ClientParams RPC + + method. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at + least + + one "/" character. The last segment of the URL's path + must represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in + a canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary + all types that they + + expect it to use in the context of Any. However, for + URLs which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in + the official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer + message along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values + in the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := anypb.New(foo) + if err != nil { + ... + } + ... + foo := &pb.Foo{} + if err := any.UnmarshalTo(foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by + default use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the + last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with + an + + additional field `@type` which contains the type URL. + Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding + a field + + `value` which holds the custom JSON in addition to the + `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } tags: - Query /ibc/core/client/v1/upgraded_client_states: @@ -5908,10 +6082,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -5972,7 +6149,7 @@ paths: QueryUpgradedClientStateResponse is the response type for the Query/UpgradedClientState RPC method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -6098,10 +6275,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -6284,10 +6464,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -6348,7 +6531,7 @@ paths: QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState RPC method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -6474,10 +6657,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -6538,7 +6724,7 @@ paths: } tags: - Query - '/ibc/core/connection/v1/client_connections/{client_id}': + /ibc/core/connection/v1/client_connections/{client_id}: get: summary: |- ClientConnections queries the connection paths associated with a client @@ -6592,7 +6778,7 @@ paths: QueryClientConnectionsResponse is the response type for the Query/ClientConnections RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -6718,10 +6904,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -6892,9 +7081,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -6948,7 +7138,7 @@ paths: method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -7074,10 +7264,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -7183,10 +7376,19 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean tags: - Query - '/ibc/core/connection/v1/connections/{connection_id}': + /ibc/core/connection/v1/connections/{connection_id}: get: summary: Connection queries an IBC connection end. operationId: Connection @@ -7331,7 +7533,7 @@ paths: which the proof was retrieved. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -7457,10 +7659,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -7527,7 +7732,7 @@ paths: type: string tags: - Query - '/ibc/core/connection/v1/connections/{connection_id}/client_state': + /ibc/core/connection/v1/connections/{connection_id}/client_state: get: summary: |- ConnectionClientState queries the client state associated with the @@ -7659,10 +7864,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -7764,7 +7972,7 @@ paths: QueryConnectionClientStateResponse is the response type for the Query/ConnectionClientState RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -7890,10 +8098,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -7960,7 +8171,7 @@ paths: type: string tags: - Query - '/ibc/core/connection/v1/connections/{connection_id}/consensus_state/revision/{revision_number}/height/{revision_height}': + /ibc/core/connection/v1/connections/{connection_id}/consensus_state/revision/{revision_number}/height/{revision_height}: get: summary: |- ConnectionConsensusState queries the consensus state associated with the @@ -8084,10 +8295,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -8123,68 +8337,307 @@ paths: string last_name = 2; } - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding a + field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + title: consensus state associated with the channel + client_id: + type: string + title: client ID associated with the consensus state + proof: + type: string + format: byte + title: merkle proof of existence + proof_height: + title: height at which the proof was retrieved + type: object + properties: + revision_number: + type: string + format: uint64 + title: the revision that the client is currently on + revision_height: + type: string + format: uint64 + title: the height within the given revision + description: >- + Normally the RevisionHeight is incremented at each height + while keeping + + RevisionNumber the same. However some consensus algorithms may + choose to + + reset the height in certain conditions e.g. hard forks, + state-machine + + breaking changes In these cases, the RevisionNumber is + incremented so that + + height continues to be monitonically increasing even as the + RevisionHeight + + gets reset + title: |- + QueryConnectionConsensusStateResponse is the response type for the + Query/ConnectionConsensusState RPC method + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at + least + + one "/" character. The last segment of the URL's path + must represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in + a canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary + all types that they + + expect it to use in the context of Any. However, for + URLs which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in + the official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer + message along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values + in the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := anypb.New(foo) + if err != nil { + ... + } + ... + foo := &pb.Foo{} + if err := any.UnmarshalTo(foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by + default use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the + last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with + an + + additional field `@type` which contains the type URL. + Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } - If the embedded message type is well-known and has a custom - JSON + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } - representation, that representation will be embedded adding a - field + If the embedded message type is well-known and has a custom + JSON - `value` which holds the custom JSON in addition to the `@type` + representation, that representation will be embedded adding + a field - field. Example (for message [google.protobuf.Duration][]): + `value` which holds the custom JSON in addition to the + `@type` - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - title: consensus state associated with the channel - client_id: - type: string - title: client ID associated with the consensus state - proof: - type: string - format: byte - title: merkle proof of existence - proof_height: - title: height at which the proof was retrieved + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + parameters: + - name: connection_id + description: connection identifier + in: path + required: true + type: string + - name: revision_number + in: path + required: true + type: string + format: uint64 + - name: revision_height + in: path + required: true + type: string + format: uint64 + tags: + - Query + /ibc/core/connection/v1/params: + get: + summary: ConnectionParams queries all parameters of the ibc connection submodule. + operationId: ConnectionParams + responses: + '200': + description: A successful response. + schema: + type: object + properties: + params: + description: params defines the parameters of the module. type: object properties: - revision_number: - type: string - format: uint64 - title: the revision that the client is currently on - revision_height: + max_expected_time_per_block: type: string format: uint64 - title: the height within the given revision - description: >- - Normally the RevisionHeight is incremented at each height - while keeping - - RevisionNumber the same. However some consensus algorithms may - choose to - - reset the height in certain conditions e.g. hard forks, - state-machine - - breaking changes In these cases, the RevisionNumber is - incremented so that + description: >- + maximum expected time per block (in nanoseconds), used to + enforce block delay. This parameter should reflect the - height continues to be monitonically increasing even as the - RevisionHeight + largest amount of time that the chain might reasonably + take to produce the next block under normal operating - gets reset - title: |- - QueryConnectionConsensusStateResponse is the response type for the - Query/ConnectionConsensusState RPC method + conditions. A safe choice is 3-5x the expected time per + block. + description: >- + QueryConnectionParamsResponse is the response type for the + Query/ConnectionParams RPC method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -8310,10 +8763,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -8372,22 +8828,6 @@ paths: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } - parameters: - - name: connection_id - description: connection identifier - in: path - required: true - type: string - - name: revision_number - in: path - required: true - type: string - format: uint64 - - name: revision_height - in: path - required: true - type: string - format: uint64 tags: - Query /ibc/core/channel/v1/channels: @@ -8487,9 +8927,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -8541,7 +8982,7 @@ paths: QueryChannelsResponse is the response type for the Query/Channels RPC method. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -8667,10 +9108,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -8776,10 +9220,19 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}: get: summary: Channel queries an IBC Channel. operationId: Channel @@ -8905,7 +9358,7 @@ paths: proof was retrieved. default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -9031,10 +9484,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -9106,7 +9562,7 @@ paths: type: string tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/client_state': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/client_state: get: summary: >- ChannelClientState queries for the client state for the channel @@ -9240,10 +9696,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -9345,7 +9804,7 @@ paths: QueryChannelClientStateResponse is the Response type for the Query/QueryChannelClientState RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -9471,10 +9930,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -9546,7 +10008,7 @@ paths: type: string tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/consensus_state/revision/{revision_number}/height/{revision_height}': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/consensus_state/revision/{revision_number}/height/{revision_height}: get: summary: |- ChannelConsensusState queries for the consensus state for the channel @@ -9670,10 +10132,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -9770,7 +10235,7 @@ paths: QueryChannelClientStateResponse is the Response type for the Query/QueryChannelClientState RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -9896,10 +10361,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -9983,7 +10451,7 @@ paths: format: uint64 tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/next_sequence': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/next_sequence: get: summary: >- NextSequenceReceive returns the next receive sequence for a given @@ -10036,7 +10504,7 @@ paths: QuerySequenceResponse is the request type for the Query/QueryNextSequenceReceiveResponse RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -10162,10 +10630,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -10237,7 +10708,7 @@ paths: type: string tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acknowledgements': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acknowledgements: get: summary: >- PacketAcknowledgements returns all the packet acknowledgements @@ -10287,9 +10758,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -10341,7 +10813,7 @@ paths: QueryPacketAcknowledgemetsResponse is the request type for the Query/QueryPacketAcknowledgements RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -10467,10 +10939,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -10586,7 +11061,16 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean - name: packet_commitment_sequences description: list of packet sequences. in: query @@ -10598,7 +11082,7 @@ paths: collectionFormat: multi tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acks/{sequence}': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acks/{sequence}: get: summary: PacketAcknowledgement queries a stored packet acknowledgement hash. operationId: PacketAcknowledgement @@ -10653,7 +11137,7 @@ paths: proof was retrieved default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -10779,10 +11263,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -10860,7 +11347,7 @@ paths: format: uint64 tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments: get: summary: |- PacketCommitments returns all the packet commitments hashes associated @@ -10908,9 +11395,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -10962,7 +11450,7 @@ paths: QueryPacketCommitmentsResponse is the request type for the Query/QueryPacketCommitments RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -11088,10 +11576,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -11207,10 +11698,19 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{packet_ack_sequences}/unreceived_acks': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{packet_ack_sequences}/unreceived_acks: get: summary: >- UnreceivedAcks returns all the unreceived IBC acknowledgements @@ -11263,7 +11763,7 @@ paths: QueryUnreceivedAcksResponse is the response type for the Query/UnreceivedAcks RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -11389,10 +11889,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -11474,7 +11977,7 @@ paths: minItems: 1 tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{packet_commitment_sequences}/unreceived_packets': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{packet_commitment_sequences}/unreceived_packets: get: summary: >- UnreceivedPackets returns all the unreceived IBC packets associated with @@ -11527,7 +12030,7 @@ paths: QueryUnreceivedPacketsResponse is the response type for the Query/UnreceivedPacketCommitments RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -11653,10 +12156,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -11738,7 +12244,7 @@ paths: minItems: 1 tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{sequence}': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{sequence}: get: summary: PacketCommitment queries a stored packet commitment hash. operationId: PacketCommitment @@ -11794,7 +12300,7 @@ paths: retrieved default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -11920,10 +12426,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -12001,7 +12510,7 @@ paths: format: uint64 tags: - Query - '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_receipts/{sequence}': + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_receipts/{sequence}: get: summary: >- PacketReceipt queries if a given packet sequence has been received on @@ -12017,7 +12526,6 @@ paths: properties: received: type: boolean - format: boolean title: success flag for if receipt exists proof: type: string @@ -12061,7 +12569,7 @@ paths: retrieved default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -12187,10 +12695,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -12268,7 +12779,7 @@ paths: format: uint64 tags: - Query - '/ibc/core/channel/v1/connections/{connection}/channels': + /ibc/core/channel/v1/connections/{connection}/channels: get: summary: |- ConnectionChannels queries all the channels associated with a connection @@ -12367,9 +12878,10 @@ paths: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -12421,7 +12933,7 @@ paths: QueryConnectionChannelsResponse is the Response type for the Query/QueryConnectionChannels RPC method default: - description: An unexpected error response + description: An unexpected error response. schema: type: object properties: @@ -12547,10 +13059,13 @@ paths: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -12661,7 +13176,16 @@ paths: in: query required: false type: boolean - format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean tags: - Query definitions: @@ -12692,7 +13216,6 @@ definitions: If left empty it will default to a value to be set by each app. count_total: type: boolean - format: boolean description: >- count_total is set to true to indicate that the result set should include @@ -12703,6 +13226,14 @@ definitions: key is set. + reverse: + type: boolean + description: >- + reverse is set to true if results are to be returned in the descending + order. + + + Since: cosmos-sdk 0.43 description: |- message SomeRequest { Foo some_parameter = 1; @@ -12717,9 +13248,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -12836,10 +13368,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -13010,10 +13545,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -13086,7 +13624,6 @@ definitions: properties: send_enabled: type: boolean - format: boolean description: >- send_enabled enables or disables all cross-chain token transfers from this @@ -13094,7 +13631,6 @@ definitions: chain. receive_enabled: type: boolean - format: boolean description: >- receive_enabled enables or disables all cross-chain token transfers to this @@ -13173,9 +13709,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -13207,7 +13744,6 @@ definitions: properties: send_enabled: type: boolean - format: boolean description: >- send_enabled enables or disables all cross-chain token transfers from this @@ -13215,7 +13751,6 @@ definitions: chain. receive_enabled: type: boolean - format: boolean description: >- receive_enabled enables or disables all cross-chain token transfers to this @@ -13227,11 +13762,18 @@ definitions: properties: controller_enabled: type: boolean - format: boolean description: controller_enabled enables or disables the controller submodule. description: |- Params defines the set of on-chain interchain accounts parameters. The following parameters may be used to disable the controller submodule. + ibc.applications.interchain_accounts.controller.v1.QueryInterchainAccountResponse: + type: object + properties: + address: + type: string + description: >- + QueryInterchainAccountResponse the response type for the + Query/InterchainAccount RPC method. ibc.applications.interchain_accounts.controller.v1.QueryParamsResponse: type: object properties: @@ -13241,7 +13783,6 @@ definitions: properties: controller_enabled: type: boolean - format: boolean description: controller_enabled enables or disables the controller submodule. description: QueryParamsResponse is the response type for the Query/Params RPC method. ibc.applications.interchain_accounts.host.v1.Params: @@ -13249,7 +13790,6 @@ definitions: properties: host_enabled: type: boolean - format: boolean description: host_enabled enables or disables the host submodule. allow_messages: type: array @@ -13270,7 +13810,6 @@ definitions: properties: host_enabled: type: boolean - format: boolean description: host_enabled enables or disables the host submodule. allow_messages: type: array @@ -13340,7 +13879,7 @@ definitions: NOTE: The amount field is an Int which implements the custom method signatures required by gogoproto. title: the packet timeout fee - title: 'Fee defines the ICS29 receive, acknowledgement and timeout fees' + title: Fee defines the ICS29 receive, acknowledgement and timeout fees ibc.applications.fee.v1.FeeEnabledChannel: type: object properties: @@ -13540,7 +14079,6 @@ definitions: properties: fee_enabled: type: boolean - format: boolean title: boolean flag representing the fee enabled channel status title: >- QueryFeeEnabledChannelResponse defines the response type for the @@ -14120,10 +14658,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -14211,6 +14752,7 @@ definitions: type: string title: client identifier client_state: + title: client state type: object properties: type_url: @@ -14316,10 +14858,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -14369,7 +14914,6 @@ definitions: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } - title: client state description: |- IdentifiedClientState defines a client state with an additional client identifier field. @@ -14508,10 +15052,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -14613,6 +15160,7 @@ definitions: type: string title: client identifier client_state: + title: client state type: object properties: type_url: @@ -14724,10 +15272,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -14781,7 +15332,6 @@ definitions: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } - title: client state description: >- IdentifiedClientState defines a client state with an additional client @@ -14795,9 +15345,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -14877,9 +15428,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -15008,10 +15560,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -15256,10 +15811,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -15327,9 +15885,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -15458,10 +16017,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -15624,10 +16186,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -15890,6 +16455,21 @@ definitions: description: |- IdentifiedConnection defines a connection with additional connection identifier field. + ibc.core.connection.v1.Params: + type: object + properties: + max_expected_time_per_block: + type: string + format: uint64 + description: >- + maximum expected time per block (in nanoseconds), used to enforce + block delay. This parameter should reflect the + + largest amount of time that the chain might reasonably take to produce + the next block under normal operating + + conditions. A safe choice is 3-5x the expected time per block. + description: Params defines the set of Connection parameters. ibc.core.connection.v1.QueryClientConnectionsResponse: type: object properties: @@ -16053,10 +16633,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -16256,10 +16839,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -16348,6 +16934,27 @@ definitions: title: |- QueryConnectionConsensusStateResponse is the response type for the Query/ConnectionConsensusState RPC method + ibc.core.connection.v1.QueryConnectionParamsResponse: + type: object + properties: + params: + description: params defines the parameters of the module. + type: object + properties: + max_expected_time_per_block: + type: string + format: uint64 + description: >- + maximum expected time per block (in nanoseconds), used to enforce + block delay. This parameter should reflect the + + largest amount of time that the chain might reasonably take to + produce the next block under normal operating + + conditions. A safe choice is 3-5x the expected time per block. + description: >- + QueryConnectionParamsResponse is the response type for the + Query/ConnectionParams RPC method. ibc.core.connection.v1.QueryConnectionResponse: type: object properties: @@ -16574,9 +17181,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -16715,7 +17323,7 @@ definitions: this channel will travel version: type: string - title: 'opaque channel version, which is agreed upon during the handshake' + title: opaque channel version, which is agreed upon during the handshake description: |- Channel defines pipeline for exactly-once packet delivery between specific modules on separate blockchains, which has at least one end capable of @@ -16790,7 +17398,7 @@ definitions: this channel will travel version: type: string - title: 'opaque channel version, which is agreed upon during the handshake' + title: opaque channel version, which is agreed upon during the handshake port_id: type: string title: port identifier @@ -16955,10 +17563,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -17158,10 +17769,13 @@ definitions: Example 4: Pack and unpack a message in Go foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) + any, err := anypb.New(foo) + if err != nil { + ... + } ... foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { + if err := any.UnmarshalTo(foo); err != nil { ... } @@ -17314,7 +17928,7 @@ definitions: this channel will travel version: type: string - title: 'opaque channel version, which is agreed upon during the handshake' + title: opaque channel version, which is agreed upon during the handshake description: >- Channel defines pipeline for exactly-once packet delivery between specific @@ -17446,9 +18060,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -17581,9 +18196,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -17754,9 +18370,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -17888,9 +18505,10 @@ definitions: next_key: type: string format: byte - title: |- + description: |- next_key is the key to be passed to PageRequest.key to - query the next page most efficiently + query the next page most efficiently. It will be empty if + there are no more results. total: type: string format: uint64 @@ -17943,7 +18561,6 @@ definitions: properties: received: type: boolean - format: boolean title: success flag for if receipt exists proof: type: string diff --git a/docs/dev/development-setup.md b/docs/dev/development-setup.md new file mode 100644 index 00000000000..61e90590806 --- /dev/null +++ b/docs/dev/development-setup.md @@ -0,0 +1,61 @@ +# Development setup + +## Dependencies + +We use [Go 1.14 Modules](https://github.com/golang/go/wiki/Modules) to manage dependency versions. + +The main branch of every Cosmos repository should just build with `go get`, which means they should be kept up-to-date with their dependencies, so we can get away with telling people they can just `go get` our software. + +Since some dependencies are not under our control, a third party may break our build, in which case we can fall back on `go mod tidy -v`. + +Other helpful commands: + +- `go get` to add a new go module (including if the existing go module is being semantic version bumped, i.e. my/module/v1 -> my/module/v2). +- `go get -u` to update an existing dependency. +- `go mod tidy` to update dependencies in `go.sum`. + +## Protobuf + +We use [Protocol Buffers](https://developers.google.com/protocol-buffers) along with [buf](https://docs.buf.build/introduction) and [gogoproto](https://github.com/gogo/protobuf) to generate code for use in ibc-go. + +For determinstic behavior around protobuf tooling, everything is containerized using Docker. Make sure to have Docker installed on your machine, or head to [Docker's website](https://docs.docker.com/get-docker/) to install it. + +For formatting code in `.proto` files, you can run the `make proto-format` command. + +For linting and checking breaking changes, we also use [buf](https://buf.build/). You can use the commands `make proto-lint` and `make proto-check-breaking` to respectively lint your proto files and check for breaking changes. + +To generate the protobuf stubs, you can run `make proto-gen`. + +We also added the `make proto-all` command to run the above commands (`proto-format`, `proto-lint` and `proto-gen`) sequentially. + +To update third-party protobuf dependencies, you can run `make proto-update-deps`. This requires `buf` to be installed in the local development environment (see [`buf`s installation documentation](https://docs.buf.build/installation) for more details). + +For generating or updating the swagger file that documents the URLs of the RESTful API that exposes the gRPC endpoints over HTTP, you can run the `proto-swagger-gen` command. + +It reads protobuf service definitions and generates a reverse-proxy server which translates a RESTful HTTP API into gRPC. + +## Developing and testing + +- The latest state of development is on `main`. +- Build the `simd` test chain binary with `make build`. +- `main` must never fail `make test`. +- No `--force` onto `main` (except when reverting a broken commit, which should seldom happen). +- Create a development branch either on `github.com/cosmos/ibc-go`, or your fork (using `git remote add fork`). +- Before submitting a pull request, begin `git rebase` on top of `main`. + +All Go tests in ibc-go can be ran by running `make test`. + +Please make sure to run `make format` before every commit - the easiest way to do this is have your editor run it for you upon saving a file. Additionally please ensure that your code is lint compliant by running `make lint-fix` (requires `golangci-lint`). + +When testing a function under a variety of different inputs, we prefer to use [table driven tests](https://github.com/golang/go/wiki/TableDrivenTests). + +All unit tests should use the testing package. Please see the testing package [README](../../testing/README.md) for more information. + +Test coverage is continuously deployed at . PRs that improve test coverage are welcome, but in general the test coverage should be used as a guidance for finding API use cases that are not covered by tests. We don't recommend adding tests that only improve coverage but not actually test a meaning use case. + +## Documentation + +- If you open a PR on ibc-go, it is mandatory to update the relevant documentation in `/docs`. +- We lint the markdown files for documentation with [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli). Please run `make docs-lint` before pushing changes in the markdown files (you will need to have `markdownlint-cli` installed, so please follow the [installation instructions](https://github.com/igorshubovych/markdownlint-cli#installation)). +- Generate the folder `docs/.vuepress/dist` with all the static files for the documentation site with `make build-docs`. +- Run the documentation site locally with `make view-docs`. diff --git a/docs/dev/go-style-guide.md b/docs/dev/go-style-guide.md new file mode 100644 index 00000000000..790c5fae3fb --- /dev/null +++ b/docs/dev/go-style-guide.md @@ -0,0 +1,115 @@ + +# Go style guide + +In order to keep our code looking good with lots of programmers working on it, it helps to have a "style guide", so all the code generally looks quite similar. This doesn't mean there is only one "right way" to write code, or even that this standard is better than your style. But if we agree to a number of stylistic practices, it makes it much easier to read and modify new code. Please feel free to make suggestions if there's something you would like to add or modify. + +We expect all contributors to be familiar with [Effective Go](https://golang.org/doc/effective_go.html) (and it's recommended reading for all Go programmers anyways). Additionally, we generally agree with the suggestions in [Uber's style guide](https://github.com/uber-go/guide/blob/master/style.md) and use that as a starting point. + +## Code Structure + +Perhaps more key for code readability than good commenting is having the right structure. As a rule of thumb, try to write in a logical order of importance, taking a little time to think how to order and divide the code such that someone could scroll down and understand the functionality of it just as well as you do. A loose example of such order would be: + +- Constants, global and package-level variables. +- Main struct definition. +- Options (only if they are seen as critical to the struct else they should be placed in another file). +- Initialization/start and stop of the service functions. +- Public functions (in order of most important). +- Private/helper functions. +- Auxiliary structs and function (can also be above private functions or in a separate file). + +## General + +- Use `gofumpt` to format all code upon saving it (or run `make format`). +- Think about documentation, and try to leave godoc comments, when it will help new developers. +- Every package should have a high level doc.go file to describe the purpose of that package, its main functions, and any other relevant information. +- Applications (e.g. clis/servers) should panic on unexpected unrecoverable errors and print a stack trace. + +## Comments + +- Use a space after the comment deliminter (ex. `// your comment`). +- Many comments are not sentences. These should begin with a lower case letter and end without a period. +- Conversely, sentences in comments should be sentenced-cased and end with a period. +- Comments should explain _why_ something is being done rather than _what_ the code is doing. For example: + + The comments in + +```go +// assign a variable foo +f := foo +// assign f to b +b := f +``` + + have little value, but the following is more useful: + +```go +f := foo +// we copy the variable f because we want to preserve the state at time of initialization +b := f +``` + +## Linting + +- Run `make lint-fix` to fix any linting errors. + +## Various + +- Functions that return functions should have the suffix `Fn`. +- Names should not [stutter](https://blog.golang.org/package-names). For example, a struct generally shouldn’t have a field named after itself; e.g., this shouldn't occur: + +```go +type middleware struct { + middleware Middleware +} +``` + +- Acronyms are all capitalized, like "RPC", "gRPC", "API". "MyID", rather than "MyId". +- Whenever it is safe to use Go's built-in `error` instantiation functions (as opposed to Cosmos SDK's error instantiation functions), prefer `errors.New()` instead of `fmt.Errorf()` unless you're actually using the format feature with arguments. + +## Importing libraries + +- Use [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports). +- Separate imports into blocks: one for the standard lib, one for external libs and one for application libs. For example: + +```go +import ( + // standard library imports + "fmt" + "testing" + + // external library imports + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + + // ibc-go library imports + "github.com/cosmos/ibc-go/modules/core/23-commitment/types" +) +``` + +## Dependencies + +- Dependencies should be pinned by a release tag, or specific commit, to avoid breaking `go get` when external dependencies are updated. +- Refer to the [contributing](./development-setup.md#dependencies) document for more details. + +## Testing + +- Make use of table driven testing where possible and not-cumbersome. Read [this blog post](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go) for more information. See the [tests](https://github.com/cosmos/ibc-go/blob/f24f41ea8a61fe87f6becab94e84de08c8aa9381/modules/apps/transfer/keeper/msg_server_test.go#L11) for [`Transfer`](https://github.com/cosmos/ibc-go/blob/f24f41ea8a61fe87f6becab94e84de08c8aa9381/modules/apps/transfer/keeper/msg_server.go#L15) for an example. +- Make use of Testify [assert](https://godoc.org/github.com/stretchr/testify/assert) and [require](https://godoc.org/github.com/stretchr/testify/require). +- When using mocks, it is recommended to use Testify [mock](https://pkg.go.dev/github.com/stretchr/testify/mock) along with [Mockery](https://github.com/vektra/mockery) for autogeneration. + +## Errors + +- Ensure that errors are concise, clear and traceable. +- Depending on the context, use either `cosmossdk.io/errors` or `stdlib` error packages. +- For wrapping errors, use `fmt.Errorf()` with `%w`. +- Panic is appropriate when an internal invariant of a system is broken, while all other cases (in particular, incorrect or invalid usage) should return errors. +- Error messages should be formatted as following: + +```go +sdkerrors.Wrapf( + , + "expected %s, got %s", + , + +) +``` diff --git a/docs/dev/project-structure.md b/docs/dev/project-structure.md new file mode 100644 index 00000000000..01fcf6b04da --- /dev/null +++ b/docs/dev/project-structure.md @@ -0,0 +1,46 @@ +# Project structure + +If you're not familiar with the overall module structure from the SDK modules, please check this [document](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules/10-structure.md) as prerequisite reading. + +Every Interchain Standard (ICS) has been developed in its own package. The development team separated the IBC TAO (Transport, Authentication, Ordering) ICS specifications from the IBC application level specification. The following sections describe the architecture of the most relevant directories that comprise this repository. + +## `modules` + +This folder contains implementations for the IBC TAO (`core`), IBC applications (`apps`) and light clients (`light-clients`). + +### `core` + +- `02-client`: This package is an implementation for Cosmos SDK-based chains of [ICS 02](https://github.com/cosmos/ibc/tree/main/spec/core/ics-002-client-semantics). This implementation defines the types and methods needed to operate light clients tracking other chain's consensus state. +- `03-connection`: This package is an implementation for Cosmos SDK-based chains of [ICS 03](https://github.com/cosmos/ibc/tree/main/spec/core/ics-003-connection-semantics). This implementation defines the types and methods necessary to perform connection handshake between two chains. +- `04-channel`: This package is an implementation for Cosmos SDK-based chains of [ICS 04](https://github.com/cosmos/ibc/tree/main/spec/core/ics-004-channel-and-packet-semantics). This implementation defines the types and methods necessary to perform channel handshake between two chains and ensure correct packet sending flow. +- `05-port`: This package is an implementation for Cosmos SDK-based chains of [ICS 05](https://github.com/cosmos/ibc/tree/main/spec/core/ics-005-port-allocation). This implements the port allocation system by which modules can bind to uniquely named ports. +- `23-commitment`: This package is an implementation for Cosmos SDK-based chains of [ICS 23](https://github.com/cosmos/ibc/tree/main/spec/core/ics-023-vector-commitments). This implementation defines the functions required to prove inclusion or non-inclusion of particular values at particular paths in state. +- `24-host`: This package is an implementation for Cosmos SDK-based chains of [ICS 24](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements). + +### `apps` + +- `transfer`: This is the Cosmos SDK implementation of the [ICS 20](https://github.com/cosmos/ibc/tree/main/spec/app/ics-020-fungible-token-transfer) protocol, which enables cross-chain fungible token transfers. For more information, read the [module's docs](../apps/transfer/overview.md) +- `27-interchain-accounts`: This is the Cosmos SDK implementation of the [ICS 27](https://github.com/cosmos/ibc/tree/main/spec/app/ics-027-interchain-accounts) protocol, which enables cross-chain account management built upon IBC. For more information, read the [module's documentation](../apps/interchain-accounts/overview.md). +- `29-fee`: This is the Cosmos SDK implementation of the [ICS 29](https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment) middleware, which handles packet incentivisation and fee distribution on top of any ICS application protocol, enabling fee payment to relayer operators. For more information, read the [module's documentation](../middleware/ics29-fee/overview.md). + +### `light-clients` + +- `06-solomachine`: This package implement the types for the Solo Machine light client specified in [ICS 06](https://github.com/cosmos/ibc/tree/main/spec/client/ics-006-solo-machine-client). +- `07-tendermint`: This package implement the types for the Tendermint consensus light client as specified in [ICS 07](https://github.com/cosmos/ibc/tree/main/spec/client/ics-007-tendermint-client). + +## `proto` + +This folder contains all the Protobuf files used for + +- common message type definitions, +- message type definitions related to genesis state, +- `Query` service and related message type definitions, +- `Msg` service and related message type definitions. + +## `testing` + +This package contains the implementation of the testing package used in unit and integration tests. Please read the [package's documentation](../../testing/README.md) for more information. + +## `e2e` + +This folder contains all the e2e tests of ibc-go. Please read the [module's documentation](../../e2e/README.md) for more information. diff --git a/docs/dev/pull-requests.md b/docs/dev/pull-requests.md new file mode 100644 index 00000000000..477a741bba9 --- /dev/null +++ b/docs/dev/pull-requests.md @@ -0,0 +1,68 @@ +# Pull request guidelines + +> To accommodate the review process we suggest that PRs are categorically broken up. Ideally each PR addresses only a single issue and does not introduce unrelated changes. Additionally, as much as possible code refactoring and cleanup should be submitted as separate PRs from bug fixes and feature additions. + +If the PR is the result of a related GitHub issue, please include `closes: #` in the PR’s description in order to auto-close the related issue once the PR is merged. This will also link the issue and the PR together so that if anyone looks at either in the future, they won’t have any problem trying to find the corresponding issue/PR as it will be recorded in the sidebar. + +If the PR is not the result of an existing issue and it fixes a bug, please provide a detailed description of the bug. For feature addtions, we recommend opening an issue first and have it discussed and agreed upon, before working on it and opening a PR. + +If possible, [tick the "Allow edits from maintainers" box](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) when opening your PR from your fork of ibc-go. This allows us to directly make minor edits / refactors and speeds up the merging process. + +If you open a PR on ibc-go, it is mandatory to update the relevant documentation in `/docs`. + +## Pull request targeting + +Ensure that you base and target your PR on the either the `main` branch or the corresponding feature branch where a large body of work is being implemented. Please make sure that the PR is made from a branch different than either `main` or the corresponding feature branch. + +All development should be then targeted against `main` or the feature branch. Bug fixes which are required for outstanding releases should be backported if the CODEOWNERS decide it is applicable. + +## Commit Messages + +Commit messages should follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/). + +When opening a PR, include the proposed commit message in the PR description. + +The commit message type should be one of: + +- `feat` / `feature` for feature work. +- `bug` / `fix` for bug fixes. +- `imp` / `improvements` for improvements. +- `doc` / `docs` / `documentation` for any documentation changes. +- `test` / `e2e` for addition or improvements of unit, integration and e2e tests or their corresponding infrastructure. +- `deprecated` for deprecation changes. +- `deps` / `build` for changes to dependencies. +- `chore` / `misc` / `nit` for any miscellaneous changes that don't fit into another category. + +**Note**: If any change is breaking, the following format must be used: + +- `type` + `(api)!` for api breaking changes, e.g. `fix(api)!: api breaking fix` +- `type` + `(statemachine)!` for state machine breaking changes, e.g. `fix(statemachine)!: state machine breaking fix` + +**`api` breaking changes take precedence over `statemachine` breaking changes.** + +## Pull request review process + +All PRs require an approval from at least one CODEOWNER before merge. PRs which cause significant changes require two approvals from CODEOWNERS. When reviewing PRs please use the following review guidelines: + +- `Approval` through the GitHub UI with the following comments: + - `Concept ACK` means that you agree with the overall proposed concept, but have neither reviewed the code nor tested it. + - `LGTM` means the above and besides you have superficially reviewed the code without considering how logic affects other parts the codebase. + - `utACK` (aka. `Untested ACK`) means the above and besides have thoroughly reviewed the code and considered the safety of logic changes, but have not tested it. + - `Tested ACK` means the above and besides you have tested the code. +- If you are only making "surface level" reviews, submit any notes as `Comments` without submitting an approval. + +A thorough review means that: + +- You understand the code and make sure that documentation is updated in the right places. +- You must also think through anything which ought to be included but is not. +- You must think through whether any added code could be partially combined (DRYed) with existing code. +- You must think through any potential security issues or incentive-compatibility flaws introduced by the changes. +- Naming must be consistent with conventions and the rest of the codebase. +- Code must live in a reasonable location, considering dependency structures (e.g. not importing testing modules in production code, or including example code modules in production code). + +## Pull request merge procedure + +- Ensure pull request branch is rebased on target branch. +- Ensure all GitHub requirements pass. +- Set the changelog entry in the commit message for the pull request. +- Squash and merge pull request. diff --git a/docs/dev/release-management.md b/docs/dev/release-management.md new file mode 100644 index 00000000000..09869569608 --- /dev/null +++ b/docs/dev/release-management.md @@ -0,0 +1,82 @@ +# Tagging a release + +## New major release branch + +Pre-requisites for creating a release branch for a new major version: + +1. Bump [Go package version](https://github.com/cosmos/ibc-go/blob/main/go.mod#L3). +2. Change all imports. For example: if the next major version is `v3`, then change all imports starting with `github.com/cosmos/ibc-go/v2` to `github.com/cosmos/ibc-go/v3`). + +Once the above pre-requisites are satified: + +1. Start on `main`. +2. Create the release branch (`release/vX.XX.X`). For example: `release/v3.0.x`. + +## New minor release branch + +1. Start on the latest release branch in the same major release line. For example: the latest release branch in the `v3` release line is `v3.2.x`. +2. Create branch from the release branch. For example: create branch `release/v3.3.x` from `v3.2.x`. + +Post-requisites for both new major and minor release branches: + +1. Add branch protection rules to new release branch. +2. Add backport task to [`mergify.yml`](https://github.com/cosmos/ibc-go/blob/main/.github/mergify.yml). +3. Create label for backport (e.g.`backport-to-v3.0.x`). + +## Point release procedure + +In order to alleviate the burden for a single person to have to cherry-pick and handle merge conflicts of all desired backporting PRs to a point release, we instead maintain a living backport branch, where all desired features and bug fixes are merged into as separate PRs. + +### Example + +Current release is `v1.0.2`. We then maintain a (living) branch `release/v1.0.x`, given `x` as the next patch release number (currently `v1.0.3`) for the `v1.0` release series. As bugs are fixed and PRs are merged into `main`, if a contributor wishes the PR to be released into the `v1.0.x` point release, the contributor must: + +1. Add the `backport-to-v1.0x` label to the PR. +2. Once the PR is merged, the Mergify GitHub application will automatically copy the changes into another branch and open a new PR agains the desired `release/v1.0.x` branch. +3. If the following has not been discussed in the original PR, then update the backport PR's description and ensure it contains the following information: + +- **[Impact]** explanation of how the bug affects users or developers. +- **[Test Case]** section with detailed instructions on how to reproduce the bug. +- **[Regression Potential]** section with a discussion how regressions are most likely to manifest, or might manifest even if it's unlikely, as a result of the change. **It is assumed that any backport PR is well-tested before it is merged in and has an overall low risk of regression**. This section should discuss the potential for state breaking changes to occur such as through out-of-gas errors. + +It is the PR's author's responsibility to fix merge conflicts, update changelog entries, and ensure CI passes. If a PR originates from an external contributor, it may be a core team member's responsibility to perform this process instead of the original author. Lastly, it is core team's responsibility to ensure that the PR meets all the backport criteria. + +Finally, when a point release is ready to be made: + +1. Checkout the release branch (e.g. `release/v1.0.x`). +2. In `CHANGELOG.md`: + +- Ensure changelog entries are verified. +- Remove any sections of the changelog that do not have any entries (e.g. if the release does not have any bug fixes, then remove the section). +- Remove the `[Unreleased]` title. +- Add release version and date of release. + +3. Create release in GitHub: + +- Select the correct target branch (e.g. `release/v1.0.x`). +- Choose a tag (e.g. `v1.0.3`). +- Write release notes. +- Check the `This is a pre-release` checkbox if needed (this applies for alpha, beta and release candidates). + +### Post-release procedure + +- Update [`CHANGELOG.md`](../../CHANGELOG.md) in `main` (remove from the `[Unreleased]` section any items that are part of the release).` +- Put back the `[Unreleased]` section in the release branch (e.g. `release/v1.0.x`) with clean sections for each of the types of changelog entries, so that entries will be added for the PRs that are backported for the next release. +- Update [version matrix](../../RELEASES.md#version-matrix) in `RELEASES.md`: add the new release and remove any tags that might not be recommended anymore. + +Additionally, for the first point release of a new major or minor release branch: + +- Update the table of supported release lines (and End of Life dates) in [`RELEASES.md`](../../RELEASES.md): add the new release line and remove any release lines that might have become discontinued. +- Update the [list of supported release lines in README.md](../../RELEASES.md#releases), if necessary. +- Update the [e2e compatibility test matrices](https://github.com/cosmos/ibc-go/tree/main/.github/compatibility-test-matrices): add the tag for the new release and remove any tags that might not be recommended anymore. +- Update the manual [e2e `simd`](https://github.com/cosmos/ibc-go/blob/main/.github/workflows/e2e-manual-simd.yaml) and [e2e `icad`](https://github.com/cosmos/ibc-go/blob/main/.github/workflows/e2e-manual-icad.yaml) test workflows: + - Add the new release and the new `icad` tag. + - Remove any tags that might not be recommended anymore. +- Bump ibc-go version in [cosmos/interchain-accounts-demo repository](https://github.com/cosmos/interchain-accounts-demo) and create a tag. +- Open a PR to `main` updating the docs site: + - Add new release branch to [`docs/versions`](../versions) file. + - Add `label` and `key` to `versions` array in [`config.js`](https://github.com/cosmos/ibc-go/blob/main/docs/.vuepress/config.js#L33). +- After changes to docs site are deployed, check [ibc.cosmos.network](https://ibc.cosmos.network) is updated. +- Open issue in [SDK tutorials repo](https://github.com/cosmos/sdk-tutorials) to update tutorials to the released version of ibc-go. + +See [this PR](https://github.com/cosmos/ibc-go/pull/2919) for an example of the involved changes. diff --git a/docs/ibc-go-image.png b/docs/ibc-go-image.png index 649c879bad9..70d8aa20205 100644 Binary files a/docs/ibc-go-image.png and b/docs/ibc-go-image.png differ diff --git a/docs/ibc/apps.md b/docs/ibc/apps.md index 11fa1e84b7e..be0457f4fe6 100644 --- a/docs/ibc/apps.md +++ b/docs/ibc/apps.md @@ -40,86 +40,86 @@ Here are the channel handshake callbacks that modules are expected to implement: ```go // Called by IBC Handler on MsgOpenInit func (k Keeper) OnChanOpenInit(ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, ) error { - // OpenInit must claim the channelCapability that IBC passes into the callback - if err := k.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return err - } + // OpenInit must claim the channelCapability that IBC passes into the callback + if err := k.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return err + } - // ... do custom initialization logic + // ... do custom initialization logic - // Use above arguments to determine if we want to abort handshake - // Examples: Abort if order == UNORDERED, - // Abort if version is unsupported - err := checkArguments(args) - return err + // Use above arguments to determine if we want to abort handshake + // Examples: Abort if order == UNORDERED, + // Abort if version is unsupported + err := checkArguments(args) + return err } // Called by IBC Handler on MsgOpenTry OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, ) (string, error) { - // OpenTry must claim the channelCapability that IBC passes into the callback - if err := k.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return err - } - - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - if err := checkArguments(args); err != nil { - return err - } - - // Construct application version - // IBC applications must return the appropriate application version - // This can be a simple string or it can be a complex version constructed - // from the counterpartyVersion and other arguments. - // The version returned will be the channel version used for both channel ends. - appVersion := negotiateAppVersion(counterpartyVersion, args) - - return appVersion, nil + // OpenTry must claim the channelCapability that IBC passes into the callback + if err := k.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return err + } + + // ... do custom initialization logic + + // Use above arguments to determine if we want to abort handshake + if err := checkArguments(args); err != nil { + return err + } + + // Construct application version + // IBC applications must return the appropriate application version + // This can be a simple string or it can be a complex version constructed + // from the counterpartyVersion and other arguments. + // The version returned will be the channel version used for both channel ends. + appVersion := negotiateAppVersion(counterpartyVersion, args) + + return appVersion, nil } // Called by IBC Handler on MsgOpenAck OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyVersion string, + ctx sdk.Context, + portID, + channelID string, + counterpartyVersion string, ) error { - // ... do custom initialization logic + // ... do custom initialization logic - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err + // Use above arguments to determine if we want to abort handshake + err := checkArguments(args) + return err } // Called by IBC Handler on MsgOpenConfirm OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - // ... do custom initialization logic + // ... do custom initialization logic - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err + // Use above arguments to determine if we want to abort handshake + err := checkArguments(args) + return err } ``` @@ -130,28 +130,28 @@ closing handshake. Closing a channel is a 2-step handshake, the initiating chain ```go // Called by IBC Handler on MsgCloseInit OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - // ... do custom finalization logic + // ... do custom finalization logic - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err + // Use above arguments to determine if we want to abort handshake + err := checkArguments(args) + return err } // Called by IBC Handler on MsgCloseConfirm OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - // ... do custom finalization logic + // ... do custom finalization logic - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err + // Use above arguments to determine if we want to abort handshake + err := checkArguments(args) + return err } ``` @@ -159,9 +159,9 @@ OnChanCloseConfirm( Application modules are expected to verify versioning used during the channel handshake procedure. -* `ChanOpenInit` callback should verify that the `MsgChanOpenInit.Version` is valid -* `ChanOpenTry` callback should construct the application version used for both channel ends. If no application version can be constructed, it must return an error. -* `ChanOpenAck` callback should verify that the `MsgChanOpenAck.CounterpartyVersion` is valid and supported. +- `ChanOpenInit` callback should verify that the `MsgChanOpenInit.Version` is valid +- `ChanOpenTry` callback should construct the application version used for both channel ends. If no application version can be constructed, it must return an error. +- `ChanOpenAck` callback should verify that the `MsgChanOpenAck.CounterpartyVersion` is valid and supported. IBC expects application modules to perform application version negotiation in `OnChanOpenTry`. The negotiated version must be returned to core IBC. If the version cannot be negotiated, an error should be returned. @@ -187,24 +187,24 @@ like so: ```go func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, state types.GenesisState) { - // ... other initialization logic - - // Only try to bind to port if it is not already bound, since we may already own - // port capability from capability InitGenesis - if !isBound(ctx, state.PortID) { - // module binds to desired ports on InitChain - // and claims returned capabilities - cap1 := keeper.IBCPortKeeper.BindPort(ctx, port1) - cap2 := keeper.IBCPortKeeper.BindPort(ctx, port2) - cap3 := keeper.IBCPortKeeper.BindPort(ctx, port3) - - // NOTE: The module's scoped capability keeper must be private - keeper.scopedKeeper.ClaimCapability(cap1) - keeper.scopedKeeper.ClaimCapability(cap2) - keeper.scopedKeeper.ClaimCapability(cap3) - } - - // ... more initialization logic + // ... other initialization logic + + // Only try to bind to port if it is not already bound, since we may already own + // port capability from capability InitGenesis + if !isBound(ctx, state.PortID) { + // module binds to desired ports on InitChain + // and claims returned capabilities + cap1 := keeper.IBCPortKeeper.BindPort(ctx, port1) + cap2 := keeper.IBCPortKeeper.BindPort(ctx, port2) + cap3 := keeper.IBCPortKeeper.BindPort(ctx, port3) + + // NOTE: The module's scoped capability keeper must be private + keeper.scopedKeeper.ClaimCapability(cap1) + keeper.scopedKeeper.ClaimCapability(cap2) + keeper.scopedKeeper.ClaimCapability(cap3) + } + + // ... more initialization logic } ``` @@ -223,25 +223,36 @@ encode and decode it to and from `[]byte`. ```go // Custom packet data defined in application module type CustomPacketData struct { - // Custom fields ... + // Custom fields ... } EncodePacketData(packetData CustomPacketData) []byte { - // encode packetData to bytes + // encode packetData to bytes } DecodePacketData(encoded []byte) (CustomPacketData) { - // decode from bytes to packet data + // decode from bytes to packet data } ``` Then a module must encode its packet data before sending it through IBC. ```go +// retrieve the dynamic capability for this channel +channelCap := scopedKeeper.GetCapability(ctx, channelCapName) // Sending custom application packet data data := EncodePacketData(customPacketData) packet.Data = data -IBCChannelKeeper.SendPacket(ctx, packet) +// Send packet to IBC, authenticating with channelCap +sequence, err := IBCChannelKeeper.SendPacket( + ctx, + channelCap, + sourcePort, + sourceChannel, + timeoutHeight, + timeoutTimestamp, + data, +) ``` A module receiving a packet must decode the `PacketData` into a structure it expects so that it can @@ -284,9 +295,16 @@ packet a module simply needs to call `SendPacket` on the `IBCChannelKeeper`. channelCap := scopedKeeper.GetCapability(ctx, channelCapName) // Sending custom application packet data data := EncodePacketData(customPacketData) -packet.Data = data // Send packet to IBC, authenticating with channelCap -IBCChannelKeeper.SendPacket(ctx, channelCap, packet) +sequence, err := IBCChannelKeeper.SendPacket( + ctx, + channelCap, + sourcePort, + sourceChannel, + timeoutHeight, + timeoutTimestamp, + data, +) ``` ::: warning @@ -306,49 +324,51 @@ The IBC handler will then commit this acknowledgement of the packet so that a re acknowledgement back to the sender module. The state changes that occurred during this callback will only be written if: + - the acknowledgement was successful as indicated by the `Success()` function of the acknowledgement - if the acknowledgement returned is nil indicating that an asynchronous process is occurring NOTE: Applications which process asynchronous acknowledgements must handle reverting state changes -when appropriate. Any state changes that occurred during the `OnRecvPacket` callback will be written -for asynchronous acknowledgements. +when appropriate. Any state changes that occurred during the `OnRecvPacket` callback will be written +for asynchronous acknowledgements. ```go OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, + ctx sdk.Context, + packet channeltypes.Packet, ) ibcexported.Acknowledgement { - // Decode the packet data - packetData := DecodePacketData(packet.Data) + // Decode the packet data + packetData := DecodePacketData(packet.Data) - // do application state changes based on packet data and return the acknowledgement - // NOTE: The acknowledgement will indicate to the IBC handler if the application - // state changes should be written via the `Success()` function. Application state - // changes are only written if the acknowledgement is successful or the acknowledgement - // returned is nil indicating that an asynchronous acknowledgement will occur. - ack := processPacket(ctx, packet, packetData) + // do application state changes based on packet data and return the acknowledgement + // NOTE: The acknowledgement will indicate to the IBC handler if the application + // state changes should be written via the `Success()` function. Application state + // changes are only written if the acknowledgement is successful or the acknowledgement + // returned is nil indicating that an asynchronous acknowledgement will occur. + ack := processPacket(ctx, packet, packetData) - return ack + return ack } ``` The Acknowledgement interface: + ```go // Acknowledgement defines the interface used to return // acknowledgements in the OnRecvPacket callback. type Acknowledgement interface { - Success() bool - Acknowledgement() []byte + Success() bool + Acknowledgement() []byte } ``` ### Acknowledgements Modules may commit an acknowledgement upon receiving and processing a packet in the case of synchronous packet processing. -In the case where a packet is processed at some later point after the packet has been received (asynchronous execution), the acknowledgement +In the case where a packet is processed at some later point after the packet has been received (asynchronous execution), the acknowledgement will be written once the packet has been processed by the application which may be well after the packet receipt. -NOTE: Most blockchain modules will want to use the synchronous execution model in which the module processes and writes the acknowledgement +NOTE: Most blockchain modules will want to use the synchronous execution model in which the module processes and writes the acknowledgement for a packet as soon as it has been received from the IBC module. This acknowledgement can then be relayed back to the original sender chain, which can take action @@ -396,22 +416,22 @@ is responsible for decoding the acknowledgement and processing it. ```go OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, ) (*sdk.Result, error) { - // Decode acknowledgement - ack := DecodeAcknowledgement(acknowledgement) + // Decode acknowledgement + ack := DecodeAcknowledgement(acknowledgement) - // process ack - res, err := processAck(ack) - return res, err + // process ack + res, err := processAck(ack) + return res, err } ``` #### Timeout Packets -If the timeout for a packet is reached before the packet is successfully received or the +If the timeout for a packet is reached before the packet is successfully received or the counterparty channel end is closed before the packet is successfully received, then the receiving chain can no longer process it. Thus, the sending chain must process the timeout using `OnTimeoutPacket` to handle this situation. Again the IBC module will verify that the timeout is @@ -420,10 +440,10 @@ timeout is reached and the packet can no longer be received. ```go OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, + ctx sdk.Context, + packet channeltypes.Packet, ) (*sdk.Result, error) { - // do custom timeout logic + // do custom timeout logic } ``` @@ -468,4 +488,4 @@ callbacks](https://github.com/cosmos/ibc-go/blob/main/modules/apps/transfer/ibc_ ## Next {hide} -Learn about [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/intro.md) {hide} +Learn about [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules/01-intro.md) {hide} diff --git a/docs/ibc/apps/apps.md b/docs/ibc/apps/apps.md index a24032168aa..86a53e6f94b 100644 --- a/docs/ibc/apps/apps.md +++ b/docs/ibc/apps/apps.md @@ -48,4 +48,4 @@ callbacks](https://github.com/cosmos/ibc-go/blob/main/modules/apps/transfer/ibc_ ## Next {hide} -Learn about [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/intro.md) {hide} +Learn about [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules/01-intro.md) {hide} diff --git a/docs/ibc/apps/bindports.md b/docs/ibc/apps/bindports.md index c0cfa703191..bf35fc0df0d 100644 --- a/docs/ibc/apps/bindports.md +++ b/docs/ibc/apps/bindports.md @@ -17,97 +17,97 @@ Currently, ports must be bound on app initialization. In order to bind modules t 1. Add port ID to the `GenesisState` proto definition: - ```protobuf - message GenesisState { - string port_id = 1; - // other fields - } - ``` + ```protobuf + message GenesisState { + string port_id = 1; + // other fields + } + ``` 1. Add port ID as a key to the module store: - ```go - // x//types/keys.go - const ( - // ModuleName defines the IBC Module name - ModuleName = "moduleName" + ```go + // x//types/keys.go + const ( + // ModuleName defines the IBC Module name + ModuleName = "moduleName" - // Version defines the current version the IBC - // module supports - Version = "moduleVersion-1" + // Version defines the current version the IBC + // module supports + Version = "moduleVersion-1" - // PortID is the default port id that module binds to - PortID = "portID" + // PortID is the default port id that module binds to + PortID = "portID" - // ... - ) - ``` + // ... + ) + ``` 1. Add port ID to `x//types/genesis.go`: - ```go - // in x//types/genesis.go - - // DefaultGenesisState returns a GenesisState with "transfer" as the default PortID. - func DefaultGenesisState() *GenesisState { - return &GenesisState{ - PortId: PortID, - // additional k-v fields - } - } - - // Validate performs basic genesis state validation returning an error upon any - // failure. - func (gs GenesisState) Validate() error { - if err := host.PortIdentifierValidator(gs.PortId); err != nil { - return err - } - //addtional validations - - return gs.Params.Validate() - } - ``` + ```go + // in x//types/genesis.go + + // DefaultGenesisState returns a GenesisState with "transfer" as the default PortID. + func DefaultGenesisState() *GenesisState { + return &GenesisState{ + PortId: PortID, + // additional k-v fields + } + } + + // Validate performs basic genesis state validation returning an error upon any + // failure. + func (gs GenesisState) Validate() error { + if err := host.PortIdentifierValidator(gs.PortId); err != nil { + return err + } + //addtional validations + + return gs.Params.Validate() + } + ``` 1. Bind to port(s) in the module keeper's `InitGenesis`: - ```go - // InitGenesis initializes the ibc-module state and binds to PortID. - func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) { - k.SetPort(ctx, state.PortId) + ```go + // InitGenesis initializes the ibc-module state and binds to PortID. + func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) { + k.SetPort(ctx, state.PortId) - // ... + // ... - // Only try to bind to port if it is not already bound, since we may already own - // port capability from capability InitGenesis - if !k.IsBound(ctx, state.PortId) { - // transfer module binds to the transfer port on InitChain - // and claims the returned capability - err := k.BindPort(ctx, state.PortId) - if err != nil { - panic(fmt.Sprintf("could not claim port capability: %v", err)) - } - } + // Only try to bind to port if it is not already bound, since we may already own + // port capability from capability InitGenesis + if !k.IsBound(ctx, state.PortId) { + // transfer module binds to the transfer port on InitChain + // and claims the returned capability + err := k.BindPort(ctx, state.PortId) + if err != nil { + panic(fmt.Sprintf("could not claim port capability: %v", err)) + } + } - // ... - } - ``` + // ... + } + ``` With: - ```go - // IsBound checks if the module is already bound to the desired port - func (k Keeper) IsBound(ctx sdk.Context, portID string) bool { - _, ok := k.scopedKeeper.GetCapability(ctx, host.PortPath(portID)) - return ok - } - - // BindPort defines a wrapper function for the port Keeper's function in - // order to expose it to module's InitGenesis function - func (k Keeper) BindPort(ctx sdk.Context, portID string) error { - cap := k.portKeeper.BindPort(ctx, portID) - return k.ClaimCapability(ctx, cap, host.PortPath(portID)) - } - ``` + ```go + // IsBound checks if the module is already bound to the desired port + func (k Keeper) IsBound(ctx sdk.Context, portID string) bool { + _, ok := k.scopedKeeper.GetCapability(ctx, host.PortPath(portID)) + return ok + } + + // BindPort defines a wrapper function for the port Keeper's function in + // order to expose it to module's InitGenesis function + func (k Keeper) BindPort(ctx sdk.Context, portID string) error { + cap := k.portKeeper.BindPort(ctx, portID) + return k.ClaimCapability(ctx, cap, host.PortPath(portID)) + } + ``` The module binds to the desired port(s) and returns the capabilities. diff --git a/docs/ibc/apps/ibcmodule.md b/docs/ibc/apps/ibcmodule.md index d5864435700..510fd5bcf31 100644 --- a/docs/ibc/apps/ibcmodule.md +++ b/docs/ibc/apps/ibcmodule.md @@ -14,7 +14,7 @@ interface](https://github.com/cosmos/ibc-go/tree/main/modules/core/05-port/types // The implementation of the IBCModule interface could for example be in a file called ibc_module.go, // but ultimately file structure is up to the developer type IBCModule struct { - keeper keeper.Keeper + keeper keeper.Keeper } ``` @@ -22,10 +22,10 @@ Additionally, in the `module.go` file, add the following line: ```go var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - // Add this line - _ porttypes.IBCModule = IBCModule{} + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + // Add this line + _ porttypes.IBCModule = IBCModule{} ) ``` @@ -45,90 +45,90 @@ Here are the channel handshake callbacks that modules are expected to implement: ```go // Called by IBC Handler on MsgOpenInit func (im IBCModule) OnChanOpenInit(ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, ) (string, error) { - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - // Examples: - // - Abort if order == UNORDERED, - // - Abort if version is unsupported - if err := checkArguments(args); err != nil { - return "", err - } - - // OpenInit must claim the channelCapability that IBC passes into the callback - if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return "", err - } - - return version, nil + // ... do custom initialization logic + + // Use above arguments to determine if we want to abort handshake + // Examples: + // - Abort if order == UNORDERED, + // - Abort if version is unsupported + if err := checkArguments(args); err != nil { + return "", err + } + + // OpenInit must claim the channelCapability that IBC passes into the callback + if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return "", err + } + + return version, nil } // Called by IBC Handler on MsgOpenTry func (im IBCModule) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, ) (string, error) { - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - if err := checkArguments(args); err != nil { - return "", err - } - - // OpenTry must claim the channelCapability that IBC passes into the callback - if err := im.keeper.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return err - } - - // Construct application version - // IBC applications must return the appropriate application version - // This can be a simple string or it can be a complex version constructed - // from the counterpartyVersion and other arguments. - // The version returned will be the channel version used for both channel ends. - appVersion := negotiateAppVersion(counterpartyVersion, args) - - return appVersion, nil + // ... do custom initialization logic + + // Use above arguments to determine if we want to abort handshake + if err := checkArguments(args); err != nil { + return "", err + } + + // OpenTry must claim the channelCapability that IBC passes into the callback + if err := im.keeper.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return err + } + + // Construct application version + // IBC applications must return the appropriate application version + // This can be a simple string or it can be a complex version constructed + // from the counterpartyVersion and other arguments. + // The version returned will be the channel version used for both channel ends. + appVersion := negotiateAppVersion(counterpartyVersion, args) + + return appVersion, nil } // Called by IBC Handler on MsgOpenAck func (im IBCModule) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyVersion string, + ctx sdk.Context, + portID, + channelID string, + counterpartyVersion string, ) error { - if counterpartyVersion != types.Version { - return sdkerrors.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: %s, expected %s", counterpartyVersion, types.Version) - } + if counterpartyVersion != types.Version { + return sdkerrors.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: %s, expected %s", counterpartyVersion, types.Version) + } - // do custom logic + // do custom logic - return nil + return nil } // Called by IBC Handler on MsgOpenConfirm func (im IBCModule) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - // do custom logic + // do custom logic - return nil + return nil } ``` @@ -137,28 +137,28 @@ The channel closing handshake will also invoke module callbacks that can return ```go // Called by IBC Handler on MsgCloseInit func (im IBCModule) OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - // ... do custom finalization logic + // ... do custom finalization logic - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err + // Use above arguments to determine if we want to abort handshake + err := checkArguments(args) + return err } // Called by IBC Handler on MsgCloseConfirm func (im IBCModule) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - // ... do custom finalization logic + // ... do custom finalization logic - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err + // Use above arguments to determine if we want to abort handshake + err := checkArguments(args) + return err } ``` @@ -209,7 +209,7 @@ Just as IBC expects modules to implement callbacks for channel handshakes, it al Once a module A and module B are connected to each other, relayers can start relaying packets and acknowledgements back and forth on the channel. -![IBC packet flow diagram](https://ibcprotocol.org/_nuxt/img/packet_flow.1d89ee0.png) +![IBC packet flow diagram](https://ibcprotocol.dev/_nuxt/img/packet_flow.1d89ee0.png) Briefly, a successful packet flow works as follows: @@ -232,9 +232,16 @@ module must trigger execution on the port-bound module through the use of callba channelCap := scopedKeeper.GetCapability(ctx, channelCapName) // Sending custom application packet data data := EncodePacketData(customPacketData) -packet.Data = data // Send packet to IBC, authenticating with channelCap -IBCChannelKeeper.SendPacket(ctx, channelCap, packet) +sequence, err := IBCChannelKeeper.SendPacket( + ctx, + channelCap, + sourcePort, + sourceChannel, + timeoutHeight, + timeoutTimestamp, + data, +) ``` ::: warning @@ -266,20 +273,20 @@ for asynchronous acknowledgements. ```go func (im IBCModule) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, + ctx sdk.Context, + packet channeltypes.Packet, ) ibcexported.Acknowledgement { - // Decode the packet data - packetData := DecodePacketData(packet.Data) + // Decode the packet data + packetData := DecodePacketData(packet.Data) - // do application state changes based on packet data and return the acknowledgement - // NOTE: The acknowledgement will indicate to the IBC handler if the application - // state changes should be written via the `Success()` function. Application state - // changes are only written if the acknowledgement is successful or the acknowledgement - // returned is nil indicating that an asynchronous acknowledgement will occur. - ack := processPacket(ctx, packet, packetData) + // do application state changes based on packet data and return the acknowledgement + // NOTE: The acknowledgement will indicate to the IBC handler if the application + // state changes should be written via the `Success()` function. Application state + // changes are only written if the acknowledgement is successful or the acknowledgement + // returned is nil indicating that an asynchronous acknowledgement will occur. + ack := processPacket(ctx, packet, packetData) - return ack + return ack } ``` @@ -289,8 +296,8 @@ Reminder, the `Acknowledgement` interface: // Acknowledgement defines the interface used to return // acknowledgements in the OnRecvPacket callback. type Acknowledgement interface { - Success() bool - Acknowledgement() []byte + Success() bool + Acknowledgement() []byte } ``` @@ -310,16 +317,16 @@ is responsible for decoding the acknowledgement and processing it. ```go func (im IBCModule) OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, ) (*sdk.Result, error) { - // Decode acknowledgement - ack := DecodeAcknowledgement(acknowledgement) + // Decode acknowledgement + ack := DecodeAcknowledgement(acknowledgement) - // process ack - res, err := processAck(ack) - return res, err + // process ack + res, err := processAck(ack) + return res, err } ``` @@ -334,9 +341,9 @@ timeout is reached and the packet can no longer be received. ```go func (im IBCModule) OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, + ctx sdk.Context, + packet channeltypes.Packet, ) (*sdk.Result, error) { - // do custom timeout logic + // do custom timeout logic } ``` diff --git a/docs/ibc/apps/keeper.md b/docs/ibc/apps/keeper.md index 6cbba0fbb8f..809ac46d8d7 100644 --- a/docs/ibc/apps/keeper.md +++ b/docs/ibc/apps/keeper.md @@ -18,70 +18,70 @@ In the previous sections, on channel handshake callbacks and port binding in `In ```go // Keeper defines the IBC app module keeper type Keeper struct { - storeKey sdk.StoreKey - cdc codec.BinaryCodec - paramSpace paramtypes.Subspace + storeKey sdk.StoreKey + cdc codec.BinaryCodec + paramSpace paramtypes.Subspace - channelKeeper types.ChannelKeeper - portKeeper types.PortKeeper - scopedKeeper capabilitykeeper.ScopedKeeper + channelKeeper types.ChannelKeeper + portKeeper types.PortKeeper + scopedKeeper capabilitykeeper.ScopedKeeper - // ... additional according to custom logic + // ... additional according to custom logic } // NewKeeper creates a new IBC app module Keeper instance func NewKeeper( - // args + // args ) Keeper { - // ... + // ... - return Keeper{ - cdc: cdc, - storeKey: key, - paramSpace: paramSpace, + return Keeper{ + cdc: cdc, + storeKey: key, + paramSpace: paramSpace, - channelKeeper: channelKeeper, - portKeeper: portKeeper, - scopedKeeper: scopedKeeper, + channelKeeper: channelKeeper, + portKeeper: portKeeper, + scopedKeeper: scopedKeeper, - // ... additional according to custom logic - } + // ... additional according to custom logic + } } // IsBound checks if the IBC app module is already bound to the desired port func (k Keeper) IsBound(ctx sdk.Context, portID string) bool { - _, ok := k.scopedKeeper.GetCapability(ctx, host.PortPath(portID)) - return ok + _, ok := k.scopedKeeper.GetCapability(ctx, host.PortPath(portID)) + return ok } // BindPort defines a wrapper function for the port Keeper's function in // order to expose it to module's InitGenesis function func (k Keeper) BindPort(ctx sdk.Context, portID string) error { - cap := k.portKeeper.BindPort(ctx, portID) - return k.ClaimCapability(ctx, cap, host.PortPath(portID)) + cap := k.portKeeper.BindPort(ctx, portID) + return k.ClaimCapability(ctx, cap, host.PortPath(portID)) } // GetPort returns the portID for the IBC app module. Used in ExportGenesis func (k Keeper) GetPort(ctx sdk.Context) string { - store := ctx.KVStore(k.storeKey) - return string(store.Get(types.PortKey)) + store := ctx.KVStore(k.storeKey) + return string(store.Get(types.PortKey)) } // SetPort sets the portID for the IBC app module. Used in InitGenesis func (k Keeper) SetPort(ctx sdk.Context, portID string) { - store := ctx.KVStore(k.storeKey) - store.Set(types.PortKey, []byte(portID)) + store := ctx.KVStore(k.storeKey) + store.Set(types.PortKey, []byte(portID)) } // AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function func (k Keeper) AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool { - return k.scopedKeeper.AuthenticateCapability(ctx, cap, name) + return k.scopedKeeper.AuthenticateCapability(ctx, cap, name) } // ClaimCapability allows the IBC app module to claim a capability that core IBC // passes to it func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error { - return k.scopedKeeper.ClaimCapability(ctx, cap, name) + return k.scopedKeeper.ClaimCapability(ctx, cap, name) } // ... additional according to custom logic diff --git a/docs/ibc/apps/packets_acks.md b/docs/ibc/apps/packets_acks.md index 1871eca8915..1d5061cf03f 100644 --- a/docs/ibc/apps/packets_acks.md +++ b/docs/ibc/apps/packets_acks.md @@ -26,15 +26,15 @@ encode and decode it to and from `[]byte`. ```go // Custom packet data defined in application module type CustomPacketData struct { - // Custom fields ... + // Custom fields ... } EncodePacketData(packetData CustomPacketData) []byte { - // encode packetData to bytes + // encode packetData to bytes } DecodePacketData(encoded []byte) (CustomPacketData) { - // decode from bytes to packet data + // decode from bytes to packet data } ``` @@ -43,10 +43,20 @@ DecodePacketData(encoded []byte) (CustomPacketData) { Then a module must encode its packet data before sending it through IBC. ```go +// retrieve the dynamic capability for this channel +channelCap := scopedKeeper.GetCapability(ctx, channelCapName) // Sending custom application packet data data := EncodePacketData(customPacketData) -packet.Data = data -IBCChannelKeeper.SendPacket(ctx, packet) +// Send packet to IBC, authenticating with channelCap +sequence, err := IBCChannelKeeper.SendPacket( + ctx, + channelCap, + sourcePort, + sourceChannel, + timeoutHeight, + timeoutTimestamp, + data, +) ``` A module receiving a packet must decode the `PacketData` into a structure it expects so that it can diff --git a/docs/ibc/apps/routing.md b/docs/ibc/apps/routing.md index 1095462dcba..73d3daa7ee0 100644 --- a/docs/ibc/apps/routing.md +++ b/docs/ibc/apps/routing.md @@ -18,19 +18,19 @@ must be registered with the module name as a route on the IBC `Router`. ```go // app.go func NewApp(...args) *App { -// ... + // ... -// Create static IBC router, add module routes, then set and seal it -ibcRouter := port.NewRouter() + // Create static IBC router, add module routes, then set and seal it + ibcRouter := port.NewRouter() -ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule) -// Note: moduleCallbacks must implement IBCModule interface -ibcRouter.AddRoute(moduleName, moduleCallbacks) + ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule) + // Note: moduleCallbacks must implement IBCModule interface + ibcRouter.AddRoute(moduleName, moduleCallbacks) -// Setting Router will finalize all routes by sealing router -// No more routes can be added -app.IBCKeeper.SetRouter(ibcRouter) + // Setting Router will finalize all routes by sealing router + // No more routes can be added + app.IBCKeeper.SetRouter(ibcRouter) -// ... + // ... } ``` diff --git a/docs/ibc/events.md b/docs/ibc/events.md index 2c584302566..080c284deaa 100644 --- a/docs/ibc/events.md +++ b/docs/ibc/events.md @@ -11,7 +11,7 @@ with an attirbute key of `action` will represent the first event for each messag being processed as emitted by the SDK's baseapp. Each IBC TAO message will also emit its module name in the format 'ibc_sub-modulename'. -All the events for the Channel handshakes, `SendPacket`, `RecvPacket`, `AcknowledgePacket`, +All the events for the Channel handshakes, `SendPacket`, `RecvPacket`, `AcknowledgePacket`, `TimeoutPacket` and `TimeoutOnClose` will emit additional events not specified here due to callbacks to IBC applications. @@ -63,7 +63,7 @@ callbacks to IBC applications. | Type | Attribute Key | Attribute Value | |-------------------------|-----------------|-------------------| | upgrade_client_proposal | title | {title} | -| upgrade_client_proposal | height | {height} | +| upgrade_client_proposal | height | {height} | ## ICS 03 - Connection @@ -81,7 +81,7 @@ callbacks to IBC applications. | Type | Attribute Key | Attribute Value | |---------------------|----------------------------|-----------------------------| -| connection_open_try | connection_id | {connectionId} | +| connection_open_try | connection_id | {connectionId} | | connection_open_try | client_id | {clientId} | | connection_open_try | counterparty_client_id | {counterparty.clientId | | connection_open_try | counterparty_connection_id | {counterparty.connectionId} | @@ -199,7 +199,7 @@ callbacks to IBC applications. | message | action | application-module-defined-field | | message | module | ibc-channel | -### MsgRecvPacket +### MsgRecvPacket | Type | Attribute Key | Attribute Value | |-------------|--------------------------|----------------------| @@ -216,7 +216,7 @@ callbacks to IBC applications. | message | action | recv_packet | | message | module | ibc-channel | -### MsgAcknowledgePacket +### MsgAcknowledgePacket | Type | Attribute Key | Attribute Value | |--------------------|--------------------------|----------------------| @@ -231,7 +231,7 @@ callbacks to IBC applications. | message | action | acknowledge_packet | | message | module | ibc-channel | -### MsgTimeoutPacket & MsgTimeoutOnClose +### MsgTimeoutPacket & MsgTimeoutOnClose | Type | Attribute Key | Attribute Value | |----------------|--------------------------|----------------------| @@ -245,4 +245,3 @@ callbacks to IBC applications. | timeout_packet | packet_channel_ordering | {channel.Ordering} | | message | action | timeout_packet | | message | module | ibc-channel | - diff --git a/docs/ibc/integration.md b/docs/ibc/integration.md index d2d9f057ea3..26b55c9f3a9 100644 --- a/docs/ibc/integration.md +++ b/docs/ibc/integration.md @@ -16,7 +16,7 @@ Integrating the IBC module to your SDK-based application is straighforward. The - Add required modules to the `module.BasicManager` - Define additional `Keeper` fields for the new modules on the `App` type -- Add the module's `StoreKeys` and initialize their `Keepers` +- Add the module's `StoreKey`s and initialize their `Keeper`s - Set up corresponding routers and routes for the `ibc` module - Add the modules to the module `Manager` - Add modules to `Begin/EndBlockers` and `InitGenesis` @@ -28,15 +28,32 @@ The first step is to add the following modules to the `BasicManager`: `x/capabil and `x/ibc-transfer`. After that, we need to grant `Minter` and `Burner` permissions to the `ibc-transfer` `ModuleAccount` to mint and burn relayed tokens. -```go +### Integrating light clients + +> Note that from v7 onwards, all light clients have to be explicitly registered in a chain's app.go and follow the steps listed below. + This is in contrast to earlier versions of ibc-go when `07-tendermint` and `06-solomachine` were added out of the box. + +All light clients must be registered with `module.BasicManager` in a chain's app.go file. + +The following code example shows how to register the existing `ibctm.AppModuleBasic{}` light client implementation. + +```diff +import ( + ... ++ ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint" + ... +) + // app.go var ( - ModuleBasics = module.NewBasicManager( // ... capability.AppModuleBasic{}, ibc.AppModuleBasic{}, transfer.AppModuleBasic{}, // i.e ibc-transfer module + + // register light clients on IBC ++ ibctm.AppModuleBasic{}, ) // module account permissions @@ -44,6 +61,7 @@ var ( // other module accounts permissions // ... ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + } ) ``` @@ -85,14 +103,14 @@ func NewApp(...args) *App { app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey]) // grant capabilities for the ibc and ibc-transfer modules - scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) // ... other modules keepers // Create IBC Keeper app.IBCKeeper = ibckeeper.NewKeeper( - appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, + appCodec, keys[ibcexported.StoreKey], app.GetSubspace(ibcexported.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, ) // Create Transfer Keepers @@ -139,7 +157,7 @@ func NewApp(...args) *App { ### Module Managers -In order to use IBC, we need to add the new modules to the module `Manager` and to the `SimulationManager` in case your application supports [simulations](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/simulator.md). +In order to use IBC, we need to add the new modules to the module `Manager` and to the `SimulationManager` in case your application supports [simulations](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules/13-simulator.md). ```go // app.go @@ -175,17 +193,6 @@ at each height during the `BeginBlock` call. The historical info is required to past historical info at any given height in order to verify the light client `ConsensusState` during the connection handhake. -The IBC module also has -[`BeginBlock`](https://github.com/cosmos/ibc-go/blob/main/modules/core/02-client/abci.go) logic as -well. This is optional as it is only required if your application uses the [localhost -client](https://github.com/cosmos/ibc/blob/master/spec/client/ics-009-loopback-client) to connect two -different modules from the same chain. - -::: tip -Only register the ibc module to the `SetOrderBeginBlockers` if your application will use the -localhost (_aka_ loopback) client. -::: - ```go // app.go func NewApp(...args) *App { @@ -194,7 +201,7 @@ func NewApp(...args) *App { // add staking and ibc modules to BeginBlockers app.mm.SetOrderBeginBlockers( // other modules ... - stakingtypes.ModuleName, ibchost.ModuleName, + stakingtypes.ModuleName, ibcexported.ModuleName, ) // ... @@ -205,7 +212,7 @@ func NewApp(...args) *App { app.mm.SetOrderInitGenesis( capabilitytypes.ModuleName, // other modules ... - ibchost.ModuleName, ibctransfertypes.ModuleName, + ibcexported.ModuleName, ibctransfertypes.ModuleName, ) // .. continues diff --git a/docs/ibc/light-clients/client-state.md b/docs/ibc/light-clients/client-state.md new file mode 100644 index 00000000000..b72b73ad217 --- /dev/null +++ b/docs/ibc/light-clients/client-state.md @@ -0,0 +1,75 @@ + + +# Implementing the `ClientState` interface + +Learn how to implement the [`ClientState`](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/exported/client.go#L40) interface. This list of methods described here does not include all methods of the interface. Some methods are explained in detail in the relevant sections of the guide. + +## `ClientType` method + +`ClientType` should return a unique string identifier of the light client. This will be used when generating a client identifier. +The format is created as follows: `ClientType-{N}` where `{N}` is the unique global nonce associated with a specific client. + +## `GetLatestHeight` method + +`GetLatestHeight` should return the latest block height that the client state represents. + +## `Validate` method + +`Validate` should validate every client state field and should return an error if any value is invalid. The light client +implementer is in charge of determining which checks are required. See the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/light-clients/07-tendermint/types/client_state.go#L101) as a reference. + +## `Status` method + +`Status` must return the status of the client. + +- An `Active` status indicates that clients are allowed to process packets. +- A `Frozen` status indicates that misbehaviour was detected in the counterparty chain and the client is not allowed to be used. +- An `Expired` status indicates that a client is not allowed to be used because it was not updated for longer than the trusting period. +- An `Unknown` status indicates that there was an error in determining the status of a client. + +All possible `Status` types can be found [here](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/exported/client.go#L26-L36). + +This field is returned in the response of the gRPC [`ibc.core.client.v1.Query/ClientStatus`](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/02-client/types/query.pb.go#L665) endpoint. + +## `ZeroCustomFields` method + +`ZeroCustomFields` should return a copy of the light client with all client customizable fields with their zero value. It should not mutate the fields of the light client. +This method is used when [scheduling upgrades](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/02-client/keeper/proposal.go#L89). Upgrades are used to upgrade chain specific fields. +In the tendermint case, this may be the chain ID or the unbonding period. +For more information about client upgrades see the [Handling upgrades](./upgrades.md) section. + +## `GetTimestampAtHeight` method + +`GetTimestampAtHeight` must return the timestamp for the consensus state associated with the provided height. +This value is used to facilitate timeouts by checking the packet timeout timestamp against the returned value. + +## `Initialize` method + +Clients must validate the initial consensus state, and set the initial client state and consensus state in the provided client store. +Clients may also store any necessary client-specific metadata. + +`Initialize` is called when a [client is created](https://github.com/cosmos/ibc-go/blob/main/modules/core/02-client/keeper/client.go#L32). + +## `VerifyMembership` method + +`VerifyMembership` must verify the existence of a value at a given commitment path at the specified height. For more information about membership proofs +see the [Existence and non-existence proofs section](./proofs.md). + +## `VerifyNonMembership` method + +`VerifyNonMembership` must verify the absence of a value at a given commitment path at a specified height. For more information about non-membership proofs +see the [Existence and non-existence proofs section](./proofs.md). + +## `VerifyClientMessage` method + +`VerifyClientMessage` must verify a `ClientMessage`. A `ClientMessage` could be a `Header`, `Misbehaviour`, or batch update. +It must handle each type of `ClientMessage` appropriately. Calls to `CheckForMisbehaviour`, `UpdateState`, and `UpdateStateOnMisbehaviour` +will assume that the content of the `ClientMessage` has been verified and can be trusted. An error should be returned +if the ClientMessage fails to verify. + +## `CheckForMisbehaviour` method + +Checks for evidence of a misbehaviour in `Header` or `Misbehaviour` type. It assumes the `ClientMessage` +has already been verified. diff --git a/docs/ibc/light-clients/consensus-state.md b/docs/ibc/light-clients/consensus-state.md new file mode 100644 index 00000000000..26166bc41a7 --- /dev/null +++ b/docs/ibc/light-clients/consensus-state.md @@ -0,0 +1,23 @@ + + +# Implementing the `ConsensusState` interface + +A `ConsensusState` is the snapshot of the counterparty chain, that an IBC client uses to verify proofs (e.g. a block). + +The further development of multiple types of IBC light clients and the difficulties presented by this generalization problem (see [ADR-006](https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-006-02-client-refactor.md) for more information about this historical context) led to the design decision of each client keeping track of and set its own `ClientState` and `ConsensusState`, as well as the simplification of client `ConsensusState` updates through the generalized `ClientMessage` interface. + +The below [`ConsensusState`](https://github.com/cosmos/ibc-go/blob/main/modules/core/exported/client.go#L134) interface is a generalized interface for the types of information a `ConsensusState` could contain. For a reference `ConsensusState` implementation, please see the [Tendermint light client `ConsensusState`](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/consensus_state.go). + +## `ClientType` method + +This is the type of client consensus. It should be the same as the `ClientType` return value for the [corresponding `ClientState` implementation](./client-state.md). + +## `GetTimestamp` method + +`GetTimestamp` should return the timestamp (in nanoseconds) of the consensus state snapshot. + +## `ValidateBasic` method + +`ValidateBasic` should validate every consensus state field and should return an error if any value is invalid. The light client implementer is in charge of determining which checks are required. diff --git a/docs/ibc/light-clients/genesis.md b/docs/ibc/light-clients/genesis.md new file mode 100644 index 00000000000..234cfa4002e --- /dev/null +++ b/docs/ibc/light-clients/genesis.md @@ -0,0 +1,36 @@ + + +# Genesis metadata + +Learn how to implement the `ExportMetadata` interface {synopsis} + +## Pre-requisite readings + +- [Cosmos SDK module genesis](https://docs.cosmos.network/v0.47/building-modules/genesis) {prereq} + +`ClientState` instances are provided their own isolated and namespaced client store upon initialisation. `ClientState` implementations may choose to store any amount of arbitrary metadata in order to verify counterparty consensus state and perform light client updates correctly. + +The `ExportMetadata` method of the [`ClientState` interface](https://github.com/cosmos/ibc-go/blob/e650be91614ced7be687c30eb42714787a3bbc59/modules/core/exported/client.go) provides light client modules with the ability to persist metadata in genesis exports. + +```go +ExportMetadata(clientStore sdk.KVStore) []GenesisMetadata +``` + +`ExportMetadata` is provided the client store and returns an array of `GenesisMetadata`. For maximum flexibility, `GenesisMetadata` is defined as a simple interface containing two distinct `Key` and `Value` accessor methods. + +```go +type GenesisMetadata interface { + // return store key that contains metadata without clientID-prefix + GetKey() []byte + // returns metadata value + GetValue() []byte +} +``` + +This allows `ClientState` instances to retrieve and export any number of key-value pairs which are maintained within the store in their raw `[]byte` form. + +When a chain is started with a `genesis.json` file which contains `ClientState` metadata (for example, when performing manual upgrades using an exported `genesis.json`) the `02-client` submodule of core IBC will handle setting the key-value pairs within their respective client stores. [See `02-client` `InitGenesis`](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/02-client/genesis.go#L18-L22). + +Please refer to the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/genesis.go#L12) for an example. diff --git a/docs/ibc/light-clients/overview.md b/docs/ibc/light-clients/overview.md new file mode 100644 index 00000000000..a06ae4afa31 --- /dev/null +++ b/docs/ibc/light-clients/overview.md @@ -0,0 +1,70 @@ + + +# Overview + +Learn how to build IBC light client modules and fulfill the interfaces required to integrate with core IBC. {synopsis} + +## Pre-requisites Readings + +- [IBC Overview](../overview.md)) {prereq} +- [IBC Transport, Authentication, and Ordering Layer - Clients](https://tutorials.cosmos.network/academy/3-ibc/4-clients.html) {prereq} +- [ICS-002 Client Semantics](https://github.com/cosmos/ibc/tree/main/spec/core/ics-002-client-semantics) {prereq} + +IBC uses light clients in order to provide trust-minimized interoperability between sovereign blockchains. Light clients operate under a strict set of rules which provide security guarantees for state updates and facilitate the ability to verify the state of a remote blockchain using merkle proofs. + +The following aims to provide a high level IBC light client module developer guide. Access to IBC light clients are gated by the core IBC `MsgServer` which utilizes the abstractions set by the `02-client` submodule to call into a light client module. A light client module developer is only required to implement a set interfaces as defined in the `modules/core/exported` package of ibc-go. + +A light client module developer should be concerned with three main interfaces: + +- [`ClientState`](#clientstate) encapsulates the light client implementation and its semantics. +- [`ConsensusState`](#consensusstate) tracks consensus data used for verification of client updates, misbehaviour detection and proof verification of counterparty state. +- [`ClientMessage`](#clientmessage) used for submitting block headers for client updates and submission of misbehaviour evidence using conflicting headers. + +Throughout this guide the `07-tendermint` light client module may be referred to as a reference example. + +## Concepts and vocabulary + +### `ClientState` + +`ClientState` is a term used to define the data structure which encapsulates opaque light client state. The `ClientState` contains all the information needed to verify a `ClientMessage` and perform membership and non-membership proof verification of counterparty state. This includes properties that refer to the remote state machine, the light client type and the specific light client instance. + +For example: + +- Constraints used for client updates. +- Constraints used for misbehaviour detection. +- Constraints used for state verification. +- Constraints used for client upgrades. + +The `ClientState` type maintained within the light client module *must* implement the [`ClientState`](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/modules/core/exported/client.go#L36) interface defined in `core/modules/exported/client.go`. +The methods which make up this interface are detailed at a more granular level in the [ClientState section of this guide](./client-state.md). + +Please refer to the `07-tendermint` light client module's [`ClientState` definition](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/proto/ibc/lightclients/tendermint/v1/tendermint.proto#L18) containing information such as chain ID, status, latest height, unbonding period and proof specifications. + +### `ConsensusState` + +`ConsensusState` is a term used to define the data structure which encapsulates consensus data at a particular point in time, i.e. a unique height or sequence number of a state machine. There must exist a single trusted `ConsensusState` for each height. `ConsensusState` generally contains a trusted root, validator set information and timestamp. + +For example, the `ConsensusState` of the `07-tendermint` light client module defines a trusted root which is used by the `ClientState` to perform verification of membership and non-membership commitment proofs, as well as the next validator set hash used for verifying headers can be trusted in client updates. + +The `ConsensusState` type maintained within the light client module *must* implement the [`ConsensusState`](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/modules/core/exported/client.go#L134) interface defined in `modules/core/exported/client.go`. +The methods which make up this interface are detailed at a more granular level in the [`ConsensusState` section of this guide](./consensus-state.md). + +### `Height` + +`Height` defines a monotonically increasing sequence number which provides ordering of consensus state data persisted through client updates. +IBC light client module developers are expected to use the [concrete type](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/proto/ibc/core/client/v1/client.proto#L89) provided by the `02-client` submodule. This implements the expectations required by the [`Height`](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/exported/client.go#L157) interface defined in `modules/core/exported/client.go`. + +### `ClientMessage` + +`ClientMessage` refers to the interface type [`ClientMessage`](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/modules/core/exported/client.go#L148) used for performing updates to a `ClientState` stored on chain. +This may be any concrete type which produces a change in state to the IBC client when verified. + +The following are considered as valid update scenarios: + +- A block header which when verified inserts a new `ConsensusState` at a unique height. +- A batch of block headers which when verified inserts `N` `ConsensusState` instances for `N` unique heights. +- Evidence of misbehaviour provided by two conflicting block headers. + +Learn more in the [Handling update and misbehaviour](./updates-and-misbehaviour.md) section. diff --git a/docs/ibc/light-clients/proofs.md b/docs/ibc/light-clients/proofs.md new file mode 100644 index 00000000000..fa4e5a84126 --- /dev/null +++ b/docs/ibc/light-clients/proofs.md @@ -0,0 +1,62 @@ + + +# Existence and non-existence proofs + +IBC uses merkle proofs in order to verify the state of a remote counterparty state machine given a trusted root, and [ICS-23](https://github.com/cosmos/ics23/tree/master/go) is a general approach for verifying merkle trees which is used in ibc-go. + +Currently, all Cosmos SDK modules contain their own stores, which maintain the state of the application module in an IAVL (immutable AVL) binary merkle tree format. Specifically with regard to IBC, core IBC maintains its own IAVL store, and IBC apps (e.g. transfer) maintain their own dedicated stores. The Cosmos SDK multistore therefore creates a simple merkle tree of all of these IAVL trees, and from each of these individual IAVL tree root hashes it derives a root hash for the application state tree as a whole (the `AppHash`). + +For the purposes of ibc-go, there are two types of proofs which are important: existence and non-existence proofs, terms which have been used interchangeably with membership and non-membership proofs. For the purposes of this guide, we will stick with "existence" and "non-existence". + +## Existence proofs + +Existence proofs are used in IBC transactions which involve verification of counterparty state for transactions which will result in the writing of provable state. For example, this includes verification of IBC store state for handshakes and packets. + +Put simply, existence proofs prove that a particular key and value exists in the tree. Under the hood, an IBC existence proof comprises of two proofs: an IAVL proof that the key exists in IBC store/IBC root hash, and a proof that the IBC root hash exists in the multistore root hash. + +## Non-existence proofs + +Non-existence proofs verify the absence of data stored within counterparty state and are used to prove that a key does NOT exist in state. As stated above, these types of proofs can be used to timeout packets by proving that the counterparty has not written a packet receipt into the store, meaning that a token transfer has NOT successfully occurred. + +Some trees (e.g. SMT) may have a sentinel empty child for non-existent keys. In this case, the ICS-23 proof spec should include this `EmptyChild` so that ICS-23 handles the non-existence proof correctly. + +In some cases, there is a necessity to "mock" non-existence proofs if the counterparty does not have ability to prove absence. Since the verification method is designed to give complete control to client implementations, clients can support chains that do not provide absence proofs by verifying the existence of a non-empty sentinel `ABSENCE` value. In these special cases, the proof provided will be an ICS-23 `Existence` proof, and the client will verify that the `ABSENCE` value is stored under the given path for the given height. + +## State verification methods: `VerifyMembership` and `VerifyNonMembership` + +The state verification functions for all IBC data types have been consolidated into two generic methods, `VerifyMembership` and `VerifyNonMembership`. + +From the [`ClientState` interface definition](https://github.com/cosmos/ibc-go/blob/e650be91614ced7be687c30eb42714787a3bbc59/modules/core/exported/client.go#L68-L91), we find: + +```go +VerifyMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path Path, + value []byte, +) error + +// VerifyNonMembership is a generic proof verification method which verifies the absence of a given CommitmentPath at a specified height. +// The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24). +VerifyNonMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path Path, +) error +``` + +Both are expected to be provided with a standardised key path, `exported.Path`, as defined in [ICS-24 host requirements](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements). Membership verification requires callers to provide the value marshalled as `[]byte`. Delay period values should be zero for non-packet processing verification. A zero proof height is now allowed by core IBC and may be passed into `VerifyMembership` and `VerifyNonMembership`. Light clients are responsible for returning an error if a zero proof height is invalid behaviour. + +Please refer to the [ICS-23 implementation](https://github.com/cosmos/ibc-go/blob/e093d85b533ab3572b32a7de60b88a0816bed4af/modules/core/23-commitment/types/merkle.go#L131-L205) for a concrete example. diff --git a/docs/ibc/light-clients/proposals.md b/docs/ibc/light-clients/proposals.md new file mode 100644 index 00000000000..c2a0a57adef --- /dev/null +++ b/docs/ibc/light-clients/proposals.md @@ -0,0 +1,32 @@ + + +# Handling proposals + +It is possible to update the client with the state of the substitute client through a governance proposal. [This type of governance proposal](https://ibc.cosmos.network/main/ibc/proposals.html) is typically used to recover an expired or frozen client, as it can recover the entire state and therefore all existing channels built on top of the client. `CheckSubstituteAndUpdateState` should be implemented to handle the proposal. + +## Implementing `CheckSubstituteAndUpdateState` + +In the [`ClientState`interface](https://github.com/cosmos/ibc-go/blob/e650be91614ced7be687c30eb42714787a3bbc59/modules/core/exported/client.go), we find: + +```go +// CheckSubstituteAndUpdateState must verify that the provided substitute may be used to update the subject client. +// The light client must set the updated client and consensus states within the clientStore for the subject client. +CheckSubstituteAndUpdateState( + ctx sdk.Context, + cdc codec.BinaryCodec, + subjectClientStore, + substituteClientStore sdk.KVStore, + substituteClient ClientState, +) error +``` + +Prior to updating, this function must verify that: + +- the substitute client is the same type as the subject client. For a reference implementation, please see the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/proposal_handle.go#L32). +- the provided substitute may be used to update the subject client. This may mean that certain parameters must remain unaltered. For example, a [valid substitute Tendermint light client](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/proposal_handle.go#L84) must NOT change the chain ID, trust level, max clock drift, unbonding period, proof specs or upgrade path. Please note that `AllowUpdateAfterMisbehaviour` and `AllowUpdateAfterExpiry` have been deprecated (see ADR 026 for more information). + +After these checks are performed, the function must [set the updated client and consensus states](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/proposal_handle.go#L77) within the client store for the subject client. + +Please refer to the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/proposal_handle.go#L27) for reference. diff --git a/docs/ibc/light-clients/setup.md b/docs/ibc/light-clients/setup.md new file mode 100644 index 00000000000..84d5a924fff --- /dev/null +++ b/docs/ibc/light-clients/setup.md @@ -0,0 +1,129 @@ + + +# Setup + +Learn how to configure light client modules and create clients using core IBC and the `02-client` submodule. {synopsis} + +A last step to finish the development of the light client, is to implement the `AppModuleBasic` interface to allow it to be added to the chain's `app.go` alongside other light client types the chain enables. + +Finally, a succinct rundown is given of the remaining steps to make the light client operational, getting the light client type passed through governance and creating the clients. + +## Configuring a light client module + +An IBC light client module must implement the [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/main/types/module/module.go#L50) interface in order to register its concrete types against the core IBC interfaces defined in `modules/core/exported`. This is accomplished via the `RegisterInterfaces` method which provides the light client module with the opportunity to register codec types using the chain's `InterfaceRegistry`. Please refer to the [`07-tendermint` codec registration](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/codec.go#L11). + +The `AppModuleBasic` interface may also be leveraged to install custom CLI handlers for light client module users. Light client modules can safely no-op for interface methods which it does not wish to implement. + +Please refer to the [core IBC documentation](../integration.md#integrating-light-clients) for how to configure additional light client modules alongside `07-tendermint` in `app.go`. + +See below for an example of the `07-tendermint` implementation of `AppModuleBasic`. + +```go +var _ module.AppModuleBasic = AppModuleBasic{} + +// AppModuleBasic defines the basic application module used by the tendermint light client. +// Only the RegisterInterfaces function needs to be implemented. All other function perform +// a no-op. +type AppModuleBasic struct{} + +// Name returns the tendermint module name. +func (AppModuleBasic) Name() string { + return ModuleName +} + +// RegisterLegacyAminoCodec performs a no-op. The Tendermint client does not support amino. +func (AppModuleBasic) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} + +// RegisterInterfaces registers module concrete types into protobuf Any. This allows core IBC +// to unmarshal tendermint light client types. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + RegisterInterfaces(registry) +} + +// DefaultGenesis performs a no-op. Genesis is not supported for the tendermint light client. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return nil +} + +// ValidateGenesis performs a no-op. Genesis is not supported for the tendermint light cilent. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + return nil +} + +// RegisterGRPCGatewayRoutes performs a no-op. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} + +// GetTxCmd performs a no-op. Please see the 02-client cli commands. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +// GetQueryCmd performs a no-op. Please see the 02-client cli commands. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil +} +``` + +## Creating clients + +A client is created by executing a new `MsgCreateClient` transaction composed with a valid `ClientState` and initial `ConsensusState` encoded as protobuf `Any`s. +Generally, this is performed by an off-chain process known as an [IBC relayer](https://github.com/cosmos/ibc/tree/main/spec/relayer/ics-018-relayer-algorithms) however, this is not a strict requirement. + +See below for a list of IBC relayer implementations: + +- [cosmos/relayer](https://github.com/cosmos/relayer) +- [informalsystems/hermes](https://github.com/informalsystems/hermes) +- [confio/ts-relayer](https://github.com/confio/ts-relayer) + +Stateless checks are performed within the [`ValidateBasic`](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/02-client/types/msgs.go#L48) method of `MsgCreateClient`. + +```protobuf +// MsgCreateClient defines a message to create an IBC client +message MsgCreateClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // light client state + google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""]; + // consensus state associated with the client that corresponds to a given + // height. + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // signer address + string signer = 3; +} +``` + +Leveraging protobuf `Any` encoding allows core IBC to [unpack](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/keeper/msg_server.go#L28-L36) both the `ClientState` and `ConsensusState` into their respective interface types registered previously using the light client module's `RegisterInterfaces` method. + +Within the `02-client` submodule, the [`ClientState` is then initialized](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/02-client/keeper/client.go#L30-L34) with its own isolated key-value store, namespaced using a unique client identifier. + +In order to successfully create an IBC client using a new client type, it [must be supported](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/02-client/keeper/client.go#L18-L24). Light client support in IBC is gated by on-chain governance. The allow list may be updated by submitting a new governance proposal to update the `02-client` parameter `AllowedClients`. + + +See below for example: + +```shell +%s tx gov submit-proposal param-change --from= +``` + +where `proposal.json` contains: + +```json +{ + "title": "IBC Clients Param Change", + "description": "Update allowed clients", + "changes": [ + { + "subspace": "ibc", + "key": "AllowedClients", + "value": ["06-solomachine", "07-tendermint", "0x-new-client"] + } + ], + "deposit": "1000stake" +} +``` diff --git a/modules/light-clients/06-solomachine/spec/01_concepts.md b/docs/ibc/light-clients/solomachine/concepts.md similarity index 75% rename from modules/light-clients/06-solomachine/spec/01_concepts.md rename to docs/ibc/light-clients/solomachine/concepts.md index 75d31bf5340..71cd6b6c706 100644 --- a/modules/light-clients/06-solomachine/spec/01_concepts.md +++ b/docs/ibc/light-clients/solomachine/concepts.md @@ -8,32 +8,32 @@ order: 1 The `ClientState` for a solo machine light client stores the latest sequence, the frozen sequence, the latest consensus state, and client flag indicating if the client should be allowed to be updated -after a governance proposal. +after a governance proposal. -If the client is not frozen then the frozen sequence is 0. +If the client is not frozen then the frozen sequence is 0. ## Consensus State -The consensus states stores the public key, diversifier, and timestamp of the solo machine light client. +The consensus states stores the public key, diversifier, and timestamp of the solo machine light client. The diversifier is used to prevent accidental misbehaviour if the same public key is used across different chains with the same client identifier. It should be unique to the chain the light client -is used on. +is used on. ## Public Key The public key can be a single public key or a multi-signature public key. The public key type used must fulfill the tendermint public key interface (this will become the SDK public key interface in the -near future). The public key must be registered on the application codec otherwise encoding/decoding -errors will arise. The public key stored in the consensus state is represented as a protobuf `Any`. -This allows for flexibility in what other public key types can be supported in the future. - +near future). The public key must be registered on the application codec otherwise encoding/decoding +errors will arise. The public key stored in the consensus state is represented as a protobuf `Any`. +This allows for flexibility in what other public key types can be supported in the future. + ## Counterparty Verification The solo machine light client can verify counterparty client state, consensus state, connection state, -channel state, packet commitments, packet acknowledgements, packet receipt absence, +channel state, packet commitments, packet acknowledgements, packet receipt absence, and the next sequence receive. At the end of each successful verification call the light -client sequence number will be incremented. +client sequence number will be incremented. Successful verification requires the current public key to sign over the proof. @@ -50,14 +50,14 @@ For example: ```go data := &ClientStateData{ Path: []byte(path.String()), - ClientState: any, + ClientState: protoAny, } dataBz, err := cdc.Marshal(data) ``` -The helper functions `...DataBytes()` in [proof.go](../types/proof.go) handle this -functionality. +The helper functions `...DataBytes()` in [proof.go](../../../../modules/light-clients/06-solomachine/proof.go) handle this +functionality. 2. Construct the `SignBytes` and marshal it. @@ -75,8 +75,8 @@ signBytes := &SignBytes{ signBz, err := cdc.Marshal(signBytes) ``` -The helper functions `...SignBytes()` in [proof.go](../types/proof.go) handle this functionality. -The `DataType` field is used to disambiguate what type of data was signed to prevent potential +The helper functions `...SignBytes()` in [proof.go](../../../../modules/light-clients/06-solomachine/proof.go) handle this functionality. +The `DataType` field is used to disambiguate what type of data was signed to prevent potential proto encoding overlap. 3. Sign the sign bytes. Embed the signatures into either `SingleSignatureData` or `MultiSignatureData`. @@ -94,13 +94,13 @@ protoSigData := signing.SignatureDataToProto(sigData) bz, err := cdc.Marshal(protoSigData) ``` -4. Construct a `TimestampedSignatureData` and marshal it. The marshaled result can be passed in +4. Construct a `TimestampedSignatureData` and marshal it. The marshaled result can be passed in as the proof parameter to the verification functions. For example: ```go -timestampedSignatureData := &types.TimestampedSignatureData{ +timestampedSignatureData := &solomachine.TimestampedSignatureData{ SignatureData: sigData, Timestamp: solomachine.Time, } @@ -108,8 +108,8 @@ timestampedSignatureData := &types.TimestampedSignatureData{ proof, err := cdc.Marshal(timestampedSignatureData) ``` -NOTE: At the end of this process, the sequence associated with the key needs to be updated. -The sequence must be incremented each time proof is generated. +NOTE: At the end of this process, the sequence associated with the key needs to be updated. +The sequence must be incremented each time proof is generated. ## Updates By Header @@ -126,14 +126,13 @@ If the update is successful: - the diversifier is updated - the timestamp is updated - the sequence is incremented by 1 -- the new consensus state is set in the client state +- the new consensus state is set in the client state ## Updates By Proposal An update by a governance proposal will only succeed if: - the substitute provided is parseable to solo machine client state -- the `AllowUpdateAfterProposal` client parameter is set to `true` - the new consensus state public key does not equal the current consensus state public key If the update is successful: @@ -142,22 +141,24 @@ If the update is successful: - the subject consensus state is updated to the substitute consensus state - the client is unfrozen (if it was previously frozen) +NOTE: Previously, `AllowUpdateAfterProposal` was used to signal the update/recovery options for the solo machine client. However, this has now been deprecated because a code migration can overwrite the client and consensus states regardless of the value of this parameter. If governance would vote to overwrite a client or consensus state, it is likely that governance would also be willing to perform a code migration to do the same. + ## Misbehaviour Misbehaviour handling will only succeed if: - the misbehaviour provided is parseable to solo machine misbehaviour - the client is not already frozen -- the current public key signed over two unique data messages at the same sequence and diversifier. +- the current public key signed over two unique data messages at the same sequence and diversifier. If the misbehaviour is successfully processed: - the client is frozen by setting the frozen sequence to the misbehaviour sequence NOTE: Misbehaviour processing is data processing order dependent. A misbehaving solo machine -could update to a new public key to prevent being frozen before misbehaviour is submitted. +could update to a new public key to prevent being frozen before misbehaviour is submitted. ## Upgrades -Upgrades to solo machine light clients are not supported since an entirely different type of +Upgrades to solo machine light clients are not supported since an entirely different type of public key can be set using normal client updates. diff --git a/modules/light-clients/06-solomachine/spec/README.md b/docs/ibc/light-clients/solomachine/solomachine.md similarity index 83% rename from modules/light-clients/06-solomachine/spec/README.md rename to docs/ibc/light-clients/solomachine/solomachine.md index 0879f1bd2be..bd9e852a2e6 100644 --- a/modules/light-clients/06-solomachine/spec/README.md +++ b/docs/ibc/light-clients/solomachine/solomachine.md @@ -16,10 +16,10 @@ This implementation of a solo machine light client supports single and multi-sig keys. The client is capable of handling public key updates by header and governance proposals. The light client is capable of processing client misbehaviour. Proofs of the counterparty state are generated by the solo machine client by signing over the desired state with a certain sequence, -diversifier, and timestamp. +diversifier, and timestamp. ## Contents -1. **[Concepts](01_concepts.md)** -2. **[State](02_state.md)** -3. **[State Transitions](03_state_transitions.md)** +1. **[Concepts](./concepts.md)** +2. **[State](./state.md)** +3. **[State Transitions](./state_transitions.md)** diff --git a/modules/light-clients/06-solomachine/spec/02_state.md b/docs/ibc/light-clients/solomachine/state.md similarity index 99% rename from modules/light-clients/06-solomachine/spec/02_state.md rename to docs/ibc/light-clients/solomachine/state.md index 51cb1f058c6..a4b9f87cf8c 100644 --- a/modules/light-clients/06-solomachine/spec/02_state.md +++ b/docs/ibc/light-clients/solomachine/state.md @@ -6,4 +6,3 @@ order: 2 The solo machine light client will only store consensus states for each update by a header or a governance proposal. The latest client state is also maintained in the store. - diff --git a/modules/light-clients/06-solomachine/spec/03_state_transitions.md b/docs/ibc/light-clients/solomachine/state_transitions.md similarity index 98% rename from modules/light-clients/06-solomachine/spec/03_state_transitions.md rename to docs/ibc/light-clients/solomachine/state_transitions.md index 48a1e18f1c9..387111a572c 100644 --- a/modules/light-clients/06-solomachine/spec/03_state_transitions.md +++ b/docs/ibc/light-clients/solomachine/state_transitions.md @@ -14,7 +14,7 @@ Successful state verification by a solo machine light client will result in: A successful update of a solo machine light client by a header will result in: -- the public key being updated to the new public key provided by the header. +- the public key being updated to the new public key provided by the header. - the diversifier being updated to the new diviersifier provided by the header. - the timestamp being updated to the new timestamp provided by the header. - the sequence being incremented by 1 diff --git a/docs/ibc/light-clients/updates-and-misbehaviour.md b/docs/ibc/light-clients/updates-and-misbehaviour.md new file mode 100644 index 00000000000..35e5cd43d4c --- /dev/null +++ b/docs/ibc/light-clients/updates-and-misbehaviour.md @@ -0,0 +1,95 @@ + + +# Handling `ClientMessage`s: updates and misbehaviour + +As mentioned before in the documentation about [implementing the `ConsensusState` interface](./consensus-state.md), [`ClientMessage`](https://github.com/cosmos/ibc-go/blob/main/modules/core/exported/client.go#L145) is an interface used to update an IBC client. This update may be performed by: + ++ a single header ++ a batch of headers ++ evidence of misbehaviour, ++ or any type which when verified produces a change to the consensus state of the IBC client. + +This interface has been purposefully kept generic in order to give the maximum amount of flexibility to the light client implementer. + +## Implementing the `ClientMessage` interface + +Find the `ClientMessage`interface in `modules/core/exported`: + +```go +type ClientMessage interface { + proto.Message + + ClientType() string + ValidateBasic() error +} +``` + +The `ClientMessage` will be passed to the client to be used in [`UpdateClient`](https://github.com/cosmos/ibc-go/blob/57da75a70145409247e85365b64a4b2fc6ddad2f/modules/core/02-client/keeper/client.go#L53), which retrieves the `ClientState` by client ID (available in `MsgUpdateClient`). This `ClientState` implements the [`ClientState` interface](./client-state.md) for its specific consenus type (e.g. Tendermint). + +`UpdateClient` will then handle a number of cases including misbehaviour and/or updating the consensus state, utilizing the specific methods defined in the relevant `ClientState`. + +```go +VerifyClientMessage(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) error +CheckForMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) bool +UpdateStateOnMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) +UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) []Height +``` + +## Handling updates and misbehaviour + +The functions for handling updates to a light client and evidence of misbehaviour are all found in the [`ClientState`](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/exported/client.go#L40) interface, and will be discussed below. + +> It is important to note that `Misbehaviour` in this particular context is referring to misbehaviour on the chain level intended to fool the light client. This will be defined by each light client. + +## `VerifyClientMessage` + +`VerifyClientMessage` must verify a `ClientMessage`. A `ClientMessage` could be a `Header`, `Misbehaviour`, or batch update. To understand how to implement a `ClientMessage`, please refer to the [Implementing the `ClientMessage` interface](#implementing-the-clientmessage-interface) section. + +It must handle each type of `ClientMessage` appropriately. Calls to `CheckForMisbehaviour`, `UpdateState`, and `UpdateStateOnMisbehaviour` will assume that the content of the `ClientMessage` has been verified and can be trusted. An error should be returned if the `ClientMessage` fails to verify. + +For an example of a `VerifyClientMessage` implementation, please check the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/update.go#L20). + +## `CheckForMisbehaviour` + +Checks for evidence of a misbehaviour in `Header` or `Misbehaviour` type. It assumes the `ClientMessage` has already been verified. + +For an example of a `CheckForMisbehaviour` implementation, please check the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/misbehaviour_handle.go#L18). + +> The Tendermint light client [defines `Misbehaviour`](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/misbehaviour.go) as two different types of situations: a situation where two conflicting `Header`s with the same height have been submitted to update a client's `ConsensusState` within the same trusting period, or that the two conflicting `Header`s have been submitted at different heights but the consensus states are not in the correct monotonic time ordering (BFT time violation). More explicitly, updating to a new height must have a timestamp greater than the previous consensus state, or, if inserting a consensus at a past height, then time must be less than those heights which come after and greater than heights which come before. + +## `UpdateStateOnMisbehaviour` + +`UpdateStateOnMisbehaviour` should perform appropriate state changes on a client state given that misbehaviour has been detected and verified. This method should only be called when misbehaviour is detected, as it does not perform any misbehaviour checks. Notably, it should freeze the client so that calling the `Status` function on the associated client state no longer returns `Active`. + +For an example of a `UpdateStateOnMisbehaviour` implementation, please check the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/update.go#L197). + +## `UpdateState` + +`UpdateState` updates and stores as necessary any associated information for an IBC client, such as the `ClientState` and corresponding `ConsensusState`. It should perform a no-op on duplicate updates. + +It assumes the `ClientMessage` has already been verified. + +For an example of a `UpdateState` implementation, please check the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/update.go#L131). + +## Putting it all together + +The `02-client` `Keeper` module in ibc-go offers a reference as to how these functions will be used to [update the client](https://github.com/cosmos/ibc-go/blob/main/modules/core/02-client/keeper/client.go#L48). + +```go +if err := clientState.VerifyClientMessage(clientMessage); err != nil { + return err +} + +foundMisbehaviour := clientState.CheckForMisbehaviour(clientMessage) +if foundMisbehaviour { + clientState.UpdateStateOnMisbehaviour(clientMessage) + // emit misbehaviour event + return +} + +clientState.UpdateState(clientMessage) // expects no-op on duplicate header + // emit update event + return +} diff --git a/docs/ibc/light-clients/upgrades.md b/docs/ibc/light-clients/upgrades.md new file mode 100644 index 00000000000..dc1553bf0c4 --- /dev/null +++ b/docs/ibc/light-clients/upgrades.md @@ -0,0 +1,62 @@ + + +# Handling upgrades + +It is vital that high-value IBC clients can upgrade along with their underlying chains to avoid disruption to the IBC ecosystem. Thus, IBC client developers will want to implement upgrade functionality to enable clients to maintain connections and channels even across chain upgrades. + +## Implementing `VerifyUpgradeAndUpdateState` + +The IBC protocol allows client implementations to provide a path to upgrading clients given the upgraded `ClientState`, upgraded `ConsensusState` and proofs for each. This path is provided in the `VerifyUpgradeAndUpdateState` method: + +```go +// NOTE: proof heights are not included as upgrade to a new revision is expected to pass only on the last height committed by the current revision. Clients are responsible for ensuring that the planned last height of the current revision is somehow encoded in the proof verification process. +// This is to ensure that no premature upgrades occur, since upgrade plans committed to by the counterparty may be cancelled or modified before the last planned height. +// If the upgrade is verified, the upgraded client and consensus states must be set in the client store. +func (cs ClientState) VerifyUpgradeAndUpdateState( + ctx sdk.Context, + cdc codec.BinaryCodec, + store sdk.KVStore, + newClient ClientState, + newConsState ConsensusState, + proofUpgradeClient, + proofUpgradeConsState []byte, +) error +``` + +> Please refer to the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/upgrade.go#L27) as an example for implementation. + +It is important to note that light clients **must** handle all management of client and consensus states including the setting of updated `ClientState` and `ConsensusState` in the client store. This can include verifying that the submitted upgraded `ClientState` is of a valid `ClientState` type, that the height of the upgraded client is not greater than the height of the current client (in order to preserve BFT monotonic time), or that certain parameters which should not be changed have not been altered in the upgraded `ClientState`. + +Developers must ensure that the `MsgUpgradeClient` does not pass until the last height of the old chain has been committed, and after the chain upgrades, the `MsgUpgradeClient` should pass once and only once on all counterparty clients. + +### Upgrade path + +Clients should have **prior knowledge of the merkle path** that the upgraded client and upgraded consensus states will use. The height at which the upgrade has occurred should also be encoded in the proof. +> The Tendermint client implementation accomplishes this by including an `UpgradePath` in the `ClientState` itself, which is used along with the upgrade height to construct the merkle path under which the client state and consensus state are committed. + +## Chain specific vs client specific client parameters + +Developers should maintain the distinction between client parameters that are uniform across every valid light client of a chain (chain-chosen parameters), and client parameters that are customizable by each individual client (client-chosen parameters); since this distinction is necessary to implement the `ZeroCustomFields` method in the [`ClientState` interface](./client-state.md): + +```go +// Utility function that zeroes out any client customizable fields in client state +// Ledger enforced fields are maintained while all custom fields are zero values +// Used to verify upgrades +func (cs ClientState) ZeroCustomFields() ClientState +``` + +Developers must ensure that the new client adopts all of the new client parameters that must be uniform across every valid light client of a chain (chain-chosen parameters), while maintaining the client parameters that are customizable by each individual client (client-chosen parameters) from the previous version of the client. `ZeroCustomFields` is a useful utility function to ensure only chain specific fields are updated during upgrades. + +## Security + +Upgrades must adhere to the IBC Security Model. IBC does not rely on the assumption of honest relayers for correctness. Thus users should not have to rely on relayers to maintain client correctness and security (though honest relayers must exist to maintain relayer liveness). While relayers may choose any set of client parameters while creating a new `ClientState`, this still holds under the security model since users can always choose a relayer-created client that suits their security and correctness needs or create a client with their desired parameters if no such client exists. + +However, when upgrading an existing client, one must keep in mind that there are already many users who depend on this client's particular parameters. **We cannot give the upgrading relayer free choice over these parameters once they have already been chosen. This would violate the security model** since users who rely on the client would have to rely on the upgrading relayer to maintain the same level of security. + +Thus, developers must make sure that their upgrade mechanism allows clients to upgrade the chain-specified parameters whenever a chain upgrade changes these parameters (examples in the Tendermint client include `UnbondingPeriod`, `TrustingPeriod`, `ChainID`, `UpgradePath`, etc), while ensuring that the relayer submitting the `MsgUpgradeClient` cannot alter the client-chosen parameters that the users are relying upon (examples in Tendermint client include `TrustLevel`, `MaxClockDrift`, etc). The previous paragraph discusses how `ZeroCustomFields` helps achieve this. + +### Document potential client parameter conflicts during upgrades + +Counterparty clients can upgrade securely by using all of the chain-chosen parameters from the chain-committed `UpgradedClient` and preserving all of the old client-chosen parameters. This enables chains to securely upgrade without relying on an honest relayer, however it can in some cases lead to an invalid final `ClientState` if the new chain-chosen parameters clash with the old client-chosen parameter. This can happen in the Tendermint client case if the upgrading chain lowers the `UnbondingPeriod` (chain-chosen) to a duration below that of a counterparty client's `TrustingPeriod` (client-chosen). Such cases should be clearly documented by developers, so that chains know which upgrades should be avoided to prevent this problem. The final upgraded client should also be validated in `VerifyUpgradeAndUpdateState` before returning to ensure that the client does not upgrade to an invalid `ClientState`. diff --git a/docs/ibc/middleware/develop.md b/docs/ibc/middleware/develop.md index 3c0c74a0186..96748c7acf0 100644 --- a/docs/ibc/middleware/develop.md +++ b/docs/ibc/middleware/develop.md @@ -32,13 +32,13 @@ Middleware allows developers to define the extensions as separate modules that c IBC middleware will wrap over an underlying IBC application and sits between core IBC and the application. It has complete control in modifying any message coming from IBC to the application, and any message coming from the application to core IBC. Thus, middleware must be completely trusted by chain developers who wish to integrate them, however this gives them complete flexibility in modifying the application(s) they wrap. -#### Interfaces +### Interfaces ```go // Middleware implements the ICS26 Module interface type Middleware interface { - porttypes.IBCModule // middleware has acccess to an underlying application which may be wrapped by more middleware - ics4Wrapper: ICS4Wrapper // middleware has access to ICS4Wrapper which may be core IBC Channel Handler or a higher-level middleware that wraps this middleware. + porttypes.IBCModule // middleware has acccess to an underlying application which may be wrapped by more middleware + ics4Wrapper: ICS4Wrapper // middleware has access to ICS4Wrapper which may be core IBC Channel Handler or a higher-level middleware that wraps this middleware. } ``` @@ -47,9 +47,28 @@ type Middleware interface { // The base application will call `sendPacket` or `writeAcknowledgement` of the middleware directly above them // which will call the next middleware until it reaches the core IBC handler. type ICS4Wrapper interface { - SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet exported.Packet) error - WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet exported.Packet, ack exported.Acknowledgement) error - GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) + SendPacket( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, + ) (sequence uint64, err error) + + WriteAcknowledgement( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + packet exported.PacketI, + ack exported.Acknowledgement, + ) error + + GetAppVersion( + ctx sdk.Context, + portID, + channelID string, + ) (string, bool) } ``` @@ -84,65 +103,65 @@ In the case where the middleware wishes to send a packet or acknowledgment witho ```go func (im IBCModule) OnChanOpenInit( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, ) (string, error) { - if version != "" { - // try to unmarshal JSON-encoded version string and pass - // the app-specific version to app callback. - // otherwise, pass version directly to app callback. - metadata, err := Unmarshal(version) - if err != nil { - // Since it is valid for fee version to not be specified, - // the above middleware version may be for another middleware. - // Pass the entire version string onto the underlying application. - return im.app.OnChanOpenInit( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - version, - ) - } - else { - metadata = { - // set middleware version to default value - MiddlewareVersion: defaultMiddlewareVersion, - // allow application to return its default version - AppVersion: "", - } - } - - doCustomLogic() - - // if the version string is empty, OnChanOpenInit is expected to return - // a default version string representing the version(s) it supports - appVersion, err := im.app.OnChanOpenInit( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - metadata.AppVersion, // note we only pass app version here - ) + if version != "" { + // try to unmarshal JSON-encoded version string and pass + // the app-specific version to app callback. + // otherwise, pass version directly to app callback. + metadata, err := Unmarshal(version) if err != nil { - return "", err + // Since it is valid for fee version to not be specified, + // the above middleware version may be for another middleware. + // Pass the entire version string onto the underlying application. + return im.app.OnChanOpenInit( + ctx, + order, + connectionHops, + portID, + channelID, + channelCap, + counterparty, + version, + ) + } + else { + metadata = { + // set middleware version to default value + MiddlewareVersion: defaultMiddlewareVersion, + // allow application to return its default version + AppVersion: "", } + } - version := constructVersion(metadata.MiddlewareVersion, appVersion) + doCustomLogic() - return version, nil + // if the version string is empty, OnChanOpenInit is expected to return + // a default version string representing the version(s) it supports + appVersion, err := im.app.OnChanOpenInit( + ctx, + order, + connectionHops, + portID, + channelID, + channelCap, + counterparty, + metadata.AppVersion, // note we only pass app version here + ) + if err != nil { + return "", err + } + + version := constructVersion(metadata.MiddlewareVersion, appVersion) + + return version, nil } ``` @@ -152,55 +171,55 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go func OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, ) (string, error) { - // try to unmarshal JSON-encoded version string and pass - // the app-specific version to app callback. - // otherwise, pass version directly to app callback. - cpMetadata, err := Unmarshal(counterpartyVersion) - if err != nil { - return app.OnChanOpenTry( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - counterpartyVersion, - ) - } - - doCustomLogic() - - // Call the underlying application's OnChanOpenTry callback. - // The try callback must select the final app-specific version string and return it. - appVersion, err := app.OnChanOpenTry( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - cpMetadata.AppVersion, // note we only pass counterparty app version here + // try to unmarshal JSON-encoded version string and pass + // the app-specific version to app callback. + // otherwise, pass version directly to app callback. + cpMetadata, err := Unmarshal(counterpartyVersion) + if err != nil { + return app.OnChanOpenTry( + ctx, + order, + connectionHops, + portID, + channelID, + channelCap, + counterparty, + counterpartyVersion, ) - if err != nil { - return "", err - } + } - // negotiate final middleware version - middlewareVersion := negotiateMiddlewareVersion(cpMetadata.MiddlewareVersion) - version := constructVersion(middlewareVersion, appVersion) + doCustomLogic() - return version, nil + // Call the underlying application's OnChanOpenTry callback. + // The try callback must select the final app-specific version string and return it. + appVersion, err := app.OnChanOpenTry( + ctx, + order, + connectionHops, + portID, + channelID, + channelCap, + counterparty, + cpMetadata.AppVersion, // note we only pass counterparty app version here + ) + if err != nil { + return "", err + } + + // negotiate final middleware version + middlewareVersion := negotiateMiddlewareVersion(cpMetadata.MiddlewareVersion) + version := constructVersion(middlewareVersion, appVersion) + + return version, nil } ``` @@ -210,27 +229,27 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go func OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyChannelID string, - counterpartyVersion string, + ctx sdk.Context, + portID, + channelID string, + counterpartyChannelID string, + counterpartyVersion string, ) error { - // try to unmarshal JSON-encoded version string and pass - // the app-specific version to app callback. - // otherwise, pass version directly to app callback. - cpMetadata, err = UnmarshalJSON(counterpartyVersion) - if err != nil { - return app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) - } - - if !isCompatible(cpMetadata.MiddlewareVersion) { - return error - } - doCustomLogic() - - // call the underlying application's OnChanOpenTry callback - return app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, cpMetadata.AppVersion) + // try to unmarshal JSON-encoded version string and pass + // the app-specific version to app callback. + // otherwise, pass version directly to app callback. + cpMetadata, err = UnmarshalJSON(counterpartyVersion) + if err != nil { + return app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) + } + + if !isCompatible(cpMetadata.MiddlewareVersion) { + return error + } + doCustomLogic() + + // call the underlying application's OnChanOpenTry callback + return app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, cpMetadata.AppVersion) } ``` @@ -240,13 +259,13 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go func OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - doCustomLogic() + doCustomLogic() - return app.OnChanOpenConfirm(ctx, portID, channelID) + return app.OnChanOpenConfirm(ctx, portID, channelID) } ``` @@ -256,13 +275,13 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go func OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - doCustomLogic() + doCustomLogic() - return app.OnChanCloseInit(ctx, portID, channelID) + return app.OnChanCloseInit(ctx, portID, channelID) } ``` @@ -272,13 +291,13 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go func OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) error { - doCustomLogic() + doCustomLogic() - return app.OnChanCloseConfirm(ctx, portID, channelID) + return app.OnChanCloseConfirm(ctx, portID, channelID) } ``` @@ -294,16 +313,16 @@ The packet callbacks just like the handshake callbacks wrap the application's pa ```go func OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, ) ibcexported.Acknowledgement { - doCustomLogic(packet) + doCustomLogic(packet) - ack := app.OnRecvPacket(ctx, packet, relayer) + ack := app.OnRecvPacket(ctx, packet, relayer) - doCustomLogic(ack) // middleware may modify outgoing ack - return ack + doCustomLogic(ack) // middleware may modify outgoing ack + return ack } ``` @@ -313,14 +332,14 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go func OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, - relayer sdk.AccAddress, + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, ) error { - doCustomLogic(packet, ack) + doCustomLogic(packet, ack) - return app.OnAcknowledgementPacket(ctx, packet, ack, relayer) + return app.OnAcknowledgementPacket(ctx, packet, ack, relayer) } ``` @@ -330,13 +349,13 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go func OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, ) error { - doCustomLogic(packet) + doCustomLogic(packet) - return app.OnTimeoutPacket(ctx, packet, relayer) + return app.OnTimeoutPacket(ctx, packet, relayer) } ``` @@ -350,14 +369,26 @@ Middleware must also wrap ICS-4 so that any communication from the application t ```go func SendPacket( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - appPacket exported.PacketI, + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + appData []byte, ) { - // middleware may modify packet - packet = doCustomLogic(appPacket) - - return ics4Keeper.SendPacket(ctx, chanCap, packet) + // middleware may modify data + data = doCustomLogic(appData) + + return ics4Keeper.SendPacket( + ctx, + chanCap, + sourcePort, + sourceChannel, + timeoutHeight, + timeoutTimestamp, + data, + ) } ``` @@ -368,15 +399,15 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go // only called for async acks func WriteAcknowledgement( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - packet exported.PacketI, - ack exported.Acknowledgement, + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + packet exported.PacketI, + ack exported.Acknowledgement, ) { - // middleware may modify acknowledgement - ack_bytes = doCustomLogic(ack) + // middleware may modify acknowledgement + ack_bytes = doCustomLogic(ack) - return ics4Keeper.WriteAcknowledgement(packet, ack_bytes) + return ics4Keeper.WriteAcknowledgement(packet, ack_bytes) } ``` @@ -387,26 +418,46 @@ See [here](https://github.com/cosmos/ibc-go/blob/48a6ae512b4ea42c29fdf6c6f5363f5 ```go // middleware must return the underlying application version func GetAppVersion( - ctx sdk.Context, - portID, - channelID string, + ctx sdk.Context, + portID, + channelID string, ) (string, bool) { - version, found := ics4Keeper.GetAppVersion(ctx, portID, channelID) - if !found { - return "", false - } + version, found := ics4Keeper.GetAppVersion(ctx, portID, channelID) + if !found { + return "", false + } + + if !MiddlewareEnabled { + return version, true + } + + // unwrap channel version + metadata, err := Unmarshal(version) + if err != nil { + panic(fmt.Errof("unable to unmarshal version: %w", err)) + } + + return metadata.AppVersion, true +} - if !MiddlewareEnabled { - return version, true - } +// middleware must return the underlying application version +func GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { + version, found := ics4Keeper.GetAppVersion(ctx, portID, channelID) + if !found { + return "", false + } - // unwrap channel version - metadata, err := Unmarshal(version) - if err != nil { - panic(fmt.Errof("unable to unmarshal version: %w", err)) - } + if !MiddlewareEnabled { + return version, true + } + + // unwrap channel version + metadata, err := Unmarshal(version) + if err != nil { + panic(fmt.Errof("unable to unmarshal version: %w", err)) + } - return metadata.AppVersion, true + return metadata.AppVersion, true } ``` diff --git a/docs/ibc/middleware/integration.md b/docs/ibc/middleware/integration.md index 12eb447f8ea..3da9fb78b5f 100644 --- a/docs/ibc/middleware/integration.md +++ b/docs/ibc/middleware/integration.md @@ -12,7 +12,7 @@ All middleware must be connected to the IBC router and wrap over an underlying b The order of middleware **matters**, function calls from IBC to the application travel from top-level middleware to the bottom middleware and then to the application. Function calls from the application to IBC goes through the bottom middleware in order to the top middleware and then to core IBC handlers. Thus the same set of middleware put in different orders may produce different effects. -### Example integration +## Example integration ```go // app.go @@ -25,11 +25,11 @@ mw3Keeper := mw3.NewKeeper(storeKey3) // Only create App Module **once** and register in app module // if the module maintains independent state and/or processes sdk.Msgs app.moduleManager = module.NewManager( - ... - mw1.NewAppModule(mw1Keeper), - mw3.NewAppModule(mw3Keeper), - transfer.NewAppModule(transferKeeper), - custom.NewAppModule(customKeeper) + ... + mw1.NewAppModule(mw1Keeper), + mw3.NewAppModule(mw3Keeper), + transfer.NewAppModule(transferKeeper), + custom.NewAppModule(customKeeper) ) mw1IBCModule := mw1.NewIBCModule(mw1Keeper) @@ -66,4 +66,3 @@ ibcRouter.AddRoute("custom1", stack2) ibcRouter.AddRoute("custom2", stack3) app.IBCKeeper.SetRouter(ibcRouter) ``` - diff --git a/docs/ibc/overview.md b/docs/ibc/overview.md index f36b366a5e0..1b1b5213a36 100644 --- a/docs/ibc/overview.md +++ b/docs/ibc/overview.md @@ -13,17 +13,17 @@ Learn about IBC, its components, and IBC use cases. {synopsis} This document serves as a guide for developers who want to write their own Inter-Blockchain Communication protocol (IBC) applications for custom use cases. -> IBC applications must be written as self-contained modules. +> IBC applications must be written as self-contained modules. Due to the modular design of the IBC protocol, IBC application developers do not need to be concerned with the low-level details of clients, -connections, and proof verification. +connections, and proof verification. This brief explanation of the lower levels of the stack gives application developers a broad understanding of the IBC protocol. Abstraction layer details for channels and ports are most relevant for application developers and describe how to define custom packets and `IBCModule` callbacks. -The requirements to have your module interact over IBC are: +The requirements to have your module interact over IBC are: - Bind to a port or ports. - Define your packet data. @@ -37,25 +37,25 @@ Read on for a detailed explanation of how to write a self-contained IBC applicat ### [Clients](https://github.com/cosmos/ibc-go/blob/main/modules/core/02-client) -IBC clients are on-chain light clients. Each light client is identified by a unique client-id. -IBC clients track the consensus states of other blockchains, along with the proof spec necessary to -properly verify proofs against the client's consensus state. A client can be associated with any number -of connections to the counterparty chain. The client identifier is auto generated using the client type -and the global client counter appended in the format: `{client-type}-{N}`. +IBC clients are on-chain light clients. Each light client is identified by a unique client-id. +IBC clients track the consensus states of other blockchains, along with the proof spec necessary to +properly verify proofs against the client's consensus state. A client can be associated with any number +of connections to the counterparty chain. The client identifier is auto generated using the client type +and the global client counter appended in the format: `{client-type}-{N}`. A `ClientState` should contain chain specific and light client specific information necessary for verifying updates -and upgrades to the IBC client. The `ClientState` may contain information such as chain-id, latest height, proof specs, +and upgrades to the IBC client. The `ClientState` may contain information such as chain-id, latest height, proof specs, unbonding periods or the status of the light client. The `ClientState` should not contain information that is specific to a given block at a certain height, this is the function of the `ConsensusState`. Each `ConsensusState` -should be associated with a unique block and should be referenced using a height. IBC clients are given a -client identifier prefixed store to store their associated client state and consensus states along with -any metadata associated with the consensus states. Consensus states are stored using their associated height. +should be associated with a unique block and should be referenced using a height. IBC clients are given a +client identifier prefixed store to store their associated client state and consensus states along with +any metadata associated with the consensus states. Consensus states are stored using their associated height. The supported IBC clients are: -* [Solo Machine light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/06-solomachine): Devices such as phones, browsers, or laptops. -* [Tendermint light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint): The default for Cosmos SDK-based chains. -* [Localhost (loopback) client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/09-localhost): Useful for +- [Solo Machine light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/06-solomachine): Devices such as phones, browsers, or laptops. +- [Tendermint light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint): The default for Cosmos SDK-based chains. +- [Localhost (loopback) client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/09-localhost): Useful for testing, simulation, and relaying packets to modules on the same application. ### IBC Client Heights @@ -64,8 +64,8 @@ IBC Client Heights are represented by the struct: ```go type Height struct { - RevisionNumber uint64 - RevisionHeight uint64 + RevisionNumber uint64 + RevisionHeight uint64 } ``` @@ -90,7 +90,7 @@ Height{RevisionNumber: 3, RevisionHeight: 0} > Height{RevisionNumber: 2, Revisio ``` When a Tendermint chain is running a particular revision, relayers can simply submit headers and proofs with the revision number -given by the chain's `chainID`, and the revision height given by the Tendermint block height. When a chain updates using a hard-fork +given by the chain's `chainID`, and the revision height given by the Tendermint block height. When a chain updates using a hard-fork and resets its block-height, it is responsible for updating its `chainID` to increment the revision number. IBC Tendermint clients then verifies the revision number against their `chainID` and treat the `RevisionHeight` as the Tendermint block-height. @@ -128,19 +128,19 @@ communicate, a blockchain commits some state to a specifically defined path that specific message type and a specific counterparty. For example, for storing a specific connectionEnd as part of a handshake or a packet intended to be relayed to a module on the counterparty chain. A relayer process monitors for updates to these paths and relays messages by submitting the data stored -under the path and a proof to the counterparty chain. +under the path and a proof to the counterparty chain. Proofs are passed from core IBC to light-clients as bytes. It is up to light client implementation to interpret these bytes appropriately. - The paths that all IBC implementations must use for committing IBC messages is defined in -[ICS-24 Host State Machine Requirements](https://github.com/cosmos/ics/tree/master/spec/core/ics-024-host-requirements). -- The proof format that all implementations must be able to produce and verify is defined in [ICS-23 Proofs](https://github.com/confio/ics23) implementation. +[ICS-24 Host State Machine Requirements](https://github.com/cosmos/ics/tree/master/spec/core/ics-024-host-requirements). +- The proof format that all implementations must be able to produce and verify is defined in [ICS-23 Proofs](https://github.com/cosmos/ics23) implementation. -### [Capabilities](https://github.com/cosmos/cosmos-sdk/blob/master/docs/core/ocap.md) +### [Capabilities](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/core/10-ocap.md) IBC is intended to work in execution environments where modules do not necessarily trust each other. Thus, IBC must authenticate module actions on ports and channels so that only modules with the -appropriate permissions can use them. +appropriate permissions can use them. This module authentication is accomplished using a [dynamic capability store](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-003-dynamic-capability-store.md). Upon binding to a port or @@ -150,11 +150,11 @@ they do not own the appropriate capability. While this background information is useful, IBC modules do not need to interact at all with these lower-level abstractions. The relevant abstraction layer for IBC application developers is -that of channels and ports. IBC applications must be written as self-contained **modules**. +that of channels and ports. IBC applications must be written as self-contained **modules**. A module on one blockchain can communicate with other modules on other blockchains by sending, receiving, and acknowledging packets through channels that are uniquely identified by the -`(channelID, portID)` tuple. +`(channelID, portID)` tuple. A useful analogy is to consider IBC modules as internet applications on a computer. A channel can then be conceptualized as an IP connection, with the IBC portID being @@ -203,7 +203,7 @@ If all handshake steps are successful, the channel is opened on both sides. At e associated with the `ChannelEnd` executes its callback. So on `ChanOpenInit`, the module on chain A executes its callback `OnChanOpenInit`. -The channel identifier is auto derived in the format: `channel-{N}` where N is the next sequence to be used. +The channel identifier is auto derived in the format: `channel-{N}` where N is the next sequence to be used. Just as ports came with dynamic capabilities, channel initialization returns a dynamic capability that the module **must** claim so that they can pass in a capability to authenticate channel actions @@ -214,24 +214,23 @@ handshake; either `OnChanOpenInit` on the initializing chain or `OnChanOpenTry` Closing a channel occurs in 2 handshake steps as defined in [ICS 04](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics). -`ChanCloseInit` closes a channel on the executing chain if the channel exists, it is not -already closed and the connection it exists upon is OPEN. Channels can only be closed by a +`ChanCloseInit` closes a channel on the executing chain if the channel exists, it is not +already closed and the connection it exists upon is OPEN. Channels can only be closed by a calling module or in the case of a packet timeout on an ORDERED channel. `ChanCloseConfirm` is a response to a counterparty channel executing `ChanCloseInit`. The channel -on the executing chain closes if the channel exists, the channel is not already closed, +on the executing chain closes if the channel exists, the channel is not already closed, the connection the channel exists upon is OPEN and the executing chain successfully verifies that the counterparty channel has been closed. - ### [Packets](https://github.com/cosmos/ibc-go/blob/main/modules/core/04-channel) Modules communicate with each other by sending packets over IBC channels. All IBC packets contain the destination `portID` and `channelID` along with the source `portID` and -`channelID`. This packet structure allows modules to know the sender module of a given packet. IBC packets -contain a sequence to optionally enforce ordering. +`channelID`. This packet structure allows modules to know the sender module of a given packet. IBC packets +contain a sequence to optionally enforce ordering. -IBC packets also contain a `TimeoutHeight` and a `TimeoutTimestamp` that determine the deadline before the receiving module must process a packet. +IBC packets also contain a `TimeoutHeight` and a `TimeoutTimestamp` that determine the deadline before the receiving module must process a packet. Modules send custom application data to each other inside the `Data []byte` field of the IBC packet. Thus, packet data is opaque to IBC handlers. It is incumbent on a sender module to encode @@ -240,8 +239,8 @@ module must decode that `Data` back to the original application data. ### [Receipts and Timeouts](https://github.com/cosmos/ibc-go/blob/main/modules/core/04-channel) -Since IBC works over a distributed network and relies on potentially faulty relayers to relay messages between ledgers, -IBC must handle the case where a packet does not get sent to its destination in a timely manner or at all. Packets must +Since IBC works over a distributed network and relies on potentially faulty relayers to relay messages between ledgers, +IBC must handle the case where a packet does not get sent to its destination in a timely manner or at all. Packets must specify a non-zero value for timeout height (`TimeoutHeight`) or timeout timestamp (`TimeoutTimestamp` ) after which a packet can no longer be successfully received on the destination chain. - The `timeoutHeight` indicates a consensus height on the destination chain after which the packet is no longer be processed, and instead counts as having timed-out. @@ -250,21 +249,21 @@ specify a non-zero value for timeout height (`TimeoutHeight`) or timeout timesta If the timeout passes without the packet being successfully received, the packet can no longer be received on the destination chain. The sending module can timeout the packet and take appropriate actions. -If the timeout is reached, then a proof of packet timeout can be submitted to the original chain. The original chain can then perform +If the timeout is reached, then a proof of packet timeout can be submitted to the original chain. The original chain can then perform application-specific logic to timeout the packet, perhaps by rolling back the packet send changes (refunding senders any locked funds, etc.). -- In ORDERED channels, a timeout of a single packet in the channel causes the channel to close. +- In ORDERED channels, a timeout of a single packet in the channel causes the channel to close. - - If packet sequence `n` times out, then a packet at sequence `k > n` cannot be received without violating the contract of ORDERED channels that packets are processed in the order that they are sent. - - Since ORDERED channels enforce this invariant, a proof that sequence `n` has not been received on the destination chain by the specified timeout of packet `n` is sufficient to timeout packet `n` and close the channel. + - If packet sequence `n` times out, then a packet at sequence `k > n` cannot be received without violating the contract of ORDERED channels that packets are processed in the order that they are sent. + - Since ORDERED channels enforce this invariant, a proof that sequence `n` has not been received on the destination chain by the specified timeout of packet `n` is sufficient to timeout packet `n` and close the channel. - In UNORDERED channels, the application-specific timeout logic for that packet is applied and the channel is not closed. - - Packets can be received in any order. + - Packets can be received in any order. - - IBC writes a packet receipt for each sequence receives in the UNORDERED channel. This receipt does not contain information; it is simply a marker intended to signify that the UNORDERED channel has received a packet at the specified sequence. + - IBC writes a packet receipt for each sequence receives in the UNORDERED channel. This receipt does not contain information; it is simply a marker intended to signify that the UNORDERED channel has received a packet at the specified sequence. - - To timeout a packet on an UNORDERED channel, a proof is required that a packet receipt **does not exist** for the packet's sequence by the specified timeout. + - To timeout a packet on an UNORDERED channel, a proof is required that a packet receipt **does not exist** for the packet's sequence by the specified timeout. For this reason, most modules should use UNORDERED channels as they require fewer liveness guarantees to function effectively for users of that channel. @@ -272,16 +271,16 @@ For this reason, most modules should use UNORDERED channels as they require fewe Modules can also choose to write application-specific acknowledgments upon processing a packet. Acknowledgments can be done: -- Synchronously on `OnRecvPacket` if the module processes packets as soon as they are received from IBC module. +- Synchronously on `OnRecvPacket` if the module processes packets as soon as they are received from IBC module. - Asynchronously if module processes packets at some later point after receiving the packet. -This acknowledgment data is opaque to IBC much like the packet `Data` and is treated by IBC as a simple byte string `[]byte`. Receiver modules must encode their acknowledgment so that the sender module can decode it correctly. The encoding must be negotiated between the two parties during version negotiation in the channel handshake. +This acknowledgment data is opaque to IBC much like the packet `Data` and is treated by IBC as a simple byte string `[]byte`. Receiver modules must encode their acknowledgment so that the sender module can decode it correctly. The encoding must be negotiated between the two parties during version negotiation in the channel handshake. The acknowledgment can encode whether the packet processing succeeded or failed, along with additional information that allows the sender module to take appropriate action. After the acknowledgment has been written by the receiving chain, a relayer relays the acknowledgment back to the original sender module. -The original sender module then executes application-specific acknowledgment logic using the contents of the acknowledgment. +The original sender module then executes application-specific acknowledgment logic using the contents of the acknowledgment. - After an acknowledgement fails, packet-send changes can be rolled back (for example, refunding senders in ICS20). @@ -291,7 +290,7 @@ The original sender module then executes application-specific acknowledgment log If you want to learn more about IBC, check the following specifications: -* [IBC specification overview](https://github.com/cosmos/ibc/blob/master/README.md) +- [IBC specification overview](https://github.com/cosmos/ibc/blob/master/README.md) ## Next {hide} diff --git a/docs/ibc/proposals.md b/docs/ibc/proposals.md index f6bf351a705..dc22eb441af 100644 --- a/docs/ibc/proposals.md +++ b/docs/ibc/proposals.md @@ -4,7 +4,7 @@ order: 5 # Governance Proposals -In uncommon situations, a highly valued client may become frozen due to uncontrollable +In uncommon situations, a highly valued client may become frozen due to uncontrollable circumstances. A highly valued client might have hundreds of channels being actively used. Some of those channels might have a significant amount of locked tokens used for ICS 20. @@ -12,41 +12,47 @@ If the one third of the validator set of the chain the client represents decides they can sign off on two valid but conflicting headers each signed by the other one third of the honest validator set. The light client can now be updated with two valid, but conflicting headers at the same height. The light client cannot know which header is trustworthy and therefore -evidence of such misbehaviour is likely to be submitted resulting in a frozen light client. +evidence of such misbehaviour is likely to be submitted resulting in a frozen light client. Frozen light clients cannot be updated under any circumstance except via a governance proposal. -Since a quorum of validators can sign arbitrary state roots which may not be valid executions +Since a quorum of validators can sign arbitrary state roots which may not be valid executions of the state machine, a governance proposal has been added to ease the complexity of unfreezing or updating clients which have become "stuck". Without this mechanism, validator sets would need -to construct a state root to unfreeze the client. Unfreezing clients, re-enables all of the channels -built upon that client. This may result in recovery of otherwise lost funds. +to construct a state root to unfreeze the client. Unfreezing clients, re-enables all of the channels +built upon that client. This may result in recovery of otherwise lost funds. -Tendermint light clients may become expired if the trusting period has passed since their +Tendermint light clients may become expired if the trusting period has passed since their last update. This may occur if relayers stop submitting headers to update the clients. -An unplanned upgrade by the counterparty chain may also result in expired clients. If the counterparty -chain undergoes an unplanned upgrade, there may be no commitment to that upgrade signed by the validator -set before the chain-id changes. In this situation, the validator set of the last valid update for the -light client is never expected to produce another valid header since the chain-id has changed, which will -ultimately lead the on-chain light client to become expired. +An unplanned upgrade by the counterparty chain may also result in expired clients. If the counterparty +chain undergoes an unplanned upgrade, there may be no commitment to that upgrade signed by the validator +set before the chain-id changes. In this situation, the validator set of the last valid update for the +light client is never expected to produce another valid header since the chain-id has changed, which will +ultimately lead the on-chain light client to become expired. In the case that a highly valued light client is frozen, expired, or rendered non-updateable, a -governance proposal may be submitted to update this client, known as the subject client. The +governance proposal may be submitted to update this client, known as the subject client. The proposal includes the client identifier for the subject and the client identifier for a substitute -client. Light client implementations may implement custom updating logic, but in most cases, +client. Light client implementations may implement custom updating logic, but in most cases, the subject will be updated to the latest consensus state of the substitute client, if the proposal passes. -The substitute client is used as a "stand in" while the subject is on trial. It is best practice to create -a substitute client *after* the subject has become frozen to avoid the substitute from also becoming frozen. -An active substitute client allows headers to be submitted during the voting period to prevent accidental expiry -once the proposal passes. +The substitute client is used as a "stand in" while the subject is on trial. It is best practice to create +a substitute client _after_ the subject has become frozen to avoid the substitute from also becoming frozen. +An active substitute client allows headers to be submitted during the voting period to prevent accidental expiry +once the proposal passes. + +_note_ two of these parameters: `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehavior` have been deprecated, and will both be set to `false` upon upgrades even if they were previously set to `true`. These parameters will no longer play a role in restricting a client upgrade. Please see ADR026 for more details. # How to recover an expired client with a governance proposal See also the relevant documentation: [ADR-026, IBC client recovery mechanisms](../architecture/adr-026-ibc-client-recovery-mechanisms.md) -### Preconditions +> **Who is this information for?** +> Although technically anyone can submit the governance proposal to recover an expired client, often it will be **relayer operators** (at least coordinating the submission). + +## Preconditions + - The chain is updated with ibc-go >= v1.1.0. -- The client identifier of an active client for the same counterparty chain. +- There exists an active client (with a known client identifier) for the same counterparty chain as the expired client. - The governance deposit. ## Steps @@ -55,7 +61,7 @@ See also the relevant documentation: [ADR-026, IBC client recovery mechanisms](. Check if the client is attached to the expected `chain-id`. For example, for an expired Tendermint client representing the Akash chain the client state looks like this on querying the client state: -``` +```text { client_id: 07-tendermint-146 client_state: @@ -70,18 +76,54 @@ The client is attached to the expected Akash `chain-id`. Note that although the ### Step 2 -If the chain has been updated to ibc-go >= v1.1.0, anyone can submit the governance proposal to recover the client by executing this via cli: +If the chain has been updated to ibc-go >= v1.1.0, anyone can submit the governance proposal to recover the client by executing this via CLI. -``` - tx gov submit-proposal update-client -``` +> Note that the Cosmos SDK has updated how governance proposals are submitted in SDK v0.46, now requiring to pass a .json proposal file + +- From SDK v0.46.x onwards + + ```shell + tx gov submit-proposal [path-to-proposal-json] + ``` + + where `proposal.json` contains: + + ```json + { + "messages": [ + { + "@type": "/ibc.core.client.v1.ClientUpdateProposal", + "title": "title_string", + "description": "description_string", + "subject_client_id": "expired_client_id_string", + "substitute_client_id": "active_client_id_string" + } + ], + "metadata": "", + "deposit": "10stake" + } + ``` + + Alternatively there's a legacy command (that is no longer recommended though): + + ```shell + tx gov submit-legacy-proposal update-client + ``` + +- Until SDK v0.45.x + + ```shell + tx gov submit-proposal update-client + ``` + +The `` identifier is the proposed client to be updated. This client must be either frozen or expired. -The `` should be a client identifier on the same chain as the expired or frozen client. This client identifier should connect to the same chain as the expired or frozen client. This means: use the active client that is currently being used to relay packets between the two chains as the replacement client. +The `` represents a substitute client. It carries all the state for the client which may be updated. It must have identical client and chain parameters to the client which may be updated (except for latest height, frozen height, and chain ID). It should be continually updated during the voting period. -After this, it is just a question of who funds the governance deposit and if the chain in question votes yes. +After this, all that remains is deciding who funds the governance deposit and ensuring the governance proposal passes. If it does, the client on trial will be updated to the latest state of the substitute. -## Important considerations +## Important considerations Please note that from v1.0.0 of ibc-go it will not be allowed for transactions to go to expired clients anymore, so please update to at least this version to prevent similar issues in the future. -Please also note that if the client on the other end of the transaction is also expired, that client will also need to update. This process updates only one client. \ No newline at end of file +Please also note that if the client on the other end of the transaction is also expired, that client will also need to update. This process updates only one client. diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index 5eaf8aaedb3..5edd28bbf0c 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -1,5406 +1,7 @@ - -# Protobuf Documentation - + -## Table of Contents - -- [ibc/applications/fee/v1/ack.proto](#ibc/applications/fee/v1/ack.proto) - - [IncentivizedAcknowledgement](#ibc.applications.fee.v1.IncentivizedAcknowledgement) - -- [ibc/core/client/v1/client.proto](#ibc/core/client/v1/client.proto) - - [ClientConsensusStates](#ibc.core.client.v1.ClientConsensusStates) - - [ClientUpdateProposal](#ibc.core.client.v1.ClientUpdateProposal) - - [ConsensusStateWithHeight](#ibc.core.client.v1.ConsensusStateWithHeight) - - [Height](#ibc.core.client.v1.Height) - - [IdentifiedClientState](#ibc.core.client.v1.IdentifiedClientState) - - [Params](#ibc.core.client.v1.Params) - - [UpgradeProposal](#ibc.core.client.v1.UpgradeProposal) - -- [ibc/core/channel/v1/channel.proto](#ibc/core/channel/v1/channel.proto) - - [Acknowledgement](#ibc.core.channel.v1.Acknowledgement) - - [Channel](#ibc.core.channel.v1.Channel) - - [Counterparty](#ibc.core.channel.v1.Counterparty) - - [IdentifiedChannel](#ibc.core.channel.v1.IdentifiedChannel) - - [Packet](#ibc.core.channel.v1.Packet) - - [PacketId](#ibc.core.channel.v1.PacketId) - - [PacketState](#ibc.core.channel.v1.PacketState) - - - [Order](#ibc.core.channel.v1.Order) - - [State](#ibc.core.channel.v1.State) - -- [ibc/applications/fee/v1/fee.proto](#ibc/applications/fee/v1/fee.proto) - - [Fee](#ibc.applications.fee.v1.Fee) - - [IdentifiedPacketFees](#ibc.applications.fee.v1.IdentifiedPacketFees) - - [PacketFee](#ibc.applications.fee.v1.PacketFee) - - [PacketFees](#ibc.applications.fee.v1.PacketFees) - -- [ibc/applications/fee/v1/genesis.proto](#ibc/applications/fee/v1/genesis.proto) - - [FeeEnabledChannel](#ibc.applications.fee.v1.FeeEnabledChannel) - - [ForwardRelayerAddress](#ibc.applications.fee.v1.ForwardRelayerAddress) - - [GenesisState](#ibc.applications.fee.v1.GenesisState) - - [RegisteredCounterpartyPayee](#ibc.applications.fee.v1.RegisteredCounterpartyPayee) - - [RegisteredPayee](#ibc.applications.fee.v1.RegisteredPayee) - -- [ibc/applications/fee/v1/metadata.proto](#ibc/applications/fee/v1/metadata.proto) - - [Metadata](#ibc.applications.fee.v1.Metadata) - -- [ibc/applications/fee/v1/query.proto](#ibc/applications/fee/v1/query.proto) - - [QueryCounterpartyPayeeRequest](#ibc.applications.fee.v1.QueryCounterpartyPayeeRequest) - - [QueryCounterpartyPayeeResponse](#ibc.applications.fee.v1.QueryCounterpartyPayeeResponse) - - [QueryFeeEnabledChannelRequest](#ibc.applications.fee.v1.QueryFeeEnabledChannelRequest) - - [QueryFeeEnabledChannelResponse](#ibc.applications.fee.v1.QueryFeeEnabledChannelResponse) - - [QueryFeeEnabledChannelsRequest](#ibc.applications.fee.v1.QueryFeeEnabledChannelsRequest) - - [QueryFeeEnabledChannelsResponse](#ibc.applications.fee.v1.QueryFeeEnabledChannelsResponse) - - [QueryIncentivizedPacketRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketRequest) - - [QueryIncentivizedPacketResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketResponse) - - [QueryIncentivizedPacketsForChannelRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketsForChannelRequest) - - [QueryIncentivizedPacketsForChannelResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketsForChannelResponse) - - [QueryIncentivizedPacketsRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketsRequest) - - [QueryIncentivizedPacketsResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketsResponse) - - [QueryPayeeRequest](#ibc.applications.fee.v1.QueryPayeeRequest) - - [QueryPayeeResponse](#ibc.applications.fee.v1.QueryPayeeResponse) - - [QueryTotalAckFeesRequest](#ibc.applications.fee.v1.QueryTotalAckFeesRequest) - - [QueryTotalAckFeesResponse](#ibc.applications.fee.v1.QueryTotalAckFeesResponse) - - [QueryTotalRecvFeesRequest](#ibc.applications.fee.v1.QueryTotalRecvFeesRequest) - - [QueryTotalRecvFeesResponse](#ibc.applications.fee.v1.QueryTotalRecvFeesResponse) - - [QueryTotalTimeoutFeesRequest](#ibc.applications.fee.v1.QueryTotalTimeoutFeesRequest) - - [QueryTotalTimeoutFeesResponse](#ibc.applications.fee.v1.QueryTotalTimeoutFeesResponse) - - - [Query](#ibc.applications.fee.v1.Query) - -- [ibc/applications/fee/v1/tx.proto](#ibc/applications/fee/v1/tx.proto) - - [MsgPayPacketFee](#ibc.applications.fee.v1.MsgPayPacketFee) - - [MsgPayPacketFeeAsync](#ibc.applications.fee.v1.MsgPayPacketFeeAsync) - - [MsgPayPacketFeeAsyncResponse](#ibc.applications.fee.v1.MsgPayPacketFeeAsyncResponse) - - [MsgPayPacketFeeResponse](#ibc.applications.fee.v1.MsgPayPacketFeeResponse) - - [MsgRegisterCounterpartyPayee](#ibc.applications.fee.v1.MsgRegisterCounterpartyPayee) - - [MsgRegisterCounterpartyPayeeResponse](#ibc.applications.fee.v1.MsgRegisterCounterpartyPayeeResponse) - - [MsgRegisterPayee](#ibc.applications.fee.v1.MsgRegisterPayee) - - [MsgRegisterPayeeResponse](#ibc.applications.fee.v1.MsgRegisterPayeeResponse) - - - [Msg](#ibc.applications.fee.v1.Msg) - -- [ibc/applications/interchain_accounts/controller/v1/controller.proto](#ibc/applications/interchain_accounts/controller/v1/controller.proto) - - [Params](#ibc.applications.interchain_accounts.controller.v1.Params) - -- [ibc/applications/interchain_accounts/controller/v1/query.proto](#ibc/applications/interchain_accounts/controller/v1/query.proto) - - [QueryParamsRequest](#ibc.applications.interchain_accounts.controller.v1.QueryParamsRequest) - - [QueryParamsResponse](#ibc.applications.interchain_accounts.controller.v1.QueryParamsResponse) - - - [Query](#ibc.applications.interchain_accounts.controller.v1.Query) - -- [ibc/applications/interchain_accounts/host/v1/host.proto](#ibc/applications/interchain_accounts/host/v1/host.proto) - - [Params](#ibc.applications.interchain_accounts.host.v1.Params) - -- [ibc/applications/interchain_accounts/host/v1/query.proto](#ibc/applications/interchain_accounts/host/v1/query.proto) - - [QueryParamsRequest](#ibc.applications.interchain_accounts.host.v1.QueryParamsRequest) - - [QueryParamsResponse](#ibc.applications.interchain_accounts.host.v1.QueryParamsResponse) - - - [Query](#ibc.applications.interchain_accounts.host.v1.Query) - -- [ibc/applications/interchain_accounts/v1/account.proto](#ibc/applications/interchain_accounts/v1/account.proto) - - [InterchainAccount](#ibc.applications.interchain_accounts.v1.InterchainAccount) - -- [ibc/applications/interchain_accounts/v1/genesis.proto](#ibc/applications/interchain_accounts/v1/genesis.proto) - - [ActiveChannel](#ibc.applications.interchain_accounts.v1.ActiveChannel) - - [ControllerGenesisState](#ibc.applications.interchain_accounts.v1.ControllerGenesisState) - - [GenesisState](#ibc.applications.interchain_accounts.v1.GenesisState) - - [HostGenesisState](#ibc.applications.interchain_accounts.v1.HostGenesisState) - - [RegisteredInterchainAccount](#ibc.applications.interchain_accounts.v1.RegisteredInterchainAccount) - -- [ibc/applications/interchain_accounts/v1/metadata.proto](#ibc/applications/interchain_accounts/v1/metadata.proto) - - [Metadata](#ibc.applications.interchain_accounts.v1.Metadata) - -- [ibc/applications/interchain_accounts/v1/packet.proto](#ibc/applications/interchain_accounts/v1/packet.proto) - - [CosmosTx](#ibc.applications.interchain_accounts.v1.CosmosTx) - - [InterchainAccountPacketData](#ibc.applications.interchain_accounts.v1.InterchainAccountPacketData) - - - [Type](#ibc.applications.interchain_accounts.v1.Type) - -- [ibc/applications/transfer/v1/transfer.proto](#ibc/applications/transfer/v1/transfer.proto) - - [DenomTrace](#ibc.applications.transfer.v1.DenomTrace) - - [Params](#ibc.applications.transfer.v1.Params) - -- [ibc/applications/transfer/v1/genesis.proto](#ibc/applications/transfer/v1/genesis.proto) - - [GenesisState](#ibc.applications.transfer.v1.GenesisState) - -- [ibc/applications/transfer/v1/query.proto](#ibc/applications/transfer/v1/query.proto) - - [QueryDenomHashRequest](#ibc.applications.transfer.v1.QueryDenomHashRequest) - - [QueryDenomHashResponse](#ibc.applications.transfer.v1.QueryDenomHashResponse) - - [QueryDenomTraceRequest](#ibc.applications.transfer.v1.QueryDenomTraceRequest) - - [QueryDenomTraceResponse](#ibc.applications.transfer.v1.QueryDenomTraceResponse) - - [QueryDenomTracesRequest](#ibc.applications.transfer.v1.QueryDenomTracesRequest) - - [QueryDenomTracesResponse](#ibc.applications.transfer.v1.QueryDenomTracesResponse) - - [QueryEscrowAddressRequest](#ibc.applications.transfer.v1.QueryEscrowAddressRequest) - - [QueryEscrowAddressResponse](#ibc.applications.transfer.v1.QueryEscrowAddressResponse) - - [QueryParamsRequest](#ibc.applications.transfer.v1.QueryParamsRequest) - - [QueryParamsResponse](#ibc.applications.transfer.v1.QueryParamsResponse) - - - [Query](#ibc.applications.transfer.v1.Query) - -- [ibc/applications/transfer/v1/tx.proto](#ibc/applications/transfer/v1/tx.proto) - - [MsgTransfer](#ibc.applications.transfer.v1.MsgTransfer) - - [MsgTransferResponse](#ibc.applications.transfer.v1.MsgTransferResponse) - - - [Msg](#ibc.applications.transfer.v1.Msg) - -- [ibc/applications/transfer/v2/packet.proto](#ibc/applications/transfer/v2/packet.proto) - - [FungibleTokenPacketData](#ibc.applications.transfer.v2.FungibleTokenPacketData) - -- [ibc/core/channel/v1/genesis.proto](#ibc/core/channel/v1/genesis.proto) - - [GenesisState](#ibc.core.channel.v1.GenesisState) - - [PacketSequence](#ibc.core.channel.v1.PacketSequence) - -- [ibc/core/channel/v1/query.proto](#ibc/core/channel/v1/query.proto) - - [QueryChannelClientStateRequest](#ibc.core.channel.v1.QueryChannelClientStateRequest) - - [QueryChannelClientStateResponse](#ibc.core.channel.v1.QueryChannelClientStateResponse) - - [QueryChannelConsensusStateRequest](#ibc.core.channel.v1.QueryChannelConsensusStateRequest) - - [QueryChannelConsensusStateResponse](#ibc.core.channel.v1.QueryChannelConsensusStateResponse) - - [QueryChannelRequest](#ibc.core.channel.v1.QueryChannelRequest) - - [QueryChannelResponse](#ibc.core.channel.v1.QueryChannelResponse) - - [QueryChannelsRequest](#ibc.core.channel.v1.QueryChannelsRequest) - - [QueryChannelsResponse](#ibc.core.channel.v1.QueryChannelsResponse) - - [QueryConnectionChannelsRequest](#ibc.core.channel.v1.QueryConnectionChannelsRequest) - - [QueryConnectionChannelsResponse](#ibc.core.channel.v1.QueryConnectionChannelsResponse) - - [QueryNextSequenceReceiveRequest](#ibc.core.channel.v1.QueryNextSequenceReceiveRequest) - - [QueryNextSequenceReceiveResponse](#ibc.core.channel.v1.QueryNextSequenceReceiveResponse) - - [QueryPacketAcknowledgementRequest](#ibc.core.channel.v1.QueryPacketAcknowledgementRequest) - - [QueryPacketAcknowledgementResponse](#ibc.core.channel.v1.QueryPacketAcknowledgementResponse) - - [QueryPacketAcknowledgementsRequest](#ibc.core.channel.v1.QueryPacketAcknowledgementsRequest) - - [QueryPacketAcknowledgementsResponse](#ibc.core.channel.v1.QueryPacketAcknowledgementsResponse) - - [QueryPacketCommitmentRequest](#ibc.core.channel.v1.QueryPacketCommitmentRequest) - - [QueryPacketCommitmentResponse](#ibc.core.channel.v1.QueryPacketCommitmentResponse) - - [QueryPacketCommitmentsRequest](#ibc.core.channel.v1.QueryPacketCommitmentsRequest) - - [QueryPacketCommitmentsResponse](#ibc.core.channel.v1.QueryPacketCommitmentsResponse) - - [QueryPacketReceiptRequest](#ibc.core.channel.v1.QueryPacketReceiptRequest) - - [QueryPacketReceiptResponse](#ibc.core.channel.v1.QueryPacketReceiptResponse) - - [QueryUnreceivedAcksRequest](#ibc.core.channel.v1.QueryUnreceivedAcksRequest) - - [QueryUnreceivedAcksResponse](#ibc.core.channel.v1.QueryUnreceivedAcksResponse) - - [QueryUnreceivedPacketsRequest](#ibc.core.channel.v1.QueryUnreceivedPacketsRequest) - - [QueryUnreceivedPacketsResponse](#ibc.core.channel.v1.QueryUnreceivedPacketsResponse) - - - [Query](#ibc.core.channel.v1.Query) - -- [ibc/core/channel/v1/upgrade.proto](#ibc/core/channel/v1/upgrade.proto) - - [ErrorReceipt](#ibc.core.channel.v1.ErrorReceipt) - - [UpgradeTimeout](#ibc.core.channel.v1.UpgradeTimeout) - -- [ibc/core/channel/v1/tx.proto](#ibc/core/channel/v1/tx.proto) - - [MsgAcknowledgement](#ibc.core.channel.v1.MsgAcknowledgement) - - [MsgAcknowledgementResponse](#ibc.core.channel.v1.MsgAcknowledgementResponse) - - [MsgChannelCloseConfirm](#ibc.core.channel.v1.MsgChannelCloseConfirm) - - [MsgChannelCloseConfirmResponse](#ibc.core.channel.v1.MsgChannelCloseConfirmResponse) - - [MsgChannelCloseInit](#ibc.core.channel.v1.MsgChannelCloseInit) - - [MsgChannelCloseInitResponse](#ibc.core.channel.v1.MsgChannelCloseInitResponse) - - [MsgChannelOpenAck](#ibc.core.channel.v1.MsgChannelOpenAck) - - [MsgChannelOpenAckResponse](#ibc.core.channel.v1.MsgChannelOpenAckResponse) - - [MsgChannelOpenConfirm](#ibc.core.channel.v1.MsgChannelOpenConfirm) - - [MsgChannelOpenConfirmResponse](#ibc.core.channel.v1.MsgChannelOpenConfirmResponse) - - [MsgChannelOpenInit](#ibc.core.channel.v1.MsgChannelOpenInit) - - [MsgChannelOpenInitResponse](#ibc.core.channel.v1.MsgChannelOpenInitResponse) - - [MsgChannelOpenTry](#ibc.core.channel.v1.MsgChannelOpenTry) - - [MsgChannelOpenTryResponse](#ibc.core.channel.v1.MsgChannelOpenTryResponse) - - [MsgChannelUpgradeAck](#ibc.core.channel.v1.MsgChannelUpgradeAck) - - [MsgChannelUpgradeAckResponse](#ibc.core.channel.v1.MsgChannelUpgradeAckResponse) - - [MsgChannelUpgradeCancel](#ibc.core.channel.v1.MsgChannelUpgradeCancel) - - [MsgChannelUpgradeCancelResponse](#ibc.core.channel.v1.MsgChannelUpgradeCancelResponse) - - [MsgChannelUpgradeConfirm](#ibc.core.channel.v1.MsgChannelUpgradeConfirm) - - [MsgChannelUpgradeConfirmResponse](#ibc.core.channel.v1.MsgChannelUpgradeConfirmResponse) - - [MsgChannelUpgradeInit](#ibc.core.channel.v1.MsgChannelUpgradeInit) - - [MsgChannelUpgradeInitResponse](#ibc.core.channel.v1.MsgChannelUpgradeInitResponse) - - [MsgChannelUpgradeTimeout](#ibc.core.channel.v1.MsgChannelUpgradeTimeout) - - [MsgChannelUpgradeTimeoutResponse](#ibc.core.channel.v1.MsgChannelUpgradeTimeoutResponse) - - [MsgChannelUpgradeTry](#ibc.core.channel.v1.MsgChannelUpgradeTry) - - [MsgChannelUpgradeTryResponse](#ibc.core.channel.v1.MsgChannelUpgradeTryResponse) - - [MsgRecvPacket](#ibc.core.channel.v1.MsgRecvPacket) - - [MsgRecvPacketResponse](#ibc.core.channel.v1.MsgRecvPacketResponse) - - [MsgTimeout](#ibc.core.channel.v1.MsgTimeout) - - [MsgTimeoutOnClose](#ibc.core.channel.v1.MsgTimeoutOnClose) - - [MsgTimeoutOnCloseResponse](#ibc.core.channel.v1.MsgTimeoutOnCloseResponse) - - [MsgTimeoutResponse](#ibc.core.channel.v1.MsgTimeoutResponse) - - - [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) - - - [Msg](#ibc.core.channel.v1.Msg) - -- [ibc/core/client/v1/genesis.proto](#ibc/core/client/v1/genesis.proto) - - [GenesisMetadata](#ibc.core.client.v1.GenesisMetadata) - - [GenesisState](#ibc.core.client.v1.GenesisState) - - [IdentifiedGenesisMetadata](#ibc.core.client.v1.IdentifiedGenesisMetadata) - -- [ibc/core/client/v1/query.proto](#ibc/core/client/v1/query.proto) - - [QueryClientParamsRequest](#ibc.core.client.v1.QueryClientParamsRequest) - - [QueryClientParamsResponse](#ibc.core.client.v1.QueryClientParamsResponse) - - [QueryClientStateRequest](#ibc.core.client.v1.QueryClientStateRequest) - - [QueryClientStateResponse](#ibc.core.client.v1.QueryClientStateResponse) - - [QueryClientStatesRequest](#ibc.core.client.v1.QueryClientStatesRequest) - - [QueryClientStatesResponse](#ibc.core.client.v1.QueryClientStatesResponse) - - [QueryClientStatusRequest](#ibc.core.client.v1.QueryClientStatusRequest) - - [QueryClientStatusResponse](#ibc.core.client.v1.QueryClientStatusResponse) - - [QueryConsensusStateHeightsRequest](#ibc.core.client.v1.QueryConsensusStateHeightsRequest) - - [QueryConsensusStateHeightsResponse](#ibc.core.client.v1.QueryConsensusStateHeightsResponse) - - [QueryConsensusStateRequest](#ibc.core.client.v1.QueryConsensusStateRequest) - - [QueryConsensusStateResponse](#ibc.core.client.v1.QueryConsensusStateResponse) - - [QueryConsensusStatesRequest](#ibc.core.client.v1.QueryConsensusStatesRequest) - - [QueryConsensusStatesResponse](#ibc.core.client.v1.QueryConsensusStatesResponse) - - [QueryUpgradedClientStateRequest](#ibc.core.client.v1.QueryUpgradedClientStateRequest) - - [QueryUpgradedClientStateResponse](#ibc.core.client.v1.QueryUpgradedClientStateResponse) - - [QueryUpgradedConsensusStateRequest](#ibc.core.client.v1.QueryUpgradedConsensusStateRequest) - - [QueryUpgradedConsensusStateResponse](#ibc.core.client.v1.QueryUpgradedConsensusStateResponse) - - - [Query](#ibc.core.client.v1.Query) - -- [ibc/core/client/v1/tx.proto](#ibc/core/client/v1/tx.proto) - - [MsgCreateClient](#ibc.core.client.v1.MsgCreateClient) - - [MsgCreateClientResponse](#ibc.core.client.v1.MsgCreateClientResponse) - - [MsgSubmitMisbehaviour](#ibc.core.client.v1.MsgSubmitMisbehaviour) - - [MsgSubmitMisbehaviourResponse](#ibc.core.client.v1.MsgSubmitMisbehaviourResponse) - - [MsgUpdateClient](#ibc.core.client.v1.MsgUpdateClient) - - [MsgUpdateClientResponse](#ibc.core.client.v1.MsgUpdateClientResponse) - - [MsgUpgradeClient](#ibc.core.client.v1.MsgUpgradeClient) - - [MsgUpgradeClientResponse](#ibc.core.client.v1.MsgUpgradeClientResponse) - - - [Msg](#ibc.core.client.v1.Msg) - -- [ibc/core/commitment/v1/commitment.proto](#ibc/core/commitment/v1/commitment.proto) - - [MerklePath](#ibc.core.commitment.v1.MerklePath) - - [MerklePrefix](#ibc.core.commitment.v1.MerklePrefix) - - [MerkleProof](#ibc.core.commitment.v1.MerkleProof) - - [MerkleRoot](#ibc.core.commitment.v1.MerkleRoot) - -- [ibc/core/connection/v1/connection.proto](#ibc/core/connection/v1/connection.proto) - - [ClientPaths](#ibc.core.connection.v1.ClientPaths) - - [ConnectionEnd](#ibc.core.connection.v1.ConnectionEnd) - - [ConnectionPaths](#ibc.core.connection.v1.ConnectionPaths) - - [Counterparty](#ibc.core.connection.v1.Counterparty) - - [IdentifiedConnection](#ibc.core.connection.v1.IdentifiedConnection) - - [Params](#ibc.core.connection.v1.Params) - - [Version](#ibc.core.connection.v1.Version) - - - [State](#ibc.core.connection.v1.State) - -- [ibc/core/connection/v1/genesis.proto](#ibc/core/connection/v1/genesis.proto) - - [GenesisState](#ibc.core.connection.v1.GenesisState) - -- [ibc/core/connection/v1/query.proto](#ibc/core/connection/v1/query.proto) - - [QueryClientConnectionsRequest](#ibc.core.connection.v1.QueryClientConnectionsRequest) - - [QueryClientConnectionsResponse](#ibc.core.connection.v1.QueryClientConnectionsResponse) - - [QueryConnectionClientStateRequest](#ibc.core.connection.v1.QueryConnectionClientStateRequest) - - [QueryConnectionClientStateResponse](#ibc.core.connection.v1.QueryConnectionClientStateResponse) - - [QueryConnectionConsensusStateRequest](#ibc.core.connection.v1.QueryConnectionConsensusStateRequest) - - [QueryConnectionConsensusStateResponse](#ibc.core.connection.v1.QueryConnectionConsensusStateResponse) - - [QueryConnectionRequest](#ibc.core.connection.v1.QueryConnectionRequest) - - [QueryConnectionResponse](#ibc.core.connection.v1.QueryConnectionResponse) - - [QueryConnectionsRequest](#ibc.core.connection.v1.QueryConnectionsRequest) - - [QueryConnectionsResponse](#ibc.core.connection.v1.QueryConnectionsResponse) - - - [Query](#ibc.core.connection.v1.Query) - -- [ibc/core/connection/v1/tx.proto](#ibc/core/connection/v1/tx.proto) - - [MsgConnectionOpenAck](#ibc.core.connection.v1.MsgConnectionOpenAck) - - [MsgConnectionOpenAckResponse](#ibc.core.connection.v1.MsgConnectionOpenAckResponse) - - [MsgConnectionOpenConfirm](#ibc.core.connection.v1.MsgConnectionOpenConfirm) - - [MsgConnectionOpenConfirmResponse](#ibc.core.connection.v1.MsgConnectionOpenConfirmResponse) - - [MsgConnectionOpenInit](#ibc.core.connection.v1.MsgConnectionOpenInit) - - [MsgConnectionOpenInitResponse](#ibc.core.connection.v1.MsgConnectionOpenInitResponse) - - [MsgConnectionOpenTry](#ibc.core.connection.v1.MsgConnectionOpenTry) - - [MsgConnectionOpenTryResponse](#ibc.core.connection.v1.MsgConnectionOpenTryResponse) - - - [Msg](#ibc.core.connection.v1.Msg) - -- [ibc/core/types/v1/genesis.proto](#ibc/core/types/v1/genesis.proto) - - [GenesisState](#ibc.core.types.v1.GenesisState) - -- [ibc/lightclients/localhost/v1/localhost.proto](#ibc/lightclients/localhost/v1/localhost.proto) - - [ClientState](#ibc.lightclients.localhost.v1.ClientState) - -- [ibc/lightclients/solomachine/v1/solomachine.proto](#ibc/lightclients/solomachine/v1/solomachine.proto) - - [ChannelStateData](#ibc.lightclients.solomachine.v1.ChannelStateData) - - [ClientState](#ibc.lightclients.solomachine.v1.ClientState) - - [ClientStateData](#ibc.lightclients.solomachine.v1.ClientStateData) - - [ConnectionStateData](#ibc.lightclients.solomachine.v1.ConnectionStateData) - - [ConsensusState](#ibc.lightclients.solomachine.v1.ConsensusState) - - [ConsensusStateData](#ibc.lightclients.solomachine.v1.ConsensusStateData) - - [Header](#ibc.lightclients.solomachine.v1.Header) - - [HeaderData](#ibc.lightclients.solomachine.v1.HeaderData) - - [Misbehaviour](#ibc.lightclients.solomachine.v1.Misbehaviour) - - [NextSequenceRecvData](#ibc.lightclients.solomachine.v1.NextSequenceRecvData) - - [PacketAcknowledgementData](#ibc.lightclients.solomachine.v1.PacketAcknowledgementData) - - [PacketCommitmentData](#ibc.lightclients.solomachine.v1.PacketCommitmentData) - - [PacketReceiptAbsenceData](#ibc.lightclients.solomachine.v1.PacketReceiptAbsenceData) - - [SignBytes](#ibc.lightclients.solomachine.v1.SignBytes) - - [SignatureAndData](#ibc.lightclients.solomachine.v1.SignatureAndData) - - [TimestampedSignatureData](#ibc.lightclients.solomachine.v1.TimestampedSignatureData) - - - [DataType](#ibc.lightclients.solomachine.v1.DataType) - -- [ibc/lightclients/solomachine/v2/solomachine.proto](#ibc/lightclients/solomachine/v2/solomachine.proto) - - [ChannelStateData](#ibc.lightclients.solomachine.v2.ChannelStateData) - - [ClientState](#ibc.lightclients.solomachine.v2.ClientState) - - [ClientStateData](#ibc.lightclients.solomachine.v2.ClientStateData) - - [ConnectionStateData](#ibc.lightclients.solomachine.v2.ConnectionStateData) - - [ConsensusState](#ibc.lightclients.solomachine.v2.ConsensusState) - - [ConsensusStateData](#ibc.lightclients.solomachine.v2.ConsensusStateData) - - [Header](#ibc.lightclients.solomachine.v2.Header) - - [HeaderData](#ibc.lightclients.solomachine.v2.HeaderData) - - [Misbehaviour](#ibc.lightclients.solomachine.v2.Misbehaviour) - - [NextSequenceRecvData](#ibc.lightclients.solomachine.v2.NextSequenceRecvData) - - [PacketAcknowledgementData](#ibc.lightclients.solomachine.v2.PacketAcknowledgementData) - - [PacketCommitmentData](#ibc.lightclients.solomachine.v2.PacketCommitmentData) - - [PacketReceiptAbsenceData](#ibc.lightclients.solomachine.v2.PacketReceiptAbsenceData) - - [SignBytes](#ibc.lightclients.solomachine.v2.SignBytes) - - [SignatureAndData](#ibc.lightclients.solomachine.v2.SignatureAndData) - - [TimestampedSignatureData](#ibc.lightclients.solomachine.v2.TimestampedSignatureData) - - - [DataType](#ibc.lightclients.solomachine.v2.DataType) - -- [ibc/lightclients/tendermint/v1/tendermint.proto](#ibc/lightclients/tendermint/v1/tendermint.proto) - - [ClientState](#ibc.lightclients.tendermint.v1.ClientState) - - [ConsensusState](#ibc.lightclients.tendermint.v1.ConsensusState) - - [Fraction](#ibc.lightclients.tendermint.v1.Fraction) - - [Header](#ibc.lightclients.tendermint.v1.Header) - - [Misbehaviour](#ibc.lightclients.tendermint.v1.Misbehaviour) - -- [Scalar Value Types](#scalar-value-types) - - - - -

Top

- -## ibc/applications/fee/v1/ack.proto - - - - - -### IncentivizedAcknowledgement -IncentivizedAcknowledgement is the acknowledgement format to be used by applications wrapped in the fee middleware - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `app_acknowledgement` | [bytes](#bytes) | | the underlying app acknowledgement bytes | -| `forward_relayer_address` | [string](#string) | | the relayer address which submits the recv packet message | -| `underlying_app_success` | [bool](#bool) | | success flag of the base application callback | - - - - - - - - - - - - - - - - -

Top

- -## ibc/core/client/v1/client.proto - - - - - -### ClientConsensusStates -ClientConsensusStates defines all the stored consensus states for a given -client. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client identifier | -| `consensus_states` | [ConsensusStateWithHeight](#ibc.core.client.v1.ConsensusStateWithHeight) | repeated | consensus states and their heights associated with the client | - - - - - - - - -### ClientUpdateProposal -ClientUpdateProposal is a governance proposal. If it passes, the substitute -client's latest consensus state is copied over to the subject client. The proposal -handler may fail if the subject and the substitute do not match in client and -chain parameters (with exception to latest height, frozen height, and chain-id). - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | the title of the update proposal | -| `description` | [string](#string) | | the description of the proposal | -| `subject_client_id` | [string](#string) | | the client identifier for the client to be updated if the proposal passes | -| `substitute_client_id` | [string](#string) | | the substitute client identifier for the client standing in for the subject client | - - - - - - - - -### ConsensusStateWithHeight -ConsensusStateWithHeight defines a consensus state with an additional height -field. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `height` | [Height](#ibc.core.client.v1.Height) | | consensus state height | -| `consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | consensus state | - - - - - - - - -### Height -Height is a monotonically increasing data type -that can be compared against another Height for the purposes of updating and -freezing clients - -Normally the RevisionHeight is incremented at each height while keeping -RevisionNumber the same. However some consensus algorithms may choose to -reset the height in certain conditions e.g. hard forks, state-machine -breaking changes In these cases, the RevisionNumber is incremented so that -height continues to be monitonically increasing even as the RevisionHeight -gets reset - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `revision_number` | [uint64](#uint64) | | the revision that the client is currently on | -| `revision_height` | [uint64](#uint64) | | the height within the given revision | - - - - - - - - -### IdentifiedClientState -IdentifiedClientState defines a client state with an additional client -identifier field. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client identifier | -| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | client state | - - - - - - - - -### Params -Params defines the set of IBC light client parameters. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `allowed_clients` | [string](#string) | repeated | allowed_clients defines the list of allowed client state types. | - - - - - - - - -### UpgradeProposal -UpgradeProposal is a gov Content type for initiating an IBC breaking -upgrade. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `title` | [string](#string) | | | -| `description` | [string](#string) | | | -| `plan` | [cosmos.upgrade.v1beta1.Plan](#cosmos.upgrade.v1beta1.Plan) | | | -| `upgraded_client_state` | [google.protobuf.Any](#google.protobuf.Any) | | An UpgradedClientState must be provided to perform an IBC breaking upgrade. This will make the chain commit to the correct upgraded (self) client state before the upgrade occurs, so that connecting chains can verify that the new upgraded client is valid by verifying a proof on the previous version of the chain. This will allow IBC connections to persist smoothly across planned chain upgrades | - - - - - - - - - - - - - - - - -

Top

- -## ibc/core/channel/v1/channel.proto - - - - - -### Acknowledgement -Acknowledgement is the recommended acknowledgement format to be used by -app-specific protocols. -NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental -conflicts with other protobuf message formats used for acknowledgements. -The first byte of any message with this format will be the non-ASCII values -`0xaa` (result) or `0xb2` (error). Implemented as defined by ICS: -https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `result` | [bytes](#bytes) | | | -| `error` | [string](#string) | | | - - - - - - - - -### Channel -Channel defines pipeline for exactly-once packet delivery between specific -modules on separate blockchains, which has at least one end capable of -sending packets and one end capable of receiving packets. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `state` | [State](#ibc.core.channel.v1.State) | | current state of the channel end | -| `ordering` | [Order](#ibc.core.channel.v1.Order) | | whether the channel is ordered or unordered | -| `counterparty` | [Counterparty](#ibc.core.channel.v1.Counterparty) | | counterparty channel end | -| `connection_hops` | [string](#string) | repeated | list of connection identifiers, in order, along which packets sent on this channel will travel | -| `version` | [string](#string) | | opaque channel version, which is agreed upon during the handshake | - - - - - - - - -### Counterparty -Counterparty defines a channel end counterparty - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port on the counterparty chain which owns the other end of the channel. | -| `channel_id` | [string](#string) | | channel end on the counterparty chain | - - - - - - - - -### IdentifiedChannel -IdentifiedChannel defines a channel with additional port and channel -identifier fields. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `state` | [State](#ibc.core.channel.v1.State) | | current state of the channel end | -| `ordering` | [Order](#ibc.core.channel.v1.Order) | | whether the channel is ordered or unordered | -| `counterparty` | [Counterparty](#ibc.core.channel.v1.Counterparty) | | counterparty channel end | -| `connection_hops` | [string](#string) | repeated | list of connection identifiers, in order, along which packets sent on this channel will travel | -| `version` | [string](#string) | | opaque channel version, which is agreed upon during the handshake | -| `port_id` | [string](#string) | | port identifier | -| `channel_id` | [string](#string) | | channel identifier | - - - - - - - - -### Packet -Packet defines a type that carries data across different chains through IBC - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequence` | [uint64](#uint64) | | number corresponds to the order of sends and receives, where a Packet with an earlier sequence number must be sent and received before a Packet with a later sequence number. | -| `source_port` | [string](#string) | | identifies the port on the sending chain. | -| `source_channel` | [string](#string) | | identifies the channel end on the sending chain. | -| `destination_port` | [string](#string) | | identifies the port on the receiving chain. | -| `destination_channel` | [string](#string) | | identifies the channel end on the receiving chain. | -| `data` | [bytes](#bytes) | | actual opaque bytes transferred directly to the application module | -| `timeout_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | block height after which the packet times out | -| `timeout_timestamp` | [uint64](#uint64) | | block timestamp (in nanoseconds) after which the packet times out | - - - - - - - - -### PacketId -PacketId is an identifer for a unique Packet -Source chains refer to packets by source port/channel -Destination chains refer to packets by destination port/channel - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | channel port identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `sequence` | [uint64](#uint64) | | packet sequence | - - - - - - - - -### PacketState -PacketState defines the generic type necessary to retrieve and store -packet commitments, acknowledgements, and receipts. -Caller is responsible for knowing the context necessary to interpret this -state as a commitment, acknowledgement, or a receipt. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | channel port identifier. | -| `channel_id` | [string](#string) | | channel unique identifier. | -| `sequence` | [uint64](#uint64) | | packet sequence. | -| `data` | [bytes](#bytes) | | embedded data that represents packet state. | - - - - - - - - - - -### Order -Order defines if a channel is ORDERED or UNORDERED - -| Name | Number | Description | -| ---- | ------ | ----------- | -| ORDER_NONE_UNSPECIFIED | 0 | zero-value for channel ordering | -| ORDER_UNORDERED | 1 | packets can be delivered in any order, which may differ from the order in which they were sent. | -| ORDER_ORDERED | 2 | packets are delivered exactly in the order which they were sent | - - - - - -### State -State defines if a channel is in one of the following states: -CLOSED, INIT, TRYOPEN, OPEN, INITUPGRADE, TRYUPGRADE or UNINITIALIZED. - -| Name | Number | Description | -| ---- | ------ | ----------- | -| STATE_UNINITIALIZED_UNSPECIFIED | 0 | Default State | -| STATE_INIT | 1 | A channel has just started the opening handshake. | -| STATE_TRYOPEN | 2 | A channel has acknowledged the handshake step on the counterparty chain. | -| STATE_OPEN | 3 | A channel has completed the handshake. Open channels are ready to send and receive packets. | -| STATE_CLOSED | 4 | A channel has been closed and can no longer be used to send or receive packets. | -| STATE_INITUPGRADE | 5 | A channel has just started the channel upgrade handshake. The chain that is proposing the upgrade should set the channel state from OPEN to UPGRADEINIT. | -| STATE_TRYUPGRADE | 6 | A channel has acknowledged the upgrade handshake step on the counterparty chain. The counterparty chain that accepts the upgrade should set the channel state from OPEN to UPGRADETRY. | - - - - - - - - - - - -

Top

- -## ibc/applications/fee/v1/fee.proto - - - - - -### Fee -Fee defines the ICS29 receive, acknowledgement and timeout fees - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `recv_fee` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the packet receive fee | -| `ack_fee` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the packet acknowledgement fee | -| `timeout_fee` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the packet timeout fee | - - - - - - - - -### IdentifiedPacketFees -IdentifiedPacketFees contains a list of type PacketFee and associated PacketId - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | unique packet identifier comprised of the channel ID, port ID and sequence | -| `packet_fees` | [PacketFee](#ibc.applications.fee.v1.PacketFee) | repeated | list of packet fees | - - - - - - - - -### PacketFee -PacketFee contains ICS29 relayer fees, refund address and optional list of permitted relayers - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `fee` | [Fee](#ibc.applications.fee.v1.Fee) | | fee encapsulates the recv, ack and timeout fees associated with an IBC packet | -| `refund_address` | [string](#string) | | the refund address for unspent fees | -| `relayers` | [string](#string) | repeated | optional list of relayers permitted to receive fees | - - - - - - - - -### PacketFees -PacketFees contains a list of type PacketFee - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet_fees` | [PacketFee](#ibc.applications.fee.v1.PacketFee) | repeated | list of packet fees | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/fee/v1/genesis.proto - - - - - -### FeeEnabledChannel -FeeEnabledChannel contains the PortID & ChannelID for a fee enabled channel - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | unique port identifier | -| `channel_id` | [string](#string) | | unique channel identifier | - - - - - - - - -### ForwardRelayerAddress -ForwardRelayerAddress contains the forward relayer address and PacketId used for async acknowledgements - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `address` | [string](#string) | | the forward relayer address | -| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | unique packet identifer comprised of the channel ID, port ID and sequence | - - - - - - - - -### GenesisState -GenesisState defines the ICS29 fee middleware genesis state - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `identified_fees` | [IdentifiedPacketFees](#ibc.applications.fee.v1.IdentifiedPacketFees) | repeated | list of identified packet fees | -| `fee_enabled_channels` | [FeeEnabledChannel](#ibc.applications.fee.v1.FeeEnabledChannel) | repeated | list of fee enabled channels | -| `registered_payees` | [RegisteredPayee](#ibc.applications.fee.v1.RegisteredPayee) | repeated | list of registered payees | -| `registered_counterparty_payees` | [RegisteredCounterpartyPayee](#ibc.applications.fee.v1.RegisteredCounterpartyPayee) | repeated | list of registered counterparty payees | -| `forward_relayers` | [ForwardRelayerAddress](#ibc.applications.fee.v1.ForwardRelayerAddress) | repeated | list of forward relayer addresses | - - - - - - - - -### RegisteredCounterpartyPayee -RegisteredCounterpartyPayee contains the relayer address and counterparty payee address for a specific channel (used -for recv fee distribution) - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channel_id` | [string](#string) | | unique channel identifier | -| `relayer` | [string](#string) | | the relayer address | -| `counterparty_payee` | [string](#string) | | the counterparty payee address | - - - - - - - - -### RegisteredPayee -RegisteredPayee contains the relayer address and payee address for a specific channel - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channel_id` | [string](#string) | | unique channel identifier | -| `relayer` | [string](#string) | | the relayer address | -| `payee` | [string](#string) | | the payee address | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/fee/v1/metadata.proto - - - - - -### Metadata -Metadata defines the ICS29 channel specific metadata encoded into the channel version bytestring -See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `fee_version` | [string](#string) | | fee_version defines the ICS29 fee version | -| `app_version` | [string](#string) | | app_version defines the underlying application version, which may or may not be a JSON encoded bytestring | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/fee/v1/query.proto - - - - - -### QueryCounterpartyPayeeRequest -QueryCounterpartyPayeeRequest defines the request type for the CounterpartyPayee rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channel_id` | [string](#string) | | unique channel identifier | -| `relayer` | [string](#string) | | the relayer address to which the counterparty is registered | - - - - - - - - -### QueryCounterpartyPayeeResponse -QueryCounterpartyPayeeResponse defines the response type for the CounterpartyPayee rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `counterparty_payee` | [string](#string) | | the counterparty payee address used to compensate forward relaying | - - - - - - - - -### QueryFeeEnabledChannelRequest -QueryFeeEnabledChannelRequest defines the request type for the FeeEnabledChannel rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | unique port identifier | -| `channel_id` | [string](#string) | | unique channel identifier | - - - - - - - - -### QueryFeeEnabledChannelResponse -QueryFeeEnabledChannelResponse defines the response type for the FeeEnabledChannel rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `fee_enabled` | [bool](#bool) | | boolean flag representing the fee enabled channel status | - - - - - - - - -### QueryFeeEnabledChannelsRequest -QueryFeeEnabledChannelsRequest defines the request type for the FeeEnabledChannels rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | -| `query_height` | [uint64](#uint64) | | block height at which to query | - - - - - - - - -### QueryFeeEnabledChannelsResponse -QueryFeeEnabledChannelsResponse defines the response type for the FeeEnabledChannels rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `fee_enabled_channels` | [FeeEnabledChannel](#ibc.applications.fee.v1.FeeEnabledChannel) | repeated | list of fee enabled channels | - - - - - - - - -### QueryIncentivizedPacketRequest -QueryIncentivizedPacketRequest defines the request type for the IncentivizedPacket rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | unique packet identifier comprised of channel ID, port ID and sequence | -| `query_height` | [uint64](#uint64) | | block height at which to query | - - - - - - - - -### QueryIncentivizedPacketResponse -QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPacket rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `incentivized_packet` | [IdentifiedPacketFees](#ibc.applications.fee.v1.IdentifiedPacketFees) | | the identified fees for the incentivized packet | - - - - - - - - -### QueryIncentivizedPacketsForChannelRequest -QueryIncentivizedPacketsForChannelRequest defines the request type for querying for all incentivized packets -for a specific channel - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `query_height` | [uint64](#uint64) | | Height to query at | - - - - - - - - -### QueryIncentivizedPacketsForChannelResponse -QueryIncentivizedPacketsResponse defines the response type for the incentivized packets RPC - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `incentivized_packets` | [IdentifiedPacketFees](#ibc.applications.fee.v1.IdentifiedPacketFees) | repeated | Map of all incentivized_packets | - - - - - - - - -### QueryIncentivizedPacketsRequest -QueryIncentivizedPacketsRequest defines the request type for the IncentivizedPackets rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | -| `query_height` | [uint64](#uint64) | | block height at which to query | - - - - - - - - -### QueryIncentivizedPacketsResponse -QueryIncentivizedPacketsResponse defines the response type for the IncentivizedPackets rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `incentivized_packets` | [IdentifiedPacketFees](#ibc.applications.fee.v1.IdentifiedPacketFees) | repeated | list of identified fees for incentivized packets | - - - - - - - - -### QueryPayeeRequest -QueryPayeeRequest defines the request type for the Payee rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channel_id` | [string](#string) | | unique channel identifier | -| `relayer` | [string](#string) | | the relayer address to which the distribution address is registered | - - - - - - - - -### QueryPayeeResponse -QueryPayeeResponse defines the response type for the Payee rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `payee_address` | [string](#string) | | the payee address to which packet fees are paid out | - - - - - - - - -### QueryTotalAckFeesRequest -QueryTotalAckFeesRequest defines the request type for the TotalAckFees rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | the packet identifier for the associated fees | - - - - - - - - -### QueryTotalAckFeesResponse -QueryTotalAckFeesResponse defines the response type for the TotalAckFees rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `ack_fees` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the total packet acknowledgement fees | - - - - - - - - -### QueryTotalRecvFeesRequest -QueryTotalRecvFeesRequest defines the request type for the TotalRecvFees rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | the packet identifier for the associated fees | - - - - - - - - -### QueryTotalRecvFeesResponse -QueryTotalRecvFeesResponse defines the response type for the TotalRecvFees rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `recv_fees` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the total packet receive fees | - - - - - - - - -### QueryTotalTimeoutFeesRequest -QueryTotalTimeoutFeesRequest defines the request type for the TotalTimeoutFees rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | the packet identifier for the associated fees | - - - - - - - - -### QueryTotalTimeoutFeesResponse -QueryTotalTimeoutFeesResponse defines the response type for the TotalTimeoutFees rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `timeout_fees` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the total packet timeout fees | - - - - - - - - - - - - - - -### Query -Query defines the ICS29 gRPC querier service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `IncentivizedPackets` | [QueryIncentivizedPacketsRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketsRequest) | [QueryIncentivizedPacketsResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketsResponse) | IncentivizedPackets returns all incentivized packets and their associated fees | GET|/ibc/apps/fee/v1/incentivized_packets| -| `IncentivizedPacket` | [QueryIncentivizedPacketRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketRequest) | [QueryIncentivizedPacketResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketResponse) | IncentivizedPacket returns all packet fees for a packet given its identifier | GET|/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/incentivized_packet| -| `IncentivizedPacketsForChannel` | [QueryIncentivizedPacketsForChannelRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketsForChannelRequest) | [QueryIncentivizedPacketsForChannelResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketsForChannelResponse) | Gets all incentivized packets for a specific channel | GET|/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/incentivized_packets| -| `TotalRecvFees` | [QueryTotalRecvFeesRequest](#ibc.applications.fee.v1.QueryTotalRecvFeesRequest) | [QueryTotalRecvFeesResponse](#ibc.applications.fee.v1.QueryTotalRecvFeesResponse) | TotalRecvFees returns the total receive fees for a packet given its identifier | GET|/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_recv_fees| -| `TotalAckFees` | [QueryTotalAckFeesRequest](#ibc.applications.fee.v1.QueryTotalAckFeesRequest) | [QueryTotalAckFeesResponse](#ibc.applications.fee.v1.QueryTotalAckFeesResponse) | TotalAckFees returns the total acknowledgement fees for a packet given its identifier | GET|/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_ack_fees| -| `TotalTimeoutFees` | [QueryTotalTimeoutFeesRequest](#ibc.applications.fee.v1.QueryTotalTimeoutFeesRequest) | [QueryTotalTimeoutFeesResponse](#ibc.applications.fee.v1.QueryTotalTimeoutFeesResponse) | TotalTimeoutFees returns the total timeout fees for a packet given its identifier | GET|/ibc/apps/fee/v1/channels/{packet_id.channel_id}/ports/{packet_id.port_id}/sequences/{packet_id.sequence}/total_timeout_fees| -| `Payee` | [QueryPayeeRequest](#ibc.applications.fee.v1.QueryPayeeRequest) | [QueryPayeeResponse](#ibc.applications.fee.v1.QueryPayeeResponse) | Payee returns the registered payee address for a specific channel given the relayer address | GET|/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/payee| -| `CounterpartyPayee` | [QueryCounterpartyPayeeRequest](#ibc.applications.fee.v1.QueryCounterpartyPayeeRequest) | [QueryCounterpartyPayeeResponse](#ibc.applications.fee.v1.QueryCounterpartyPayeeResponse) | CounterpartyPayee returns the registered counterparty payee for forward relaying | GET|/ibc/apps/fee/v1/channels/{channel_id}/relayers/{relayer}/counterparty_payee| -| `FeeEnabledChannels` | [QueryFeeEnabledChannelsRequest](#ibc.applications.fee.v1.QueryFeeEnabledChannelsRequest) | [QueryFeeEnabledChannelsResponse](#ibc.applications.fee.v1.QueryFeeEnabledChannelsResponse) | FeeEnabledChannels returns a list of all fee enabled channels | GET|/ibc/apps/fee/v1/fee_enabled| -| `FeeEnabledChannel` | [QueryFeeEnabledChannelRequest](#ibc.applications.fee.v1.QueryFeeEnabledChannelRequest) | [QueryFeeEnabledChannelResponse](#ibc.applications.fee.v1.QueryFeeEnabledChannelResponse) | FeeEnabledChannel returns true if the provided port and channel identifiers belong to a fee enabled channel | GET|/ibc/apps/fee/v1/channels/{channel_id}/ports/{port_id}/fee_enabled| - - - - - - -

Top

- -## ibc/applications/fee/v1/tx.proto - - - - - -### MsgPayPacketFee -MsgPayPacketFee defines the request type for the PayPacketFee rpc -This Msg can be used to pay for a packet at the next sequence send & should be combined with the Msg that will be -paid for - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `fee` | [Fee](#ibc.applications.fee.v1.Fee) | | fee encapsulates the recv, ack and timeout fees associated with an IBC packet | -| `source_port_id` | [string](#string) | | the source port unique identifier | -| `source_channel_id` | [string](#string) | | the source channel unique identifer | -| `signer` | [string](#string) | | account address to refund fee if necessary | -| `relayers` | [string](#string) | repeated | optional list of relayers permitted to the receive packet fees | - - - - - - - - -### MsgPayPacketFeeAsync -MsgPayPacketFeeAsync defines the request type for the PayPacketFeeAsync rpc -This Msg can be used to pay for a packet at a specified sequence (instead of the next sequence send) - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | unique packet identifier comprised of the channel ID, port ID and sequence | -| `packet_fee` | [PacketFee](#ibc.applications.fee.v1.PacketFee) | | the packet fee associated with a particular IBC packet | - - - - - - - - -### MsgPayPacketFeeAsyncResponse -MsgPayPacketFeeAsyncResponse defines the response type for the PayPacketFeeAsync rpc - - - - - - - - -### MsgPayPacketFeeResponse -MsgPayPacketFeeResponse defines the response type for the PayPacketFee rpc - - - - - - - - -### MsgRegisterCounterpartyPayee -MsgRegisterCounterpartyPayee defines the request type for the RegisterCounterpartyPayee rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | unique port identifier | -| `channel_id` | [string](#string) | | unique channel identifier | -| `relayer` | [string](#string) | | the relayer address | -| `counterparty_payee` | [string](#string) | | the counterparty payee address | - - - - - - - - -### MsgRegisterCounterpartyPayeeResponse -MsgRegisterCounterpartyPayeeResponse defines the response type for the RegisterCounterpartyPayee rpc - - - - - - - - -### MsgRegisterPayee -MsgRegisterPayee defines the request type for the RegisterPayee rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | unique port identifier | -| `channel_id` | [string](#string) | | unique channel identifier | -| `relayer` | [string](#string) | | the relayer address | -| `payee` | [string](#string) | | the payee address | - - - - - - - - -### MsgRegisterPayeeResponse -MsgRegisterPayeeResponse defines the response type for the RegisterPayee rpc - - - - - - - - - - - - - - -### Msg -Msg defines the ICS29 Msg service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `RegisterPayee` | [MsgRegisterPayee](#ibc.applications.fee.v1.MsgRegisterPayee) | [MsgRegisterPayeeResponse](#ibc.applications.fee.v1.MsgRegisterPayeeResponse) | RegisterPayee defines a rpc handler method for MsgRegisterPayee RegisterPayee is called by the relayer on each channelEnd and allows them to set an optional payee to which reverse and timeout relayer packet fees will be paid out. The payee should be registered on the source chain from which packets originate as this is where fee distribution takes place. This function may be called more than once by a relayer, in which case, the latest payee is always used. | | -| `RegisterCounterpartyPayee` | [MsgRegisterCounterpartyPayee](#ibc.applications.fee.v1.MsgRegisterCounterpartyPayee) | [MsgRegisterCounterpartyPayeeResponse](#ibc.applications.fee.v1.MsgRegisterCounterpartyPayeeResponse) | RegisterCounterpartyPayee defines a rpc handler method for MsgRegisterCounterpartyPayee RegisterCounterpartyPayee is called by the relayer on each channelEnd and allows them to specify the counterparty payee address before relaying. This ensures they will be properly compensated for forward relaying since the destination chain must include the registered counterparty payee address in the acknowledgement. This function may be called more than once by a relayer, in which case, the latest counterparty payee address is always used. | | -| `PayPacketFee` | [MsgPayPacketFee](#ibc.applications.fee.v1.MsgPayPacketFee) | [MsgPayPacketFeeResponse](#ibc.applications.fee.v1.MsgPayPacketFeeResponse) | PayPacketFee defines a rpc handler method for MsgPayPacketFee PayPacketFee is an open callback that may be called by any module/user that wishes to escrow funds in order to incentivize the relaying of the packet at the next sequence NOTE: This method is intended to be used within a multi msg transaction, where the subsequent msg that follows initiates the lifecycle of the incentivized packet | | -| `PayPacketFeeAsync` | [MsgPayPacketFeeAsync](#ibc.applications.fee.v1.MsgPayPacketFeeAsync) | [MsgPayPacketFeeAsyncResponse](#ibc.applications.fee.v1.MsgPayPacketFeeAsyncResponse) | PayPacketFeeAsync defines a rpc handler method for MsgPayPacketFeeAsync PayPacketFeeAsync is an open callback that may be called by any module/user that wishes to escrow funds in order to incentivize the relaying of a known packet (i.e. at a particular sequence) | | - - - - - - -

Top

- -## ibc/applications/interchain_accounts/controller/v1/controller.proto - - - - - -### Params -Params defines the set of on-chain interchain accounts parameters. -The following parameters may be used to disable the controller submodule. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `controller_enabled` | [bool](#bool) | | controller_enabled enables or disables the controller submodule. | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/interchain_accounts/controller/v1/query.proto - - - - - -### QueryParamsRequest -QueryParamsRequest is the request type for the Query/Params RPC method. - - - - - - - - -### QueryParamsResponse -QueryParamsResponse is the response type for the Query/Params RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `params` | [Params](#ibc.applications.interchain_accounts.controller.v1.Params) | | params defines the parameters of the module. | - - - - - - - - - - - - - - -### Query -Query provides defines the gRPC querier service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `Params` | [QueryParamsRequest](#ibc.applications.interchain_accounts.controller.v1.QueryParamsRequest) | [QueryParamsResponse](#ibc.applications.interchain_accounts.controller.v1.QueryParamsResponse) | Params queries all parameters of the ICA controller submodule. | GET|/ibc/apps/interchain_accounts/controller/v1/params| - - - - - - -

Top

- -## ibc/applications/interchain_accounts/host/v1/host.proto - - - - - -### Params -Params defines the set of on-chain interchain accounts parameters. -The following parameters may be used to disable the host submodule. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `host_enabled` | [bool](#bool) | | host_enabled enables or disables the host submodule. | -| `allow_messages` | [string](#string) | repeated | allow_messages defines a list of sdk message typeURLs allowed to be executed on a host chain. | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/interchain_accounts/host/v1/query.proto - - - - - -### QueryParamsRequest -QueryParamsRequest is the request type for the Query/Params RPC method. - - - - - - - - -### QueryParamsResponse -QueryParamsResponse is the response type for the Query/Params RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `params` | [Params](#ibc.applications.interchain_accounts.host.v1.Params) | | params defines the parameters of the module. | - - - - - - - - - - - - - - -### Query -Query provides defines the gRPC querier service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `Params` | [QueryParamsRequest](#ibc.applications.interchain_accounts.host.v1.QueryParamsRequest) | [QueryParamsResponse](#ibc.applications.interchain_accounts.host.v1.QueryParamsResponse) | Params queries all parameters of the ICA host submodule. | GET|/ibc/apps/interchain_accounts/host/v1/params| - - - - - - -

Top

- -## ibc/applications/interchain_accounts/v1/account.proto - - - - - -### InterchainAccount -An InterchainAccount is defined as a BaseAccount & the address of the account owner on the controller chain - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `base_account` | [cosmos.auth.v1beta1.BaseAccount](#cosmos.auth.v1beta1.BaseAccount) | | | -| `account_owner` | [string](#string) | | | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/interchain_accounts/v1/genesis.proto - - - - - -### ActiveChannel -ActiveChannel contains a connection ID, port ID and associated active channel ID - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection_id` | [string](#string) | | | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | - - - - - - - - -### ControllerGenesisState -ControllerGenesisState defines the interchain accounts controller genesis state - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `active_channels` | [ActiveChannel](#ibc.applications.interchain_accounts.v1.ActiveChannel) | repeated | | -| `interchain_accounts` | [RegisteredInterchainAccount](#ibc.applications.interchain_accounts.v1.RegisteredInterchainAccount) | repeated | | -| `ports` | [string](#string) | repeated | | -| `params` | [ibc.applications.interchain_accounts.controller.v1.Params](#ibc.applications.interchain_accounts.controller.v1.Params) | | | - - - - - - - - -### GenesisState -GenesisState defines the interchain accounts genesis state - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `controller_genesis_state` | [ControllerGenesisState](#ibc.applications.interchain_accounts.v1.ControllerGenesisState) | | | -| `host_genesis_state` | [HostGenesisState](#ibc.applications.interchain_accounts.v1.HostGenesisState) | | | - - - - - - - - -### HostGenesisState -HostGenesisState defines the interchain accounts host genesis state - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `active_channels` | [ActiveChannel](#ibc.applications.interchain_accounts.v1.ActiveChannel) | repeated | | -| `interchain_accounts` | [RegisteredInterchainAccount](#ibc.applications.interchain_accounts.v1.RegisteredInterchainAccount) | repeated | | -| `port` | [string](#string) | | | -| `params` | [ibc.applications.interchain_accounts.host.v1.Params](#ibc.applications.interchain_accounts.host.v1.Params) | | | - - - - - - - - -### RegisteredInterchainAccount -RegisteredInterchainAccount contains a connection ID, port ID and associated interchain account address - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection_id` | [string](#string) | | | -| `port_id` | [string](#string) | | | -| `account_address` | [string](#string) | | | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/interchain_accounts/v1/metadata.proto - - - - - -### Metadata -Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring -See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `version` | [string](#string) | | version defines the ICS27 protocol version | -| `controller_connection_id` | [string](#string) | | controller_connection_id is the connection identifier associated with the controller chain | -| `host_connection_id` | [string](#string) | | host_connection_id is the connection identifier associated with the host chain | -| `address` | [string](#string) | | address defines the interchain account address to be fulfilled upon the OnChanOpenTry handshake step NOTE: the address field is empty on the OnChanOpenInit handshake step | -| `encoding` | [string](#string) | | encoding defines the supported codec format | -| `tx_type` | [string](#string) | | tx_type defines the type of transactions the interchain account can execute | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/interchain_accounts/v1/packet.proto - - - - - -### CosmosTx -CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `messages` | [google.protobuf.Any](#google.protobuf.Any) | repeated | | - - - - - - - - -### InterchainAccountPacketData -InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `type` | [Type](#ibc.applications.interchain_accounts.v1.Type) | | | -| `data` | [bytes](#bytes) | | | -| `memo` | [string](#string) | | | - - - - - - - - - - -### Type -Type defines a classification of message issued from a controller chain to its associated interchain accounts -host - -| Name | Number | Description | -| ---- | ------ | ----------- | -| TYPE_UNSPECIFIED | 0 | Default zero value enumeration | -| TYPE_EXECUTE_TX | 1 | Execute a transaction on an interchain accounts host chain | - - - - - - - - - - - -

Top

- -## ibc/applications/transfer/v1/transfer.proto - - - - - -### DenomTrace -DenomTrace contains the base denomination for ICS20 fungible tokens and the -source tracing information path. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [string](#string) | | path defines the chain of port/channel identifiers used for tracing the source of the fungible token. | -| `base_denom` | [string](#string) | | base denomination of the relayed fungible token. | - - - - - - - - -### Params -Params defines the set of IBC transfer parameters. -NOTE: To prevent a single token from being transferred, set the -TransfersEnabled parameter to true and then set the bank module's SendEnabled -parameter for the denomination to false. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `send_enabled` | [bool](#bool) | | send_enabled enables or disables all cross-chain token transfers from this chain. | -| `receive_enabled` | [bool](#bool) | | receive_enabled enables or disables all cross-chain token transfers to this chain. | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/transfer/v1/genesis.proto - - - - - -### GenesisState -GenesisState defines the ibc-transfer genesis state - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `denom_traces` | [DenomTrace](#ibc.applications.transfer.v1.DenomTrace) | repeated | | -| `params` | [Params](#ibc.applications.transfer.v1.Params) | | | - - - - - - - - - - - - - - - - -

Top

- -## ibc/applications/transfer/v1/query.proto - - - - - -### QueryDenomHashRequest -QueryDenomHashRequest is the request type for the Query/DenomHash RPC -method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `trace` | [string](#string) | | The denomination trace ([port_id]/[channel_id])+/[denom] | - - - - - - - - -### QueryDenomHashResponse -QueryDenomHashResponse is the response type for the Query/DenomHash RPC -method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `hash` | [string](#string) | | hash (in hex format) of the denomination trace information. | - - - - - - - - -### QueryDenomTraceRequest -QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC -method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `hash` | [string](#string) | | hash (in hex format) or denom (full denom with ibc prefix) of the denomination trace information. | - - - - - - - - -### QueryDenomTraceResponse -QueryDenomTraceResponse is the response type for the Query/DenomTrace RPC -method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `denom_trace` | [DenomTrace](#ibc.applications.transfer.v1.DenomTrace) | | denom_trace returns the requested denomination trace information. | - - - - - - - - -### QueryDenomTracesRequest -QueryConnectionsRequest is the request type for the Query/DenomTraces RPC -method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination defines an optional pagination for the request. | - - - - - - - - -### QueryDenomTracesResponse -QueryConnectionsResponse is the response type for the Query/DenomTraces RPC -method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `denom_traces` | [DenomTrace](#ibc.applications.transfer.v1.DenomTrace) | repeated | denom_traces returns all denominations trace information. | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination defines the pagination in the response. | - - - - - - - - -### QueryEscrowAddressRequest -QueryEscrowAddressRequest is the request type for the EscrowAddress RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | unique port identifier | -| `channel_id` | [string](#string) | | unique channel identifier | - - - - - - - - -### QueryEscrowAddressResponse -QueryEscrowAddressResponse is the response type of the EscrowAddress RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `escrow_address` | [string](#string) | | the escrow account address | - - - - - - - - -### QueryParamsRequest -QueryParamsRequest is the request type for the Query/Params RPC method. - - - - - - - - -### QueryParamsResponse -QueryParamsResponse is the response type for the Query/Params RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `params` | [Params](#ibc.applications.transfer.v1.Params) | | params defines the parameters of the module. | - - - - - - - - - - - - - - -### Query -Query provides defines the gRPC querier service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `DenomTrace` | [QueryDenomTraceRequest](#ibc.applications.transfer.v1.QueryDenomTraceRequest) | [QueryDenomTraceResponse](#ibc.applications.transfer.v1.QueryDenomTraceResponse) | DenomTrace queries a denomination trace information. | GET|/ibc/apps/transfer/v1/denom_traces/{hash}| -| `DenomTraces` | [QueryDenomTracesRequest](#ibc.applications.transfer.v1.QueryDenomTracesRequest) | [QueryDenomTracesResponse](#ibc.applications.transfer.v1.QueryDenomTracesResponse) | DenomTraces queries all denomination traces. | GET|/ibc/apps/transfer/v1/denom_traces| -| `Params` | [QueryParamsRequest](#ibc.applications.transfer.v1.QueryParamsRequest) | [QueryParamsResponse](#ibc.applications.transfer.v1.QueryParamsResponse) | Params queries all parameters of the ibc-transfer module. | GET|/ibc/apps/transfer/v1/params| -| `DenomHash` | [QueryDenomHashRequest](#ibc.applications.transfer.v1.QueryDenomHashRequest) | [QueryDenomHashResponse](#ibc.applications.transfer.v1.QueryDenomHashResponse) | DenomHash queries a denomination hash information. | GET|/ibc/apps/transfer/v1/denom_hashes/{trace}| -| `EscrowAddress` | [QueryEscrowAddressRequest](#ibc.applications.transfer.v1.QueryEscrowAddressRequest) | [QueryEscrowAddressResponse](#ibc.applications.transfer.v1.QueryEscrowAddressResponse) | EscrowAddress returns the escrow address for a particular port and channel id. | GET|/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address| - - - - - - -

Top

- -## ibc/applications/transfer/v1/tx.proto - - - - - -### MsgTransfer -MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between -ICS20 enabled chains. See ICS Spec here: -https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `source_port` | [string](#string) | | the port on which the packet will be sent | -| `source_channel` | [string](#string) | | the channel by which the packet will be sent | -| `token` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | the tokens to be transferred | -| `sender` | [string](#string) | | the sender address | -| `receiver` | [string](#string) | | the recipient address on the destination chain | -| `timeout_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | Timeout height relative to the current block height. The timeout is disabled when set to 0. | -| `timeout_timestamp` | [uint64](#uint64) | | Timeout timestamp in absolute nanoseconds since unix epoch. The timeout is disabled when set to 0. | - - - - - - - - -### MsgTransferResponse -MsgTransferResponse defines the Msg/Transfer response type. - - - - - - - - - - - - - - -### Msg -Msg defines the ibc/transfer Msg service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `Transfer` | [MsgTransfer](#ibc.applications.transfer.v1.MsgTransfer) | [MsgTransferResponse](#ibc.applications.transfer.v1.MsgTransferResponse) | Transfer defines a rpc handler method for MsgTransfer. | | - - - - - - -

Top

- -## ibc/applications/transfer/v2/packet.proto - - - - - -### FungibleTokenPacketData -FungibleTokenPacketData defines a struct for the packet payload -See FungibleTokenPacketData spec: -https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `denom` | [string](#string) | | the token denomination to be transferred | -| `amount` | [string](#string) | | the token amount to be transferred | -| `sender` | [string](#string) | | the sender address | -| `receiver` | [string](#string) | | the recipient address on the destination chain | - - - - - - - - - - - - - - - - -

Top

- -## ibc/core/channel/v1/genesis.proto - - - - - -### GenesisState -GenesisState defines the ibc channel submodule's genesis state. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channels` | [IdentifiedChannel](#ibc.core.channel.v1.IdentifiedChannel) | repeated | | -| `acknowledgements` | [PacketState](#ibc.core.channel.v1.PacketState) | repeated | | -| `commitments` | [PacketState](#ibc.core.channel.v1.PacketState) | repeated | | -| `receipts` | [PacketState](#ibc.core.channel.v1.PacketState) | repeated | | -| `send_sequences` | [PacketSequence](#ibc.core.channel.v1.PacketSequence) | repeated | | -| `recv_sequences` | [PacketSequence](#ibc.core.channel.v1.PacketSequence) | repeated | | -| `ack_sequences` | [PacketSequence](#ibc.core.channel.v1.PacketSequence) | repeated | | -| `next_channel_sequence` | [uint64](#uint64) | | the sequence for the next generated channel identifier | - - - - - - - - -### PacketSequence -PacketSequence defines the genesis type necessary to retrieve and store -next send and receive sequences. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `sequence` | [uint64](#uint64) | | | - - - - - - - - - - - - - - - - -

Top

- -## ibc/core/channel/v1/query.proto - - - - - -### QueryChannelClientStateRequest -QueryChannelClientStateRequest is the request type for the Query/ClientState -RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | - - - - - - - - -### QueryChannelClientStateResponse -QueryChannelClientStateResponse is the Response type for the -Query/QueryChannelClientState RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `identified_client_state` | [ibc.core.client.v1.IdentifiedClientState](#ibc.core.client.v1.IdentifiedClientState) | | client state associated with the channel | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryChannelConsensusStateRequest -QueryChannelConsensusStateRequest is the request type for the -Query/ConsensusState RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `revision_number` | [uint64](#uint64) | | revision number of the consensus state | -| `revision_height` | [uint64](#uint64) | | revision height of the consensus state | - - - - - - - - -### QueryChannelConsensusStateResponse -QueryChannelClientStateResponse is the Response type for the -Query/QueryChannelClientState RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | consensus state associated with the channel | -| `client_id` | [string](#string) | | client ID associated with the consensus state | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryChannelRequest -QueryChannelRequest is the request type for the Query/Channel RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | - - - - - - - - -### QueryChannelResponse -QueryChannelResponse is the response type for the Query/Channel RPC method. -Besides the Channel end, it includes a proof and the height from which the -proof was retrieved. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channel` | [Channel](#ibc.core.channel.v1.Channel) | | channel associated with the request identifiers | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryChannelsRequest -QueryChannelsRequest is the request type for the Query/Channels RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination request | - - - - - - - - -### QueryChannelsResponse -QueryChannelsResponse is the response type for the Query/Channels RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channels` | [IdentifiedChannel](#ibc.core.channel.v1.IdentifiedChannel) | repeated | list of stored channels of the chain. | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination response | -| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | query block height | - - - - - - - - -### QueryConnectionChannelsRequest -QueryConnectionChannelsRequest is the request type for the -Query/QueryConnectionChannels RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection` | [string](#string) | | connection unique identifier | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination request | - - - - - - - - -### QueryConnectionChannelsResponse -QueryConnectionChannelsResponse is the Response type for the -Query/QueryConnectionChannels RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channels` | [IdentifiedChannel](#ibc.core.channel.v1.IdentifiedChannel) | repeated | list of channels associated with a connection. | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination response | -| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | query block height | - - - - - - - - -### QueryNextSequenceReceiveRequest -QueryNextSequenceReceiveRequest is the request type for the -Query/QueryNextSequenceReceiveRequest RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | - - - - - - - - -### QueryNextSequenceReceiveResponse -QuerySequenceResponse is the request type for the -Query/QueryNextSequenceReceiveResponse RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `next_sequence_receive` | [uint64](#uint64) | | next sequence receive number | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryPacketAcknowledgementRequest -QueryPacketAcknowledgementRequest is the request type for the -Query/PacketAcknowledgement RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `sequence` | [uint64](#uint64) | | packet sequence | - - - - - - - - -### QueryPacketAcknowledgementResponse -QueryPacketAcknowledgementResponse defines the client query response for a -packet which also includes a proof and the height from which the -proof was retrieved - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `acknowledgement` | [bytes](#bytes) | | packet associated with the request fields | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryPacketAcknowledgementsRequest -QueryPacketAcknowledgementsRequest is the request type for the -Query/QueryPacketCommitments RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination request | -| `packet_commitment_sequences` | [uint64](#uint64) | repeated | list of packet sequences | - - - - - - - - -### QueryPacketAcknowledgementsResponse -QueryPacketAcknowledgemetsResponse is the request type for the -Query/QueryPacketAcknowledgements RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `acknowledgements` | [PacketState](#ibc.core.channel.v1.PacketState) | repeated | | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination response | -| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | query block height | - - - - - - - - -### QueryPacketCommitmentRequest -QueryPacketCommitmentRequest is the request type for the -Query/PacketCommitment RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `sequence` | [uint64](#uint64) | | packet sequence | - - - - - - - - -### QueryPacketCommitmentResponse -QueryPacketCommitmentResponse defines the client query response for a packet -which also includes a proof and the height from which the proof was -retrieved - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `commitment` | [bytes](#bytes) | | packet associated with the request fields | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryPacketCommitmentsRequest -QueryPacketCommitmentsRequest is the request type for the -Query/QueryPacketCommitments RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination request | - - - - - - - - -### QueryPacketCommitmentsResponse -QueryPacketCommitmentsResponse is the request type for the -Query/QueryPacketCommitments RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `commitments` | [PacketState](#ibc.core.channel.v1.PacketState) | repeated | | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination response | -| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | query block height | - - - - - - - - -### QueryPacketReceiptRequest -QueryPacketReceiptRequest is the request type for the -Query/PacketReceipt RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `sequence` | [uint64](#uint64) | | packet sequence | - - - - - - - - -### QueryPacketReceiptResponse -QueryPacketReceiptResponse defines the client query response for a packet -receipt which also includes a proof, and the height from which the proof was -retrieved - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `received` | [bool](#bool) | | success flag for if receipt exists | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryUnreceivedAcksRequest -QueryUnreceivedAcks is the request type for the -Query/UnreceivedAcks RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `packet_ack_sequences` | [uint64](#uint64) | repeated | list of acknowledgement sequences | - - - - - - - - -### QueryUnreceivedAcksResponse -QueryUnreceivedAcksResponse is the response type for the -Query/UnreceivedAcks RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequences` | [uint64](#uint64) | repeated | list of unreceived acknowledgement sequences | -| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | query block height | - - - - - - - - -### QueryUnreceivedPacketsRequest -QueryUnreceivedPacketsRequest is the request type for the -Query/UnreceivedPackets RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | port unique identifier | -| `channel_id` | [string](#string) | | channel unique identifier | -| `packet_commitment_sequences` | [uint64](#uint64) | repeated | list of packet sequences | - - - - - - - - -### QueryUnreceivedPacketsResponse -QueryUnreceivedPacketsResponse is the response type for the -Query/UnreceivedPacketCommitments RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequences` | [uint64](#uint64) | repeated | list of unreceived packet sequences | -| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | query block height | - - - - - - - - - - - - - - -### Query -Query provides defines the gRPC querier service - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `Channel` | [QueryChannelRequest](#ibc.core.channel.v1.QueryChannelRequest) | [QueryChannelResponse](#ibc.core.channel.v1.QueryChannelResponse) | Channel queries an IBC Channel. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}| -| `Channels` | [QueryChannelsRequest](#ibc.core.channel.v1.QueryChannelsRequest) | [QueryChannelsResponse](#ibc.core.channel.v1.QueryChannelsResponse) | Channels queries all the IBC channels of a chain. | GET|/ibc/core/channel/v1/channels| -| `ConnectionChannels` | [QueryConnectionChannelsRequest](#ibc.core.channel.v1.QueryConnectionChannelsRequest) | [QueryConnectionChannelsResponse](#ibc.core.channel.v1.QueryConnectionChannelsResponse) | ConnectionChannels queries all the channels associated with a connection end. | GET|/ibc/core/channel/v1/connections/{connection}/channels| -| `ChannelClientState` | [QueryChannelClientStateRequest](#ibc.core.channel.v1.QueryChannelClientStateRequest) | [QueryChannelClientStateResponse](#ibc.core.channel.v1.QueryChannelClientStateResponse) | ChannelClientState queries for the client state for the channel associated with the provided channel identifiers. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/client_state| -| `ChannelConsensusState` | [QueryChannelConsensusStateRequest](#ibc.core.channel.v1.QueryChannelConsensusStateRequest) | [QueryChannelConsensusStateResponse](#ibc.core.channel.v1.QueryChannelConsensusStateResponse) | ChannelConsensusState queries for the consensus state for the channel associated with the provided channel identifiers. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/consensus_state/revision/{revision_number}/height/{revision_height}| -| `PacketCommitment` | [QueryPacketCommitmentRequest](#ibc.core.channel.v1.QueryPacketCommitmentRequest) | [QueryPacketCommitmentResponse](#ibc.core.channel.v1.QueryPacketCommitmentResponse) | PacketCommitment queries a stored packet commitment hash. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{sequence}| -| `PacketCommitments` | [QueryPacketCommitmentsRequest](#ibc.core.channel.v1.QueryPacketCommitmentsRequest) | [QueryPacketCommitmentsResponse](#ibc.core.channel.v1.QueryPacketCommitmentsResponse) | PacketCommitments returns all the packet commitments hashes associated with a channel. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments| -| `PacketReceipt` | [QueryPacketReceiptRequest](#ibc.core.channel.v1.QueryPacketReceiptRequest) | [QueryPacketReceiptResponse](#ibc.core.channel.v1.QueryPacketReceiptResponse) | PacketReceipt queries if a given packet sequence has been received on the queried chain | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_receipts/{sequence}| -| `PacketAcknowledgement` | [QueryPacketAcknowledgementRequest](#ibc.core.channel.v1.QueryPacketAcknowledgementRequest) | [QueryPacketAcknowledgementResponse](#ibc.core.channel.v1.QueryPacketAcknowledgementResponse) | PacketAcknowledgement queries a stored packet acknowledgement hash. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acks/{sequence}| -| `PacketAcknowledgements` | [QueryPacketAcknowledgementsRequest](#ibc.core.channel.v1.QueryPacketAcknowledgementsRequest) | [QueryPacketAcknowledgementsResponse](#ibc.core.channel.v1.QueryPacketAcknowledgementsResponse) | PacketAcknowledgements returns all the packet acknowledgements associated with a channel. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acknowledgements| -| `UnreceivedPackets` | [QueryUnreceivedPacketsRequest](#ibc.core.channel.v1.QueryUnreceivedPacketsRequest) | [QueryUnreceivedPacketsResponse](#ibc.core.channel.v1.QueryUnreceivedPacketsResponse) | UnreceivedPackets returns all the unreceived IBC packets associated with a channel and sequences. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{packet_commitment_sequences}/unreceived_packets| -| `UnreceivedAcks` | [QueryUnreceivedAcksRequest](#ibc.core.channel.v1.QueryUnreceivedAcksRequest) | [QueryUnreceivedAcksResponse](#ibc.core.channel.v1.QueryUnreceivedAcksResponse) | UnreceivedAcks returns all the unreceived IBC acknowledgements associated with a channel and sequences. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_commitments/{packet_ack_sequences}/unreceived_acks| -| `NextSequenceReceive` | [QueryNextSequenceReceiveRequest](#ibc.core.channel.v1.QueryNextSequenceReceiveRequest) | [QueryNextSequenceReceiveResponse](#ibc.core.channel.v1.QueryNextSequenceReceiveResponse) | NextSequenceReceive returns the next receive sequence for a given channel. | GET|/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/next_sequence| - - - - - - -

Top

- -## ibc/core/channel/v1/upgrade.proto - - - - - -### ErrorReceipt -ErrorReceipt defines a type which encapsulates the upgrade sequence and error associated with the -upgrade handshake failure. When a channel upgrade handshake is aborted both chains are expected to increment to the -next sequence. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequence` | [uint64](#uint64) | | the channel upgrade sequence | -| `error` | [string](#string) | | the error message detailing the cause of failure | - - - - - - - - -### UpgradeTimeout -UpgradeTimeout defines a type which encapsulates the upgrade timeout values at which the counterparty -must no longer proceed with the upgrade handshake. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `timeout_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | block height after which the upgrade times out | -| `timeout_timestamp` | [uint64](#uint64) | | block timestamp (in nanoseconds) after which the upgrade times out | - - - - - - - - - - - - - - - - -

Top

- -## ibc/core/channel/v1/tx.proto - - - - - -### MsgAcknowledgement -MsgAcknowledgement receives incoming IBC acknowledgement - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet` | [Packet](#ibc.core.channel.v1.Packet) | | | -| `acknowledgement` | [bytes](#bytes) | | | -| `proof_acked` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgAcknowledgementResponse -MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `result` | [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) | | | - - - - - - - - -### MsgChannelCloseConfirm -MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B -to acknowledge the change of channel state to CLOSED on Chain A. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `proof_init` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelCloseConfirmResponse -MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response -type. - - - - - - - - -### MsgChannelCloseInit -MsgChannelCloseInit defines a msg sent by a Relayer to Chain A -to close a channel with Chain B. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelCloseInitResponse -MsgChannelCloseInitResponse defines the Msg/ChannelCloseInit response type. - - - - - - - - -### MsgChannelOpenAck -MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge -the change of channel state to TRYOPEN on Chain B. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `counterparty_channel_id` | [string](#string) | | | -| `counterparty_version` | [string](#string) | | | -| `proof_try` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelOpenAckResponse -MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type. - - - - - - - - -### MsgChannelOpenConfirm -MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to -acknowledge the change of channel state to OPEN on Chain A. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `proof_ack` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelOpenConfirmResponse -MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response -type. - - - - - - - - -### MsgChannelOpenInit -MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It -is called by a relayer on Chain A. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel` | [Channel](#ibc.core.channel.v1.Channel) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelOpenInitResponse -MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `channel_id` | [string](#string) | | | -| `version` | [string](#string) | | | - - - - - - - - -### MsgChannelOpenTry -MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel -on Chain B. The version field within the Channel field has been deprecated. Its -value will be ignored by core IBC. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `previous_channel_id` | [string](#string) | | **Deprecated.** Deprecated: this field is unused. Crossing hello's are no longer supported in core IBC. | -| `channel` | [Channel](#ibc.core.channel.v1.Channel) | | NOTE: the version field within the channel has been deprecated. Its value will be ignored by core IBC. | -| `counterparty_version` | [string](#string) | | | -| `proof_init` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelOpenTryResponse -MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `version` | [string](#string) | | | - - - - - - - - -### MsgChannelUpgradeAck -MsgChannelUpgradeAck defines the request type for the ChannelUpgradeAck rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `counterparty_channel` | [Channel](#ibc.core.channel.v1.Channel) | | | -| `proof_channel` | [bytes](#bytes) | | | -| `proof_upgrade_sequence` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelUpgradeAckResponse -MsgChannelUpgradeAckResponse defines MsgChannelUpgradeAck response type - - - - - - - - -### MsgChannelUpgradeCancel -MsgChannelUpgradeCancel defines the request type for the ChannelUpgradeCancel rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `error_receipt` | [ErrorReceipt](#ibc.core.channel.v1.ErrorReceipt) | | | -| `proof_error_receipt` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelUpgradeCancelResponse -MsgChannelUpgradeCancelResponse defines the MsgChannelUpgradeCancel response type - - - - - - - - -### MsgChannelUpgradeConfirm -MsgChannelUpgradeConfirm defines the request type for the ChannelUpgradeConfirm rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `counterparty_channel` | [Channel](#ibc.core.channel.v1.Channel) | | | -| `proof_channel` | [bytes](#bytes) | | | -| `proof_upgrade_error` | [bytes](#bytes) | | | -| `proof_upgrade_sequence` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelUpgradeConfirmResponse -MsgChannelUpgradeConfirmResponse defines the MsgChannelUpgradeConfirm response type - - - - - - - - -### MsgChannelUpgradeInit -MsgChanelUpgradeInit defines the request type for the ChannelUpgradeInit rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `proposed_upgrade_channel` | [Channel](#ibc.core.channel.v1.Channel) | | | -| `timeout_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `timeout_timestamp` | [uint64](#uint64) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelUpgradeInitResponse -MsgChannelUpgradeInitResponse defines the MsgChannelUpgradeInit response type - - - - - - - - -### MsgChannelUpgradeTimeout -MsgChannelUpgradeTimeout defines the request type for the ChannelUpgradeTimeout rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `counterparty_channel` | [Channel](#ibc.core.channel.v1.Channel) | | | -| `previous_error_receipt` | [ErrorReceipt](#ibc.core.channel.v1.ErrorReceipt) | | | -| `proof_channel` | [bytes](#bytes) | | | -| `proof_error_receipt` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelUpgradeTimeoutResponse -MsgChannelUpgradeTimeoutRepsonse defines the MsgChannelUpgradeTimeout response type - - - - - - - - -### MsgChannelUpgradeTry -MsgChannelUpgradeTry defines the request type for the ChannelUpgradeTry rpc - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `port_id` | [string](#string) | | | -| `channel_id` | [string](#string) | | | -| `counterparty_channel` | [Channel](#ibc.core.channel.v1.Channel) | | | -| `counterparty_sequence` | [uint64](#uint64) | | | -| `proposed_upgrade_channel` | [Channel](#ibc.core.channel.v1.Channel) | | | -| `timeout_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `timeout_timestamp` | [uint64](#uint64) | | | -| `proof_channel` | [bytes](#bytes) | | | -| `proof_upgrade_timeout` | [bytes](#bytes) | | | -| `proof_upgrade_sequence` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgChannelUpgradeTryResponse -MsgChannelUpgradeTryResponse defines the MsgChannelUpgradeTry response type - - - - - - - - -### MsgRecvPacket -MsgRecvPacket receives incoming IBC packet - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet` | [Packet](#ibc.core.channel.v1.Packet) | | | -| `proof_commitment` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgRecvPacketResponse -MsgRecvPacketResponse defines the Msg/RecvPacket response type. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `result` | [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) | | | - - - - - - - - -### MsgTimeout -MsgTimeout receives timed-out packet - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet` | [Packet](#ibc.core.channel.v1.Packet) | | | -| `proof_unreceived` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `next_sequence_recv` | [uint64](#uint64) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgTimeoutOnClose -MsgTimeoutOnClose timed-out packet upon counterparty channel closure. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `packet` | [Packet](#ibc.core.channel.v1.Packet) | | | -| `proof_unreceived` | [bytes](#bytes) | | | -| `proof_close` | [bytes](#bytes) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `next_sequence_recv` | [uint64](#uint64) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgTimeoutOnCloseResponse -MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `result` | [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) | | | - - - - - - - - -### MsgTimeoutResponse -MsgTimeoutResponse defines the Msg/Timeout response type. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `result` | [ResponseResultType](#ibc.core.channel.v1.ResponseResultType) | | | - - - - - - - - - - -### ResponseResultType -ResponseResultType defines the possible outcomes of the execution of a message - -| Name | Number | Description | -| ---- | ------ | ----------- | -| RESPONSE_RESULT_TYPE_UNSPECIFIED | 0 | Default zero value enumeration | -| RESPONSE_RESULT_TYPE_NOOP | 1 | The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) | -| RESPONSE_RESULT_TYPE_SUCCESS | 2 | The message was executed successfully | - - - - - - - - - -### Msg -Msg defines the ibc/channel Msg service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `ChannelOpenInit` | [MsgChannelOpenInit](#ibc.core.channel.v1.MsgChannelOpenInit) | [MsgChannelOpenInitResponse](#ibc.core.channel.v1.MsgChannelOpenInitResponse) | ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. | | -| `ChannelOpenTry` | [MsgChannelOpenTry](#ibc.core.channel.v1.MsgChannelOpenTry) | [MsgChannelOpenTryResponse](#ibc.core.channel.v1.MsgChannelOpenTryResponse) | ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. | | -| `ChannelOpenAck` | [MsgChannelOpenAck](#ibc.core.channel.v1.MsgChannelOpenAck) | [MsgChannelOpenAckResponse](#ibc.core.channel.v1.MsgChannelOpenAckResponse) | ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. | | -| `ChannelOpenConfirm` | [MsgChannelOpenConfirm](#ibc.core.channel.v1.MsgChannelOpenConfirm) | [MsgChannelOpenConfirmResponse](#ibc.core.channel.v1.MsgChannelOpenConfirmResponse) | ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. | | -| `ChannelCloseInit` | [MsgChannelCloseInit](#ibc.core.channel.v1.MsgChannelCloseInit) | [MsgChannelCloseInitResponse](#ibc.core.channel.v1.MsgChannelCloseInitResponse) | ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. | | -| `ChannelCloseConfirm` | [MsgChannelCloseConfirm](#ibc.core.channel.v1.MsgChannelCloseConfirm) | [MsgChannelCloseConfirmResponse](#ibc.core.channel.v1.MsgChannelCloseConfirmResponse) | ChannelCloseConfirm defines a rpc handler method for MsgChannelCloseConfirm. | | -| `RecvPacket` | [MsgRecvPacket](#ibc.core.channel.v1.MsgRecvPacket) | [MsgRecvPacketResponse](#ibc.core.channel.v1.MsgRecvPacketResponse) | RecvPacket defines a rpc handler method for MsgRecvPacket. | | -| `Timeout` | [MsgTimeout](#ibc.core.channel.v1.MsgTimeout) | [MsgTimeoutResponse](#ibc.core.channel.v1.MsgTimeoutResponse) | Timeout defines a rpc handler method for MsgTimeout. | | -| `TimeoutOnClose` | [MsgTimeoutOnClose](#ibc.core.channel.v1.MsgTimeoutOnClose) | [MsgTimeoutOnCloseResponse](#ibc.core.channel.v1.MsgTimeoutOnCloseResponse) | TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. | | -| `Acknowledgement` | [MsgAcknowledgement](#ibc.core.channel.v1.MsgAcknowledgement) | [MsgAcknowledgementResponse](#ibc.core.channel.v1.MsgAcknowledgementResponse) | Acknowledgement defines a rpc handler method for MsgAcknowledgement. | | -| `ChannelUpgradeInit` | [MsgChannelUpgradeInit](#ibc.core.channel.v1.MsgChannelUpgradeInit) | [MsgChannelUpgradeInitResponse](#ibc.core.channel.v1.MsgChannelUpgradeInitResponse) | ChannelUpgradeInit defines a rpc handler method for MsgChannelUpgradeInit. | | -| `ChannelUpgradeTry` | [MsgChannelUpgradeTry](#ibc.core.channel.v1.MsgChannelUpgradeTry) | [MsgChannelUpgradeTryResponse](#ibc.core.channel.v1.MsgChannelUpgradeTryResponse) | ChannelUpgradeTry defines a rpc handler method for MsgChannelUpgradeTry. | | -| `ChannelUpgradeAck` | [MsgChannelUpgradeAck](#ibc.core.channel.v1.MsgChannelUpgradeAck) | [MsgChannelUpgradeAckResponse](#ibc.core.channel.v1.MsgChannelUpgradeAckResponse) | ChannelUpgradeAck defines a rpc handler method for MsgChannelUpgradeAck. | | -| `ChannelUpgradeConfirm` | [MsgChannelUpgradeConfirm](#ibc.core.channel.v1.MsgChannelUpgradeConfirm) | [MsgChannelUpgradeConfirmResponse](#ibc.core.channel.v1.MsgChannelUpgradeConfirmResponse) | ChannelUpgradeConfirm defines a rpc handler method for MsgChannelUpgradeConfirm. | | -| `ChannelUpgradeTimeout` | [MsgChannelUpgradeTimeout](#ibc.core.channel.v1.MsgChannelUpgradeTimeout) | [MsgChannelUpgradeTimeoutResponse](#ibc.core.channel.v1.MsgChannelUpgradeTimeoutResponse) | ChannelUpgradeTimeout defines a rpc handler method for MsgChannelUpgradeTimeout. | | -| `ChannelUpgradeCancel` | [MsgChannelUpgradeCancel](#ibc.core.channel.v1.MsgChannelUpgradeCancel) | [MsgChannelUpgradeCancelResponse](#ibc.core.channel.v1.MsgChannelUpgradeCancelResponse) | ChannelUpgradeCancel defines a rpc handler method for MsgChannelUpgradeCancel. | | - - - - - - -

Top

- -## ibc/core/client/v1/genesis.proto - - - - - -### GenesisMetadata -GenesisMetadata defines the genesis type for metadata that clients may return -with ExportMetadata - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `key` | [bytes](#bytes) | | store key of metadata without clientID-prefix | -| `value` | [bytes](#bytes) | | metadata value | - - - - - - - - -### GenesisState -GenesisState defines the ibc client submodule's genesis state. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `clients` | [IdentifiedClientState](#ibc.core.client.v1.IdentifiedClientState) | repeated | client states with their corresponding identifiers | -| `clients_consensus` | [ClientConsensusStates](#ibc.core.client.v1.ClientConsensusStates) | repeated | consensus states from each client | -| `clients_metadata` | [IdentifiedGenesisMetadata](#ibc.core.client.v1.IdentifiedGenesisMetadata) | repeated | metadata from each client | -| `params` | [Params](#ibc.core.client.v1.Params) | | | -| `create_localhost` | [bool](#bool) | | create localhost on initialization | -| `next_client_sequence` | [uint64](#uint64) | | the sequence for the next generated client identifier | - - - - - - - - -### IdentifiedGenesisMetadata -IdentifiedGenesisMetadata has the client metadata with the corresponding -client id. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | | -| `client_metadata` | [GenesisMetadata](#ibc.core.client.v1.GenesisMetadata) | repeated | | - - - - - - - - - - - - - - - - -

Top

- -## ibc/core/client/v1/query.proto - - - - - -### QueryClientParamsRequest -QueryClientParamsRequest is the request type for the Query/ClientParams RPC -method. - - - - - - - - -### QueryClientParamsResponse -QueryClientParamsResponse is the response type for the Query/ClientParams RPC -method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `params` | [Params](#ibc.core.client.v1.Params) | | params defines the parameters of the module. | - - - - - - - - -### QueryClientStateRequest -QueryClientStateRequest is the request type for the Query/ClientState RPC -method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client state unique identifier | - - - - - - - - -### QueryClientStateResponse -QueryClientStateResponse is the response type for the Query/ClientState RPC -method. Besides the client state, it includes a proof and the height from -which the proof was retrieved. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | client state associated with the request identifier | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryClientStatesRequest -QueryClientStatesRequest is the request type for the Query/ClientStates RPC -method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination request | - - - - - - - - -### QueryClientStatesResponse -QueryClientStatesResponse is the response type for the Query/ClientStates RPC -method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_states` | [IdentifiedClientState](#ibc.core.client.v1.IdentifiedClientState) | repeated | list of stored ClientStates of the chain. | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination response | - - - - - - - - -### QueryClientStatusRequest -QueryClientStatusRequest is the request type for the Query/ClientStatus RPC -method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client unique identifier | - - - - - - - - -### QueryClientStatusResponse -QueryClientStatusResponse is the response type for the Query/ClientStatus RPC -method. It returns the current status of the IBC client. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `status` | [string](#string) | | | - - - - - - - - -### QueryConsensusStateHeightsRequest -QueryConsensusStateHeightsRequest is the request type for Query/ConsensusStateHeights -RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client identifier | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination request | - - - - - - - - -### QueryConsensusStateHeightsResponse -QueryConsensusStateHeightsResponse is the response type for the -Query/ConsensusStateHeights RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `consensus_state_heights` | [Height](#ibc.core.client.v1.Height) | repeated | consensus state heights | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination response | - - - - - - - - -### QueryConsensusStateRequest -QueryConsensusStateRequest is the request type for the Query/ConsensusState -RPC method. Besides the consensus state, it includes a proof and the height -from which the proof was retrieved. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client identifier | -| `revision_number` | [uint64](#uint64) | | consensus state revision number | -| `revision_height` | [uint64](#uint64) | | consensus state revision height | -| `latest_height` | [bool](#bool) | | latest_height overrrides the height field and queries the latest stored ConsensusState | - - - - - - - - -### QueryConsensusStateResponse -QueryConsensusStateResponse is the response type for the Query/ConsensusState -RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | consensus state associated with the client identifier at the given height | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryConsensusStatesRequest -QueryConsensusStatesRequest is the request type for the Query/ConsensusStates -RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client identifier | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | pagination request | - - - - - - - - -### QueryConsensusStatesResponse -QueryConsensusStatesResponse is the response type for the -Query/ConsensusStates RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `consensus_states` | [ConsensusStateWithHeight](#ibc.core.client.v1.ConsensusStateWithHeight) | repeated | consensus states associated with the identifier | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination response | - - - - - - - - -### QueryUpgradedClientStateRequest -QueryUpgradedClientStateRequest is the request type for the -Query/UpgradedClientState RPC method - - - - - - - - -### QueryUpgradedClientStateResponse -QueryUpgradedClientStateResponse is the response type for the -Query/UpgradedClientState RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `upgraded_client_state` | [google.protobuf.Any](#google.protobuf.Any) | | client state associated with the request identifier | - - - - - - - - -### QueryUpgradedConsensusStateRequest -QueryUpgradedConsensusStateRequest is the request type for the -Query/UpgradedConsensusState RPC method - - - - - - - - -### QueryUpgradedConsensusStateResponse -QueryUpgradedConsensusStateResponse is the response type for the -Query/UpgradedConsensusState RPC method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `upgraded_consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | Consensus state associated with the request identifier | - - - - - - - - - - - - - - -### Query -Query provides defines the gRPC querier service - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `ClientState` | [QueryClientStateRequest](#ibc.core.client.v1.QueryClientStateRequest) | [QueryClientStateResponse](#ibc.core.client.v1.QueryClientStateResponse) | ClientState queries an IBC light client. | GET|/ibc/core/client/v1/client_states/{client_id}| -| `ClientStates` | [QueryClientStatesRequest](#ibc.core.client.v1.QueryClientStatesRequest) | [QueryClientStatesResponse](#ibc.core.client.v1.QueryClientStatesResponse) | ClientStates queries all the IBC light clients of a chain. | GET|/ibc/core/client/v1/client_states| -| `ConsensusState` | [QueryConsensusStateRequest](#ibc.core.client.v1.QueryConsensusStateRequest) | [QueryConsensusStateResponse](#ibc.core.client.v1.QueryConsensusStateResponse) | ConsensusState queries a consensus state associated with a client state at a given height. | GET|/ibc/core/client/v1/consensus_states/{client_id}/revision/{revision_number}/height/{revision_height}| -| `ConsensusStates` | [QueryConsensusStatesRequest](#ibc.core.client.v1.QueryConsensusStatesRequest) | [QueryConsensusStatesResponse](#ibc.core.client.v1.QueryConsensusStatesResponse) | ConsensusStates queries all the consensus state associated with a given client. | GET|/ibc/core/client/v1/consensus_states/{client_id}| -| `ConsensusStateHeights` | [QueryConsensusStateHeightsRequest](#ibc.core.client.v1.QueryConsensusStateHeightsRequest) | [QueryConsensusStateHeightsResponse](#ibc.core.client.v1.QueryConsensusStateHeightsResponse) | ConsensusStateHeights queries the height of every consensus states associated with a given client. | GET|/ibc/core/client/v1/consensus_states/{client_id}/heights| -| `ClientStatus` | [QueryClientStatusRequest](#ibc.core.client.v1.QueryClientStatusRequest) | [QueryClientStatusResponse](#ibc.core.client.v1.QueryClientStatusResponse) | Status queries the status of an IBC client. | GET|/ibc/core/client/v1/client_status/{client_id}| -| `ClientParams` | [QueryClientParamsRequest](#ibc.core.client.v1.QueryClientParamsRequest) | [QueryClientParamsResponse](#ibc.core.client.v1.QueryClientParamsResponse) | ClientParams queries all parameters of the ibc client. | GET|/ibc/client/v1/params| -| `UpgradedClientState` | [QueryUpgradedClientStateRequest](#ibc.core.client.v1.QueryUpgradedClientStateRequest) | [QueryUpgradedClientStateResponse](#ibc.core.client.v1.QueryUpgradedClientStateResponse) | UpgradedClientState queries an Upgraded IBC light client. | GET|/ibc/core/client/v1/upgraded_client_states| -| `UpgradedConsensusState` | [QueryUpgradedConsensusStateRequest](#ibc.core.client.v1.QueryUpgradedConsensusStateRequest) | [QueryUpgradedConsensusStateResponse](#ibc.core.client.v1.QueryUpgradedConsensusStateResponse) | UpgradedConsensusState queries an Upgraded IBC consensus state. | GET|/ibc/core/client/v1/upgraded_consensus_states| - - - - - - -

Top

- -## ibc/core/client/v1/tx.proto - - - - - -### MsgCreateClient -MsgCreateClient defines a message to create an IBC client - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | light client state | -| `consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | consensus state associated with the client that corresponds to a given height. | -| `signer` | [string](#string) | | signer address | - - - - - - - - -### MsgCreateClientResponse -MsgCreateClientResponse defines the Msg/CreateClient response type. - - - - - - - - -### MsgSubmitMisbehaviour -MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for -light client misbehaviour. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client unique identifier | -| `misbehaviour` | [google.protobuf.Any](#google.protobuf.Any) | | misbehaviour used for freezing the light client | -| `signer` | [string](#string) | | signer address | - - - - - - - - -### MsgSubmitMisbehaviourResponse -MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response -type. - - - - - - - - -### MsgUpdateClient -MsgUpdateClient defines an sdk.Msg to update a IBC client state using -the given header. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client unique identifier | -| `header` | [google.protobuf.Any](#google.protobuf.Any) | | header to update the light client | -| `signer` | [string](#string) | | signer address | - - - - - - - - -### MsgUpdateClientResponse -MsgUpdateClientResponse defines the Msg/UpdateClient response type. - - - - - - - - -### MsgUpgradeClient -MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client -state - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client unique identifier | -| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | upgraded client state | -| `consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | upgraded consensus state, only contains enough information to serve as a basis of trust in update logic | -| `proof_upgrade_client` | [bytes](#bytes) | | proof that old chain committed to new client | -| `proof_upgrade_consensus_state` | [bytes](#bytes) | | proof that old chain committed to new consensus state | -| `signer` | [string](#string) | | signer address | - - - - - - - - -### MsgUpgradeClientResponse -MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. - - - - - - - - - - - - - - -### Msg -Msg defines the ibc/client Msg service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `CreateClient` | [MsgCreateClient](#ibc.core.client.v1.MsgCreateClient) | [MsgCreateClientResponse](#ibc.core.client.v1.MsgCreateClientResponse) | CreateClient defines a rpc handler method for MsgCreateClient. | | -| `UpdateClient` | [MsgUpdateClient](#ibc.core.client.v1.MsgUpdateClient) | [MsgUpdateClientResponse](#ibc.core.client.v1.MsgUpdateClientResponse) | UpdateClient defines a rpc handler method for MsgUpdateClient. | | -| `UpgradeClient` | [MsgUpgradeClient](#ibc.core.client.v1.MsgUpgradeClient) | [MsgUpgradeClientResponse](#ibc.core.client.v1.MsgUpgradeClientResponse) | UpgradeClient defines a rpc handler method for MsgUpgradeClient. | | -| `SubmitMisbehaviour` | [MsgSubmitMisbehaviour](#ibc.core.client.v1.MsgSubmitMisbehaviour) | [MsgSubmitMisbehaviourResponse](#ibc.core.client.v1.MsgSubmitMisbehaviourResponse) | SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. | | - - - - - - -

Top

- -## ibc/core/commitment/v1/commitment.proto - - - - - -### MerklePath -MerklePath is the path used to verify commitment proofs, which can be an -arbitrary structured object (defined by a commitment type). -MerklePath is represented from root-to-leaf - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `key_path` | [string](#string) | repeated | | - - - - - - - - -### MerklePrefix -MerklePrefix is merkle path prefixed to the key. -The constructed key from the Path and the key will be append(Path.KeyPath, -append(Path.KeyPrefix, key...)) - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `key_prefix` | [bytes](#bytes) | | | - - - - - - - - -### MerkleProof -MerkleProof is a wrapper type over a chain of CommitmentProofs. -It demonstrates membership or non-membership for an element or set of -elements, verifiable in conjunction with a known commitment root. Proofs -should be succinct. -MerkleProofs are ordered from leaf-to-root - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `proofs` | [ics23.CommitmentProof](#ics23.CommitmentProof) | repeated | | - - - - - - - - -### MerkleRoot -MerkleRoot defines a merkle root hash. -In the Cosmos SDK, the AppHash of a block header becomes the root. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `hash` | [bytes](#bytes) | | | - - - - - - - - - - - - - - - - -

Top

- -## ibc/core/connection/v1/connection.proto - - - - - -### ClientPaths -ClientPaths define all the connection paths for a client state. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `paths` | [string](#string) | repeated | list of connection paths | - - - - - - - - -### ConnectionEnd -ConnectionEnd defines a stateful object on a chain connected to another -separate one. -NOTE: there must only be 2 defined ConnectionEnds to establish -a connection between two chains. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client associated with this connection. | -| `versions` | [Version](#ibc.core.connection.v1.Version) | repeated | IBC version which can be utilised to determine encodings or protocols for channels or packets utilising this connection. | -| `state` | [State](#ibc.core.connection.v1.State) | | current state of the connection end. | -| `counterparty` | [Counterparty](#ibc.core.connection.v1.Counterparty) | | counterparty chain associated with this connection. | -| `delay_period` | [uint64](#uint64) | | delay period that must pass before a consensus state can be used for packet-verification NOTE: delay period logic is only implemented by some clients. | - - - - - - - - -### ConnectionPaths -ConnectionPaths define all the connection paths for a given client state. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client state unique identifier | -| `paths` | [string](#string) | repeated | list of connection paths | - - - - - - - - -### Counterparty -Counterparty defines the counterparty chain associated with a connection end. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | identifies the client on the counterparty chain associated with a given connection. | -| `connection_id` | [string](#string) | | identifies the connection end on the counterparty chain associated with a given connection. | -| `prefix` | [ibc.core.commitment.v1.MerklePrefix](#ibc.core.commitment.v1.MerklePrefix) | | commitment merkle prefix of the counterparty chain. | - - - - - - - - -### IdentifiedConnection -IdentifiedConnection defines a connection with additional connection -identifier field. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `id` | [string](#string) | | connection identifier. | -| `client_id` | [string](#string) | | client associated with this connection. | -| `versions` | [Version](#ibc.core.connection.v1.Version) | repeated | IBC version which can be utilised to determine encodings or protocols for channels or packets utilising this connection | -| `state` | [State](#ibc.core.connection.v1.State) | | current state of the connection end. | -| `counterparty` | [Counterparty](#ibc.core.connection.v1.Counterparty) | | counterparty chain associated with this connection. | -| `delay_period` | [uint64](#uint64) | | delay period associated with this connection. | - - - - - - - - -### Params -Params defines the set of Connection parameters. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `max_expected_time_per_block` | [uint64](#uint64) | | maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the largest amount of time that the chain might reasonably take to produce the next block under normal operating conditions. A safe choice is 3-5x the expected time per block. | - - - - - - - - -### Version -Version defines the versioning scheme used to negotiate the IBC verison in -the connection handshake. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `identifier` | [string](#string) | | unique version identifier | -| `features` | [string](#string) | repeated | list of features compatible with the specified identifier | - - - - - - - - - - -### State -State defines if a connection is in one of the following states: -INIT, TRYOPEN, OPEN or UNINITIALIZED. - -| Name | Number | Description | -| ---- | ------ | ----------- | -| STATE_UNINITIALIZED_UNSPECIFIED | 0 | Default State | -| STATE_INIT | 1 | A connection end has just started the opening handshake. | -| STATE_TRYOPEN | 2 | A connection end has acknowledged the handshake step on the counterparty chain. | -| STATE_OPEN | 3 | A connection end has completed the handshake. | - - - - - - - - - - - -

Top

- -## ibc/core/connection/v1/genesis.proto - - - - - -### GenesisState -GenesisState defines the ibc connection submodule's genesis state. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connections` | [IdentifiedConnection](#ibc.core.connection.v1.IdentifiedConnection) | repeated | | -| `client_connection_paths` | [ConnectionPaths](#ibc.core.connection.v1.ConnectionPaths) | repeated | | -| `next_connection_sequence` | [uint64](#uint64) | | the sequence for the next generated connection identifier | -| `params` | [Params](#ibc.core.connection.v1.Params) | | | - - - - - - - - - - - - - - - - -

Top

- -## ibc/core/connection/v1/query.proto - - - - - -### QueryClientConnectionsRequest -QueryClientConnectionsRequest is the request type for the -Query/ClientConnections RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | client identifier associated with a connection | - - - - - - - - -### QueryClientConnectionsResponse -QueryClientConnectionsResponse is the response type for the -Query/ClientConnections RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection_paths` | [string](#string) | repeated | slice of all the connection paths associated with a client. | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was generated | - - - - - - - - -### QueryConnectionClientStateRequest -QueryConnectionClientStateRequest is the request type for the -Query/ConnectionClientState RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection_id` | [string](#string) | | connection identifier | - - - - - - - - -### QueryConnectionClientStateResponse -QueryConnectionClientStateResponse is the response type for the -Query/ConnectionClientState RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `identified_client_state` | [ibc.core.client.v1.IdentifiedClientState](#ibc.core.client.v1.IdentifiedClientState) | | client state associated with the channel | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryConnectionConsensusStateRequest -QueryConnectionConsensusStateRequest is the request type for the -Query/ConnectionConsensusState RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection_id` | [string](#string) | | connection identifier | -| `revision_number` | [uint64](#uint64) | | | -| `revision_height` | [uint64](#uint64) | | | - - - - - - - - -### QueryConnectionConsensusStateResponse -QueryConnectionConsensusStateResponse is the response type for the -Query/ConnectionConsensusState RPC method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | consensus state associated with the channel | -| `client_id` | [string](#string) | | client ID associated with the consensus state | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryConnectionRequest -QueryConnectionRequest is the request type for the Query/Connection RPC -method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection_id` | [string](#string) | | connection unique identifier | - - - - - - - - -### QueryConnectionResponse -QueryConnectionResponse is the response type for the Query/Connection RPC -method. Besides the connection end, it includes a proof and the height from -which the proof was retrieved. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection` | [ConnectionEnd](#ibc.core.connection.v1.ConnectionEnd) | | connection associated with the request identifier | -| `proof` | [bytes](#bytes) | | merkle proof of existence | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | height at which the proof was retrieved | - - - - - - - - -### QueryConnectionsRequest -QueryConnectionsRequest is the request type for the Query/Connections RPC -method - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `pagination` | [cosmos.base.query.v1beta1.PageRequest](#cosmos.base.query.v1beta1.PageRequest) | | | - - - - - - - - -### QueryConnectionsResponse -QueryConnectionsResponse is the response type for the Query/Connections RPC -method. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connections` | [IdentifiedConnection](#ibc.core.connection.v1.IdentifiedConnection) | repeated | list of stored connections of the chain. | -| `pagination` | [cosmos.base.query.v1beta1.PageResponse](#cosmos.base.query.v1beta1.PageResponse) | | pagination response | -| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | query block height | - - - - - - - - - - - - - - -### Query -Query provides defines the gRPC querier service - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `Connection` | [QueryConnectionRequest](#ibc.core.connection.v1.QueryConnectionRequest) | [QueryConnectionResponse](#ibc.core.connection.v1.QueryConnectionResponse) | Connection queries an IBC connection end. | GET|/ibc/core/connection/v1/connections/{connection_id}| -| `Connections` | [QueryConnectionsRequest](#ibc.core.connection.v1.QueryConnectionsRequest) | [QueryConnectionsResponse](#ibc.core.connection.v1.QueryConnectionsResponse) | Connections queries all the IBC connections of a chain. | GET|/ibc/core/connection/v1/connections| -| `ClientConnections` | [QueryClientConnectionsRequest](#ibc.core.connection.v1.QueryClientConnectionsRequest) | [QueryClientConnectionsResponse](#ibc.core.connection.v1.QueryClientConnectionsResponse) | ClientConnections queries the connection paths associated with a client state. | GET|/ibc/core/connection/v1/client_connections/{client_id}| -| `ConnectionClientState` | [QueryConnectionClientStateRequest](#ibc.core.connection.v1.QueryConnectionClientStateRequest) | [QueryConnectionClientStateResponse](#ibc.core.connection.v1.QueryConnectionClientStateResponse) | ConnectionClientState queries the client state associated with the connection. | GET|/ibc/core/connection/v1/connections/{connection_id}/client_state| -| `ConnectionConsensusState` | [QueryConnectionConsensusStateRequest](#ibc.core.connection.v1.QueryConnectionConsensusStateRequest) | [QueryConnectionConsensusStateResponse](#ibc.core.connection.v1.QueryConnectionConsensusStateResponse) | ConnectionConsensusState queries the consensus state associated with the connection. | GET|/ibc/core/connection/v1/connections/{connection_id}/consensus_state/revision/{revision_number}/height/{revision_height}| - - - - - - -

Top

- -## ibc/core/connection/v1/tx.proto - - - - - -### MsgConnectionOpenAck -MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to -acknowledge the change of connection state to TRYOPEN on Chain B. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection_id` | [string](#string) | | | -| `counterparty_connection_id` | [string](#string) | | | -| `version` | [Version](#ibc.core.connection.v1.Version) | | | -| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `proof_try` | [bytes](#bytes) | | proof of the initialization the connection on Chain B: `UNITIALIZED -> TRYOPEN` | -| `proof_client` | [bytes](#bytes) | | proof of client state included in message | -| `proof_consensus` | [bytes](#bytes) | | proof of client consensus state | -| `consensus_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgConnectionOpenAckResponse -MsgConnectionOpenAckResponse defines the Msg/ConnectionOpenAck response type. - - - - - - - - -### MsgConnectionOpenConfirm -MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to -acknowledge the change of connection state to OPEN on Chain A. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `connection_id` | [string](#string) | | | -| `proof_ack` | [bytes](#bytes) | | proof for the change of the connection state on Chain A: `INIT -> OPEN` | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgConnectionOpenConfirmResponse -MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm -response type. - - - - - - - - -### MsgConnectionOpenInit -MsgConnectionOpenInit defines the msg sent by an account on Chain A to -initialize a connection with Chain B. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | | -| `counterparty` | [Counterparty](#ibc.core.connection.v1.Counterparty) | | | -| `version` | [Version](#ibc.core.connection.v1.Version) | | | -| `delay_period` | [uint64](#uint64) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgConnectionOpenInitResponse -MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response -type. - - - - - - - - -### MsgConnectionOpenTry -MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a -connection on Chain B. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | | -| `previous_connection_id` | [string](#string) | | **Deprecated.** Deprecated: this field is unused. Crossing hellos are no longer supported in core IBC. | -| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | | -| `counterparty` | [Counterparty](#ibc.core.connection.v1.Counterparty) | | | -| `delay_period` | [uint64](#uint64) | | | -| `counterparty_versions` | [Version](#ibc.core.connection.v1.Version) | repeated | | -| `proof_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `proof_init` | [bytes](#bytes) | | proof of the initialization the connection on Chain A: `UNITIALIZED -> INIT` | -| `proof_client` | [bytes](#bytes) | | proof of client state included in message | -| `proof_consensus` | [bytes](#bytes) | | proof of client consensus state | -| `consensus_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `signer` | [string](#string) | | | - - - - - - - - -### MsgConnectionOpenTryResponse -MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. - - - - - - - - - - - - - - -### Msg -Msg defines the ibc/connection Msg service. - -| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | -| ----------- | ------------ | ------------- | ------------| ------- | -------- | -| `ConnectionOpenInit` | [MsgConnectionOpenInit](#ibc.core.connection.v1.MsgConnectionOpenInit) | [MsgConnectionOpenInitResponse](#ibc.core.connection.v1.MsgConnectionOpenInitResponse) | ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit. | | -| `ConnectionOpenTry` | [MsgConnectionOpenTry](#ibc.core.connection.v1.MsgConnectionOpenTry) | [MsgConnectionOpenTryResponse](#ibc.core.connection.v1.MsgConnectionOpenTryResponse) | ConnectionOpenTry defines a rpc handler method for MsgConnectionOpenTry. | | -| `ConnectionOpenAck` | [MsgConnectionOpenAck](#ibc.core.connection.v1.MsgConnectionOpenAck) | [MsgConnectionOpenAckResponse](#ibc.core.connection.v1.MsgConnectionOpenAckResponse) | ConnectionOpenAck defines a rpc handler method for MsgConnectionOpenAck. | | -| `ConnectionOpenConfirm` | [MsgConnectionOpenConfirm](#ibc.core.connection.v1.MsgConnectionOpenConfirm) | [MsgConnectionOpenConfirmResponse](#ibc.core.connection.v1.MsgConnectionOpenConfirmResponse) | ConnectionOpenConfirm defines a rpc handler method for MsgConnectionOpenConfirm. | | - - - - - - -

Top

- -## ibc/core/types/v1/genesis.proto - - - - - -### GenesisState -GenesisState defines the ibc module's genesis state. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_genesis` | [ibc.core.client.v1.GenesisState](#ibc.core.client.v1.GenesisState) | | ICS002 - Clients genesis state | -| `connection_genesis` | [ibc.core.connection.v1.GenesisState](#ibc.core.connection.v1.GenesisState) | | ICS003 - Connections genesis state | -| `channel_genesis` | [ibc.core.channel.v1.GenesisState](#ibc.core.channel.v1.GenesisState) | | ICS004 - Channel genesis state | - - - - - - - - - - - - - - - - -

Top

- -## ibc/lightclients/localhost/v1/localhost.proto - - - - - -### ClientState -ClientState defines a loopback (localhost) client. It requires (read-only) -access to keys outside the client prefix. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `chain_id` | [string](#string) | | self chain ID | -| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | self latest block height | - - - - - - - - - - - - - - - - -

Top

- -## ibc/lightclients/solomachine/v1/solomachine.proto - - - - - -### ChannelStateData -ChannelStateData returns the SignBytes data for channel state -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `channel` | [ibc.core.channel.v1.Channel](#ibc.core.channel.v1.Channel) | | | - - - - - - - - -### ClientState -ClientState defines a solo machine client that tracks the current consensus -state and if the client is frozen. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequence` | [uint64](#uint64) | | latest sequence of the client state | -| `frozen_sequence` | [uint64](#uint64) | | frozen sequence of the solo machine | -| `consensus_state` | [ConsensusState](#ibc.lightclients.solomachine.v1.ConsensusState) | | | -| `allow_update_after_proposal` | [bool](#bool) | | when set to true, will allow governance to update a solo machine client. The client will be unfrozen if it is frozen. | - - - - - - - - -### ClientStateData -ClientStateData returns the SignBytes data for client state verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | | - - - - - - - - -### ConnectionStateData -ConnectionStateData returns the SignBytes data for connection state -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `connection` | [ibc.core.connection.v1.ConnectionEnd](#ibc.core.connection.v1.ConnectionEnd) | | | - - - - - - - - -### ConsensusState -ConsensusState defines a solo machine consensus state. The sequence of a -consensus state is contained in the "height" key used in storing the -consensus state. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `public_key` | [google.protobuf.Any](#google.protobuf.Any) | | public key of the solo machine | -| `diversifier` | [string](#string) | | diversifier allows the same public key to be re-used across different solo machine clients (potentially on different chains) without being considered misbehaviour. | -| `timestamp` | [uint64](#uint64) | | | - - - - - - - - -### ConsensusStateData -ConsensusStateData returns the SignBytes data for consensus state -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | | - - - - - - - - -### Header -Header defines a solo machine consensus header - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequence` | [uint64](#uint64) | | sequence to update solo machine public key at | -| `timestamp` | [uint64](#uint64) | | | -| `signature` | [bytes](#bytes) | | | -| `new_public_key` | [google.protobuf.Any](#google.protobuf.Any) | | | -| `new_diversifier` | [string](#string) | | | - - - - - - - - -### HeaderData -HeaderData returns the SignBytes data for update verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `new_pub_key` | [google.protobuf.Any](#google.protobuf.Any) | | header public key | -| `new_diversifier` | [string](#string) | | header diversifier | - - - - - - - - -### Misbehaviour -Misbehaviour defines misbehaviour for a solo machine which consists -of a sequence and two signatures over different messages at that sequence. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | | -| `sequence` | [uint64](#uint64) | | | -| `signature_one` | [SignatureAndData](#ibc.lightclients.solomachine.v1.SignatureAndData) | | | -| `signature_two` | [SignatureAndData](#ibc.lightclients.solomachine.v1.SignatureAndData) | | | - - - - - - - - -### NextSequenceRecvData -NextSequenceRecvData returns the SignBytes data for verification of the next -sequence to be received. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `next_seq_recv` | [uint64](#uint64) | | | - - - - - - - - -### PacketAcknowledgementData -PacketAcknowledgementData returns the SignBytes data for acknowledgement -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `acknowledgement` | [bytes](#bytes) | | | - - - - - - - - -### PacketCommitmentData -PacketCommitmentData returns the SignBytes data for packet commitment -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `commitment` | [bytes](#bytes) | | | - - - - - - - - -### PacketReceiptAbsenceData -PacketReceiptAbsenceData returns the SignBytes data for -packet receipt absence verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | - - - - - - - - -### SignBytes -SignBytes defines the signed bytes used for signature verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequence` | [uint64](#uint64) | | | -| `timestamp` | [uint64](#uint64) | | | -| `diversifier` | [string](#string) | | | -| `data_type` | [DataType](#ibc.lightclients.solomachine.v1.DataType) | | type of the data used | -| `data` | [bytes](#bytes) | | marshaled data | - - - - - - - - -### SignatureAndData -SignatureAndData contains a signature and the data signed over to create that -signature. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `signature` | [bytes](#bytes) | | | -| `data_type` | [DataType](#ibc.lightclients.solomachine.v1.DataType) | | | -| `data` | [bytes](#bytes) | | | -| `timestamp` | [uint64](#uint64) | | | - - - - - - - - -### TimestampedSignatureData -TimestampedSignatureData contains the signature data and the timestamp of the -signature. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `signature_data` | [bytes](#bytes) | | | -| `timestamp` | [uint64](#uint64) | | | - - - - - - - - - - -### DataType -DataType defines the type of solo machine proof being created. This is done -to preserve uniqueness of different data sign byte encodings. - -| Name | Number | Description | -| ---- | ------ | ----------- | -| DATA_TYPE_UNINITIALIZED_UNSPECIFIED | 0 | Default State | -| DATA_TYPE_CLIENT_STATE | 1 | Data type for client state verification | -| DATA_TYPE_CONSENSUS_STATE | 2 | Data type for consensus state verification | -| DATA_TYPE_CONNECTION_STATE | 3 | Data type for connection state verification | -| DATA_TYPE_CHANNEL_STATE | 4 | Data type for channel state verification | -| DATA_TYPE_PACKET_COMMITMENT | 5 | Data type for packet commitment verification | -| DATA_TYPE_PACKET_ACKNOWLEDGEMENT | 6 | Data type for packet acknowledgement verification | -| DATA_TYPE_PACKET_RECEIPT_ABSENCE | 7 | Data type for packet receipt absence verification | -| DATA_TYPE_NEXT_SEQUENCE_RECV | 8 | Data type for next sequence recv verification | -| DATA_TYPE_HEADER | 9 | Data type for header verification | - - - - - - - - - - - -

Top

- -## ibc/lightclients/solomachine/v2/solomachine.proto - - - - - -### ChannelStateData -ChannelStateData returns the SignBytes data for channel state -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `channel` | [ibc.core.channel.v1.Channel](#ibc.core.channel.v1.Channel) | | | - - - - - - - - -### ClientState -ClientState defines a solo machine client that tracks the current consensus -state and if the client is frozen. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequence` | [uint64](#uint64) | | latest sequence of the client state | -| `is_frozen` | [bool](#bool) | | frozen sequence of the solo machine | -| `consensus_state` | [ConsensusState](#ibc.lightclients.solomachine.v2.ConsensusState) | | | -| `allow_update_after_proposal` | [bool](#bool) | | when set to true, will allow governance to update a solo machine client. The client will be unfrozen if it is frozen. | - - - - - - - - -### ClientStateData -ClientStateData returns the SignBytes data for client state verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | | - - - - - - - - -### ConnectionStateData -ConnectionStateData returns the SignBytes data for connection state -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `connection` | [ibc.core.connection.v1.ConnectionEnd](#ibc.core.connection.v1.ConnectionEnd) | | | - - - - - - - - -### ConsensusState -ConsensusState defines a solo machine consensus state. The sequence of a -consensus state is contained in the "height" key used in storing the -consensus state. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `public_key` | [google.protobuf.Any](#google.protobuf.Any) | | public key of the solo machine | -| `diversifier` | [string](#string) | | diversifier allows the same public key to be re-used across different solo machine clients (potentially on different chains) without being considered misbehaviour. | -| `timestamp` | [uint64](#uint64) | | | - - - - - - - - -### ConsensusStateData -ConsensusStateData returns the SignBytes data for consensus state -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `consensus_state` | [google.protobuf.Any](#google.protobuf.Any) | | | - - - - - - - - -### Header -Header defines a solo machine consensus header - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequence` | [uint64](#uint64) | | sequence to update solo machine public key at | -| `timestamp` | [uint64](#uint64) | | | -| `signature` | [bytes](#bytes) | | | -| `new_public_key` | [google.protobuf.Any](#google.protobuf.Any) | | | -| `new_diversifier` | [string](#string) | | | - - - - - - - - -### HeaderData -HeaderData returns the SignBytes data for update verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `new_pub_key` | [google.protobuf.Any](#google.protobuf.Any) | | header public key | -| `new_diversifier` | [string](#string) | | header diversifier | - - - - - - - - -### Misbehaviour -Misbehaviour defines misbehaviour for a solo machine which consists -of a sequence and two signatures over different messages at that sequence. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | | -| `sequence` | [uint64](#uint64) | | | -| `signature_one` | [SignatureAndData](#ibc.lightclients.solomachine.v2.SignatureAndData) | | | -| `signature_two` | [SignatureAndData](#ibc.lightclients.solomachine.v2.SignatureAndData) | | | - - - - - - - - -### NextSequenceRecvData -NextSequenceRecvData returns the SignBytes data for verification of the next -sequence to be received. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `next_seq_recv` | [uint64](#uint64) | | | - - - - - - - - -### PacketAcknowledgementData -PacketAcknowledgementData returns the SignBytes data for acknowledgement -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `acknowledgement` | [bytes](#bytes) | | | - - - - - - - - -### PacketCommitmentData -PacketCommitmentData returns the SignBytes data for packet commitment -verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | -| `commitment` | [bytes](#bytes) | | | - - - - - - - - -### PacketReceiptAbsenceData -PacketReceiptAbsenceData returns the SignBytes data for -packet receipt absence verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `path` | [bytes](#bytes) | | | - - - - - - - - -### SignBytes -SignBytes defines the signed bytes used for signature verification. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `sequence` | [uint64](#uint64) | | | -| `timestamp` | [uint64](#uint64) | | | -| `diversifier` | [string](#string) | | | -| `data_type` | [DataType](#ibc.lightclients.solomachine.v2.DataType) | | type of the data used | -| `data` | [bytes](#bytes) | | marshaled data | - - - - - - - - -### SignatureAndData -SignatureAndData contains a signature and the data signed over to create that -signature. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `signature` | [bytes](#bytes) | | | -| `data_type` | [DataType](#ibc.lightclients.solomachine.v2.DataType) | | | -| `data` | [bytes](#bytes) | | | -| `timestamp` | [uint64](#uint64) | | | - - - - - - - - -### TimestampedSignatureData -TimestampedSignatureData contains the signature data and the timestamp of the -signature. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `signature_data` | [bytes](#bytes) | | | -| `timestamp` | [uint64](#uint64) | | | - - - - - - - - - - -### DataType -DataType defines the type of solo machine proof being created. This is done -to preserve uniqueness of different data sign byte encodings. - -| Name | Number | Description | -| ---- | ------ | ----------- | -| DATA_TYPE_UNINITIALIZED_UNSPECIFIED | 0 | Default State | -| DATA_TYPE_CLIENT_STATE | 1 | Data type for client state verification | -| DATA_TYPE_CONSENSUS_STATE | 2 | Data type for consensus state verification | -| DATA_TYPE_CONNECTION_STATE | 3 | Data type for connection state verification | -| DATA_TYPE_CHANNEL_STATE | 4 | Data type for channel state verification | -| DATA_TYPE_PACKET_COMMITMENT | 5 | Data type for packet commitment verification | -| DATA_TYPE_PACKET_ACKNOWLEDGEMENT | 6 | Data type for packet acknowledgement verification | -| DATA_TYPE_PACKET_RECEIPT_ABSENCE | 7 | Data type for packet receipt absence verification | -| DATA_TYPE_NEXT_SEQUENCE_RECV | 8 | Data type for next sequence recv verification | -| DATA_TYPE_HEADER | 9 | Data type for header verification | - - - - - - - - - - - -

Top

- -## ibc/lightclients/tendermint/v1/tendermint.proto - - - - - -### ClientState -ClientState from Tendermint tracks the current validator set, latest height, -and a possible frozen height. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `chain_id` | [string](#string) | | | -| `trust_level` | [Fraction](#ibc.lightclients.tendermint.v1.Fraction) | | | -| `trusting_period` | [google.protobuf.Duration](#google.protobuf.Duration) | | duration of the period since the LastestTimestamp during which the submitted headers are valid for upgrade | -| `unbonding_period` | [google.protobuf.Duration](#google.protobuf.Duration) | | duration of the staking unbonding period | -| `max_clock_drift` | [google.protobuf.Duration](#google.protobuf.Duration) | | defines how much new (untrusted) header's Time can drift into the future. | -| `frozen_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | Block height when the client was frozen due to a misbehaviour | -| `latest_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | Latest height the client was updated to | -| `proof_specs` | [ics23.ProofSpec](#ics23.ProofSpec) | repeated | Proof specifications used in verifying counterparty state | -| `upgrade_path` | [string](#string) | repeated | Path at which next upgraded client will be committed. Each element corresponds to the key for a single CommitmentProof in the chained proof. NOTE: ClientState must stored under `{upgradePath}/{upgradeHeight}/clientState` ConsensusState must be stored under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using the default upgrade module, upgrade_path should be []string{"upgrade", "upgradedIBCState"}` | -| `allow_update_after_expiry` | [bool](#bool) | | **Deprecated.** allow_update_after_expiry is deprecated | -| `allow_update_after_misbehaviour` | [bool](#bool) | | **Deprecated.** allow_update_after_misbehaviour is deprecated | - - - - - - - - -### ConsensusState -ConsensusState defines the consensus state from Tendermint. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `timestamp` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | timestamp that corresponds to the block height in which the ConsensusState was stored. | -| `root` | [ibc.core.commitment.v1.MerkleRoot](#ibc.core.commitment.v1.MerkleRoot) | | commitment root (i.e app hash) | -| `next_validators_hash` | [bytes](#bytes) | | | - - - - - - - - -### Fraction -Fraction defines the protobuf message type for tmmath.Fraction that only -supports positive values. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `numerator` | [uint64](#uint64) | | | -| `denominator` | [uint64](#uint64) | | | - - - - - - - - -### Header -Header defines the Tendermint client consensus Header. -It encapsulates all the information necessary to update from a trusted -Tendermint ConsensusState. The inclusion of TrustedHeight and -TrustedValidators allows this update to process correctly, so long as the -ConsensusState for the TrustedHeight exists, this removes race conditions -among relayers The SignedHeader and ValidatorSet are the new untrusted update -fields for the client. The TrustedHeight is the height of a stored -ConsensusState on the client that will be used to verify the new untrusted -header. The Trusted ConsensusState must be within the unbonding period of -current time in order to correctly verify, and the TrustedValidators must -hash to TrustedConsensusState.NextValidatorsHash since that is the last -trusted validator set at the TrustedHeight. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `signed_header` | [tendermint.types.SignedHeader](#tendermint.types.SignedHeader) | | | -| `validator_set` | [tendermint.types.ValidatorSet](#tendermint.types.ValidatorSet) | | | -| `trusted_height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | | -| `trusted_validators` | [tendermint.types.ValidatorSet](#tendermint.types.ValidatorSet) | | | - - - - - - - - -### Misbehaviour -Misbehaviour is a wrapper over two conflicting Headers -that implements Misbehaviour interface expected by ICS-02 - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `client_id` | [string](#string) | | | -| `header_1` | [Header](#ibc.lightclients.tendermint.v1.Header) | | | -| `header_2` | [Header](#ibc.lightclients.tendermint.v1.Header) | | | - - - - - - - - - - - - - - - -## Scalar Value Types - -| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby | -| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- | -| double | | double | double | float | float64 | double | float | Float | -| float | | float | float | float | float32 | float | float | Float | -| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | -| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum | -| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) | -| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) | -| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | -| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum | -| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) | -| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum | -| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | -| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum | -| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | -| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) | -| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) | +# Protobuf documentation +See [ibc-go Buf Protobuf documentation](https://buf.build/cosmos/ibc/tags/main). diff --git a/docs/ibc/relayer.md b/docs/ibc/relayer.md index ce3fabe252d..d8fdd6a2164 100644 --- a/docs/ibc/relayer.md +++ b/docs/ibc/relayer.md @@ -7,7 +7,7 @@ order: 6 ## Pre-requisites Readings - [IBC Overview](./overview.md) {prereq} -- [Events](https://github.com/cosmos/cosmos-sdk/blob/master/docs/core/events.md) {prereq} +- [Events](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/core/08-events.md) {prereq} ## Events @@ -17,20 +17,20 @@ Any message that uses IBC will emit events for the corresponding TAO logic execu the [IBC events document](./events.md). In the SDK, it can be assumed that for every message there is an event emitted with the type `message`, -attribute key `action`, and an attribute value representing the type of message sent -(`channel_open_init` would be the attribute value for `MsgChannelOpenInit`). If a relayer queries +attribute key `action`, and an attribute value representing the type of message sent +(`channel_open_init` would be the attribute value for `MsgChannelOpenInit`). If a relayer queries for transaction events, it can split message events using this event Type/Attribute Key pair. The Event Type `message` with the Attribute Key `module` may be emitted multiple times for a single -message due to application callbacks. It can be assumed that any TAO logic executed will result in +message due to application callbacks. It can be assumed that any TAO logic executed will result in a module event emission with the attribute value `ibc_` (02-client emits `ibc_client`). -### Subscribing with Tendermint +### Subscribing with Tendermint -Calling the Tendermint RPC method `Subscribe` via [Tendermint's Websocket](https://docs.tendermint.com/v0.35/rpc/) will return events using +Calling the Tendermint RPC method `Subscribe` via [Tendermint's Websocket](https://docs.tendermint.com/main/rpc/) will return events using Tendermint's internal representation of them. Instead of receiving back a list of events as they were emitted, Tendermint will return the type `map[string][]string` which maps a string in the -form `.` to `attribute_value`. This causes extraction of the event +form `.` to `attribute_value`. This causes extraction of the event ordering to be non-trivial, but still possible. A relayer should use the `message.action` key to extract the number of messages in the transaction @@ -42,5 +42,5 @@ piece of information needed to relay a packet. ## Example Implementations -- [Golang Relayer](https://github.com/iqlusioninc/relayer) -- [Hermes](https://github.com/informalsystems/ibc-rs/tree/master/relayer) +- [Golang Relayer](https://github.com/cosmos/relayer) +- [Hermes](https://github.com/informalsystems/ibc-rs/tree/master/crates/relayer) diff --git a/docs/ibc/upgrades/README.md b/docs/ibc/upgrades/README.md index 11ccabe2378..8245e85a2ec 100644 --- a/docs/ibc/upgrades/README.md +++ b/docs/ibc/upgrades/README.md @@ -4,9 +4,9 @@ parent: order: 3 --> -### Upgrading IBC Chains Overview +# Upgrading IBC Chains Overview -This directory contains information on how to upgrade an IBC chain without breaking counterparty clients and connections. +This directory contains information on how to upgrade an IBC chain without breaking counterparty clients and connections. IBC-connnected chains must be able to upgrade without breaking connections to other chains. Otherwise there would be a massive disincentive towards upgrading and disrupting high-value IBC connections, thus preventing chains in the IBC ecosystem from evolving and improving. Many chain upgrades may be irrelevant to IBC, however some upgrades could potentially break counterparty clients if not handled correctly. Thus, any IBC chain that wishes to perform a IBC-client-breaking upgrade must perform an IBC upgrade in order to allow counterparty clients to securely upgrade to the new light client. diff --git a/docs/ibc/upgrades/developer-guide.md b/docs/ibc/upgrades/developer-guide.md index 73a19b93664..05b5552279b 100644 --- a/docs/ibc/upgrades/developer-guide.md +++ b/docs/ibc/upgrades/developer-guide.md @@ -6,45 +6,4 @@ order: 2 Learn how to implement upgrade functionality for your custom IBC client. {synopsis} -As mentioned in the [README](./README.md), it is vital that high-value IBC clients can upgrade along with their underlying chains to avoid disruption to the IBC ecosystem. Thus, IBC client developers will want to implement upgrade functionality to enable clients to maintain connections and channels even across chain upgrades. - -The IBC protocol allows client implementations to provide a path to upgrading clients given the upgraded client state, upgraded consensus state and proofs for each. - -```go -// Upgrade functions -// NOTE: proof heights are not included as upgrade to a new revision is expected to pass only on the last -// height committed by the current revision. Clients are responsible for ensuring that the planned last -// height of the current revision is somehow encoded in the proof verification process. -// This is to ensure that no premature upgrades occur, since upgrade plans committed to by the counterparty -// may be cancelled or modified before the last planned height. -VerifyUpgradeAndUpdateState( - ctx sdk.Context, - cdc codec.BinaryCodec, - store sdk.KVStore, - newClient ClientState, - newConsState ConsensusState, - proofUpgradeClient, - proofUpgradeConsState []byte, -) (upgradedClient ClientState, upgradedConsensus ConsensusState, err error) -``` - -Note that the clients should have prior knowledge of the merkle path that the upgraded client and upgraded consensus states will use. The height at which the upgrade has occurred should also be encoded in the proof. The Tendermint client implementation accomplishes this by including an `UpgradePath` in the ClientState itself, which is used along with the upgrade height to construct the merkle path under which the client state and consensus state are committed. - -Developers must ensure that the `UpgradeClientMsg` does not pass until the last height of the old chain has been committed, and after the chain upgrades, the `UpgradeClientMsg` should pass once and only once on all counterparty clients. - -Developers must ensure that the new client adopts all of the new Client parameters that must be uniform across every valid light client of a chain (chain-chosen parameters), while maintaining the Client parameters that are customizable by each individual client (client-chosen parameters) from the previous version of the client. - -Upgrades must adhere to the IBC Security Model. IBC does not rely on the assumption of honest relayers for correctness. Thus users should not have to rely on relayers to maintain client correctness and security (though honest relayers must exist to maintain relayer liveness). While relayers may choose any set of client parameters while creating a new `ClientState`, this still holds under the security model since users can always choose a relayer-created client that suits their security and correctness needs or create a Client with their desired parameters if no such client exists. - -However, when upgrading an existing client, one must keep in mind that there are already many users who depend on this client's particular parameters. We cannot give the upgrading relayer free choice over these parameters once they have already been chosen. This would violate the security model since users who rely on the client would have to rely on the upgrading relayer to maintain the same level of security. Thus, developers must make sure that their upgrade mechanism allows clients to upgrade the chain-specified parameters whenever a chain upgrade changes these parameters (examples in the Tendermint client include `UnbondingPeriod`, `TrustingPeriod`, `ChainID`, `UpgradePath`, etc.), while ensuring that the relayer submitting the `UpgradeClientMsg` cannot alter the client-chosen parameters that the users are relying upon (examples in Tendermint client include `TrustLevel`, `MaxClockDrift`, etc). - -Developers should maintain the distinction between Client parameters that are uniform across every valid light client of a chain (chain-chosen parameters), and Client parameters that are customizable by each individual client (client-chosen parameters); since this distinction is necessary to implement the `ZeroCustomFields` method in the `ClientState` interface: - -```go -// Utility function that zeroes out any client customizable fields in client state -// Ledger enforced fields are maintained while all custom fields are zero values -// Used to verify upgrades -ZeroCustomFields() ClientState -``` - -Counterparty clients can upgrade securely by using all of the chain-chosen parameters from the chain-committed `UpgradedClient` and preserving all of the old client-chosen parameters. This enables chains to securely upgrade without relying on an honest relayer, however it can in some cases lead to an invalid final `ClientState` if the new chain-chosen parameters clash with the old client-chosen parameter. This can happen in the Tendermint client case if the upgrading chain lowers the `UnbondingPeriod` (chain-chosen) to a duration below that of a counterparty client's `TrustingPeriod` (client-chosen). Such cases should be clearly documented by developers, so that chains know which upgrades should be avoided to prevent this problem. The final upgraded client should also be validated in `VerifyUpgradeAndUpdateState` before returning to ensure that the client does not upgrade to an invalid `ClientState`. +Please see the section [Handling upgrades](../light-clients/upgrades.md) from the light client developer guide for more information. diff --git a/docs/ibc/upgrades/genesis-restart.md b/docs/ibc/upgrades/genesis-restart.md index 1b6ab4e45b2..abb0fa9a817 100644 --- a/docs/ibc/upgrades/genesis-restart.md +++ b/docs/ibc/upgrades/genesis-restart.md @@ -8,21 +8,21 @@ Learn how to upgrade your chain and counterparty clients using genesis restarts. **NOTE**: Regular genesis restarts are currently unsupported by relayers! -### IBC Client Breaking Upgrades +## IBC Client Breaking Upgrades -IBC client breaking upgrades are possible using genesis restarts. +IBC client breaking upgrades are possible using genesis restarts. It is highly recommended to use the in-place migrations instead of a genesis restart. -Genesis restarts should be used sparingly and as backup plans. +Genesis restarts should be used sparingly and as backup plans. Genesis restarts still require the usage of an IBC upgrade proposal in order to correctly upgrade counterparty clients. -#### Step-by-Step Upgrade Process for SDK Chains +### Step-by-Step Upgrade Process for SDK Chains If the IBC-connected chain is conducting an upgrade that will break counterparty clients, it must ensure that the upgrade is first supported by IBC using the [IBC Client Breaking Upgrade List](https://github.com/cosmos/ibc-go/blob/main/docs/ibc/upgrades/quick-guide.md#ibc-client-breaking-upgrades) and then execute the upgrade process described below in order to prevent counterparty clients from breaking. 1. Create a 02-client [`UpgradeProposal`](https://github.com/cosmos/ibc-go/blob/main/docs/ibc/proto-docs.md#upgradeproposal) with an `UpgradePlan` and a new IBC ClientState in the `UpgradedClientState` field. Note that the `UpgradePlan` must specify an upgrade height **only** (no upgrade time), and the `ClientState` should only include the fields common to all valid clients and zero out any client-customizable fields (such as TrustingPeriod). -2. Vote on and pass the `UpgradeProposal` -3. Halt the node after successful upgrade. +2. Vote on and pass the `UpgradeProposal`. +3. Halt the node after successful upgrade. 4. Export the genesis file. 5. Swap to the new binary. 6. Run migrations on the genesis file. @@ -35,15 +35,12 @@ Upon the `UpgradeProposal` passing, the upgrade module will commit the UpgradedC Once the chain reaches the upgrade height and halts, a relayer can upgrade the counterparty clients to the last block of the old chain. They can then submit the proofs of the `UpgradedClient` and `UpgradedConsensusState` against this last block and upgrade the counterparty client. -#### Step-by-Step Upgrade Process for Relayers Upgrading Counterparty Clients +### Step-by-Step Upgrade Process for Relayers Upgrading Counterparty Clients These steps are identical to the regular [IBC client breaking upgrade process](https://github.com/cosmos/ibc-go/blob/main/docs/ibc/upgrades/quick-guide.md#step-by-step-upgrade-process-for-relayers-upgrading-counterparty-clients). -### Non-IBC Client Breaking Upgrades +## Non-IBC Client Breaking Upgrades -While ibc-go supports genesis restarts which do not break IBC clients, relayers do not support this upgrade path. +While ibc-go supports genesis restarts which do not break IBC clients, relayers do not support this upgrade path. Here is a tracking issue on [Hermes](https://github.com/informalsystems/ibc-rs/issues/1152). Please do not attempt a regular genesis restarts unless you have a tool to update counterparty clients correctly. - - - diff --git a/docs/ibc/upgrades/quick-guide.md b/docs/ibc/upgrades/quick-guide.md index 2c82b3a9047..1bdca7a567e 100644 --- a/docs/ibc/upgrades/quick-guide.md +++ b/docs/ibc/upgrades/quick-guide.md @@ -8,7 +8,7 @@ Learn how to upgrade your chain and counterparty clients. {synopsis} The information in this doc for upgrading chains is relevant to SDK chains. However, the guide for counterparty clients is relevant to any Tendermint client that enables upgrades. -### IBC Client Breaking Upgrades +## IBC Client Breaking Upgrades IBC-connected chains must perform an IBC upgrade if their upgrade will break counterparty IBC clients. The current IBC protocol supports upgrading tendermint chains for a specific subset of IBC-client-breaking upgrades. Here is the exhaustive list of IBC client-breaking upgrades and whether the IBC protocol currently supports such upgrades. @@ -26,18 +26,18 @@ Note: Since upgrades are only implemented for Tendermint clients, this doc only 8. Upgrading to a non-backwards compatible version of IBC: **Unsupported**, as IBC version is negotiated on connection handshake. 9. Changing the Tendermint LightClient algorithm: **Partially Supported**. Changes to the light client algorithm that do not change the ClientState or ConsensusState struct may be supported, provided that the counterparty is also upgraded to support the new light client algorithm. Changes that require updating the ClientState and ConsensusState structs themselves are theoretically possible by providing a path to translate an older ClientState struct into the new ClientState struct; however this is not currently implemented. -### Step-by-Step Upgrade Process for SDK chains +## Step-by-Step Upgrade Process for SDK chains If the IBC-connected chain is conducting an upgrade that will break counterparty clients, it must ensure that the upgrade is first supported by IBC using the list above and then execute the upgrade process described below in order to prevent counterparty clients from breaking. 1. Create a 02-client [`UpgradeProposal`](https://github.com/cosmos/ibc-go/blob/main/docs/ibc/proto-docs.md#upgradeproposal) with an `UpgradePlan` and a new IBC ClientState in the `UpgradedClientState` field. Note that the `UpgradePlan` must specify an upgrade height **only** (no upgrade time), and the `ClientState` should only include the fields common to all valid clients and zero out any client-customizable fields (such as TrustingPeriod). -2. Vote on and pass the `UpgradeProposal` +2. Vote on and pass the `UpgradeProposal`. Upon the `UpgradeProposal` passing, the upgrade module will commit the UpgradedClient under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedClient`. On the block right before the upgrade height, the upgrade module will also commit an initial consensus state for the next chain under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedConsState`. Once the chain reaches the upgrade height and halts, a relayer can upgrade the counterparty clients to the last block of the old chain. They can then submit the proofs of the `UpgradedClient` and `UpgradedConsensusState` against this last block and upgrade the counterparty client. -### Step-by-Step Upgrade Process for Relayers Upgrading Counterparty Clients +## Step-by-Step Upgrade Process for Relayers Upgrading Counterparty Clients Once the upgrading chain has committed to upgrading, relayers must wait till the chain halts at the upgrade height before upgrading counterparty clients. This is because chains may reschedule or cancel upgrade plans before they occur. Thus, relayers must wait till the chain reaches the upgrade height and halts before they can be sure the upgrade will take place. diff --git a/docs/middleware/ics29-fee/fee-distribution.md b/docs/middleware/ics29-fee/fee-distribution.md index 79f03792566..f3e1efc2515 100644 --- a/docs/middleware/ics29-fee/fee-distribution.md +++ b/docs/middleware/ics29-fee/fee-distribution.md @@ -26,23 +26,23 @@ Fee distribution for incentivized packet relays takes place on the packet source The counterparty payee address registered on the destination chain is encoded into the packet acknowledgement and communicated as such to the source chain for fee distribution. **If a counterparty payee is not registered for the forward relayer on the destination chain, the escrowed fees will be refunded upon fee distribution.** -### Relayer operator actions? +### Relayer operator actions A transaction must be submitted **to the destination chain** including a `CounterpartyPayee` address of an account on the source chain. The transaction must be signed by the `Relayer`. -Note: If a module account address is used as the `CounterpartyPayee` it is recommended to [turn off invariant checks](https://github.com/cosmos/ibc-go/blob/71d7480c923f4227453e8a80f51be01ae7ee845e/testing/simapp/app.go#L659) for that module. +Note: If a module account address is used as the `CounterpartyPayee` but the module has been set as a blocked address in the `BankKeeper`, the refunding to the module account will fail. This is because many modules use invariants to compare internal tracking of module account balances against the actual balance of the account stored in the `BankKeeper`. If a token transfer to the module account occurs without going through this module and updating the account balance of the module on the `BankKeeper`, then invariants may break and unknown behaviour could occur depending on the module implementation. Therefore, if it is desirable to use a module account that is currently blocked, the module developers should be consulted to gauge to possibility of removing the module account from the blocked list. ```go type MsgRegisterCounterpartyPayee struct { - // unique port identifier - PortId string - // unique channel identifier - ChannelId string - // the relayer address - Relayer string - // the counterparty payee address - CounterpartyPayee string + // unique port identifier + PortId string + // unique channel identifier + ChannelId string + // the relayer address + Relayer string + // the counterparty payee address + CounterpartyPayee string } ``` @@ -50,16 +50,16 @@ type MsgRegisterCounterpartyPayee struct { > > - `PortId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators). > - `ChannelId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). -> - `Relayer` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/basics/accounts.md#Addresses)). +> - `Relayer` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/basics/03-accounts.md#addresses)). > - `CounterpartyPayee` is empty. See below for an example CLI command: ```bash simd tx ibc-fee register-counterparty-payee transfer channel-0 \ -cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh \ -osmo1v5y0tz01llxzf4c2afml8s3awue0ymju22wxx2 \ ---from cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh + cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh \ + osmo1v5y0tz01llxzf4c2afml8s3awue0ymju22wxx2 \ + --from cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh ``` ## Register an alternative payee address for reverse and timeout relaying @@ -80,14 +80,14 @@ Note: If a module account address is used as the `Payee` it is recommended to [t ```go type MsgRegisterPayee struct { - // unique port identifier - PortId string - // unique channel identifier - ChannelId string - // the relayer address - Relayer string - // the payee address - Payee string + // unique port identifier + PortId string + // unique channel identifier + ChannelId string + // the relayer address + Relayer string + // the payee address + Payee string } ``` @@ -95,14 +95,14 @@ type MsgRegisterPayee struct { > > - `PortId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators). > - `ChannelId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). -> - `Relayer` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/basics/accounts.md#Addresses)). -> - `Payee` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/basics/accounts.md#Addresses)). +> - `Relayer` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/basics/03-accounts.md#addresses)). +> - `Payee` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/basics/03-accounts.md#addresses)). See below for an example CLI command: ```bash simd tx ibc-fee register-payee transfer channel-0 \ -cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh \ -cosmos153lf4zntqt33a4v0sm5cytrxyqn78q7kz8j8x5 \ ---from cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh + cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh \ + cosmos153lf4zntqt33a4v0sm5cytrxyqn78q7kz8j8x5 \ + --from cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh ``` diff --git a/docs/middleware/ics29-fee/integration.md b/docs/middleware/ics29-fee/integration.md index f1d0158e702..7912726327e 100644 --- a/docs/middleware/ics29-fee/integration.md +++ b/docs/middleware/ics29-fee/integration.md @@ -14,14 +14,97 @@ Learn how to configure the Fee Middleware module with IBC applications. The foll The Fee Middleware module, as the name suggests, plays the role of an IBC middleware and as such must be configured by chain developers to route and handle IBC messages correctly. For Cosmos SDK chains this setup is done via the `app/app.go` file, where modules are constructed and configured in order to bootstrap the blockchain application. +## Example integration of the Fee Middleware module + +```go +// app.go + +// Register the AppModule for the fee middleware module +ModuleBasics = module.NewBasicManager( + ... + ibcfee.AppModuleBasic{}, + ... +) + +... + +// Add module account permissions for the fee middleware module +maccPerms = map[string][]string{ + ... + ibcfeetypes.ModuleName: nil, +} + +... + +// Add fee middleware Keeper +type App struct { + ... + + IBCFeeKeeper ibcfeekeeper.Keeper + + ... +} + +... + +// Create store keys +keys := sdk.NewKVStoreKeys( + ... + ibcfeetypes.StoreKey, + ... +) + +... + +app.IBCFeeKeeper = ibcfeekeeper.NewKeeper( + appCodec, keys[ibcfeetypes.StoreKey], + app.IBCKeeper.ChannelKeeper, // may be replaced with IBC middleware + app.IBCKeeper.ChannelKeeper, + &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, +) + + +// See the section below for configuring an application stack with the fee middleware module + +... + +// Register fee middleware AppModule +app.moduleManager = module.NewManager( + ... + ibcfee.NewAppModule(app.IBCFeeKeeper), +) + +... + +// Add fee middleware to begin blocker logic +app.moduleManager.SetOrderBeginBlockers( + ... + ibcfeetypes.ModuleName, + ... +) + +// Add fee middleware to end blocker logic +app.moduleManager.SetOrderEndBlockers( + ... + ibcfeetypes.ModuleName, + ... +) + +// Add fee middleware to init genesis logic +app.moduleManager.SetOrderInitGenesis( + ... + ibcfeetypes.ModuleName, + ... +) +``` + ## Configuring an application stack with Fee Middleware -As mentioned in [IBC middleware development](../../ibc/middleware/develop.md) an application stack may be composed of many or no middlewares that nest a base application. +As mentioned in [IBC middleware development](../../ibc/middleware/develop.md) an application stack may be composed of many or no middlewares that nest a base application. These layers form the complete set of application logic that enable developers to build composable and flexible IBC application stacks. For example, an application stack may be just a single base application like `transfer`, however, the same application stack composed with `29-fee` will nest the `transfer` base application by wrapping it with the Fee Middleware module. - ### Transfer See below for an example of how to create an application stack using `transfer` and `29-fee`. @@ -76,10 +159,10 @@ icaHostStack = ibcfee.NewIBCMiddleware(icaHostStack, app.IBCFeeKeeper) // Add authentication module, controller and host to IBC router ibcRouter. - // the ICA Controller middleware needs to be explicitly added to the IBC Router because the - // ICA controller module owns the port capability for ICA. The ICA authentication module - // owns the channel capability. - AddRoute(ibcmock.ModuleName+icacontrollertypes.SubModuleName, icaControllerStack) // ica with mock auth module stack route to ica (top level of middleware stack) - AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). - AddRoute(icahosttypes.SubModuleName, icaHostStack). -``` \ No newline at end of file + // the ICA Controller middleware needs to be explicitly added to the IBC Router because the + // ICA controller module owns the port capability for ICA. The ICA authentication module + // owns the channel capability. + AddRoute(ibcmock.ModuleName+icacontrollertypes.SubModuleName, icaControllerStack) // ica with mock auth module stack route to ica (top level of middleware stack) + AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). + AddRoute(icahosttypes.SubModuleName, icaHostStack). +``` diff --git a/docs/middleware/ics29-fee/msgs.md b/docs/middleware/ics29-fee/msgs.md index 0003d5982ee..1f2dde03841 100644 --- a/docs/middleware/ics29-fee/msgs.md +++ b/docs/middleware/ics29-fee/msgs.md @@ -10,61 +10,61 @@ Learn about the different ways to pay for fees, how the fees are paid out and wh The fee middleware module exposes two different ways to pay fees for relaying IBC packets: -1. `MsgPayPacketFee`, which enables the escrowing of fees for a packet at the next sequence send and should be combined into one `MultiMsgTx` with the message that will be paid for. - - Note that the `Relayers` field has been set up to allow for an optional whitelist of relayers permitted to receive this fee, however, this feature has not yet been enabled at this time. - - ```go - type MsgPayPacketFee struct{ - // fee encapsulates the recv, ack and timeout fees associated with an IBC packet - Fee Fee - // the source port unique identifier - SourcePortId string - // the source channel unique identifer - SourceChannelId string - // account address to refund fee if necessary - Signer string - // optional list of relayers permitted to the receive packet fee - Relayers []string - } - ``` - - The `Fee` message contained in this synchronous fee payment method configures different fees which will be paid out for `MsgRecvPacket`, `MsgAcknowledgement`, and `MsgTimeout`/`MsgTimeoutOnClose`. - - ```go - type Fee struct { - RecvFee types.Coins - AckFee types.Coins - TimeoutFee types.Coins - } - ``` +### `MsgPayPacketFee` + +`MsgPayPacketFee` enables the escrowing of fees for a packet at the next sequence send and should be combined into one `MultiMsgTx` with the message that will be paid for. Note that the `Relayers` field has been set up to allow for an optional whitelist of relayers permitted to receive this fee, however, this feature has not yet been enabled at this time. + +```go +type MsgPayPacketFee struct{ + // fee encapsulates the recv, ack and timeout fees associated with an IBC packet + Fee Fee + // the source port unique identifier + SourcePortId string + // the source channel unique identifer + SourceChannelId string + // account address to refund fee if necessary + Signer string + // optional list of relayers permitted to the receive packet fee + Relayers []string +} +``` + +The `Fee` message contained in this synchronous fee payment method configures different fees which will be paid out for `MsgRecvPacket`, `MsgAcknowledgement`, and `MsgTimeout`/`MsgTimeoutOnClose`. + +```go +type Fee struct { + RecvFee types.Coins + AckFee types.Coins + TimeoutFee types.Coins +} +``` The diagram below shows the `MultiMsgTx` with the `MsgTransfer` coming from a token transfer message, along with `MsgPayPacketFee`. ![MsgPayPacketFee](../../assets/fee-mw/msgpaypacket.png) -2. `MsgPayPacketFeeAsync`, which enables the asynchronous escrowing of fees for a specified packet: +### `MsgPayPacketFeeAsync` - Note that a packet can be 'topped up' multiple times with additional fees of any coin denomination by broadcasting multiple `MsgPayPacketFeeAsync` messages. +`MsgPayPacketFeeAsync` enables the asynchronous escrowing of fees for a specified packet. Note that a packet can be 'topped up' multiple times with additional fees of any coin denomination by broadcasting multiple `MsgPayPacketFeeAsync` messages. - ```go - type MsgPayPacketFeeAsync struct { - // unique packet identifier comprised of the channel ID, port ID and sequence - PacketId channeltypes.PacketId - // the packet fee associated with a particular IBC packet - PacketFee PacketFee - } - ``` +```go +type MsgPayPacketFeeAsync struct { + // unique packet identifier comprised of the channel ID, port ID and sequence + PacketId channeltypes.PacketId + // the packet fee associated with a particular IBC packet + PacketFee PacketFee +} +``` - where the `PacketFee` also specifies the `Fee` to be paid as well as the refund address for fees which are not paid out +where the `PacketFee` also specifies the `Fee` to be paid as well as the refund address for fees which are not paid out - ```go - type PacketFee struct { - Fee Fee - RefundAddress string - Relayers []string - } - ``` +```go +type PacketFee struct { + Fee Fee + RefundAddress string + Relayers []string +} +``` The diagram below shows how multiple `MsgPayPacketFeeAsync` can be broadcasted asynchronously. Escrowing of the fee associated with a packet can be carried out by any party because ICS-29 does not dictate a particular fee payer. In fact, chains can choose to simply not expose this fee payment to end users at all and rely on a different module account or even the community pool as the source of relayer incentives. diff --git a/docs/migrations/migration-template.md b/docs/migrations/migration-template.md index 701b74290dd..dc546603012 100644 --- a/docs/migrations/migration-template.md +++ b/docs/migrations/migration-template.md @@ -1,15 +1,15 @@ # Migrating from to -This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. -Any changes that must be done by a user of ibc-go should be documented here. +This guide provides instructions for migrating to a new version of ibc-go. There are four sections based on the four potential user groups of this document: -- Chains -- IBC Apps -- Relayers -- IBC Light Clients -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. +- [Chains](#chains) +- [IBC Apps](#ibc-apps) +- [Relayers](#relayers) +- [IBC Light Clients](#ibc-light-clients) + +**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated on major version releases. ## Chains diff --git a/docs/migrations/sdk-to-v1.md b/docs/migrations/sdk-to-v1.md index d5c1993ea73..76868e356f4 100644 --- a/docs/migrations/sdk-to-v1.md +++ b/docs/migrations/sdk-to-v1.md @@ -1,26 +1,27 @@ # Migrating to ibc-go -This file contains information on how to migrate from the IBC module contained in the SDK 0.41.x and 0.42.x lines to the IBC module in the ibc-go repository based on the 0.44 SDK version. +This file contains information on how to migrate from the IBC module contained in the SDK 0.41.x and 0.42.x lines to the IBC module in the ibc-go repository based on the 0.44 SDK version. ## Import Changes The most obvious changes is import name changes. We need to change: + - applications -> apps - cosmos-sdk/x/ibc -> ibc-go On my GNU/Linux based machine I used the following commands, executed in order: -``` +```shell grep -RiIl 'cosmos-sdk\/x\/ibc\/applications' | xargs sed -i 's/cosmos-sdk\/x\/ibc\/applications/ibc-go\/modules\/apps/g' ``` -``` +```shell grep -RiIl 'cosmos-sdk\/x\/ibc' | xargs sed -i 's/cosmos-sdk\/x\/ibc/ibc-go\/modules/g' ``` ref: [explanation of the above commands](https://www.internalpointers.com/post/linux-find-and-replace-text-multiple-files) -Executing these commands out of order will cause issues. +Executing these commands out of order will cause issues. Feel free to use your own method for modifying import names. @@ -29,11 +30,12 @@ Update the import paths before running `go mod tidy`. ## Chain Upgrades -Chains may choose to upgrade via an upgrade proposal or genesis upgrades. Both in-place store migrations and genesis migrations are supported. +Chains may choose to upgrade via an upgrade proposal or genesis upgrades. Both in-place store migrations and genesis migrations are supported. **WARNING**: Please read at least the quick guide for [IBC client upgrades](../ibc/upgrades/README.md) before upgrading your chain. It is highly recommended you do not change the chain-ID during an upgrade, otherwise you must follow the IBC client upgrade instructions. Both in-place store migrations and genesis migrations will: + - migrate the solo machine client state from v1 to v2 protobuf definitions - prune all solo machine consensus states - prune all expired tendermint consensus states @@ -45,20 +47,21 @@ Chains must set a new connection parameter during either in place store migratio The new chain binary will need to run migrations in the upgrade handler. The fromVM (previous module version) for the IBC module should be 1. This will allow migrations to be run for IBC updating the version from 1 to 2. Ex: + ```go app.UpgradeKeeper.SetUpgradeHandler("my-upgrade-proposal", - func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { - // set max expected block time parameter. Replace the default with your expected value - // https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 - app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) - - fromVM := map[string]uint64{ - ... // other modules - "ibc": 1, - ... - } - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) + func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { + // set max expected block time parameter. Replace the default with your expected value + // https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 + app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) + + fromVM := map[string]uint64{ + ... // other modules + "ibc": 1, + ... + } + return app.mm.RunMigrations(ctx, app.configurator, fromVM) + }) ``` @@ -69,8 +72,8 @@ To perform genesis migrations, the following code must be added to your existing ```go // add imports as necessary import ( - ibcv100 "github.com/cosmos/ibc-go/modules/core/legacy/v100" - ibchost "github.com/cosmos/ibc-go/modules/core/24-host" + ibcv100 "github.com/cosmos/ibc-go/modules/core/legacy/v100" + ibchost "github.com/cosmos/ibc-go/modules/core/24-host" ) ... @@ -80,77 +83,76 @@ import ( // https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 newGenState, err = ibcv100.MigrateGenesis(newGenState, clientCtx, *genDoc, expectedTimePerBlock) if err != nil { - return err + return err } ``` **NOTE:** The genesis chain-id, time and height MUST be updated before migrating IBC, otherwise the tendermint consensus state will not be pruned. - ## IBC Keeper Changes The IBC Keeper now takes in the Upgrade Keeper. Please add the chains' Upgrade Keeper after the Staking Keeper: ```diff - // Create IBC Keeper - app.IBCKeeper = ibckeeper.NewKeeper( -- appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, scopedIBCKeeper, -+ appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, - ) - -``` +// Create IBC Keeper +app.IBCKeeper = ibckeeper.NewKeeper( +- appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, scopedIBCKeeper, ++ appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, +) +``` ## Proposals ### UpdateClientProposal -The `UpdateClient` has been modified to take in two client-identifiers and one initial height. Please see the [documentation](../ibc/proposals.md) for more information. +The `UpdateClient` has been modified to take in two client-identifiers and one initial height. Please see the [documentation](../ibc/proposals.md) for more information. ### UpgradeProposal -A new IBC proposal type has been added, `UpgradeProposal`. This handles an IBC (breaking) Upgrade. -The previous `UpgradedClientState` field in an Upgrade `Plan` has been deprecated in favor of this new proposal type. +A new IBC proposal type has been added, `UpgradeProposal`. This handles an IBC (breaking) Upgrade. +The previous `UpgradedClientState` field in an Upgrade `Plan` has been deprecated in favor of this new proposal type. ### Proposal Handler Registration -The `ClientUpdateProposalHandler` has been renamed to `ClientProposalHandler`. +The `ClientUpdateProposalHandler` has been renamed to `ClientProposalHandler`. It handles both `UpdateClientProposal`s and `UpgradeProposal`s. -Add this import: +Add this import: ```diff -+ ibcclienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" ++ ibcclienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" ``` Please ensure the governance module adds the correct route: ```diff -- AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)) -+ AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) +- AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)) ++ AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) ``` -NOTE: Simapp registration was incorrect in the 0.41.x releases. The `UpdateClient` proposal handler should be registered with the router key belonging to `ibc-go/core/02-client/types` -as shown in the diffs above. +NOTE: Simapp registration was incorrect in the 0.41.x releases. The `UpdateClient` proposal handler should be registered with the router key belonging to `ibc-go/core/02-client/types` +as shown in the diffs above. ### Proposal CLI Registration Please ensure both proposal type CLI commands are registered on the governance module by adding the following arguments to `gov.NewAppModuleBasic()`: Add the following import: + ```diff -+ ibcclientclient "github.com/cosmos/ibc-go/modules/core/02-client/client" ++ ibcclientclient "github.com/cosmos/ibc-go/modules/core/02-client/client" ``` -Register the cli commands: +Register the cli commands: -```diff - gov.NewAppModuleBasic( - paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, -+ ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, - ), +```diff +gov.NewAppModuleBasic( + paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, ++ ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, +), ``` -REST routes are not supported for these proposals. +REST routes are not supported for these proposals. ## Proto file changes @@ -162,11 +164,11 @@ The solo machine has replaced the FrozenSequence uint64 field with a IsFrozen bo ### OnRecvPacket -Application developers need to update their `OnRecvPacket` callback logic. +Application developers need to update their `OnRecvPacket` callback logic. The `OnRecvPacket` callback has been modified to only return the acknowledgement. The acknowledgement returned must implement the `Acknowledgement` interface. The acknowledgement should indicate if it represents a successful processing of a packet by returning true on `Success()` and false in all other cases. A return value of false on `Success()` will result in all state changes which occurred in the callback being discarded. More information can be found in the [documentation](https://github.com/cosmos/ibc-go/blob/main/docs/ibc/apps.md#receiving-packets). -The `OnRecvPacket`, `OnAcknowledgementPacket`, and `OnTimeoutPacket` callbacks are now passed the `sdk.AccAddress` of the relayer who relayed the IBC packet. Applications may use or ignore this information. +The `OnRecvPacket`, `OnAcknowledgementPacket`, and `OnTimeoutPacket` callbacks are now passed the `sdk.AccAddress` of the relayer who relayed the IBC packet. Applications may use or ignore this information. ## IBC Event changes @@ -178,9 +180,9 @@ The `consensus_height` attribute has been removed in the Misbehaviour event emit ## Relevant SDK changes -* (codec) [\#9226](https://github.com/cosmos/cosmos-sdk/pull/9226) Rename codec interfaces and methods, to follow a general Go interfaces: - * `codec.Marshaler` → `codec.Codec` (this defines objects which serialize other objects) - * `codec.BinaryMarshaler` → `codec.BinaryCodec` - * `codec.JSONMarshaler` → `codec.JSONCodec` - * Removed `BinaryBare` suffix from `BinaryCodec` methods (`MarshalBinaryBare`, `UnmarshalBinaryBare`, ...) - * Removed `Binary` infix from `BinaryCodec` methods (`MarshalBinaryLengthPrefixed`, `UnmarshalBinaryLengthPrefixed`, ...) +- (codec) [\#9226](https://github.com/cosmos/cosmos-sdk/pull/9226) Rename codec interfaces and methods, to follow a general Go interfaces: + - `codec.Marshaler` → `codec.Codec` (this defines objects which serialize other objects) + - `codec.BinaryMarshaler` → `codec.BinaryCodec` + - `codec.JSONMarshaler` → `codec.JSONCodec` + - Removed `BinaryBare` suffix from `BinaryCodec` methods (`MarshalBinaryBare`, `UnmarshalBinaryBare`, ...) + - Removed `Binary` infix from `BinaryCodec` methods (`MarshalBinaryLengthPrefixed`, `UnmarshalBinaryLengthPrefixed`, ...) diff --git a/docs/migrations/support-denoms-with-slashes.md b/docs/migrations/support-denoms-with-slashes.md index 3bc3d1b6b83..3c1bf2c253f 100644 --- a/docs/migrations/support-denoms-with-slashes.md +++ b/docs/migrations/support-denoms-with-slashes.md @@ -4,6 +4,7 @@ This document is intended to highlight significant changes which may require mor Any changes that must be done by a user of ibc-go should be documented here. There are four sections based on the four potential user groups of this document: + - Chains - IBC Apps - Relayers @@ -29,11 +30,10 @@ The transfer module will now support slashes in base denoms, so we must iterate ```go app.UpgradeKeeper.SetUpgradeHandler("MigrateTraces", - func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // transfer module consensus version has been bumped to 2 - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) - + func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // transfer module consensus version has been bumped to 2 + return app.mm.RunMigrations(ctx, app.configurator, fromVM) + }) ``` This is only necessary if there are denom traces in the store with incorrect trace information from previously received coins that had a slash in the base denom. However, it is recommended that any chain upgrading to support base denominations with slashes runs this code for safety. @@ -48,33 +48,33 @@ The migration code required may look like: ```go func migrateGenesisSlashedDenomsUpgrade(appState genutiltypes.AppMap, clientCtx client.Context, genDoc *tmtypes.GenesisDoc) (genutiltypes.AppMap, error) { - if appState[ibctransfertypes.ModuleName] != nil { - transferGenState := &ibctransfertypes.GenesisState{} - clientCtx.Codec.MustUnmarshalJSON(appState[ibctransfertypes.ModuleName], transferGenState) + if appState[ibctransfertypes.ModuleName] != nil { + transferGenState := &ibctransfertypes.GenesisState{} + clientCtx.Codec.MustUnmarshalJSON(appState[ibctransfertypes.ModuleName], transferGenState) - substituteTraces := make([]ibctransfertypes.DenomTrace, len(transferGenState.DenomTraces)) - for i, dt := range transferGenState.DenomTraces { - // replace all previous traces with the latest trace if validation passes - // note most traces will have same value - newTrace := ibctransfertypes.ParseDenomTrace(dt.GetFullDenomPath()) + substituteTraces := make([]ibctransfertypes.DenomTrace, len(transferGenState.DenomTraces)) + for i, dt := range transferGenState.DenomTraces { + // replace all previous traces with the latest trace if validation passes + // note most traces will have same value + newTrace := ibctransfertypes.ParseDenomTrace(dt.GetFullDenomPath()) - if err := newTrace.Validate(); err != nil { - substituteTraces[i] = dt - } else { - substituteTraces[i] = newTrace - } - } + if err := newTrace.Validate(); err != nil { + substituteTraces[i] = dt + } else { + substituteTraces[i] = newTrace + } + } - transferGenState.DenomTraces = substituteTraces + transferGenState.DenomTraces = substituteTraces - // delete old genesis state - delete(appState, ibctransfertypes.ModuleName) + // delete old genesis state + delete(appState, ibctransfertypes.ModuleName) - // set new ibc transfer genesis state - appState[ibctransfertypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(transferGenState) - } + // set new ibc transfer genesis state + appState[ibctransfertypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(transferGenState) + } - return appState, nil + return appState, nil } ``` diff --git a/docs/migrations/v1-to-v2.md b/docs/migrations/v1-to-v2.md index a42da400e43..bef0254ccbb 100644 --- a/docs/migrations/v1-to-v2.md +++ b/docs/migrations/v1-to-v2.md @@ -4,12 +4,14 @@ This document is intended to highlight significant changes which may require mor Any changes that must be done by a user of ibc-go should be documented here. There are four sections based on the four potential user groups of this document: + - Chains - IBC Apps - Relayers - IBC Light Clients **Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. + ```go github.com/cosmos/ibc-go -> github.com/cosmos/ibc-go/v2 ``` @@ -21,26 +23,26 @@ github.com/cosmos/ibc-go -> github.com/cosmos/ibc-go/v2 ## IBC Apps A new function has been added to the app module interface: + ```go // NegotiateAppVersion performs application version negotiation given the provided channel ordering, connectionID, portID, counterparty and proposed version. - // An error is returned if version negotiation cannot be performed. For example, an application module implementing this interface - // may decide to return an error in the event of the proposed version being incompatible with it's own - NegotiateAppVersion( - ctx sdk.Context, - order channeltypes.Order, - connectionID string, - portID string, - counterparty channeltypes.Counterparty, - proposedVersion string, - ) (version string, err error) -} +// An error is returned if version negotiation cannot be performed. For example, an application module implementing this interface +// may decide to return an error in the event of the proposed version being incompatible with it's own +NegotiateAppVersion( + ctx sdk.Context, + order channeltypes.Order, + connectionID string, + portID string, + counterparty channeltypes.Counterparty, + proposedVersion string, +) (version string, err error) ``` This function should perform application version negotiation and return the negotiated version. If the version cannot be negotiated, an error should be returned. This function is only used on the client side. -#### sdk.Result removed +### `sdk.Result` removed -sdk.Result has been removed as a return value in the application callbacks. Previously it was being discarded by core IBC and was thus unused. +`sdk.Result` has been removed as a return value in the application callbacks. Previously it was being discarded by core IBC and was thus unused. ## Relayers diff --git a/docs/migrations/v2-to-v3.md b/docs/migrations/v2-to-v3.md index a37f74cf420..75586cefe59 100644 --- a/docs/migrations/v2-to-v3.md +++ b/docs/migrations/v2-to-v3.md @@ -4,12 +4,14 @@ This document is intended to highlight significant changes which may require mor Any changes that must be done by a user of ibc-go should be documented here. There are four sections based on the four potential user groups of this document: + - Chains - IBC Apps - Relayers - IBC Light Clients **Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. + ```go github.com/cosmos/ibc-go/v2 -> github.com/cosmos/ibc-go/v3 ``` @@ -20,7 +22,7 @@ No genesis or in-place migrations are required when upgrading from v1 or v2 of i ### ICS20 -The `transferkeeper.NewKeeper(...)` now takes in an ICS4Wrapper. +The `transferkeeper.NewKeeper(...)` now takes in an ICS4Wrapper. The ICS4Wrapper should be the IBC Channel Keeper unless ICS 20 is being connected to a middleware application. ### ICS27 @@ -30,80 +32,79 @@ Please see the [ICS27 documentation](../apps/interchain-accounts/overview.md) fo ### Upgrade Proposal -If the chain will adopt ICS27, it must set the appropriate params during the execution of the upgrade handler in `app.go`: +If the chain will adopt ICS27, it must set the appropriate params during the execution of the upgrade handler in `app.go`: + ```go app.UpgradeKeeper.SetUpgradeHandler("v3", - func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // set the ICS27 consensus version so InitGenesis is not run - fromVM[icatypes.ModuleName] = icamodule.ConsensusVersion() - - // create ICS27 Controller submodule params - controllerParams := icacontrollertypes.Params{ - ControllerEnabled: true, - } - - // create ICS27 Host submodule params - hostParams := icahosttypes.Params{ - HostEnabled: true, - AllowMessages: []string{"/cosmos.bank.v1beta1.MsgSend", ...}, - } - - // initialize ICS27 module - icamodule.InitModule(ctx, controllerParams, hostParams) - - ... - - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) + func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // set the ICS27 consensus version so InitGenesis is not run + fromVM[icatypes.ModuleName] = icamodule.ConsensusVersion() + + // create ICS27 Controller submodule params + controllerParams := icacontrollertypes.Params{ + ControllerEnabled: true, + } + // create ICS27 Host submodule params + hostParams := icahosttypes.Params{ + HostEnabled: true, + AllowMessages: []string{"/cosmos.bank.v1beta1.MsgSend", ...}, + } + + // initialize ICS27 module + icamodule.InitModule(ctx, controllerParams, hostParams) + + ... + + return app.mm.RunMigrations(ctx, app.configurator, fromVM) + }) ``` -The host and controller submodule params only need to be set if the chain integrates those submodules. +The host and controller submodule params only need to be set if the chain integrates those submodules. For example, if a chain chooses not to integrate a controller submodule, it may pass empty params into `InitModule`. #### Add `StoreUpgrades` for ICS27 module -For ICS27 it is also necessary to [manually add store upgrades](https://docs.cosmos.network/v0.44/core/upgrade.html#add-storeupgrades-for-new-modules) for the new ICS27 module and then configure the store loader to apply those upgrades in `app.go`: +For ICS27 it is also necessary to [manually add store upgrades](https://docs.cosmos.network/v0.45/core/upgrade.html#add-storeupgrades-for-new-modules) for the new ICS27 module and then configure the store loader to apply those upgrades in `app.go`: ```go if upgradeInfo.Name == "v3" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { - storeUpgrades := store.StoreUpgrades{ - Added: []string{icacontrollertypes.StoreKey, icahosttypes.StoreKey}, - } + storeUpgrades := store.StoreUpgrades{ + Added: []string{icacontrollertypes.StoreKey, icahosttypes.StoreKey}, + } - app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) } ``` -This ensures that the new module's stores are added to the multistore before the migrations begin. +This ensures that the new module's stores are added to the multistore before the migrations begin. The host and controller submodule keys only need to be added if the chain integrates those submodules. For example, if a chain chooses not to integrate a controller submodule, it does not need to add the controller key to the `Added` field. - ### Genesis migrations -If the chain will adopt ICS27 and chooses to upgrade via a genesis export, then the ICS27 parameters must be set during genesis migration. +If the chain will adopt ICS27 and chooses to upgrade via a genesis export, then the ICS27 parameters must be set during genesis migration. The migration code required may look like: ```go - controllerGenesisState := icatypes.DefaultControllerGenesis() - // overwrite parameters as desired - controllerGenesisState.Params = icacontrollertypes.Params{ - ControllerEnabled: true, - } - - hostGenesisState := icatypes.DefaultHostGenesis() - // overwrite parameters as desired - hostGenesisState.Params = icahosttypes.Params{ - HostEnabled: true, - AllowMessages: []string{"/cosmos.bank.v1beta1.MsgSend", ...}, - } - - icaGenesisState := icatypes.NewGenesisState(controllerGenesisState, hostGenesisState) - - // set new ics27 genesis state - appState[icatypes.ModuleName] = clientCtx.JSONCodec.MustMarshalJSON(icaGenesisState) + controllerGenesisState := icatypes.DefaultControllerGenesis() + // overwrite parameters as desired + controllerGenesisState.Params = icacontrollertypes.Params{ + ControllerEnabled: true, + } + + hostGenesisState := icatypes.DefaultHostGenesis() + // overwrite parameters as desired + hostGenesisState.Params = icahosttypes.Params{ + HostEnabled: true, + AllowMessages: []string{"/cosmos.bank.v1beta1.MsgSend", ...}, + } + + icaGenesisState := icatypes.NewGenesisState(controllerGenesisState, hostGenesisState) + + // set new ics27 genesis state + appState[icatypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(icaGenesisState) ``` ### Ante decorator @@ -112,28 +113,28 @@ The field of type `channelkeeper.Keeper` in the `AnteDecorator` structure has be ```diff type AnteDecorator struct { -- k channelkeeper.Keeper -+ k *keeper.Keeper +- k channelkeeper.Keeper ++ k *keeper.Keeper } - func NewAnteDecorator(k channelkeeper.Keeper) AnteDecorator { -+ func NewAnteDecorator(k *keeper.Keeper) AnteDecorator { - return AnteDecorator{k: k} ++ func NewAnteDecorator(k *keeper.Keeper) AnteDecorator { + return AnteDecorator{k: k} } ``` ## IBC Apps - ### `OnChanOpenTry` must return negotiated application version The `OnChanOpenTry` application callback has been modified. -The return signature now includes the application version. -IBC applications must perform application version negoitation in `OnChanOpenTry` using the counterparty version. +The return signature now includes the application version. +IBC applications must perform application version negoitation in `OnChanOpenTry` using the counterparty version. The negotiated application version then must be returned in `OnChanOpenTry` to core IBC. Core IBC will set this version in the TRYOPEN channel. ### `OnChanOpenAck` will take additional `counterpartyChannelID` argument + The `OnChanOpenAck` application callback has been modified. The arguments now include the counterparty channel id. @@ -146,17 +147,17 @@ Now applications will perform this version negotiation during the channel handsh ### Channel state will not be set before application callback -The channel handshake logic has been reorganized within core IBC. +The channel handshake logic has been reorganized within core IBC. Channel state will not be set in state after the application callback is performed. Applications must rely only on the passed in channel parameters instead of querying the channel keeper for channel state. ### IBC application callbacks moved from `AppModule` to `IBCModule` -Previously, IBC module callbacks were apart of the `AppModule` type. -The recommended approach is to create an `IBCModule` type and move the IBC module callbacks from `AppModule` to `IBCModule` in a separate file `ibc_module.go`. +Previously, IBC module callbacks were apart of the `AppModule` type. +The recommended approach is to create an `IBCModule` type and move the IBC module callbacks from `AppModule` to `IBCModule` in a separate file `ibc_module.go`. -The mock module go API has been broken in this release by applying the above format. -The IBC module callbacks have been moved from the mock modules `AppModule` into a new type `IBCModule`. +The mock module go API has been broken in this release by applying the above format. +The IBC module callbacks have been moved from the mock modules `AppModule` into a new type `IBCModule`. As apart of this release, the mock module now supports middleware testing. Please see the [README](../../testing/README.md#middleware-testing) for more information. @@ -164,16 +165,15 @@ Please review the [mock](../../testing/mock/ibc_module.go) and [transfer](../../ ### IBC testing package -`TestChain`s are now created with chainID's beginning from an index of 1. Any calls to `GetChainID(0)` will now fail. Please increment all calls to `GetChainID` by 1. +`TestChain`s are now created with chainID's beginning from an index of 1. Any calls to `GetChainID(0)` will now fail. Please increment all calls to `GetChainID` by 1. ## Relayers `AppVersion` gRPC has been removed. -The `version` string in `MsgChanOpenTry` has been deprecated and will be ignored by core IBC. +The `version` string in `MsgChanOpenTry` has been deprecated and will be ignored by core IBC. Relayers no longer need to determine the version to use on the `ChanOpenTry` step. -IBC applications will determine the correct version using the counterparty version. +IBC applications will determine the correct version using the counterparty version. ## IBC Light Clients -The `GetProofSpecs` function has been removed from the `ClientState` interface. This function was previously unused by core IBC. Light clients which don't use this function may remove it. - +The `GetProofSpecs` function has been removed from the `ClientState` interface. This function was previously unused by core IBC. Light clients which don't use this function may remove it. diff --git a/docs/migrations/v3-to-v4.md b/docs/migrations/v3-to-v4.md index bdf8654dcb7..81cf97b3521 100644 --- a/docs/migrations/v3-to-v4.md +++ b/docs/migrations/v3-to-v4.md @@ -4,12 +4,14 @@ This document is intended to highlight significant changes which may require mor Any changes that must be done by a user of ibc-go should be documented here. There are four sections based on the four potential user groups of this document: + - Chains - IBC Apps - Relayers - IBC Light Clients **Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. + ```go github.com/cosmos/ibc-go/v3 -> github.com/cosmos/ibc-go/v4 ``` @@ -18,20 +20,39 @@ No genesis or in-place migrations required when upgrading from v1 or v2 of ibc-g ## Chains +### ICS27 - Interchain Accounts + +The controller submodule implements now the 05-port `Middleware` interface instead of the 05-port `IBCModule` interface. Chains that integrate the controller submodule, need to create it with the `NewIBCMiddleware` constructor function. For example: + +```diff +- icacontroller.NewIBCModule(app.ICAControllerKeeper, icaAuthIBCModule) ++ icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) +``` + +where `icaAuthIBCModule` is the Interchain Accounts authentication IBC Module. + +### ICS29 - Fee Middleware + +The Fee Middleware module, as the name suggests, plays the role of an IBC middleware and as such must be configured by chain developers to route and handle IBC messages correctly. + +Please read the Fee Middleware [integration documentation](https://ibc.cosmos.network/main/middleware/ics29-fee/integration.html) for an in depth guide on how to congfigure the module correctly in order to incentivize IBC packets. + +Take a look at the following diff for an [example setup](https://github.com/cosmos/ibc-go/pull/1432/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08aL366) of how to incentivize ics27 channels. + ### Migration to fix support for base denoms with slashes As part of [v1.5.0](https://github.com/cosmos/ibc-go/releases/tag/v1.5.0), [v2.3.0](https://github.com/cosmos/ibc-go/releases/tag/v2.3.0) and [v3.1.0](https://github.com/cosmos/ibc-go/releases/tag/v3.1.0) some [migration handler code sample was documented](https://github.com/cosmos/ibc-go/blob/main/docs/migrations/support-denoms-with-slashes.md#upgrade-proposal) that needs to run in order to correct the trace information of coins transferred using ICS20 whose base denom contains slashes. Based on feedback from the community we add now an improved solution to run the same migration that does not require copying a large piece of code over from the migration document, but instead requires only adding a one-line upgrade handler. -If the chain will migrate to supporting base denoms with slashes, it must set the appropriate params during the execution of the upgrade handler in `app.go`: +If the chain will migrate to supporting base denoms with slashes, it must set the appropriate params during the execution of the upgrade handler in `app.go`: + ```go app.UpgradeKeeper.SetUpgradeHandler("MigrateTraces", - func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // transfer module consensus version has been bumped to 2 - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) - + func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // transfer module consensus version has been bumped to 2 + return app.mm.RunMigrations(ctx, app.configurator, fromVM) + }) ``` If a chain receives coins of a base denom with slashes before it upgrades to supporting it, the receive may pass however the trace information will be incorrect. @@ -44,13 +65,15 @@ This incorrect trace information must be corrected when the chain does upgrade t ### ICS03 - Connection -Crossing hellos have been removed from 03-connection handshake negotiation. +Crossing hellos have been removed from 03-connection handshake negotiation. `PreviousConnectionId` in `MsgConnectionOpenTry` has been deprecated and is no longer used by core IBC. -### ICS04 - Channel +`NewMsgConnectionOpenTry` no longer takes in the `PreviousConnectionId` as crossing hellos are no longer supported. A non-empty `PreviousConnectionId` will fail basic validation for this message. -The `WriteAcknowledgement` API now takes the `exported.Acknowledgement` type instead of passing in the acknowledgement byte array directly. -This is an API breaking change and as such IBC application developers will have to update any calls to `WriteAcknowledgement`. +### ICS04 - Channel + +The `WriteAcknowledgement` API now takes the `exported.Acknowledgement` type instead of passing in the acknowledgement byte array directly. +This is an API breaking change and as such IBC application developers will have to update any calls to `WriteAcknowledgement`. The `OnChanOpenInit` application callback has been modified. The return signature now includes the application version as detailed in the latest IBC [spec changes](https://github.com/cosmos/ibc/pull/629). @@ -59,34 +82,36 @@ The `NewErrorAcknowledgement` method signature has changed. It now accepts an `error` rather than a `string`. This was done in order to prevent accidental state changes. All error acknowledgements now contain a deterministic ABCI code and error message. It is the responsibility of the application developer to emit error details in events. -Crossing hellos have been removed from 04-channel handshake negotiation. -IBC Applications no longer need to account from already claimed capabilities in the `OnChanOpenTry` callback. The capability provided by core IBC must be able to be claimed with error. +Crossing hellos have been removed from 04-channel handshake negotiation. +IBC Applications no longer need to account from already claimed capabilities in the `OnChanOpenTry` callback. The capability provided by core IBC must be able to be claimed with error. `PreviousChannelId` in `MsgChannelOpenTry` has been deprecated and is no longer used by core IBC. +`NewMsgChannelOpenTry` no longer takes in the `PreviousChannelId` as crossing hellos are no longer supported. A non-empty `PreviousChannelId` will fail basic validation for this message. + ### ICS27 - Interchain Accounts The `RegisterInterchainAccount` API has been modified to include an additional `version` argument. This change has been made in order to support ICS29 fee middleware, for relayer incentivization of ICS27 packets. -Consumers of the `RegisterInterchainAccount` are now expected to build the appropriate JSON encoded version string themselves and pass it accordingly. +Consumers of the `RegisterInterchainAccount` are now expected to build the appropriate JSON encoded version string themselves and pass it accordingly. This should be constructed within the interchain accounts authentication module which leverages the APIs exposed via the interchain accounts `controllerKeeper`. If an empty string is passed in the `version` argument, then the version will be initialized to a default value in the `OnChanOpenInit` callback of the controller's handler, so that channel handshake can proceed. The following code snippet illustrates how to construct an appropriate interchain accounts `Metadata` and encode it as a JSON bytestring: ```go icaMetadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: controllerConnectionID, - HostConnectionId: hostConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, + Version: icatypes.Version, + ControllerConnectionId: controllerConnectionID, + HostConnectionId: hostConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, } appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) if err != nil { - return err + return err } if err := k.icaControllerKeeper.RegisterInterchainAccount(ctx, msg.ConnectionId, msg.Owner, string(appVersion)); err != nil { - return err + return err } ``` @@ -94,30 +119,30 @@ Similarly, if the application stack is configured to route through ICS29 fee mid ```go icaMetadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: controllerConnectionID, - HostConnectionId: hostConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, + Version: icatypes.Version, + ControllerConnectionId: controllerConnectionID, + HostConnectionId: hostConnectionID, + Encoding: icatypes.EncodingProtobuf, + TxType: icatypes.TxTypeSDKMultiMsg, } appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) if err != nil { - return err + return err } feeMetadata := feetypes.Metadata{ - AppVersion: string(appVersion), - FeeVersion: feetypes.Version, + AppVersion: string(appVersion), + FeeVersion: feetypes.Version, } feeEnabledVersion, err := feetypes.ModuleCdc.MarshalJSON(&feeMetadata) if err != nil { - return err + return err } if err := k.icaControllerKeeper.RegisterInterchainAccount(ctx, msg.ConnectionId, msg.Owner, string(feeEnabledVersion)); err != nil { - return err + return err } ``` diff --git a/docs/migrations/v4-to-v5.md b/docs/migrations/v4-to-v5.md new file mode 100644 index 00000000000..f6fb7e61bb8 --- /dev/null +++ b/docs/migrations/v4-to-v5.md @@ -0,0 +1,434 @@ +# Migrating from v4 to v5 + +This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. +Any changes that must be done by a user of ibc-go should be documented here. + +There are four sections based on the four potential user groups of this document: + +- [Chains](#chains) +- [IBC Apps](#ibc-apps) +- [Relayers](#relayers) +- [IBC Light Clients](#ibc-light-clients) + +**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. + +```go +github.com/cosmos/ibc-go/v4 -> github.com/cosmos/ibc-go/v5 +``` + +## Chains + +### Ante decorator + +The `AnteDecorator` type in `core/ante` has been renamed to `RedundantRelayDecorator` (and the corresponding constructor function to `NewRedundantRelayDecorator`). Therefore in the function that creates the instance of the `sdk.AnteHandler` type (e.g. `NewAnteHandler`) the change would be like this: + +```diff +func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { + // parameter validation + + anteDecorators := []sdk.AnteDecorator{ + // other ante decorators +- ibcante.NewAnteDecorator(opts.IBCkeeper), ++ ibcante.NewRedundantRelayDecorator(options.IBCKeeper), + } + + return sdk.ChainAnteDecorators(anteDecorators...), nil +} +``` + +The `AnteDecorator` was actually renamed twice, but in [this PR](https://github.com/cosmos/ibc-go/pull/1820) you can see the changes made for the final rename. + +## IBC Apps + +### Core + +The `key` parameter of the `NewKeeper` function in `modules/core/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): + +```diff +func NewKeeper( + cdc codec.BinaryCodec, +- key sdk.StoreKey, ++ key storetypes.StoreKey, + paramSpace paramtypes.Subspace, + stakingKeeper clienttypes.StakingKeeper, + upgradeKeeper clienttypes.UpgradeKeeper, + scopedKeeper capabilitykeeper.ScopedKeeper, +) *Keeper +``` + +The `RegisterRESTRoutes` function in `modules/core` has been removed. + +### ICS03 - Connection + +The `key` parameter of the `NewKeeper` function in `modules/core/03-connection/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): + +```diff +func NewKeeper( + cdc codec.BinaryCodec, +- key sdk.StoreKey, ++ key storetypes.StoreKey, + paramSpace paramtypes.Subspace, + ck types.ClientKeeper +) Keeper +``` + +### ICS04 - Channel + +The function `NewPacketId` in `modules/core/04-channel/types` has been renamed to `NewPacketID`: + +```diff +- func NewPacketId( ++ func NewPacketID( + portID, + channelID string, + seq uint64 +) PacketId +``` + +The `key` parameter of the `NewKeeper` function in `modules/core/04-channel/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): + +```diff +func NewKeeper( + cdc codec.BinaryCodec, +- key sdk.StoreKey, ++ key storetypes.StoreKey, + clientKeeper types.ClientKeeper, + connectionKeeper types.ConnectionKeeper, + portKeeper types.PortKeeper, + scopedKeeper capabilitykeeper.ScopedKeeper, +) Keeper +``` + +### ICS20 - Transfer + +The `key` parameter of the `NewKeeper` function in `modules/apps/transfer/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): + +```diff +func NewKeeper( + cdc codec.BinaryCodec, +- key sdk.StoreKey, ++ key storetypes.StoreKey, + paramSpace paramtypes.Subspace, + ics4Wrapper types.ICS4Wrapper, + channelKeeper types.ChannelKeeper, + portKeeper types.PortKeeper, + authKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, + scopedKeeper capabilitykeeper.ScopedKeeper, +) Keeper +``` + +The `amount` parameter of function `GetTransferCoin` in `modules/apps/transfer/types` is now of type `math.Int` (`"cosmossdk.io/math"`): + +```diff +func GetTransferCoin( + portID, channelID, baseDenom string, +- amount sdk.Int ++ amount math.Int +) sdk.Coin +``` + +The `RegisterRESTRoutes` function in `modules/apps/transfer` has been removed. + +### ICS27 - Interchain Accounts + +The `key` and `msgRouter` parameters of the `NewKeeper` functions in + +- `modules/apps/27-interchain-accounts/controller/keeper` +- and `modules/apps/27-interchain-accounts/host/keeper` + +have changed type. The `key` parameter is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`), and the `msgRouter` parameter is now of type `*icatypes.MessageRouter` (where `icatypes` is an import alias for `"github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/types"`): + +```diff +// NewKeeper creates a new interchain accounts controller Keeper instance +func NewKeeper( + cdc codec.BinaryCodec, +- key sdk.StoreKey, ++ key storetypes.StoreKey, + paramSpace paramtypes.Subspace, + ics4Wrapper icatypes.ICS4Wrapper, + channelKeeper icatypes.ChannelKeeper, + portKeeper icatypes.PortKeeper, + scopedKeeper capabilitykeeper.ScopedKeeper, +- msgRouter *baseapp.MsgServiceRouter, ++ msgRouter *icatypes.MessageRouter, +) Keeper +``` + +```diff +// NewKeeper creates a new interchain accounts host Keeper instance +func NewKeeper( + cdc codec.BinaryCodec, +- key sdk.StoreKey, ++ key storetypes.StoreKey, + paramSpace paramtypes.Subspace, + channelKeeper icatypes.ChannelKeeper, + portKeeper icatypes.PortKeeper, + accountKeeper icatypes.AccountKeeper, + scopedKeeper capabilitykeeper.ScopedKeeper, +- msgRouter *baseapp.MsgServiceRouter, ++ msgRouter *icatypes.MessageRouter, +) Keeper +``` + +The new `MessageRouter` interface is defined as: + +```go +type MessageRouter interface { + Handler(msg sdk.Msg) baseapp.MsgServiceHandler +} +``` + +The `RegisterRESTRoutes` function in `modules/apps/27-interchain-accounts` has been removed. + +An additional parameter, `ics4Wrapper` has been added to the `host` submodule `NewKeeper` function in `modules/apps/27-interchain-accounts/host/keeper`. +This allows the `host` submodule to correctly unwrap the channel version for channel reopening handshakes in the `OnChanOpenTry` callback. + +```diff +func NewKeeper( + cdc codec.BinaryCodec, + key storetypes.StoreKey, + paramSpace paramtypes.Subspace, ++ ics4Wrapper icatypes.ICS4Wrapper, + channelKeeper icatypes.ChannelKeeper, + portKeeper icatypes.PortKeeper, + accountKeeper icatypes.AccountKeeper, + scopedKeeper icatypes.ScopedKeeper, + msgRouter icatypes.MessageRouter, +) Keeper +``` + +#### Cosmos SDK message handler responses in packet acknowledgement + +The construction of the transaction response of a message execution on the host chain has changed. The `Data` field in the `sdk.TxMsgData` has been deprecated and since Cosmos SDK 0.46 the `MsgResponses` field contains the message handler responses packed into `Any`s. + +For chains on Cosmos SDK 0.45 and below, the message response was constructed like this: + +```go +txMsgData := &sdk.TxMsgData{ + Data: make([]*sdk.MsgData, len(msgs)), +} + +for i, msg := range msgs { + // message validation + + msgResponse, err := k.executeMsg(cacheCtx, msg) + // return if err != nil + + txMsgData.Data[i] = &sdk.MsgData{ + MsgType: sdk.MsgTypeURL(msg), + Data: msgResponse, + } +} + +// emit events + +txResponse, err := proto.Marshal(txMsgData) +// return if err != nil + +return txResponse, nil +``` + +And for chains on Cosmos SDK 0.46 and above, it is now done like this: + +```go +txMsgData := &sdk.TxMsgData{ + MsgResponses: make([]*codectypes.Any, len(msgs)), +} + +for i, msg := range msgs { + // message validation + + protoAny, err := k.executeMsg(cacheCtx, msg) + // return if err != nil + + txMsgData.MsgResponses[i] = protoAny +} + +// emit events + +txResponse, err := proto.Marshal(txMsgData) +// return if err != nil + +return txResponse, nil +``` + +When handling the acknowledgement in the `OnAcknowledgementPacket` callback of a custom ICA controller module, then depending on whether `txMsgData.Data` is empty or not, the logic to handle the message handler response will be different. **Only controller chains on Cosmos SDK 0.46 or above will be able to write the logic needed to handle the response from a host chain on Cosmos SDK 0.46 or above.** + +```go +var ack channeltypes.Acknowledgement +if err := channeltypes.SubModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { + return err +} + +var txMsgData sdk.TxMsgData +if err := proto.Unmarshal(ack.GetResult(), txMsgData); err != nil { + return err +} + +switch len(txMsgData.Data) { +case 0: // for SDK 0.46 and above + for _, msgResponse := range txMsgData.MsgResponses { + // unmarshall msgResponse and execute logic based on the response + } + return nil +default: // for SDK 0.45 and below + for _, msgData := range txMsgData.Data { + // unmarshall msgData and execute logic based on the response + } +} +``` + +See [ADR-03](../architecture/adr-003-ics27-acknowledgement.md/#next-major-version-format) for more information or the [corrresponding documentation about authentication modules](../apps/interchain-accounts/auth-modules.md#onacknowledgementpacket). + +### ICS29 - Fee Middleware + +The `key` parameter of the `NewKeeper` function in `modules/apps/29-fee` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): + +```diff +func NewKeeper( + cdc codec.BinaryCodec, +- key sdk.StoreKey, ++ key storetypes.StoreKey, + paramSpace paramtypes.Subspace, + ics4Wrapper types.ICS4Wrapper, + channelKeeper types.ChannelKeeper, + portKeeper types.PortKeeper, + authKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, +) Keeper +``` + +The `RegisterRESTRoutes` function in `modules/apps/29-fee` has been removed. + +### IBC testing package + +The `MockIBCApp` type has been renamed to `IBCApp` (and the corresponding constructor function to `NewIBCApp`). This has resulted therefore in: + +- The `IBCApp` field of the `*IBCModule` in `testing/mock` to change its type as well to `*IBCApp`: + +```diff +type IBCModule struct { + appModule *AppModule +- IBCApp *MockIBCApp // base application of an IBC middleware stack ++ IBCApp *IBCApp // base application of an IBC middleware stack +} +``` + +- The `app` parameter to `*NewIBCModule` in `testing/mock` to change its type as well to `*IBCApp`: + +```diff +func NewIBCModule( + appModule *AppModule, +- app *MockIBCApp ++ app *IBCApp +) IBCModule +``` + +The `MockEmptyAcknowledgement` type has been renamed to `EmptyAcknowledgement` (and the corresponding constructor function to `NewEmptyAcknowledgement`). + +The `TestingApp` interface in `testing` has gone through some modifications: + +- The return type of the function `GetStakingKeeper` is not the concrete type `stakingkeeper.Keeper` anymore (where `stakingkeeper` is an import alias for `"github.com/cosmos/cosmos-sdk/x/staking/keeper"`), but it has been changed to the interface `ibctestingtypes.StakingKeeper` (where `ibctestingtypes` is an import alias for `""github.com/cosmos/ibc-go/v5/testing/types"`). See this [PR](https://github.com/cosmos/ibc-go/pull/2028) for more details. The `StakingKeeper` interface is defined as: + +```go +type StakingKeeper interface { + GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool) +} +``` + +- The return type of the function `LastCommitID` has changed to `storetypes.CommitID` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`). + +See the following `git diff` for more details: + +```diff +type TestingApp interface { + abci.Application + + // ibc-go additions + GetBaseApp() *baseapp.BaseApp +- GetStakingKeeper() stakingkeeper.Keeper ++ GetStakingKeeper() ibctestingtypes.StakingKeeper + GetIBCKeeper() *keeper.Keeper + GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper + GetTxConfig() client.TxConfig + + // Implemented by SimApp + AppCodec() codec.Codec + + // Implemented by BaseApp +- LastCommitID() sdk.CommitID ++ LastCommitID() storetypes.CommitID + LastBlockHeight() int64 +} +``` + +The `powerReduction` parameter of the function `SetupWithGenesisValSet` in `testing` is now of type `math.Int` (`"cosmossdk.io/math"`): + +```diff +func SetupWithGenesisValSet( + t *testing.T, + valSet *tmtypes.ValidatorSet, + genAccs []authtypes.GenesisAccount, + chainID string, +- powerReduction sdk.Int, ++ powerReduction math.Int, + balances ...banktypes.Balance +) TestingApp +``` + +The `accAmt` parameter of the functions + +- `AddTestAddrsFromPubKeys` , +- `AddTestAddrs` +- and `AddTestAddrsIncremental` + +in `testing/simapp` are now of type `math.Int` (`"cosmossdk.io/math"`): + +```diff +func AddTestAddrsFromPubKeys( + app *SimApp, + ctx sdk.Context, + pubKeys []cryptotypes.PubKey, +- accAmt sdk.Int, ++ accAmt math.Int +) +func addTestAddrs( + app *SimApp, + ctx sdk.Context, + accNum int, +- accAmt sdk.Int, ++ accAmt math.Int, + strategy GenerateAccountStrategy +) []sdk.AccAddress +func AddTestAddrsIncremental( + app *SimApp, + ctx sdk.Context, + accNum int, +- accAmt sdk.Int, ++ accAmt math.Int +) []sdk.AccAddress +``` + +The `RegisterRESTRoutes` function in `testing/mock` has been removed. + +## Relayers + +- No relevant changes were made in this release. + +## IBC Light Clients + +### ICS02 - Client + +The `key` parameter of the `NewKeeper` function in `modules/core/02-client/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): + +```diff +func NewKeeper( + cdc codec.BinaryCodec, +- key sdk.StoreKey, ++ key storetypes.StoreKey, + paramSpace paramtypes.Subspace, + sk types.StakingKeeper, + uk types.UpgradeKeeper +) Keeper +``` diff --git a/docs/migrations/v5-to-v6.md b/docs/migrations/v5-to-v6.md new file mode 100644 index 00000000000..06052170970 --- /dev/null +++ b/docs/migrations/v5-to-v6.md @@ -0,0 +1,292 @@ +# Migrating from ibc-go v5 to v6 + +This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. +Any changes that must be done by a user of ibc-go should be documented here. + +There are four sections based on the four potential user groups of this document: + +- Chains +- IBC Apps +- Relayers +- IBC Light Clients + +**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. + +## Chains + +The `ibc-go/v6` release introduces a new set of migrations for `27-interchain-accounts`. Ownership of ICS27 channel capabilities is transferred from ICS27 authentication modules and will now reside with the ICS27 controller submodule moving forward. + +For chains which contain a custom authentication module using the ICS27 controller submodule this requires a migration function to be included in the chain upgrade handler. A subsequent migration handler is run automatically, asserting the ownership of ICS27 channel capabilities has been transferred successfully. + +This migration is not required for chains which *do not* contain a custom authentication module using the ICS27 controller submodule. + +This migration facilitates the addition of the ICS27 controller submodule `MsgServer` which provides a standardised approach to integrating existing forms of authentication such as `x/gov` and `x/group` provided by the Cosmos SDK. + +For more information please refer to [ADR 009](../architecture/adr-009-v6-ics27-msgserver.md). + +### Upgrade proposal + +Please refer to [PR #2383](https://github.com/cosmos/ibc-go/pull/2383) for integrating the ICS27 channel capability migration logic or follow the steps outlined below: + +1. Add the upgrade migration logic to chain distribution. This may be, for example, maintained under a package `app/upgrades/v6`. + +```go +package v6 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + v6 "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/migrations/v6" +) + +const ( + UpgradeName = "v6" +) + +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + cdc codec.BinaryCodec, + capabilityStoreKey *storetypes.KVStoreKey, + capabilityKeeper *capabilitykeeper.Keeper, + moduleName string, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + if err := v6.MigrateICS27ChannelCapability(ctx, cdc, capabilityStoreKey, capabilityKeeper, moduleName); err != nil { + return nil, err + } + + return mm.RunMigrations(ctx, configurator, vm) + } +} +``` + +2. Set the upgrade handler in `app.go`. The `moduleName` parameter refers to the authentication module's `ScopedKeeper` name. This is the name provided upon instantiation in `app.go` via the [`x/capability` keeper `ScopeToModule(moduleName string)`](https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/capability/keeper/keeper.go#L70) method. [See here for an example in `simapp`](https://github.com/cosmos/ibc-go/blob/v5.0.0/testing/simapp/app.go#L304). + +```go +app.UpgradeKeeper.SetUpgradeHandler( + v6.UpgradeName, + v6.CreateUpgradeHandler( + app.mm, + app.configurator, + app.appCodec, + app.keys[capabilitytypes.ModuleName], + app.CapabilityKeeper, + >>>> moduleName <<<<, + ), +) +``` + +## IBC Apps + +### ICS27 - Interchain Accounts + +#### Controller APIs + +In previous releases of ibc-go, chain developers integrating the ICS27 interchain accounts controller functionality were expected to create a custom `Base Application` referred to as an authentication module, see the section [Building an authentication module](../apps/interchain-accounts/auth-modules.md) from the documentation. + +The `Base Application` was intended to be composed with the ICS27 controller submodule `Keeper` and faciliate many forms of message authentication depending on a chain's particular use case. + +Prior to ibc-go v6 the controller submodule exposed only these two functions (to which we will refer as the legacy APIs): + +- [`RegisterInterchainAccount`](https://github.com/cosmos/ibc-go/blob/v5.0.0/modules/apps/27-interchain-accounts/controller/keeper/account.go#L19) +- [`SendTx`](https://github.com/cosmos/ibc-go/blob/v5.0.0/modules/apps/27-interchain-accounts/controller/keeper/relay.go#L18) + +However, these functions have now been deprecated in favour of the new controller submodule `MsgServer` and will be removed in later releases. + +Both APIs remain functional and maintain backwards compatibility in ibc-go v6, however consumers of these APIs are now recommended to follow the message passing paradigm outlined in Cosmos SDK [ADR 031](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-031-msg-service.md) and [ADR 033](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-033-protobuf-inter-module-comm.md). This is facilitated by the Cosmos SDK [`MsgServiceRouter`](https://github.com/cosmos/cosmos-sdk/blob/main/baseapp/msg_service_router.go#L17) and chain developers creating custom application logic can now omit the ICS27 controller submodule `Keeper` from their module and instead depend on message routing. + +Depending on the use case, developers of custom authentication modules face one of three scenarios: + +![AuthModuleDecisionTree](../assets/auth-module-decision-tree.png) + +**My authentication module needs to access IBC packet callbacks** + +Application developers that wish to consume IBC packet callbacks and react upon packet acknowledgements **must** continue using the controller submodule's legacy APIs. The authentication modules will not need a `ScopedKeeper` anymore, though, because the channel capability will be claimed by the controller submodule. For example, given an Interchain Accounts authentication module keeper `ICAAuthKeeper`, the authentication module's `ScopedKeeper` (`scopedICAAuthKeeper`) is not needed anymore and can be removed for the argument list of the keeper constructor function, as shown here: + +```diff +app.ICAAuthKeeper = icaauthkeeper.NewKeeper( + appCodec, + keys[icaauthtypes.StoreKey], + app.ICAControllerKeeper, +- scopedICAAuthKeeper, +) +``` + +Please note that the authentication module's `ScopedKeeper` name is still needed as part of the channel capability migration described in section [Upgrade proposal](#upgrade-proposal) above. Therefore the authentication module's `ScopedKeeper` cannot be completely removed from the chain code until the migration has run. + +In the future, the use of the legacy APIs for accessing packet callbacks will be replaced by IBC Actor Callbacks (see [ADR 008](https://github.com/cosmos/ibc-go/pull/1976) for more details) and it will also be possible to access them with the `MsgServiceRouter`. + +**My authentication module does not need access to IBC packet callbacks** + +The authentication module can migrate from using the legacy APIs and it can be composed instead with the `MsgServiceRouter`, so that the authentication module is able to pass messages to the controller submodule's `MsgServer` to register interchain accounts and send packets to the interchain account. For example, given an Interchain Accounts authentication module keeper `ICAAuthKeeper`, the ICS27 controller submodule keeper (`ICAControllerKeeper`) and authentication module scoped keeper (`scopedICAAuthKeeper`) are not needed anymore and can be replaced with the `MsgServiceRouter`, as shown here: + +```diff +app.ICAAuthKeeper = icaauthkeeper.NewKeeper( + appCodec, + keys[icaauthtypes.StoreKey], +- app.ICAControllerKeeper, +- scopedICAAuthKeeper, ++ app.MsgServiceRouter(), +) +``` + +In your authentication module you can route messages to the controller submodule's `MsgServer` instead of using the legacy APIs. For example, for registering an interchain account: + +```diff +- if err := keeper.icaControllerKeeper.RegisterInterchainAccount( +- ctx, +- connectionID, +- owner.String(), +- version, +- ); err != nil { +- return err +- } ++ msg := controllertypes.NewMsgRegisterInterchainAccount( ++ connectionID, ++ owner.String(), ++ version, ++ ) ++ handler := keeper.msgRouter.Handler(msg) ++ res, err := handler(ctx, msg) ++ if err != nil { ++ return err ++ } +``` + +where `controllertypes` is an import alias for `"github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/types"`. + +In addition, in this use case the authentication module does not need to implement the `IBCModule` interface anymore. + +**I do not need a custom authentication module anymore** + +If your authentication module does not have any extra functionality compared to the default authentication module added in ibc-go v6 (the `MsgServer`), or if you can use a generic authentication module, such as the `x/auth`, `x/gov` or `x/group` modules from the Cosmos SDK (v0.46 and later), then you can remove your authentication module completely and use instead the gRPC endpoints of the `MsgServer` or the CLI added in ibc-go v6. + +Please remember that the authentication module's `ScopedKeeper` name is still needed as part of the channel capability migration described in section [Upgrade proposal](#upgrade-proposal) above. + +#### Host params + +The ICS27 host submodule default params have been updated to include the `AllowAllHostMsgs` wildcard `*`. +This enables execution of any `sdk.Msg` type for ICS27 registered on the host chain `InterfaceRegistry`. + +```diff +// AllowAllHostMsgs holds the string key that allows all message types on interchain accounts host module +const AllowAllHostMsgs = "*" + +... + +// DefaultParams is the default parameter configuration for the host submodule +func DefaultParams() Params { +- return NewParams(DefaultHostEnabled, nil) ++ return NewParams(DefaultHostEnabled, []string{AllowAllHostMsgs}) +} +``` + +#### API breaking changes + +`SerializeCosmosTx` takes in a `[]proto.Message` instead of `[]sdk.Message`. This allows for the serialization of proto messages without requiring the fulfillment of the `sdk.Msg` interface. + +The `27-interchain-accounts` genesis types have been moved to their own package: `modules/apps/27-interchain-acccounts/genesis/types`. +This change facilitates the addition of the ICS27 controller submodule `MsgServer` and avoids cyclic imports. This should have minimal disruption to chain developers integrating `27-interchain-accounts`. + +The ICS27 host submodule `NewKeeper` function in `modules/apps/27-interchain-acccounts/host/keeper` now includes an additional parameter of type `ICS4Wrapper`. +This provides the host submodule with the ability to correctly unwrap channel versions in the event of a channel reopening handshake. + +```diff +func NewKeeper( + cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, +- channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, ++ ics4Wrapper icatypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, + accountKeeper icatypes.AccountKeeper, scopedKeeper icatypes.ScopedKeeper, msgRouter icatypes.MessageRouter, +) Keeper +``` + +### ICS29 - `NewKeeper` API change + +The `NewKeeper` function of ICS29 has been updated to remove the `paramSpace` parameter as it was unused. + +```diff +func NewKeeper( +- cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, +- ics4Wrapper types.ICS4Wrapper, channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, ++ cdc codec.BinaryCodec, key storetypes.StoreKey, ++ ics4Wrapper types.ICS4Wrapper, channelKeeper types.ChannelKeeper, ++ portKeeper types.PortKeeper, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, +) Keeper { +``` + +### ICS20 - `SendTransfer` is no longer exported + +The `SendTransfer` function of ICS20 has been removed. IBC transfers should now be initiated with `MsgTransfer` and routed to the ICS20 `MsgServer`. + +See below for example: + +```go +if handler := msgRouter.Handler(msgTransfer); handler != nil { + if err := msgTransfer.ValidateBasic(); err != nil { + return nil, err + } + + res, err := handler(ctx, msgTransfer) + if err != nil { + return nil, err + } +} +``` + +### ICS04 - `SendPacket` API change + +The `SendPacket` API has been simplified: + +```diff +// SendPacket is called by a module in order to send an IBC packet on a channel +func (k Keeper) SendPacket( + ctx sdk.Context, + channelCap *capabilitytypes.Capability, +- packet exported.PacketI, +-) error { ++ sourcePort string, ++ sourceChannel string, ++ timeoutHeight clienttypes.Height, ++ timeoutTimestamp uint64, ++ data []byte, ++) (uint64, error) { +``` + +Callers no longer need to pass in a pre-constructed packet. +The destination port/channel identifiers and the packet sequence will be determined by core IBC. +`SendPacket` will return the packet sequence. + +### IBC testing package + +The `SendPacket` API has been simplified: + +```diff +// SendPacket is called by a module in order to send an IBC packet on a channel +func (k Keeper) SendPacket( + ctx sdk.Context, + channelCap *capabilitytypes.Capability, +- packet exported.PacketI, +-) error { ++ sourcePort string, ++ sourceChannel string, ++ timeoutHeight clienttypes.Height, ++ timeoutTimestamp uint64, ++ data []byte, ++) (uint64, error) { +``` + +Callers no longer need to pass in a pre-constructed packet. `SendPacket` will return the packet sequence. + +## Relayers + +- No relevant changes were made in this release. + +## IBC Light Clients + +- No relevant changes were made in this release. diff --git a/docs/migrations/v6-to-v7.md b/docs/migrations/v6-to-v7.md new file mode 100644 index 00000000000..4e15fc5061b --- /dev/null +++ b/docs/migrations/v6-to-v7.md @@ -0,0 +1,351 @@ +# Migrating from ibc-go v6 to v7 + +This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. +Any changes that must be done by a user of ibc-go should be documented here. + +There are four sections based on the four potential user groups of this document: + +- Chains +- IBC Apps +- Relayers +- IBC Light Clients + +**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. + +## Chains + +Chains will perform automatic migrations to remove existing localhost clients and to migrate the solomachine to v3 of the protobuf definition. + +An optional upgrade handler has been added to prune expired tendermint consensus states. It may be used during any upgrade (from v7 onwards). +Add the following to the function call to the upgrade handler in `app/app.go`, to perform the optional state pruning. + +```go +import ( + // ... + ibctmmigrations "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint/migrations" +) + +// ... + +app.UpgradeKeeper.SetUpgradeHandler( + upgradeName, + func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { + // prune expired tendermint consensus states to save storage space + _, err := ibctmmigrations.PruneExpiredConsensusStates(ctx, app.Codec, app.IBCKeeper.ClientKeeper) + if err != nil { + return nil, err + } + + return app.mm.RunMigrations(ctx, app.configurator, fromVM) + }, +) +``` + +Checkout the logs to see how many consensus states are pruned. + +### Light client registration + +Chains must explicitly register the types of any light client modules it wishes to integrate. + +#### Tendermint registration + +To register the tendermint client, modify the `app.go` file to include the tendermint `AppModuleBasic`: + +```diff +import ( + // ... ++ ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint" +) + +// ... + +ModuleBasics = module.NewBasicManager( + ... + ibc.AppModuleBasic{}, ++ ibctm.AppModuleBasic{}, + ... +) +``` + +It may be useful to reference the [PR](https://github.com/cosmos/ibc-go/pull/2825) which added the `AppModuleBasic` for the tendermint client. + +#### Solo machine registration + +To register the solo machine client, modify the `app.go` file to include the solo machine `AppModuleBasic`: + +```diff +import ( + // ... ++ solomachine "github.com/cosmos/ibc-go/v6/modules/light-clients/06-solomachine" +) + +// ... + +ModuleBasics = module.NewBasicManager( + ... + ibc.AppModuleBasic{}, ++ solomachine.AppModuleBasic{}, + ... +) +``` + +It may be useful to reference the [PR](https://github.com/cosmos/ibc-go/pull/2826) which added the `AppModuleBasic` for the solo machine client. + +### Testing package API + +The `SetChannelClosed` utility method in `testing/endpoint.go` has been updated to `SetChannelState`, which will take a `channeltypes.State` argument so that the `ChannelState` can be set to any of the possible channel states. + +## IBC Apps + +- No relevant changes were made in this release. + +## Relayers + +- No relevant changes were made in this release. + +## IBC Light Clients + +### `ClientState` interface changes + +The `VerifyUpgradeAndUpdateState` function has been modified. The client state and consensus state return values have been removed. + +Light clients **must** handle all management of client and consensus states including the setting of updated client state and consensus state in the client store. + +The `Initialize` method is now expected to set the initial client state, consensus state and any client-specific metadata in the provided store upon client creation. + +The `CheckHeaderAndUpdateState` method has been split into 4 new methods: + +- `VerifyClientMessage` verifies a `ClientMessage`. A `ClientMessage` could be a `Header`, `Misbehaviour`, or batch update. Calls to `CheckForMisbehaviour`, `UpdateState`, and `UpdateStateOnMisbehaviour` will assume that the content of the `ClientMessage` has been verified and can be trusted. An error should be returned if the `ClientMessage` fails to verify. + +- `CheckForMisbehaviour` checks for evidence of a misbehaviour in `Header` or `Misbehaviour` types. + +- `UpdateStateOnMisbehaviour` performs appropriate state changes on a `ClientState` given that misbehaviour has been detected and verified. + +- `UpdateState` updates and stores as necessary any associated information for an IBC client, such as the `ClientState` and corresponding `ConsensusState`. An error is returned if `ClientMessage` is of type `Misbehaviour`. Upon successful update, a list containing the updated consensus state height is returned. + +The `CheckMisbehaviourAndUpdateState` function has been removed from `ClientState` interface. This functionality is now encapsulated by the usage of `VerifyClientMessage`, `CheckForMisbehaviour`, `UpdateStateOnMisbehaviour`. + +The function `GetTimestampAtHeight` has been added to the `ClientState` interface. It should return the timestamp for a consensus state associated with the provided height. + +Prior to ibc-go/v7 the `ClientState` interface defined a method for each data type which was being verified in the counterparty state store. +The state verification functions for all IBC data types have been consolidated into two generic methods, `VerifyMembership` and `VerifyNonMembership`. +Both are expected to be provided with a standardised key path, `exported.Path`, as defined in [ICS 24 host requirements](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements). Membership verification requires callers to provide the marshalled value `[]byte`. Delay period values should be zero for non-packet processing verification. A zero proof height is now allowed by core IBC and may be passed into `VerifyMembership` and `VerifyNonMembership`. Light clients are responsible for returning an error if a zero proof height is invalid behaviour. + +See below for an example of how ibc-go now performs channel state verification. + +```go +merklePath := commitmenttypes.NewMerklePath(host.ChannelPath(portID, channelID)) +merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) +if err != nil { + return err +} + +channelEnd, ok := channel.(channeltypes.Channel) +if !ok { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "invalid channel type %T", channel) +} + +bz, err := k.cdc.Marshal(&channelEnd) +if err != nil { + return err +} + +if err := clientState.VerifyMembership( + ctx, clientStore, k.cdc, height, + 0, 0, // skip delay period checks for non-packet processing verification + proof, merklePath, bz, +); err != nil { + return sdkerrors.Wrapf(err, "failed channel state verification for client (%s)", clientID) +} +``` + +### `Header` and `Misbehaviour` + +`exported.Header` and `exported.Misbehaviour` interface types have been merged and renamed to `ClientMessage` interface. + +`GetHeight` function has been removed from `exported.Header` and thus is not included in the `ClientMessage` interface + +### `ConsensusState` + +The `GetRoot` function has been removed from consensus state interface since it was not used by core IBC. + +### Client keeper + +Keeper function `CheckMisbehaviourAndUpdateState` has been removed since function `UpdateClient` can now handle updating `ClientState` on `ClientMessage` type which can be any `Misbehaviour` implementations. + +### SDK message + +`MsgSubmitMisbehaviour` is deprecated since `MsgUpdateClient` can now submit a `ClientMessage` type which can be any `Misbehaviour` implementations. + +The field `header` in `MsgUpdateClient` has been renamed to `client_message`. + +## Solomachine + +The `06-solomachine` client implementation has been simplified in ibc-go/v7. In-place store migrations have been added to migrate solomachine clients from `v2` to `v3`. + +### `ClientState` + +The `ClientState` protobuf message definition has been updated to remove the deprecated `bool` field `allow_update_after_proposal`. + +```diff +message ClientState { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + bool is_frozen = 2 [(gogoproto.moretags) = "yaml:\"is_frozen\""]; + ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; +- bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; +} +``` + +### `Header` and `Misbehaviour` + +The `06-solomachine` protobuf message `Header` has been updated to remove the `sequence` field. This field was seen as redundant as the implementation can safely rely on the `sequence` value maintained within the `ClientState`. + +```diff +message Header { + option (gogoproto.goproto_getters) = false; + +- uint64 sequence = 1; +- uint64 timestamp = 2; +- bytes signature = 3; +- google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; +- string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; ++ uint64 timestamp = 1; ++ bytes signature = 2; ++ google.protobuf.Any new_public_key = 3 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; ++ string new_diversifier = 4 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} +``` + +Similarly, the `Misbehaviour` protobuf message has been updated to remove the `client_id` field. + +```diff +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + +- string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; +- uint64 sequence = 2; +- SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; +- SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; ++ uint64 sequence = 1; ++ SignatureAndData signature_one = 2 [(gogoproto.moretags) = "yaml:\"signature_one\""]; ++ SignatureAndData signature_two = 3 [(gogoproto.moretags) = "yaml:\"signature_two\""]; +} +``` + +### `SignBytes` + +Most notably, the `SignBytes` protobuf definition has been modified to replace the `data_type` field with a new field, `path`. The `path` field is defined as `bytes` and represents a serialized [ICS-24](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements) standardized key path under which the `data` is stored. + +```diff +message SignBytes { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + uint64 timestamp = 2; + string diversifier = 3; +- DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; ++ bytes path = 4; + bytes data = 5; +} +``` + +The `DataType` enum and all associated data types have been removed, greatly reducing the number of message definitions and complexity in constructing the `SignBytes` message type. Likewise, solomachine implementations must now use the serialized `path` value when constructing `SignatureAndData` for signature verification of `SignBytes` data. + +```diff +message SignatureAndData { + option (gogoproto.goproto_getters) = false; + + bytes signature = 1; +- DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; ++ bytes path = 2; + bytes data = 3; + uint64 timestamp = 4; +} +``` + +For more information, please refer to [ADR-007](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/docs/architecture/adr-007-solomachine-signbytes.md). + +### IBC module constants + +IBC module constants have been moved from the `host` package to the `exported` package. Any usages will need to be updated. + +```diff +import ( + // ... +- host "github.com/cosmos/ibc-go/v6/modules/core/24-host" ++ ibcexported "github.com/cosmos/ibc-go/v6/modules/core/exported" + // ... +) + +- host.ModuleName ++ ibcexported.ModuleName + +- host.StoreKey ++ ibcexported.StoreKey + +- host.QuerierRoute ++ ibcexported.QuerierRoute + +- host.RouterKey ++ ibcexported.RouterKey +``` + +## Upgrading to Cosmos SDK 0.47 + +The following should be considered as complementary to [Cosmos SDK v0.47 UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc2/UPGRADING.md). + +### Protobuf + +Protobuf code generation, linting and formatting have been updated to leverage the `ghcr.io/cosmos/proto-builder:0.11.5` docker container. IBC protobuf definitions are now packaged and published to [buf.build/cosmos/ibc](https://buf.build/cosmos/ibc) via CI workflows. The `third_party/proto` directory has been removed in favour of dependency management using [buf.build](https://docs.buf.build/introduction). + +### App modules + +Legacy APIs of the `AppModule` interface have been removed from ibc-go modules. For example, for + +```diff +- // Route implements the AppModule interface +- func (am AppModule) Route() sdk.Route { +- return sdk.Route{} +- } +- +- // QuerierRoute implements the AppModule interface +- func (AppModule) QuerierRoute() string { +- return types.QuerierRoute +- } +- +- // LegacyQuerierHandler implements the AppModule interface +- func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { +- return nil +- } +- +- // ProposalContents doesn't return any content functions for governance proposals. +- func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { +- return nil +- } +``` + +### Imports + +Imports for ics23 have been updated as the repository have been migrated from confio to cosmos. + +```diff +import ( + // ... +- ics23 "github.com/confio/ics23/go" ++ ics23 "github.com/cosmos/ics23/go" + // ... +) +``` + +Imports for gogoproto have been updated. + +```diff +import ( + // ... +- "github.com/gogo/protobuf/proto" ++ "github.com/cosmos/gogoproto/proto" + // ... +) +``` diff --git a/docs/package-lock.json b/docs/package-lock.json index ff82a7755b0..552c3164446 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1,8 +1,14279 @@ { "name": "docs", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "docs", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "vuepress-theme-cosmos": "^1.0.183" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.12.0.tgz", + "integrity": "sha512-l+G560B6N1k0rIcOjTO1yCzFUbg2Zy2HCii9s03e13jGgqduVQmk79UUCYszjsJ5GPJpUEKcVEtAIpP7tjsXVA==", + "dependencies": { + "@algolia/cache-common": "4.12.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.12.0.tgz", + "integrity": "sha512-2Z8BV+NX7oN7RmmQbLqmW8lfN9aAjOexX1FJjzB0YfKC9ifpi9Jl4nSxlnbU+iLR6QhHo0IfuyQ7wcnucCGCGQ==" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.12.0.tgz", + "integrity": "sha512-b6ANkZF6vGAo+sYv6g25W5a0u3o6F549gEAgtTDTVA1aHcdWwe/HG/dTJ7NsnHbuR+A831tIwnNYQjRp3/V/Jw==", + "dependencies": { + "@algolia/cache-common": "4.12.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.12.0.tgz", + "integrity": "sha512-gzXN75ZydNheNXUN3epS+aLsKnB/PHFVlGUUjXL8WHs4lJP3B5FtHvaA/NCN5DsM3aamhuY5p0ff1XIA+Lbcrw==", + "dependencies": { + "@algolia/client-common": "4.12.0", + "@algolia/client-search": "4.12.0", + "@algolia/transporter": "4.12.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.12.0.tgz", + "integrity": "sha512-rO2cZCt00Opk66QBZb7IBGfCq4ZE3EiuGkXssf2Monb5urujy0r8CknK2i7bzaKtPbd2vlvhmLP4CEHQqF6SLQ==", + "dependencies": { + "@algolia/client-common": "4.12.0", + "@algolia/client-search": "4.12.0", + "@algolia/requester-common": "4.12.0", + "@algolia/transporter": "4.12.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.12.0.tgz", + "integrity": "sha512-fcrFN7FBmxiSyjeu3sF4OnPkC1l7/8oyQ8RMM8CHpVY8cad6/ay35MrfRfgfqdzdFA8LzcBYO7fykuJv0eOqxw==", + "dependencies": { + "@algolia/requester-common": "4.12.0", + "@algolia/transporter": "4.12.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.12.0.tgz", + "integrity": "sha512-wCJfSQEmX6ZOuJBJGjy+sbXiW0iy7tMNAhsVMV9RRaJE4727e5WAqwFWZssD877WQ74+/nF/VyTaB1+wejo33Q==", + "dependencies": { + "@algolia/client-common": "4.12.0", + "@algolia/requester-common": "4.12.0", + "@algolia/transporter": "4.12.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.12.0.tgz", + "integrity": "sha512-ik6dswcTQtOdZN+8aKntI9X2E6Qpqjtyda/+VANiHThY9GD2PBXuNuuC2HvlF26AbBYp5xaSE/EKxn1DIiIJ4Q==", + "dependencies": { + "@algolia/client-common": "4.12.0", + "@algolia/requester-common": "4.12.0", + "@algolia/transporter": "4.12.0" + } + }, + "node_modules/@algolia/logger-common": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.12.0.tgz", + "integrity": "sha512-V//9rzLdJujA3iZ/tPhmKR/m2kjSZrymxOfUiF3024u2/7UyOpH92OOCrHUf023uMGYHRzyhBz5ESfL1oCdh7g==" + }, + "node_modules/@algolia/logger-console": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.12.0.tgz", + "integrity": "sha512-pHvoGv53KXRIJHLk9uxBwKirwEo12G9+uo0sJLWESThAN3v5M+ycliU1AkUXQN8+9rds2KxfULAb+vfyfBKf8A==", + "dependencies": { + "@algolia/logger-common": "4.12.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.12.0.tgz", + "integrity": "sha512-rGlHNMM3jIZBwSpz33CVkeXHilzuzHuFXEEW1icP/k3KW7kwBrKFJwBy42RzAJa5BYlLsTCFTS3xkPhYwTQKLg==", + "dependencies": { + "@algolia/requester-common": "4.12.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.12.0.tgz", + "integrity": "sha512-qgfdc73nXqpVyOMr6CMTx3nXvud9dP6GcMGDqPct+fnxogGcJsp24cY2nMqUrAfgmTJe9Nmy7Lddv0FyHjONMg==" + }, + "node_modules/@algolia/requester-node-http": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.12.0.tgz", + "integrity": "sha512-mOTRGf/v/dXshBoZKNhMG00ZGxoUH9QdSpuMKYnuWwIgstN24uj3DQx+Ho3c+uq0TYfq7n2v71uoJWuiW32NMQ==", + "dependencies": { + "@algolia/requester-common": "4.12.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.12.0.tgz", + "integrity": "sha512-MOQVHZ4BcBpf3LtOY/3fqXHAcvI8MahrXDHk9QrBE/iGensQhDiZby5Dn3o2JN/zd9FMnVbdPQ8gnkiMwZiakQ==", + "dependencies": { + "@algolia/cache-common": "4.12.0", + "@algolia/logger-common": "4.12.0", + "@algolia/requester-common": "4.12.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", + "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", + "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.12", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.10", + "@babel/types": "^7.16.8", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", + "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", + "dependencies": { + "@babel/types": "^7.16.8", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", + "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz", + "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==", + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dependencies": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz", + "integrity": "sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz", + "integrity": "sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "regexpu-core": "^4.7.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", + "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz", + "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", + "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", + "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz", + "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-wrap-function": "^7.16.8", + "@babel/types": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", + "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-member-expression-to-functions": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", + "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "dependencies": { + "@babel/types": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz", + "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==", + "dependencies": { + "@babel/helper-function-name": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.8", + "@babel/types": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", + "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz", + "integrity": "sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz", + "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz", + "integrity": "sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", + "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz", + "integrity": "sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.16.7.tgz", + "integrity": "sha512-DoEpnuXK14XV9btI1k8tzNGCutMclpj4yru8aXKoHlVmbO1s+2A+g2+h4JhcjrxkFJqzbymnLG6j/niOf3iFXQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-decorators": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", + "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", + "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz", + "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", + "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", + "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", + "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz", + "integrity": "sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==", + "dependencies": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz", + "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", + "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", + "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.16.10", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", + "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-create-class-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz", + "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.16.7.tgz", + "integrity": "sha512-vQ+PxL+srA7g6Rx6I1e15m55gftknl2X8GCUW1JTlkTaXZLJOS0UcaY0eK9jYT7IYf4awn6qwyghVHLDz1WyMw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", + "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", + "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz", + "integrity": "sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-remap-async-to-generator": "^7.16.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz", + "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz", + "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz", + "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-optimise-call-expression": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz", + "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz", + "integrity": "sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz", + "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz", + "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz", + "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz", + "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz", + "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz", + "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz", + "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz", + "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==", + "dependencies": { + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", + "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz", + "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz", + "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==", + "dependencies": { + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz", + "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz", + "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz", + "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-replace-supers": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz", + "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz", + "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz", + "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==", + "dependencies": { + "regenerator-transform": "^0.14.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz", + "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.10.tgz", + "integrity": "sha512-9nwTiqETv2G7xI4RvXHNfpGdr8pAA+Q/YtN3yLK7OoK7n9OibVm/xymJ838a9A6E/IciOLPj82lZk0fW6O4O7w==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz", + "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz", + "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz", + "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz", + "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz", + "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", + "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz", + "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.16.11", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz", + "integrity": "sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==", + "dependencies": { + "@babel/compat-data": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-validator-option": "^7.16.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-async-generator-functions": "^7.16.8", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/plugin-proposal-class-static-block": "^7.16.7", + "@babel/plugin-proposal-dynamic-import": "^7.16.7", + "@babel/plugin-proposal-export-namespace-from": "^7.16.7", + "@babel/plugin-proposal-json-strings": "^7.16.7", + "@babel/plugin-proposal-logical-assignment-operators": "^7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-numeric-separator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-proposal-private-methods": "^7.16.11", + "@babel/plugin-proposal-private-property-in-object": "^7.16.7", + "@babel/plugin-proposal-unicode-property-regex": "^7.16.7", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.16.7", + "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-block-scoped-functions": "^7.16.7", + "@babel/plugin-transform-block-scoping": "^7.16.7", + "@babel/plugin-transform-classes": "^7.16.7", + "@babel/plugin-transform-computed-properties": "^7.16.7", + "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-dotall-regex": "^7.16.7", + "@babel/plugin-transform-duplicate-keys": "^7.16.7", + "@babel/plugin-transform-exponentiation-operator": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-function-name": "^7.16.7", + "@babel/plugin-transform-literals": "^7.16.7", + "@babel/plugin-transform-member-expression-literals": "^7.16.7", + "@babel/plugin-transform-modules-amd": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.16.8", + "@babel/plugin-transform-modules-systemjs": "^7.16.7", + "@babel/plugin-transform-modules-umd": "^7.16.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.8", + "@babel/plugin-transform-new-target": "^7.16.7", + "@babel/plugin-transform-object-super": "^7.16.7", + "@babel/plugin-transform-parameters": "^7.16.7", + "@babel/plugin-transform-property-literals": "^7.16.7", + "@babel/plugin-transform-regenerator": "^7.16.7", + "@babel/plugin-transform-reserved-words": "^7.16.7", + "@babel/plugin-transform-shorthand-properties": "^7.16.7", + "@babel/plugin-transform-spread": "^7.16.7", + "@babel/plugin-transform-sticky-regex": "^7.16.7", + "@babel/plugin-transform-template-literals": "^7.16.7", + "@babel/plugin-transform-typeof-symbol": "^7.16.7", + "@babel/plugin-transform-unicode-escapes": "^7.16.7", + "@babel/plugin-transform-unicode-regex": "^7.16.7", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.16.8", + "babel-plugin-polyfill-corejs2": "^0.3.0", + "babel-plugin-polyfill-corejs3": "^0.5.0", + "babel-plugin-polyfill-regenerator": "^0.3.0", + "core-js-compat": "^3.20.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", + "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", + "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.10", + "@babel/types": "^7.16.8", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@babel/types": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cosmos-ui/vue": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@cosmos-ui/vue/-/vue-0.35.0.tgz", + "integrity": "sha512-WTCJBWSoiDckgvXWPByKkQ7ZVSf9LSMsizIAHBnsi0Zp3GOaEqPNBpgjGt2JEhpDPr7+YwyIgmqQ0S3D+Hq5iQ==", + "dependencies": { + "algoliasearch": "^4.1.0", + "axios": "^0.19.2", + "clipboard-copy": "^3.1.0", + "fuse.js": "^3.4.6", + "hotkeys-js": "^3.7.3", + "js-base64": "^2.5.2", + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "prismjs": "^1.19.0", + "querystring": "^0.2.0", + "tiny-cookie": "^2.3.1", + "vue": "^2.6.10" + } + }, + "node_modules/@cosmos-ui/vue/node_modules/axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", + "dependencies": { + "follow-redirects": "1.5.10" + } + }, + "node_modules/@cosmos-ui/vue/node_modules/clipboard-copy": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-3.2.0.tgz", + "integrity": "sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/@cosmos-ui/vue/node_modules/entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==" + }, + "node_modules/@cosmos-ui/vue/node_modules/markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dependencies": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dependencies": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/highlight.js": { + "version": "9.12.4", + "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.4.tgz", + "integrity": "sha512-t2szdkwmg2JJyuCM20e8kR2X59WCE5Zkl4bzm1u1Oukjm79zpbiAv+QjnwLnuuV0WHEcX2NgUItu0pAMKuOPww==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.8", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", + "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" + }, + "node_modules/@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==" + }, + "node_modules/@types/markdown-it": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-10.0.3.tgz", + "integrity": "sha512-daHJk22isOUvNssVGF2zDnnSyxHhFYhtjeX4oQaKD6QzL3ZR1QSgiD1g+Q6/WSWYVogNXYDXODtbgW/WiFCtyw==", + "dependencies": { + "@types/highlight.js": "^9.7.0", + "@types/linkify-it": "*", + "@types/mdurl": "*", + "highlight.js": "^9.7.0" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + }, + "node_modules/@types/node": { + "version": "17.0.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz", + "integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA==" + }, + "node_modules/@types/q": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==" + }, + "node_modules/@types/tapable": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", + "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==" + }, + "node_modules/@types/uglify-js": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", + "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/@types/uglify-js/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@types/webpack": { + "version": "4.41.32", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.32.tgz", + "integrity": "sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==", + "dependencies": { + "@types/node": "*", + "@types/tapable": "^1", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "anymatch": "^3.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/@types/webpack-dev-server": { + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.6.tgz", + "integrity": "sha512-XCph0RiiqFGetukCTC3KVnY1jwLcZ84illFRMbyFzCcWl90B/76ew0tSqF46oBhnLC4obNDG7dMO0JfTN0MgMQ==", + "dependencies": { + "@types/connect-history-api-fallback": "*", + "@types/express": "*", + "@types/serve-static": "*", + "@types/webpack": "^4", + "http-proxy-middleware": "^1.0.0" + } + }, + "node_modules/@types/webpack-sources": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.0.tgz", + "integrity": "sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==", + "dependencies": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + } + }, + "node_modules/@types/webpack/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/babel-helper-vue-jsx-merge-props": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz", + "integrity": "sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==" + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz", + "integrity": "sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz", + "integrity": "sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "@vue/babel-helper-vue-transform-on": "^1.0.2", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + } + }, + "node_modules/@vue/babel-plugin-transform-vue-jsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz", + "integrity": "sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA==", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", + "html-tags": "^2.0.0", + "lodash.kebabcase": "^4.1.1", + "svg-tags": "^1.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-plugin-transform-vue-jsx/node_modules/html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/babel-preset-app": { + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.5.15.tgz", + "integrity": "sha512-J+YttzvwRfV1BPczf8r3qCevznYk+jh531agVF+5EYlHF4Sgh/cGXTz9qkkiux3LQgvhEGXgmCteg1n38WuuKg==", + "dependencies": { + "@babel/core": "^7.11.0", + "@babel/helper-compilation-targets": "^7.9.6", + "@babel/helper-module-imports": "^7.8.3", + "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-proposal-decorators": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.11.0", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.0", + "@vue/babel-plugin-jsx": "^1.0.3", + "@vue/babel-preset-jsx": "^1.2.4", + "babel-plugin-dynamic-import-node": "^2.3.3", + "core-js": "^3.6.5", + "core-js-compat": "^3.6.5", + "semver": "^6.1.0" + }, + "peerDependencies": { + "@babel/core": "*", + "core-js": "^3", + "vue": "^2 || ^3.0.0-0" + }, + "peerDependenciesMeta": { + "core-js": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/@vue/babel-preset-jsx": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz", + "integrity": "sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w==", + "dependencies": { + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", + "@vue/babel-sugar-composition-api-inject-h": "^1.2.1", + "@vue/babel-sugar-composition-api-render-instance": "^1.2.4", + "@vue/babel-sugar-functional-vue": "^1.2.2", + "@vue/babel-sugar-inject-h": "^1.2.2", + "@vue/babel-sugar-v-model": "^1.2.3", + "@vue/babel-sugar-v-on": "^1.2.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-sugar-composition-api-inject-h": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz", + "integrity": "sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ==", + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-sugar-composition-api-render-instance": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz", + "integrity": "sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q==", + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-sugar-functional-vue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz", + "integrity": "sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w==", + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-sugar-inject-h": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz", + "integrity": "sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw==", + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-sugar-v-model": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz", + "integrity": "sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ==", + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", + "camelcase": "^5.0.0", + "html-tags": "^2.0.0", + "svg-tags": "^1.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-sugar-v-model/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@vue/babel-sugar-v-model/node_modules/html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/babel-sugar-v-on": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz", + "integrity": "sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw==", + "dependencies": { + "@babel/plugin-syntax-jsx": "^7.2.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.2.1", + "camelcase": "^5.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-sugar-v-on/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@vue/component-compiler-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz", + "integrity": "sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==", + "dependencies": { + "consolidate": "^0.15.1", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.2", + "merge-source-map": "^1.1.0", + "postcss": "^7.0.36", + "postcss-selector-parser": "^6.0.2", + "source-map": "~0.6.1", + "vue-template-es2015-compiler": "^1.9.0" + }, + "optionalDependencies": { + "prettier": "^1.18.2 || ^2.0.0" + } + }, + "node_modules/@vue/component-compiler-utils/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/@vue/component-compiler-utils/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/component-compiler-utils/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "node_modules/@vuepress/core": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-1.9.7.tgz", + "integrity": "sha512-u5eb1mfNLV8uG2UuxlvpB/FkrABxeMHqymTsixOnsOg2REziv9puEIbqaZ5BjLPvbCDvSj6rn+DwjENmBU+frQ==", + "dependencies": { + "@babel/core": "^7.8.4", + "@vue/babel-preset-app": "^4.1.2", + "@vuepress/markdown": "1.9.7", + "@vuepress/markdown-loader": "1.9.7", + "@vuepress/plugin-last-updated": "1.9.7", + "@vuepress/plugin-register-components": "1.9.7", + "@vuepress/shared-utils": "1.9.7", + "@vuepress/types": "1.9.7", + "autoprefixer": "^9.5.1", + "babel-loader": "^8.0.4", + "bundle-require": "2.1.8", + "cache-loader": "^3.0.0", + "chokidar": "^2.0.3", + "connect-history-api-fallback": "^1.5.0", + "copy-webpack-plugin": "^5.0.2", + "core-js": "^3.6.4", + "cross-spawn": "^6.0.5", + "css-loader": "^2.1.1", + "esbuild": "0.14.7", + "file-loader": "^3.0.1", + "js-yaml": "^3.13.1", + "lru-cache": "^5.1.1", + "mini-css-extract-plugin": "0.6.0", + "optimize-css-assets-webpack-plugin": "^5.0.1", + "portfinder": "^1.0.13", + "postcss-loader": "^3.0.0", + "postcss-safe-parser": "^4.0.1", + "toml": "^3.0.0", + "url-loader": "^1.0.1", + "vue": "^2.6.10", + "vue-loader": "^15.7.1", + "vue-router": "^3.4.5", + "vue-server-renderer": "^2.6.10", + "vue-template-compiler": "^2.6.10", + "vuepress-html-webpack-plugin": "^3.2.0", + "vuepress-plugin-container": "^2.0.2", + "webpack": "^4.8.1", + "webpack-chain": "^6.0.0", + "webpack-dev-server": "^3.5.1", + "webpack-merge": "^4.1.2", + "webpackbar": "3.2.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/@vuepress/markdown": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-1.9.7.tgz", + "integrity": "sha512-DFOjYkwV6fT3xXTGdTDloeIrT1AbwJ9pwefmrp0rMgC6zOz3XUJn6qqUwcYFO5mNBWpbiFQ3JZirCtgOe+xxBA==", + "dependencies": { + "@vuepress/shared-utils": "1.9.7", + "markdown-it": "^8.4.1", + "markdown-it-anchor": "^5.0.2", + "markdown-it-chain": "^1.3.0", + "markdown-it-emoji": "^1.4.0", + "markdown-it-table-of-contents": "^0.4.0", + "prismjs": "^1.13.0" + } + }, + "node_modules/@vuepress/markdown-loader": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/markdown-loader/-/markdown-loader-1.9.7.tgz", + "integrity": "sha512-mxXF8FtX/QhOg/UYbe4Pr1j5tcf/aOEI502rycTJ3WF2XAtOmewjkGV4eAA6f6JmuM/fwzOBMZKDyy9/yo2I6Q==", + "dependencies": { + "@vuepress/markdown": "1.9.7", + "loader-utils": "^1.1.0", + "lru-cache": "^5.1.1" + } + }, + "node_modules/@vuepress/markdown/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "node_modules/@vuepress/markdown/node_modules/markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "dependencies": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/@vuepress/plugin-active-header-links": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-1.9.7.tgz", + "integrity": "sha512-G1M8zuV9Og3z8WBiKkWrofG44NEXsHttc1MYreDXfeWh/NLjr9q1GPCEXtiCjrjnHZHB3cSQTKnTqAHDq35PGA==", + "dependencies": { + "@vuepress/types": "1.9.7", + "lodash.debounce": "^4.0.8" + } + }, + "node_modules/@vuepress/plugin-google-analytics": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-google-analytics/-/plugin-google-analytics-1.8.2.tgz", + "integrity": "sha512-BMFayLzT2BvXmnhM9mDHw0UPU7J0pH1X9gQA4HmZxOf7f3+atK5eJGsc1Ia/+1FTG2ESvhFLUU/CC3h5arjEJw==" + }, + "node_modules/@vuepress/plugin-last-updated": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-last-updated/-/plugin-last-updated-1.9.7.tgz", + "integrity": "sha512-FiFBOl49dlFRjbLRnRAv77HDWfe+S/eCPtMQobq4/O3QWuL3Na5P4fCTTVzq1K7rWNO9EPsWNB2Jb26ndlQLKQ==", + "dependencies": { + "@vuepress/types": "1.9.7", + "cross-spawn": "^6.0.5" + } + }, + "node_modules/@vuepress/plugin-nprogress": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-1.9.7.tgz", + "integrity": "sha512-sI148igbdRfLgyzB8PdhbF51hNyCDYXsBn8bBWiHdzcHBx974sVNFKtfwdIZcSFsNrEcg6zo8YIrQ+CO5vlUhQ==", + "dependencies": { + "@vuepress/types": "1.9.7", + "nprogress": "^0.2.0" + } + }, + "node_modules/@vuepress/plugin-register-components": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-register-components/-/plugin-register-components-1.9.7.tgz", + "integrity": "sha512-l/w1nE7Dpl+LPMb8+AHSGGFYSP/t5j6H4/Wltwc2QcdzO7yqwC1YkwwhtTXvLvHOV8O7+rDg2nzvq355SFkfKA==", + "dependencies": { + "@vuepress/shared-utils": "1.9.7", + "@vuepress/types": "1.9.7" + } + }, + "node_modules/@vuepress/plugin-search": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-search/-/plugin-search-1.9.7.tgz", + "integrity": "sha512-MLpbUVGLxaaHEwflFxvy0pF9gypFVUT3Q9Zc6maWE+0HDWAvzMxo6GBaj6mQPwjOqNQMf4QcN3hDzAZktA+DQg==", + "dependencies": { + "@vuepress/types": "1.9.7" + } + }, + "node_modules/@vuepress/shared-utils": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/shared-utils/-/shared-utils-1.9.7.tgz", + "integrity": "sha512-lIkO/eSEspXgVHjYHa9vuhN7DuaYvkfX1+TTJDiEYXIwgwqtvkTv55C+IOdgswlt0C/OXDlJaUe1rGgJJ1+FTw==", + "dependencies": { + "chalk": "^2.3.2", + "escape-html": "^1.0.3", + "fs-extra": "^7.0.1", + "globby": "^9.2.0", + "gray-matter": "^4.0.1", + "hash-sum": "^1.0.2", + "semver": "^6.0.0", + "toml": "^3.0.0", + "upath": "^1.1.0" + } + }, + "node_modules/@vuepress/theme-default": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/theme-default/-/theme-default-1.9.7.tgz", + "integrity": "sha512-NZzCLIl+bgJIibhkqVmk/NSku57XIuXugxAN3uiJrCw6Mu6sb3xOvbk0En3k+vS2BKHxAZ6Cx7dbCiyknDQnSA==", + "dependencies": { + "@vuepress/plugin-active-header-links": "1.9.7", + "@vuepress/plugin-nprogress": "1.9.7", + "@vuepress/plugin-search": "1.9.7", + "@vuepress/types": "1.9.7", + "docsearch.js": "^2.5.2", + "lodash": "^4.17.15", + "stylus": "^0.54.8", + "stylus-loader": "^3.0.2", + "vuepress-plugin-container": "^2.0.2", + "vuepress-plugin-smooth-scroll": "^0.0.3" + } + }, + "node_modules/@vuepress/theme-default/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@vuepress/theme-default/node_modules/stylus": { + "version": "0.54.8", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz", + "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==", + "dependencies": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.6", + "mkdirp": "~1.0.4", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.3.0", + "source-map": "^0.7.3" + }, + "bin": { + "stylus": "bin/stylus" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@vuepress/types": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@vuepress/types/-/types-1.9.7.tgz", + "integrity": "sha512-moLQzkX3ED2o18dimLemUm7UVDKxhcrJmGt5C0Ng3xxrLPaQu7UqbROtEKB3YnMRt4P/CA91J+Ck+b9LmGabog==", + "dependencies": { + "@types/markdown-it": "^10.0.0", + "@types/webpack-dev-server": "^3", + "webpack-chain": "^6.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dependencies": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" + }, + "node_modules/@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dependencies": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" + }, + "node_modules/@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agentkeepalive": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz", + "integrity": "sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8=", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "peerDependencies": { + "ajv": ">=5.0.0" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/algoliasearch": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.12.0.tgz", + "integrity": "sha512-fZOMMm+F3Bi5M/MoFIz7hiuyCitJza0Hu+r8Wzz4LIQClC6YGMRq7kT6NNU1fSSoFDSeJIwMfedbbi5G9dJoVQ==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.12.0", + "@algolia/cache-common": "4.12.0", + "@algolia/cache-in-memory": "4.12.0", + "@algolia/client-account": "4.12.0", + "@algolia/client-analytics": "4.12.0", + "@algolia/client-common": "4.12.0", + "@algolia/client-personalization": "4.12.0", + "@algolia/client-search": "4.12.0", + "@algolia/logger-common": "4.12.0", + "@algolia/logger-console": "4.12.0", + "@algolia/requester-browser-xhr": "4.12.0", + "@algolia/requester-common": "4.12.0", + "@algolia/requester-node-http": "4.12.0", + "@algolia/transporter": "4.12.0" + } + }, + "node_modules/alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert-never": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", + "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autocomplete.js": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.36.0.tgz", + "integrity": "sha512-jEwUXnVMeCHHutUt10i/8ZiRaCb0Wo+ZyKxeGsYwBDtw6EJHqEeDrq4UwZRD8YBSvp3g6klP678il2eeiVXN2Q==", + "dependencies": { + "immediate": "^3.2.3" + } + }, + "node_modules/autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/autoprefixer/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, + "node_modules/axios/node_modules/follow-redirects": { + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/babel-loader": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz", + "integrity": "sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==", + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^1.4.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", + "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==", + "dependencies": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.3.1", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz", + "integrity": "sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.1", + "core-js-compat": "^3.20.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", + "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "node_modules/body-parser": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "dependencies": { + "bytes": "3.1.1", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dependencies": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "node_modules/boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/boxen/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-sign/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dependencies": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" + }, + "node_modules/buffer-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", + "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "node_modules/bundle-require": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-2.1.8.tgz", + "integrity": "sha512-oOEg3A0hy/YzvNWNowtKD0pmhZKseOFweCbgyMqTIih4gRY1nJWsvrOCT27L9NbIyL5jMjTFrAUpGxxpW68Puw==", + "peerDependencies": { + "esbuild": ">=0.13" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.12", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.12.tgz", + "integrity": "sha512-rM7E2ygtMkJqD9c7WnFU6fruFcN3xe4FM5yUmgxhZzIKJk4uHl9U/fhwdajGFQbQuv43FAUo1Fe8gX/oIKDeSA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cache-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-3.0.1.tgz", + "integrity": "sha512-HzJIvGiGqYsFUrMjAJNDbVZoG7qQA+vy9AIoKs7s9DscNfki0I589mf2w6/tW+kkFH3zyiknoWV5Jdynu6b/zw==", + "dependencies": { + "buffer-json": "^2.0.0", + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.2.3", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/cache-loader/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "engines": { + "node": ">=4" + } + }, + "node_modules/cache-loader/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cache-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/cache-loader/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "engines": { + "node": ">=4" + } + }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001301", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz", + "integrity": "sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dependencies": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", + "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", + "dependencies": { + "css-select": "^4.1.3", + "css-what": "^5.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0", + "domutils": "^2.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/chokidar/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/chokidar/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/chokidar/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==" + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboard-copy": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-4.0.1.tgz", + "integrity": "sha512-wOlqdqziE/NNTUJsfSgXmBMIrYmfd5V0HCGsR8uAKHcg+h9NENWINcfRjtWGU77wDHC8B8ijV4hMTGYbrKovng==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/color-string": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", + "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" + }, + "node_modules/consolidate": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", + "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", + "dependencies": { + "bluebird": "^3.1.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", + "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", + "dependencies": { + "cacache": "^12.0.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.1", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dependencies": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + }, + "node_modules/copy-webpack-plugin/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-js": { + "version": "3.20.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz", + "integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.20.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.3.tgz", + "integrity": "sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw==", + "dependencies": { + "browserslist": "^4.19.1", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dependencies": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + } + }, + "node_modules/css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "engines": { + "node": "*" + } + }, + "node_modules/css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dependencies": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + }, + "engines": { + "node": ">4" + } + }, + "node_modules/css-loader": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", + "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", + "dependencies": { + "camelcase": "^5.2.0", + "icss-utils": "^4.1.0", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.14", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^2.0.6", + "postcss-modules-scope": "^2.1.0", + "postcss-modules-values": "^2.0.0", + "postcss-value-parser": "^3.3.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/css-loader/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/css-loader/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/css-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", + "dependencies": { + "css": "^2.0.0" + } + }, + "node_modules/css-parse/node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css-parse/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-parse/node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/css-select": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", + "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^5.1.0", + "domhandler": "^4.3.0", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", + "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "dependencies": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "dependencies": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=" + }, + "node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dependencies": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + }, + "node_modules/dns-packet": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", + "dependencies": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dependencies": { + "buffer-indexof": "^1.0.0" + } + }, + "node_modules/docsearch.js": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/docsearch.js/-/docsearch.js-2.6.3.tgz", + "integrity": "sha512-GN+MBozuyz664ycpZY0ecdQE0ND/LSgJKhTLA0/v3arIS3S1Rpf2OJz6A35ReMsm91V5apcmzr5/kM84cvUg+A==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @docsearch/js.", + "dependencies": { + "algoliasearch": "^3.24.5", + "autocomplete.js": "0.36.0", + "hogan.js": "^3.0.2", + "request": "^2.87.0", + "stack-utils": "^1.0.1", + "to-factory": "^1.0.0", + "zepto": "^1.2.0" + } + }, + "node_modules/docsearch.js/node_modules/algoliasearch": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.35.1.tgz", + "integrity": "sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ==", + "dependencies": { + "agentkeepalive": "^2.2.0", + "debug": "^2.6.9", + "envify": "^4.0.0", + "es6-promise": "^4.1.0", + "events": "^1.1.0", + "foreach": "^2.0.5", + "global": "^4.3.2", + "inherits": "^2.0.1", + "isarray": "^2.0.1", + "load-script": "^1.0.0", + "object-keys": "^1.0.11", + "querystring-es3": "^0.2.1", + "reduce": "^1.0.1", + "semver": "^5.1.0", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/docsearch.js/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/docsearch.js/node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/docsearch.js/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/docsearch.js/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", + "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.52", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.52.tgz", + "integrity": "sha512-JGkh8HEh5PnVrhU4HbpyyO0O791dVY6k7AdqfDeqbcRMeoGxtNHWT77deR2nhvbLe4dKpxjlDEvdEwrvRLGu2Q==" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/enhanced-resolve/node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz", + "integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==", + "dependencies": { + "esprima": "^4.0.0", + "through": "~2.3.4" + }, + "bin": { + "envify": "bin/envify" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/esbuild": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.7.tgz", + "integrity": "sha512-+u/msd6iu+HvfysUPkZ9VHm83LImmSNnecYPfFI01pQ7TTcsFR+V0BkybZX7mPtIaI7LCrse6YRj+v3eraJSgw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "optionalDependencies": { + "esbuild-android-arm64": "0.14.7", + "esbuild-darwin-64": "0.14.7", + "esbuild-darwin-arm64": "0.14.7", + "esbuild-freebsd-64": "0.14.7", + "esbuild-freebsd-arm64": "0.14.7", + "esbuild-linux-32": "0.14.7", + "esbuild-linux-64": "0.14.7", + "esbuild-linux-arm": "0.14.7", + "esbuild-linux-arm64": "0.14.7", + "esbuild-linux-mips64le": "0.14.7", + "esbuild-linux-ppc64le": "0.14.7", + "esbuild-netbsd-64": "0.14.7", + "esbuild-openbsd-64": "0.14.7", + "esbuild-sunos-64": "0.14.7", + "esbuild-windows-32": "0.14.7", + "esbuild-windows-64": "0.14.7", + "esbuild-windows-arm64": "0.14.7" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.7.tgz", + "integrity": "sha512-9/Q1NC4JErvsXzJKti0NHt+vzKjZOgPIjX/e6kkuCzgfT/GcO3FVBcGIv4HeJG7oMznE6KyKhvLrFgt7CdU2/w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.7.tgz", + "integrity": "sha512-Z9X+3TT/Xj+JiZTVlwHj2P+8GoiSmUnGVz0YZTSt8WTbW3UKw5Pw2ucuJ8VzbD2FPy0jbIKJkko/6CMTQchShQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.7.tgz", + "integrity": "sha512-68e7COhmwIiLXBEyxUxZSSU0akgv8t3e50e2QOtKdBUE0F6KIRISzFntLe2rYlNqSsjGWsIO6CCc9tQxijjSkw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.7.tgz", + "integrity": "sha512-76zy5jAjPiXX/S3UvRgG85Bb0wy0zv/J2lel3KtHi4V7GUTBfhNUPt0E5bpSXJ6yMT7iThhnA5rOn+IJiUcslQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.7.tgz", + "integrity": "sha512-lSlYNLiqyzd7qCN5CEOmLxn7MhnGHPcu5KuUYOG1i+t5A6q7LgBmfYC9ZHJBoYyow3u4CNu79AWHbvVLpE/VQQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.7.tgz", + "integrity": "sha512-Vk28u409wVOXqTaT6ek0TnfQG4Ty1aWWfiysIaIRERkNLhzLhUf4i+qJBN8mMuGTYOkE40F0Wkbp6m+IidOp2A==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.7.tgz", + "integrity": "sha512-+Lvz6x+8OkRk3K2RtZwO+0a92jy9si9cUea5Zoru4yJ/6EQm9ENX5seZE0X9DTwk1dxJbjmLsJsd3IoowyzgVg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.7.tgz", + "integrity": "sha512-OzpXEBogbYdcBqE4uKynuSn5YSetCvK03Qv1HcOY1VN6HmReuatjJ21dCH+YPHSpMEF0afVCnNfffvsGEkxGJQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.7.tgz", + "integrity": "sha512-kJd5beWSqteSAW086qzCEsH6uwpi7QRIpzYWHzEYwKKu9DiG1TwIBegQJmLpPsLp4v5RAFjea0JAmAtpGtRpqg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.7.tgz", + "integrity": "sha512-mFWpnDhZJmj/h7pxqn1GGDsKwRfqtV7fx6kTF5pr4PfXe8pIaTERpwcKkoCwZUkWAOmUEjMIUAvFM72A6hMZnA==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.7.tgz", + "integrity": "sha512-wM7f4M0bsQXfDL4JbbYD0wsr8cC8KaQ3RPWc/fV27KdErPW7YsqshZZSjDV0kbhzwpNNdhLItfbaRT8OE8OaKA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.7.tgz", + "integrity": "sha512-J/afS7woKyzGgAL5FlgvMyqgt5wQ597lgsT+xc2yJ9/7BIyezeXutXqfh05vszy2k3kSvhLesugsxIA71WsqBw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ] + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.7.tgz", + "integrity": "sha512-7CcxgdlCD+zAPyveKoznbgr3i0Wnh0L8BDGRCjE/5UGkm5P/NQko51tuIDaYof8zbmXjjl0OIt9lSo4W7I8mrw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.7.tgz", + "integrity": "sha512-GKCafP2j/KUljVC3nesw1wLFSZktb2FGCmoT1+730zIF5O6hNroo0bSEofm6ZK5mNPnLiSaiLyRB9YFgtkd5Xg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ] + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.7.tgz", + "integrity": "sha512-5I1GeL/gZoUUdTPA0ws54bpYdtyeA2t6MNISalsHpY269zK8Jia/AXB3ta/KcDHv2SvNwabpImeIPXC/k0YW6A==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.7.tgz", + "integrity": "sha512-CIGKCFpQOSlYsLMbxt8JjxxvVw9MlF1Rz2ABLVfFyHUF5OeqHD5fPhGrCVNaVrhO8Xrm+yFmtjcZudUGr5/WYQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.7.tgz", + "integrity": "sha512-eOs1eSivOqN7cFiRIukEruWhaCf75V0N8P0zP7dh44LIhLl8y6/z++vv9qQVbkBm5/D7M7LfCfCTmt1f1wHOCw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/express": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", + "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.6", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dependencies": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", + "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", + "dependencies": { + "loader-utils": "^1.0.2", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dependencies": { + "debug": "=3.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/fuse.js": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.6.1.tgz", + "integrity": "sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dependencies": { + "ini": "1.3.7" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" + }, + "node_modules/highlight.js": { + "version": "9.18.5", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.5.tgz", + "integrity": "sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==", + "deprecated": "Support has ended for 9.x series. Upgrade to @latest", + "hasInstallScript": true, + "engines": { + "node": "*" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha1-TNnhq9QpQUbnZ55B14mHMrAse/0=", + "dependencies": { + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "bin": { + "hulk": "bin/hulk" + } + }, + "node_modules/hogan.js/node_modules/mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "engines": { + "node": "*" + } + }, + "node_modules/hotkeys-js": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.8.7.tgz", + "integrity": "sha512-ckAx3EkUr5XjDwjEHDorHxRO2Kb7z6Z2Sxul4MbBkN8Nho7XDslQsgMJT+CiJ5Z4TgRxxvKHEpuLE3imzqy4Lg==" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" + }, + "node_modules/hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" + }, + "node_modules/html-entities": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==" + }, + "node_modules/html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dependencies": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + }, + "bin": { + "html-minifier": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", + "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", + "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", + "dependencies": { + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-proxy-middleware/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/http-proxy-middleware/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" + }, + "node_modules/icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + }, + "node_modules/import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dependencies": { + "import-from": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dependencies": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" + }, + "node_modules/internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dependencies": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "node_modules/is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dependencies": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dependencies": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-installed-globally/node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "node_modules/javascript-stringify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-1.6.0.tgz", + "integrity": "sha1-FC0RHzpuPa6PSpr9d9RYVbWpzOM=" + }, + "node_modules/js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "node_modules/json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/jsonp/-/jsonp-0.2.1.tgz", + "integrity": "sha1-pltPoPEL2nGaBUQep7lMVfPhW64=", + "dependencies": { + "debug": "^2.1.3" + } + }, + "node_modules/jsonp/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "dependencies": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" + }, + "node_modules/loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "node_modules/lodash.chunk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", + "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "node_modules/lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "node_modules/loglevel": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", + "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "peerDependencies": { + "markdown-it": "*" + } + }, + "node_modules/markdown-it-attrs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.1.3.tgz", + "integrity": "sha512-d5yg/lzQV2KFI/4LPsZQB3uxQrf0/l2/RnMPCPm4lYLOZUSmFlpPccyojnzaHkfQpAD8wBHfnfUW0aMhpKOS2g==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "markdown-it": ">= 9.0.0 < 13.0.0" + } + }, + "node_modules/markdown-it-chain": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/markdown-it-chain/-/markdown-it-chain-1.3.0.tgz", + "integrity": "sha512-XClV8I1TKy8L2qsT9iX3qiV+50ZtcInGXI80CA+DP62sMs7hXlyV/RM3hfwy5O3Ad0sJm9xIwQELgANfESo8mQ==", + "dependencies": { + "webpack-chain": "^4.9.0" + }, + "engines": { + "node": ">=6.9" + }, + "peerDependencies": { + "markdown-it": ">=5.0.0" + } + }, + "node_modules/markdown-it-chain/node_modules/webpack-chain": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-4.12.1.tgz", + "integrity": "sha512-BCfKo2YkDe2ByqkEWe1Rw+zko4LsyS75LVr29C6xIrxAg9JHJ4pl8kaIZ396SUSNp6b4815dRZPSTAS8LlURRQ==", + "dependencies": { + "deepmerge": "^1.5.2", + "javascript-stringify": "^1.6.0" + } + }, + "node_modules/markdown-it-container": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-2.0.0.tgz", + "integrity": "sha1-ABm0P9Au7+zi8ZYKKJX7qBpARpU=" + }, + "node_modules/markdown-it-emoji": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", + "integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw=" + }, + "node_modules/markdown-it-table-of-contents": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.4.4.tgz", + "integrity": "sha512-TAIHTHPwa9+ltKvKPWulm/beozQU41Ab+FIefRaQV1NRnpzwcV9QOe6wXQS5WLivm5Q/nlo0rl6laGkMDZE7Gw==", + "engines": { + "node": ">6.4.0" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/markdown-it/node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/merge-source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz", + "integrity": "sha512-79q5P7YGI6rdnVyIAV4NXpBQJFWdkzJxCim3Kog4078fM0piAaFlwocqbejdWtLW1cEzCexPrh6EdyFsPgVdAw==", + "dependencies": { + "loader-utils": "^1.1.0", + "normalize-url": "^2.0.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.4.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dependencies": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" + }, + "node_modules/nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "optional": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "node_modules/node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dependencies": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E=" + }, + "node_modules/nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", + "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "bin": { + "opencollective-postinstall": "index.js" + } + }, + "node_modules/opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/optimize-css-assets-webpack-plugin": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz", + "integrity": "sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q==", + "dependencies": { + "cssnano": "^4.1.10", + "last-call-webpack-plugin": "^3.0.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dependencies": { + "retry": "^0.12.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dependencies": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "engines": { + "node": ">=4" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/portfinder/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "dependencies": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dependencies": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-colormin/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-load-config": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "dependencies": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dependencies": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dependencies": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dependencies": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dependencies": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dependencies": { + "postcss": "^7.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", + "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0", + "postcss-value-parser": "^3.3.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-values": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", + "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", + "dependencies": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^7.0.6" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dependencies": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dependencies": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-safe-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", + "dependencies": { + "postcss": "^7.0.26" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", + "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-svgo/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dependencies": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/postcss/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "node_modules/postcss/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "optional": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-error": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^2.0.4" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/pug": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", + "dependencies": { + "pug-code-gen": "^3.0.2", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.0.0", + "pug-runtime": "^3.0.0", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", + "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-plain-loader": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pug-plain-loader/-/pug-plain-loader-1.1.0.tgz", + "integrity": "sha512-1nYgIJLaahRuHJHhzSPODV44aZfb00bO7kiJiMkke6Hj4SVZftuvx6shZ4BOokk50dJc2RSFqNUBOlus0dniFQ==", + "dependencies": { + "loader-utils": "^1.1.0" + }, + "peerDependencies": { + "pug": "^2.0.0 || ^3.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "dependencies": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/reduce": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce/-/reduce-1.0.2.tgz", + "integrity": "sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ==", + "dependencies": { + "object-keys": "^1.1.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", + "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz", + "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", + "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^9.0.0", + "regjsgen": "^0.5.2", + "regjsparser": "^0.7.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" + }, + "node_modules/regjsparser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", + "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "node_modules/renderkid": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", + "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^3.0.1" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated" + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "engines": { + "node": ">= 4" + } + }, + "node_modules/rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" + }, + "node_modules/rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + }, + "node_modules/selfsigned": { + "version": "1.10.14", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz", + "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==", + "dependencies": { + "node-forge": "^0.10.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/sitemap": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-3.2.2.tgz", + "integrity": "sha512-TModL/WU4m2q/mQcrDgNANn0P4LwprM9MMvG4hu5zP4c6IIKs2YLTu6nXXnNr8ODW/WFtxKggiJ1EGn2W0GNmg==", + "dependencies": { + "lodash.chunk": "^4.2.0", + "lodash.padstart": "^4.6.1", + "whatwg-url": "^7.0.0", + "xmlbuilder": "^13.0.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=4.0.0" + } + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/smoothscroll-polyfill": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz", + "integrity": "sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==" + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs-client": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz", + "integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==", + "dependencies": { + "debug": "^3.2.6", + "eventsource": "^1.0.7", + "faye-websocket": "^0.11.3", + "inherits": "^2.0.4", + "json3": "^3.3.3", + "url-parse": "^1.5.3" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/sockjs-client/node_modules/eventsource": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", + "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/sockjs-client/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sort-keys/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy-transport/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/spdy-transport/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/spdy/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + }, + "node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/std-env": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-2.3.1.tgz", + "integrity": "sha512-eOsoKTWnr6C8aWrqJJ2KAReXoa7Vn5Ywyw6uCXgA/xDhxPoaIsBa5aNJmISY04dLwXPBnDHW4diGM7Sn5K4R/g==", + "dependencies": { + "ci-info": "^3.1.1" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/stylehacks/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylus": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.56.0.tgz", + "integrity": "sha512-Ev3fOb4bUElwWu4F9P9WjnnaSpc8XB9OFHSFZSKMFL1CE1oM+oFXWEgAqPmmZIyhBihuqIQlFsVTypiiS9RxeA==", + "dependencies": { + "css": "^3.0.0", + "debug": "^4.3.2", + "glob": "^7.1.6", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "source-map": "^0.7.3" + }, + "bin": { + "stylus": "bin/stylus" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stylus-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", + "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", + "dependencies": { + "loader-utils": "^1.0.2", + "lodash.clonedeep": "^4.5.0", + "when": "~3.6.x" + }, + "peerDependencies": { + "stylus": ">=0.52.4" + } + }, + "node_modules/stylus/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/stylus/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=" + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/svgo/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dependencies": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "engines": { + "node": ">=4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/terser-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + }, + "node_modules/tiny-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tiny-cookie/-/tiny-cookie-2.3.2.tgz", + "integrity": "sha512-qbymkVh+6+Gc/c9sqnvbG+dOHH6bschjphK3SHgIfT6h/t+63GBL37JXNoXEc6u/+BcwU6XmaWUuf19ouLVtPg==" + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "node_modules/to-factory": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-factory/-/to-factory-1.0.0.tgz", + "integrity": "sha1-hzivi9lxIK0dQEeXKtpVY7+UebE=" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=" + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + }, + "node_modules/toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=" + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, + "node_modules/uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "dependencies": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-js/node_modules/commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + }, + "node_modules/uglify-js/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", + "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "node_modules/uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dependencies": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/update-notifier/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/update-notifier/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated" + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-loader": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", + "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", + "dependencies": { + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "node_modules/url/node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v-runtime-template": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/v-runtime-template/-/v-runtime-template-1.10.0.tgz", + "integrity": "sha512-WLlq9jUepSfUrMEenw3mn7FDXX6hhbl11JjC1OKhwLzifHzVrY5a696TUHDPyj9jke3GGnR7b+2T3od/RL5cww==" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz", + "integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ==" + }, + "node_modules/vue-hot-reload-api": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", + "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==" + }, + "node_modules/vue-loader": { + "version": "15.9.8", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.8.tgz", + "integrity": "sha512-GwSkxPrihfLR69/dSV3+5CdMQ0D+jXg8Ma1S4nQXKJAznYFX14vHdc/NetQc34Dw+rBbIJyP7JOuVb9Fhprvog==", + "dependencies": { + "@vue/component-compiler-utils": "^3.1.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" + }, + "peerDependencies": { + "css-loader": "*", + "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "cache-loader": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz", + "integrity": "sha512-FUlILrW3DGitS2h+Xaw8aRNvGTwtuaxrRkNSHWTizOfLUie7wuYwezeZ50iflRn8YPV5kxmU2LQuu3nM/b3Zsg==" + }, + "node_modules/vue-server-renderer": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.14.tgz", + "integrity": "sha512-HifYRa/LW7cKywg9gd4ZtvtRuBlstQBao5ZCWlg40fyB4OPoGfEXAzxb0emSLv4pBDOHYx0UjpqvxpiQFEuoLA==", + "dependencies": { + "chalk": "^1.1.3", + "hash-sum": "^1.0.2", + "he": "^1.1.0", + "lodash.template": "^4.5.0", + "lodash.uniq": "^4.5.0", + "resolve": "^1.2.0", + "serialize-javascript": "^3.1.0", + "source-map": "0.5.6" + } + }, + "node_modules/vue-server-renderer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-server-renderer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-server-renderer/node_modules/serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/vue-server-renderer/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-server-renderer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/vue-style-loader": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", + "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", + "dependencies": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + } + }, + "node_modules/vue-template-compiler": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "node_modules/vue-template-es2015-compiler": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", + "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==" + }, + "node_modules/vuepress": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-1.9.7.tgz", + "integrity": "sha512-aSXpoJBGhgjaWUsT1Zs/ZO8JdDWWsxZRlVme/E7QYpn+ZB9iunSgPMozJQNFaHzcRq4kPx5A4k9UhzLRcvtdMg==", + "hasInstallScript": true, + "dependencies": { + "@vuepress/core": "1.9.7", + "@vuepress/theme-default": "1.9.7", + "@vuepress/types": "1.9.7", + "cac": "^6.5.6", + "envinfo": "^7.2.0", + "opencollective-postinstall": "^2.0.2", + "update-notifier": "^4.0.0" + }, + "bin": { + "vuepress": "cli.js" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/vuepress-html-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vuepress-html-webpack-plugin/-/vuepress-html-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-BebAEl1BmWlro3+VyDhIOCY6Gef2MCBllEVAP3NUAtMguiyOwo/dClbwJ167WYmcxHJKLl7b0Chr9H7fpn1d0A==", + "dependencies": { + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" + }, + "engines": { + "node": ">=6.9" + }, + "peerDependencies": { + "webpack": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/vuepress-html-webpack-plugin/node_modules/big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "engines": { + "node": "*" + } + }, + "node_modules/vuepress-html-webpack-plugin/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vuepress-html-webpack-plugin/node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/vuepress-html-webpack-plugin/node_modules/loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dependencies": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "node_modules/vuepress-html-webpack-plugin/node_modules/util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dependencies": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "node_modules/vuepress-plugin-container": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/vuepress-plugin-container/-/vuepress-plugin-container-2.1.5.tgz", + "integrity": "sha512-TQrDX/v+WHOihj3jpilVnjXu9RcTm6m8tzljNJwYhxnJUW0WWQ0hFLcDTqTBwgKIFdEiSxVOmYE+bJX/sq46MA==", + "dependencies": { + "@vuepress/shared-utils": "^1.2.0", + "markdown-it-container": "^2.0.0" + } + }, + "node_modules/vuepress-plugin-google-tag-manager": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/vuepress-plugin-google-tag-manager/-/vuepress-plugin-google-tag-manager-0.0.5.tgz", + "integrity": "sha512-Hm1GNDdNmc4Vs9c3OMfTtHicB/oZWNCmzMFPdlOObVN1OjizIjImdm+LZIwiVKVndT2TQ4BPhMx7HQkovmD2Lg==" + }, + "node_modules/vuepress-plugin-sitemap": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/vuepress-plugin-sitemap/-/vuepress-plugin-sitemap-2.3.1.tgz", + "integrity": "sha512-n+8lbukhrKrsI9H/EX0EBgkE1pn85LAQFvQ5dIvrZP4Kz6JxPOPPNTQmZMhahQV1tXbLZQCEN7A1WZH4x+arJQ==", + "dependencies": { + "sitemap": "^3.0.0" + }, + "bin": { + "vuepress-sitemap": "cli.js" + }, + "peerDependencies": { + "chalk": "^2.0.0", + "commander": "^2.0.0", + "esm": "^3.0.0" + } + }, + "node_modules/vuepress-plugin-smooth-scroll": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/vuepress-plugin-smooth-scroll/-/vuepress-plugin-smooth-scroll-0.0.3.tgz", + "integrity": "sha512-qsQkDftLVFLe8BiviIHaLV0Ea38YLZKKonDGsNQy1IE0wllFpFIEldWD8frWZtDFdx6b/O3KDMgVQ0qp5NjJCg==", + "dependencies": { + "smoothscroll-polyfill": "^0.4.3" + } + }, + "node_modules/vuepress-theme-cosmos": { + "version": "1.0.183", + "resolved": "https://registry.npmjs.org/vuepress-theme-cosmos/-/vuepress-theme-cosmos-1.0.183.tgz", + "integrity": "sha512-nLSL0YF6ar2yhZkDvp6o313xBSu/Zc3O3OxRsgLMZcKyWanNqyyh0jFrUqMZcjz7vylRRDth6C2/E0YeisFCbw==", + "dependencies": { + "@cosmos-ui/vue": "^0.35.0", + "@vuepress/plugin-google-analytics": "1.8.2", + "algoliasearch": "^4.2.0", + "axios": "^0.24.0", + "cheerio": "^1.0.0-rc.3", + "clipboard-copy": "^4.0.1", + "entities": "3.0.1", + "esm": "^3.2.25", + "gray-matter": "^4.0.2", + "hotkeys-js": "3.8.7", + "jsonp": "^0.2.1", + "markdown-it": "^12.0.0", + "markdown-it-attrs": "^4.0.0", + "prismjs": "^1.22.0", + "pug": "^3.0.1", + "pug-plain-loader": "^1.0.0", + "stylus": "^0.56.0", + "stylus-loader": "^3.0.2", + "tiny-cookie": "^2.3.2", + "v-runtime-template": "^1.10.0", + "vuepress": "^1.5.4", + "vuepress-plugin-google-tag-manager": "0.0.5", + "vuepress-plugin-sitemap": "^2.3.1" + } + }, + "node_modules/watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "optional": true, + "dependencies": { + "chokidar": "^2.1.8" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + }, + "webpack-command": { + "optional": true + } + } + }, + "node_modules/webpack-chain": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.5.1.tgz", + "integrity": "sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==", + "dependencies": { + "deepmerge": "^1.5.2", + "javascript-stringify": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-chain/node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==" + }, + "node_modules/webpack-dev-middleware": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "dependencies": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz", + "integrity": "sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA==", + "dependencies": { + "ansi-html-community": "0.0.8", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.8", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 6.11.5" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dependencies": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-dev-server/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack-dev-server/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack-sources/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "optional": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "optional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/webpack/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/webpack/node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/webpack/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/webpack/node_modules/watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dependencies": { + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + }, + "optionalDependencies": { + "chokidar": "^3.4.1", + "watchpack-chokidar2": "^2.0.1" + } + }, + "node_modules/webpackbar": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-3.2.0.tgz", + "integrity": "sha512-PC4o+1c8gWWileUfwabe0gqptlXUDJd5E0zbpr2xHP1VSOVlZVPBZ8j6NCR8zM5zbKdxPhctHXahgpNK1qFDPw==", + "dependencies": { + "ansi-escapes": "^4.1.0", + "chalk": "^2.4.1", + "consola": "^2.6.0", + "figures": "^3.0.0", + "pretty-time": "^1.1.0", + "std-env": "^2.2.1", + "text-table": "^0.2.0", + "wrap-ansi": "^5.1.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/when": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", + "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=" + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/widest-line/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dependencies": { + "errno": "~0.1.7" + } + }, + "node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/xmlbuilder": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz", + "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "engines": { + "node": ">=4" + } + }, + "node_modules/zepto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zepto/-/zepto-1.2.0.tgz", + "integrity": "sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g=" + } + }, "dependencies": { "@algolia/cache-browser-local-storage": { "version": "4.12.0", @@ -2088,12 +16359,14 @@ "ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "requires": {} }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "requires": {} }, "algoliasearch": { "version": "4.12.0", @@ -2326,9 +16599,9 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "requires": { "lodash": "^4.17.14" } @@ -2886,7 +17159,8 @@ "bundle-require": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-2.1.8.tgz", - "integrity": "sha512-oOEg3A0hy/YzvNWNowtKD0pmhZKseOFweCbgyMqTIih4gRY1nJWsvrOCT27L9NbIyL5jMjTFrAUpGxxpW68Puw==" + "integrity": "sha512-oOEg3A0hy/YzvNWNowtKD0pmhZKseOFweCbgyMqTIih4gRY1nJWsvrOCT27L9NbIyL5jMjTFrAUpGxxpW68Puw==", + "requires": {} }, "bytes": { "version": "3.0.0", @@ -4825,14 +19099,6 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" }, - "eventsource": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", - "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", - "requires": { - "original": "^1.0.0" - } - }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -5347,6 +19613,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "optional": true, "requires": { "is-glob": "^4.0.1" } @@ -6673,12 +20940,14 @@ "markdown-it-anchor": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", - "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==" + "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", + "requires": {} }, "markdown-it-attrs": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.1.3.tgz", - "integrity": "sha512-d5yg/lzQV2KFI/4LPsZQB3uxQrf0/l2/RnMPCPm4lYLOZUSmFlpPccyojnzaHkfQpAD8wBHfnfUW0aMhpKOS2g==" + "integrity": "sha512-d5yg/lzQV2KFI/4LPsZQB3uxQrf0/l2/RnMPCPm4lYLOZUSmFlpPccyojnzaHkfQpAD8wBHfnfUW0aMhpKOS2g==", + "requires": {} }, "markdown-it-chain": { "version": "1.3.0", @@ -6906,9 +21175,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" }, "mississippi": { "version": "3.0.0", @@ -7305,14 +21574,6 @@ "last-call-webpack-plugin": "^3.0.0" } }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "requires": { - "url-parse": "^1.4.3" - } - }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -8143,9 +22404,9 @@ "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==" }, "prismjs": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.26.0.tgz", - "integrity": "sha512-HUoH9C5Z3jKkl3UunCyiD5jwk0+Hz0fIgQ2nbwU2Oo/ceuTAQAg+pPVnfdt2TJWRVLcxKh9iuoYDUSc8clb5UQ==" + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" }, "process": { "version": "0.11.10", @@ -9192,6 +23453,11 @@ "ms": "^2.1.1" } }, + "eventsource": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", + "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==" + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -9467,6 +23733,14 @@ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -9510,14 +23784,6 @@ "define-properties": "^1.1.3" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -9711,9 +23977,9 @@ "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" }, "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", "requires": { "commander": "^2.20.0", "source-map": "~0.6.1", @@ -10322,9 +24588,9 @@ } }, "url-parse": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.4.tgz", - "integrity": "sha512-ITeAByWWoqutFClc/lRZnFplgXgEZr3WJ6XngMM/N9DMIm4K8zXPCZ1Jdu0rERwO84w1WC5wkle2ubwTA4NTBg==", + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -10658,24 +24924,6 @@ "vuepress-plugin-sitemap": "^2.3.1" } }, - "watchpack": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", - "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "dependencies": { - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - } - } - }, "watchpack-chokidar2": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", diff --git a/docs/package.json b/docs/package.json index 500868b7237..89dfa64033f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -13,11 +13,6 @@ "author": "", "license": "ISC", "dependencies": { - "glob-parent": "^5.1.2", - "vue": "^2.6.14", "vuepress-theme-cosmos": "^1.0.183" - }, - "devDependencies": { - "watchpack": "^2.2.0" } } diff --git a/docs/apps/interchain-accounts/requirements.md b/docs/requirements/ics27-requirements.md similarity index 88% rename from docs/apps/interchain-accounts/requirements.md rename to docs/requirements/ics27-requirements.md index fff919f8088..ed9d274b518 100644 --- a/docs/apps/interchain-accounts/requirements.md +++ b/docs/requirements/ics27-requirements.md @@ -55,65 +55,64 @@ Using Interchain Accounts, a service could be built in which a user sends tokens | ID | Description | Verification | Status | | --- | ----------- | ------------ | ------ | -| 1.01 | A chain shall have the ability to enable or disable Interchain Accounts controller functionality in the genesis state. | The controller parameters have a [flag](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/types/host.pb.go#L30) to enable/disable the controller submodule, and this flag [is stored during genesis initialization](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/params.go#L24). | `Implemented` | -| 1.02 | A chain shall have the ability to export the Interchain Accounts controller genesis state. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go#L47) | `Implemented` | -| 1.03 | A chain shall have the ability to initialize the Interchain Accounts controller genesis state. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go#L10) | `Implemented` | -| 1.04 | A chain shall have the ability to set the Interchain Accounts controller parameters when upgrading or via proposal. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/module_test.go#L33) | `Implemented` | -| 1.05 | A chain shall have the ability to enable or disable Interchain Accounts host functionality in the genesis state. | The host parameters have a [flag](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/types/host.pb.go#L30) to enable/disable the host submodule, and this flag [is stored during genesis initialization](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/params.go#L31) | `Implemented` | -| 1.06 | A chain shall have the ability to export the Interchain Accounts host genesis state. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go#L46) | `Implemented` | -| 1.07 | A chain shall have the ability to initialize the Interchain Accounts host genesis state. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go#L10) | `Implemented` | -| 1.08 | A chain shall have the ability to set the Interchain Accounts host parameters when upgrading or via proposal. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/module_test.go#L33) | `Implemented` | -| 1.09 | The host chain shall have the ability to whitelist what types of messages or transactions that it chooses to facilitate (e.g. it can decide that registered interchain accounts cannot execute staking messages). | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/params_test.go#L5) | `Implemented` | +| 1.01 | A chain shall have the ability to enable or disable Interchain Accounts controller functionality in the genesis state. | The controller parameters have a [flag](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/types/host.pb.go#L30) to enable/disable the controller submodule, and this flag [is stored during genesis initialization](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/params.go#L24). | `Verified` | +| 1.02 | A chain shall have the ability to export the Interchain Accounts controller genesis state. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go#L47) | `Verified` | +| 1.03 | A chain shall have the ability to initialize the Interchain Accounts controller genesis state. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go#L10) | `Verified` | +| 1.04 | A chain shall have the ability to set the Interchain Accounts controller parameters when upgrading or via proposal. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/module_test.go#L33) | `Verified` | +| 1.05 | A chain shall have the ability to enable or disable Interchain Accounts host functionality in the genesis state. | The host parameters have a [flag](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/types/host.pb.go#L30) to enable/disable the host submodule, and this flag [is stored during genesis initialization](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/params.go#L31) | `Verified` | +| 1.06 | A chain shall have the ability to export the Interchain Accounts host genesis state. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go#L46) | `Verified` | +| 1.07 | A chain shall have the ability to initialize the Interchain Accounts host genesis state. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go#L10) | `Verified` | +| 1.08 | A chain shall have the ability to set the Interchain Accounts host parameters when upgrading or via proposal. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/module_test.go#L33) | `Verified` | +| 1.09 | The host chain shall have the ability to whitelist what types of messages or transactions that it chooses to facilitate (e.g. it can decide that registered interchain accounts cannot execute staking messages). | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/params_test.go#L5) | `Verified` | ### 2 - Registration | ID | Description | Verification | Status | | --- | ----------- | ------------ | ------ | -| 2.01 | The controller chain can programmatically create interchain accounts on the host chain that shall be controlled only by the owner account on the controller chain. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/account_test.go#L10) | `Implemented` | -| 2.02 | An interchain account shall be created by any actor without the approval of a third party (e.g. chain governance). | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/account_test.go#L10) | `Implemented` | +| 2.01 | The controller chain can programmatically create interchain accounts on the host chain that shall be controlled only by the owner account on the controller chain. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/account_test.go#L10) | `Verified` | +| 2.02 | An interchain account shall be created by any actor without the approval of a third party (e.g. chain governance). | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/account_test.go#L10) | `Verified` | ### 3 - Control -| ID | Description | Verification | Status | -| --- | ----------- | ------------ | ------ | -| 3.01 | The controller chain can programmatically control the interchain account by submitting transactions to be executed on the host chain on the behalf of the interchain account. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go#L29) | `Implemented` | -| 3.02 | Under no circumstances shall the owner account on the controller chain irretrievably lose control over the registered interchain account on the host chain. | If the channel between controller and host closes, then [a relayer can open a new channel on the existing controller port](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/account.go#L16-L17). | `Implemented` | +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 3.01 | The controller chain can programmatically control the interchain account by submitting transactions to be executed on the host chain on the behalf of the interchain account. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go#L29) | `Verified` | +| 3.02 | Under no circumstances shall the owner account on the controller chain irretrievably lose control over the registered interchain account on the host chain. | If the channel between controller and host closes, then [a relayer can open a new channel on the existing controller port](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/account.go#L16-L17). | `Verified` | ### 4 - Host execution -| ID | Description | Verification | Status | -| --- | ----------- | ------------ | ------ | -| 4.01 | Transactions shall be executed by an interchain account on the host chain in exactly the same order in which they are submitted by the controller chain. | IBC packets with SDK messages will be sent from the controller to the host over an [ordered channel](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/account.go#L60). | `Implemented` | -| 4.02 | The host shall execute only messages in the allow list. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/relay_test.go#L340) | `Implemented` | -| 4.03 | The controller chain shall know how the host chain will handle the transaction bytes in advance. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go#L109-L133) | `Implemented` | -| 4.04 | Each transaction submitted by the controller chain shall be executed only once by the interchain account on the host chain. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/relay_test.go#L248) | `Implemented` | +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 4.01 | Transactions shall be executed by an interchain account on the host chain in exactly the same order in which they are submitted by the controller chain. | IBC packets with SDK messages will be sent from the controller to the host over an [ordered channel](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/account.go#L60). | `Verified` | +| 4.02 | The host shall execute only messages in the allow list. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/relay_test.go#L340) | `Verified` | +| 4.03 | The controller chain shall know how the host chain will handle the transaction bytes in advance. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go#L109-L133) | `Verified` | +| 4.04 | Each transaction submitted by the controller chain shall be executed only once by the interchain account on the host chain. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/relay_test.go#L248) | `Verified` | # Non-functional requirements ## 5 - Security | ID | Description | Verification | Status | -| -- | ----------- | ------------ | ------ | -| 5.01 | There shall be no means for the interchain account to execute transactions that have not been submitted first by the respective owner account on the controller chain. |[Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/relay_test.go#L361) | `Implemented` | -| 5.02 | Every interchain account on the host chain shall have one and only one respective owner account on the controller chain. | The interchain account on the host [is generated using the host connection ID and the address of the owner on the controller](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/handshake.go#L73-L76). | `Implemented` | -| 5.03 | The owner account on a controller chain shall not be able to control interchain accounts registered by other owner accounts on the same controller chain. | Before the host logic executes the received messages, it [retrieves the interchain account associated with the port ID](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/relay.go#L94) over which it received the message. For owner address B to be able to execute a message with the interchain account registered with owner address A, it would need to send the messages over a channel that binds to a port ID that contains the owner address A, and since we have assumption number 3, this should not be allowed by applications. | `Implemented` | -| 5.04 | A controller chain shall not be able to control interchain accounts registered by owner accounts on different controller chains. | Same as 5.03. | `Implemented` | | -| 5.05 | Each interchain account on the host chain is owned by a single owner account on the controller chain. It shall not be possible to register a second interchain account with the same owner account on the controller chain. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/account_test.go#L42) | `Implemented` | +| -- | ----------- | ------------ | ------ | +| 5.01 | There shall be no means for the interchain account to execute transactions that have not been submitted first by the respective owner account on the controller chain. |[Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/relay_test.go#L361) | `Verified` | +| 5.02 | Every interchain account on the host chain shall have one and only one respective owner account on the controller chain. | The interchain account on the host [is generated using the host connection ID and the address of the owner on the controller](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/handshake.go#L73-L76). | `Verified` | +| 5.03 | The owner account on a controller chain shall not be able to control interchain accounts registered by other owner accounts on the same controller chain. | Before the host logic executes the received messages, it [retrieves the interchain account associated with the port ID](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/keeper/relay.go#L94) over which it received the message. For owner address B to be able to execute a message with the interchain account registered with owner address A, it would need to send the messages over a channel that binds to a port ID that contains the owner address A, and since we have assumption number 3, this should not be allowed by applications. | `Verified` | +| 5.04 | A controller chain shall not be able to control interchain accounts registered by owner accounts on different controller chains. | Same as 5.03. | `Verified` | | +| 5.05 | Each interchain account on the host chain is owned by a single owner account on the controller chain. It shall not be possible to register a second interchain account with the same owner account on the controller chain. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/account_test.go#L42) | `Verified` | # External interface requirements ## 6 - CLI -| ID | Description | Verification | Status | -| -- | ----------- | ------------ | ------ | -| 6.01 | There shall be a CLI command available to query the host parameters. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/client/cli/query.go#L22) | `Implemented` | -| 6.02 | There shall be a CLI command available to query the receive packet events on the host chain to check the result of the execution of the message on the host. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/client/cli/query.go#L51) | `Implemented` | -| 6.03 | There shall be a CLI command available to query the controller parameters. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/client/cli/query.go#L15) | `Implemented` | - +| ID | Description | Verification | Status | +| -- | ----------- | ------------ | ------ | +| 6.01 | There shall be a CLI command available to query the host parameters. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/client/cli/query.go#L22) | `Verified` | +| 6.02 | There shall be a CLI command available to query the receive packet events on the host chain to check the result of the execution of the message on the host. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/client/cli/query.go#L51) | `Verified` | +| 6.03 | There shall be a CLI command available to query the controller parameters. | [Acceptance tests](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/client/cli/query.go#L15) | `Verified` | ## 7 - Application developers -| ID | Description | Verification | Status | +| ID | Description | Verification | Status | | -- | ----------- | ------------ | ------ | -| 7.01 | An IBC application developer shall be able to develop an Interchain Accounts authentication module that can register interchain accounts. | The [`RegisterInterchainAccount` function](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/account.go#L18) is the entry point to registering an interchain account. | `Implemented` | -| 7.02 | An IBC application developer shall be able to develop an Interchain Accounts authentication module that can send messages from the controller to the host. | The [`SendTx` function](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/relay.go#L18) takes pre-built packet data containing messages to be executed on the host chain from an authentication module and attempts to send the packet. | `Implemented` | \ No newline at end of file +| 7.01 | An IBC application developer shall be able to develop an Interchain Accounts authentication module that can register interchain accounts. | The [`RegisterInterchainAccount` function](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/account.go#L18) is the entry point to registering an interchain account. | `Verified` | +| 7.02 | An IBC application developer shall be able to develop an Interchain Accounts authentication module that can send messages from the controller to the host. | The [`SendTx` function](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/controller/keeper/relay.go#L18) takes pre-built packet data containing messages to be executed on the host chain from an authentication module and attempts to send the packet. | `Verified` | diff --git a/docs/requirements/ics29-v1-requirements.md b/docs/requirements/ics29-v1-requirements.md new file mode 100644 index 00000000000..65c76dc4cc9 --- /dev/null +++ b/docs/requirements/ics29-v1-requirements.md @@ -0,0 +1,177 @@ +# Business requirements + +> **TL;DR**: There is no general incentivization mechanism to reward relayers for their service ensuring Interchain liveness. + +## Problem + +The Interchain dream will never scale unless there is a clear way to incentivize relayers. An interface that can be easily adopted by any applications is needed, without precluding chains that do not use tokens. + +Though IBC does not depend on relayer operators for transaction verification, the relayer infrastructure ensures liveness of the Interchain network — operators listen for packets sent through channels opened between chains, and perform the vital service of ferrying these packets (and proof of the transaction on the sending chain/receipt on the receiving chain) to the clients on each side of the channel. Though relaying is permissionless and completely decentralized and accessible, it does come with operational costs. Running full nodes to query transaction proofs and paying for transaction fees associated with IBC packets are two of the primary cost burdens which have driven the overall discussion on a general incentivization mechanism for relayers. + +## Objectives + +Provide a general fee payment design that can be adopted by any ICS application protocol as middleware. + +## Scope + +| Features | Release | +| --------- | ------- | +| Incentivize timely delivery of a packet (successfully submit `MsgRecvPacket`). | v1 | +| Incentivize relaying acknowledgement for a packet (successfully submit `MsgAcknowledgement`). | v1 | +| Incentivize relaying timeout for a packet when the timeout has expired before packet is delivered (successfully submit `MsgTimeout`). | v1 | +| Enable permissionless or permissioned relaying. | v1 | +| Allow opt-in for chains (an application with fee support on chain A could connect to the couterparty application without fee support on chain B). | v1 | + +# User requirements + +## Use cases + +- A packet already sent may be incentivized for one or more of the messages `MsgRecvPacket`, `MsgAcknowledgement`, `MsgTimeout`. +- The next packet to be sent may be incentivized for one or more of the messages `MsgRecvPacket`, `MsgAcknowledgement`, `MsgTimeout`. + +# Functional requirements + +## Assumptions + +1. Relayer addresses should not be forgeable. + +## Known limitations + +1. Without channel upgradability it is not possible to use fee incentivization on an existing channel. + +## Terminology + +See section [Definitions](https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment#definitions) in ICS 29 spec. + +## Features + +### 1 - Configuration + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 1.02 | A chain shall have the ability to export the fee middleware genesis state. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/genesis_test.go#L69) | `Verified` | +| 1.03 | A chain shall have the ability to initialize the fee middleware genesis state. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/genesis_test.go#L9) | `Verified` | + +### 2 - Payee registration + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 2.01 | A relayer shall have the ability to register for a channel an optional payee address to which fees shall be distributed for successful relaying `MsgAcknowledgement` and `MsgTimeout`. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L23) | `Verified` | +| 2.02 | The payee address shall only be registered if the channel exist. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L28) | `Verified` | +| 2.03 | The payee address shall only be registered if the channel is fee enabled. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L35) | `Verified` | +| 2.04 | The payee address shall only be registered if the address is a valid `Bech32` address. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L42) | `Verified` | +| 2.05 | The payee address shall only be registered if the address is not blocked. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L49) | `Verified` | + +### 3 - Counterparty payee registration + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 3.01 | A relayer shall have the ability to register a counterparty payee to which fees shall be distributed for successful relaying of `MsgRecvPacket`. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L102) | `Verified` | +| 3.02 | The counterparty payee address shall only be registered if the channel exists. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L115) | `Verified` | +| 3.03 | The counterparty payee address shall only be registered if the channel is fee enabled. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L122) | `Verified` | +| 3.04 | The counterparty payee address may be an arbitrary string (since the counterparty chain may not be Cosmos-SDK based). | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L42) | `Verified` | + +### 4 - Fee incentivization + +#### Synchronously + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 4.01 | If a channel is fee-enabled, the next sequence packet may be incentivized. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L178) | `Verified` | +| 4.02 | If the fee module is not locked, the next sequence packet may be incentivized. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L210) | `Verified` | +| 4.03 | The next sequence packet may be incentivized for some or all of `MsgRecvPacket`, `MsgAcknowledgement`, `MsgTimeout`. | Fees for any of the messages may be zero, but [not all of them](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/types/fee.go#L87). | `Verified` | +| 4.04 | A blocked account address shall not be allowed to incentivize the next sequence packet. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L239) | `Verified` | +| 4.05 | A non-valid `Bech32` account address shall not be allowed to incentivize the next sequence packet. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L225) | `Verified` | +| 4.06 | The next sequence packet may be incentivized by multiple account addresses. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L183) | `Verified` | +| 4.07 | The next sequence packet shall only be incentivized with valid coin denominations. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L246-L266) | `Verified` | + +#### Aynchronously + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 4.08 | Only packets that have been sent may be incentivized. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L376) | `Verified` | +| 4.09 | A packet sent may be incentivized for some or all of `MsgRecvPacket`, `MsgAcknowledgement`, `MsgTimeout`. | Fees for any of the messages may be zero, but [not all of them](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/types/fee.go#L87). | `Verified` | +| 4.10 | Only packets that have not gone through the packet life cycle (i.e. have not been acknowledged or timed out yet) may be incentivized. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L382-L410) | `Verified` | +| 4.11 | If a channel exists, a packet sent may be incentivized. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L365) | +| 4.12 | If a channel is fee-enabled, a packet sent may be incentivized. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L357) | `Verified` | +| 4.13 | If the fee module is not locked, a packet sent may be incentivized. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L350) | `Verified` | +| 4.14 | A non-valid `Bech32` account address shall not be allowed to incentivize a packet sent. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L412) | `Verified` | +| 4.15 | An account that does not exist shall not be allowed to incentivize a packet sent. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L419) | `Verified` | +| 4.16 | A blocked account shall not be allowed to incentivize a packet sent. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/msg_server_test.go#L426) | `Verified` | + +### 5 - Fee distribution + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 5.01 | Fee distribution shall occurr on the source chain from which packets originate. | Either in [`OnAcknowledgementPacket`](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/ibc_middleware.go#L288) or in [`OnTimeoutPacket`](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/ibc_middleware.go#L330). | `Verified` | + +#### `OnAcknowledgementPacket` + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 5.02 | Fees for successful relaying of `MsgAcknowledgement` shall be distributed to the relayer address (or its associated payee address if one has been registered). | If a payee address exists for the relayer address, then [fees are distributed to the payee address](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/ibc_middleware.go#L288); otherwise [fees are distributed to the relayer address](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/ibc_middleware.go#L277). | `Verified` | +| 5.03 | Fees for successful relaying of `MsgRecvPacket` shall be distributed to the payee address of the relayer address. | [Fees are distributed to the payee address registered on the counterparty chain](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow.go#L93) if it is a valid `Bech32` address and is not a blocked address. | `Verified` | + +#### `OnTimeoutPacket` + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 5.05 | Fees for successful relaying of `MsgTimeout` shall be distributed to the relayer address (or its associated payee address if one has been registered). | If a payee address exists for the relayer address, then [fees are distributed to the payee address](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/ibc_middleware.go#L330); otherwise [fees are distributed to the relayer address](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/ibc_middleware.go#L319). | `Verified` | + +### 6 - Fee refunding + +#### `OnAcknowledgementPacket` + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 6.01 | On successful processing of `MsgAcknowledgement`, fees for successful relay of `MsgTimeout` shall be refunded. | [Fees are refunded is the refund address is a valid `Bech32` address](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow.go#L103). | `Verified` | +| 6.02 | On successful processing of `MsgAcknowledgement`, if fees for successful relay of `MsgRecvPacket` cannot be distributed, then they should be refunded. | [Fees are refunded](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow.go#L96) if the payee address registered on the counterparty chain for the relayer is either [invalid](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow_test.go#L105) or a [blocked address](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow_test.go#L120). | `Verified` | + +#### `OnTimeoutPacket` + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 6.03 | On successful processing of `MsgTimeout`, fees for successful relay of `MsgRecvPacket` shall be refunded. | [Fees are refunded is the refund address is a valid `Bech32` address](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow.go#L146). | `Verified` | +| 6.04 | On successful processing of `MsgTimeout`, fees for successful relay of `MsgAcknowledgement` shall be refunded. | [Fees are refunded is the refund address is a valid `Bech32` address](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow.go#L149). | `Verified` | + +#### Channel closure + +| ID | Description | Verification | Status | +| --- | ----------- | ------------ | ------ | +| 6.04 | Packet fees are refunded on channel closure. | Both on [`OnChanCloseInit`](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/ibc_middleware.go#L182) and [`OnChanCloseConfirm`](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/ibc_middleware.go#L207). | `Verified` | + +# Non-functional requirements + +## 7 - Security + +| ID | Description | Verification | Status | +| -- | ----------- | ------------ | ------ | +| 7.01 | If the escrow account does not have sufficient funds while distributing fees in `OnAcknowledgementPacket`, the fee module shall become locked. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow_test.go#L85) | `Verified` | +| 7.02 | If the escrow account does not have sufficient funds while distributing fees in `OnTimeoutPacket`, the fee module shall become locked. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow_test.go#L236) | `Verified` | +| 7.03 | If the escrow account does not have sufficient funds while refunding fees in channel closure, the fee module shall become locked. | [Acceptance test](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/keeper/escrow_test.go#L377) | `Verified` | + +# External interface requirements + +## 8 - CLI + +### Query + +| ID | Description | Verification | Status | +| -- | ----------- | ------------ | ------ | +| 8.01 | There shall be a CLI command available to query for the incentivization of an unrelayed packet by port ID, channel ID and packet sequence. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#L64) | `Verified` | +| 8.02 | There shall be a CLI command to query for the incentivization of all unrelayed packets on all open channels. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#L64) | `Verified` | +| 8.03 | There shall be a CLI command available to query for the total fees for `MsgRecvPacket` for a given port ID, channel ID and packet sequence. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#L105) | `Verified` | +| 8.04 | There shall be a CLI command available to query for the total fees for `MsgAcknowledgement` for a given port ID, channel ID and packet sequence. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#L151) | `Verified` | +| 8.05 | There shall be a CLI command available to query for the total fees for `MsgTimeout` for a given port ID, channel ID and packet sequence. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#L197) | `Verified` | +| 8.06 | There shall be a CLI command available to query for the payee address registered for a relayer for a specific channel ID. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#243) | `Verified` | +| 8.07 | There shall be a CLI command available to query for the counterparty payee address registered for a relayer for a specific channel ID. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#282) | `Verified` | +| 8.08 | There shall be a CLI command available to query if a channel is fee-enabled for a port ID and channel ID. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#L362) | `Verified` | +| 8.09 | There shall be a CLI command available to query for all the unrelayed incentivized packets in a channel by a port ID and channel ID. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/query.go#L397) | `Verified` | + +### Transaction + +| ID | Description | Verification | Status | +| -- | ----------- | ------------ | ------ | +| 8.10 | There shall be a CLI command available to register a payee address for a channel by port ID and channel ID. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/tx.go#L26) | `Verified` | +| 8.11 | There shall be a CLI command available to register a counterparty payee address for a channel by port ID and channel ID. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/tx.go#L51) | `Verified` | +| 8.12 | There shall be a CLI command available to incentivize a packet by port ID, channel ID and packet sequence. | [CLI](https://github.com/cosmos/ibc-go/blob/v4.0.0/modules/apps/29-fee/client/cli/tx.go#L76) | `Verified` | diff --git a/docs/requirements/requirements-template.md b/docs/requirements/requirements-template.md new file mode 100644 index 00000000000..6afd9961bf8 --- /dev/null +++ b/docs/requirements/requirements-template.md @@ -0,0 +1,53 @@ + + +# Business requirements + + + + + +## Problem + + + +## Objectives + + + +## Scope + + + + + +# User requirements + +## Use cases + + + +# Functional requirements + + + +## Assumptions and dependencies + + + +## Features + + + +# External interface requirements + + + +# Non-functional requirements + + \ No newline at end of file diff --git a/docs/roadmap/roadmap.md b/docs/roadmap/roadmap.md index eaf416adfb9..241cb5c16ab 100644 --- a/docs/roadmap/roadmap.md +++ b/docs/roadmap/roadmap.md @@ -4,54 +4,68 @@ order: 1 # Roadmap ibc-go -_Lastest update: July 7, 2022_ +_Lastest update: December 21st, 2022_ This document endeavours to inform the wider IBC community about plans and priorities for work on ibc-go by the team at Interchain GmbH. It is intended to broadly inform all users of ibc-go, including developers and operators of IBC, relayer, chain and wallet applications. -This roadmap should be read as a high-level guide, rather than a commitment to schedules and deliverables. The degree of specificity is inversely proportional to the timeline. We will update this document periodically to reflect the status and plans. +This roadmap should be read as a high-level guide, rather than a commitment to schedules and deliverables. The degree of specificity is inversely proportional to the timeline. We will update this document periodically to reflect the status and plans. For the latest expected release timelines, please check [here](https://github.com/cosmos/ibc-go/wiki/Release-timeline). -## Q3 - 2022 +## v7.0.0 -At a high level we will focus on: +### 02-client refactor -### Features +This refactor will make the development of light clients easier. The ibc-go implementation will finally align with the spec and light clients will be required to set their own client and consensus states. This will allow more flexibility for light clients to manage their own internal storage and do batch updates. See [ADR 006](../architecture/adr-006-02-client-refactor.md) for more information. -- Releasing [v4.0.0](https://github.com/cosmos/ibc-go/milestone/26), which includes the ICS-29 Fee Middleware module. -- Finishing and releasing the [refactoring of 02-client](https://github.com/cosmos/ibc-go/milestone/16). This refactor will make the development of light clients easier. -- Starting the implementation of channel upgradability (see [epic](https://github.com/cosmos/ibc-go/issues/1599) and [alpha milestone](https://github.com/cosmos/ibc-go/milestone/29)) with the goal of cutting an alpha1 pre-release by the end of the quarter. Channel upgradability will allow chains to renegotiate an existing channel to take advantage of new features without having to create a new channel, thus preserving all existing packet state processed on the channel. -- Implementing the new [`ORDERED_ALLOW_TIMEOUT` channel type](https://github.com/cosmos/ibc-go/milestone/31) and hopefully releasing it as well. This new channel type will allow packets on an ordered channel to timeout without causing the closure of the channel. +Follow the progress with the [beta](https://github.com/cosmos/ibc-go/milestone/25) and [RC](https://github.com/cosmos/ibc-go/milestone/27) milestones or in the [project board](https://github.com/orgs/cosmos/projects/7/views/14). -### Testing and infrastructure +### Upgrade Cosmos SDK v0.47 -- Adding [automated e2e tests](https://github.com/cosmos/ibc-go/milestone/32) to the repo's CI. +Follow the progress with the [milestone](https://github.com/cosmos/ibc-go/milestone/36). -### Documentation and backlog +### Add `authz` support to 20-transfer -- Finishing and releasing the upgrade to Cosmos SDK v0.46. -- Writing the [light client implementation guide](https://github.com/cosmos/ibc-go/issues/59). -- Working on [core backlog issues](https://github.com/cosmos/ibc-go/milestone/28). -- Depending on the timeline of the Cosmos SDK, implementing and testing the changes needed to support the [transtion to SMT storage](https://github.com/cosmos/ibc-go/milestone/21). +Authz goes cross chain: users can grant permission for their tokens to be transferred to another chain on their behalf. See [this issue](https://github.com/cosmos/ibc-go/issues/2431) for more details. -We have also received a lot of feedback to improve Interchain Accounts and we might also work on a few things, but will depend on priorities and availability. +## v7.1.0 -For a detail view of each iteration's planned work, please check out our [project board](https://github.com/orgs/cosmos/projects/7). +Because it is so important to have an ibc-go release compatible with the latest Cosmos SDK release, a couple of features will take a little longer and be released in [v7.1.0](https://github.com/cosmos/ibc-go/milestone/37). -### Release schedule +### Localhost connection -#### **July** +This feature will add support for applications on a chain to communicate with applications on the same chain using the existing standard interface to communicate with applications on remote chains. This is a powerful UX improvement, particularly for those users interested in interacting with multiple smart contracts on a single chain through one interface. -We will probably cut at least one more release candidate of v4.0.0 before the final release, which should happen around the end of the month. +For more details, see the design proposal and discussion [here](https://github.com/cosmos/ibc-go/discussions/2191). -For the Rho upgrade of the Cosmos Hub we will also release a new minor version of v3 with SDK 0.46. +A special shout out to Strangelove for their substantial contribution on this feature. -#### **August** +### Support for Wasm light clients -In the first half we will probably start cutting release candidates for the 02-client refactor. Final release would most likely come out at the end of the month or beginning of September. +We will add support for Wasm light clients. The first Wasm client developed with ibc-go/v7 02-client refactor and stored as Wasm bytecode will be the GRANDPA light client used for Cosmos <> Substrate IBC connections. This feature will be used also for a NEAR light client in the future. -#### **September** +This feature was developed by Composable and Strangelove but will be upstreamed into ibc-go. -We might cut some pre-releases for the new channel type, and by the end of the month we expect to cut the first alpha pre-release for channel upgradability. +## v8.0.0 -## Q4 - 2022 +### Channel upgradability -We will continue the implementation and cut the final release of [channel upgradability](https://github.com/cosmos/ibc/blob/master/spec/core/ics-004-channel-and-packet-semantics/UPGRADES.md). At the end of Q3 or maybe beginning of Q4 we might also work on designing the implementation and scoping the engineering work to add support for [multihop channels](https://github.com/cosmos/ibc/pull/741/files), so that we could start the implementation of this feature during Q4 (but this is still be decided). +Channel upgradability will allow chains to renegotiate an existing channel to take advantage of new features without having to create a new channel, thus preserving all existing packet state processed on the channel. + +Follow the progress with the [alpha milestone](https://github.com/cosmos/ibc-go/milestone/29) or the [project board](https://github.com/orgs/cosmos/projects/7/views/17). + +### Path unwinding + +This feature will allow tokens with non-native denoms to be sent back automatically to their native chains before being sent to a final destination chain. This will allow tokens to reach a final destination with the least amount possible of hops from their native chain. + +For more details, see this [discussion](https://github.com/cosmos/ibc/discussions/824). + +--- + +This roadmap is also available as a [project board](https://github.com/orgs/cosmos/projects/7/views/25). + +For the latest expected release timelines, please check [here](https://github.com/cosmos/ibc-go/wiki/Release-timeline). + +For the latest information on the progress of the work or the decisions made that might influence the roadmap, please follow our [engineering updates](https://github.com/cosmos/ibc-go/wiki/Engineering-updates). + +--- + +**Note**: release version numbers may be subject to change. diff --git a/docs/versions b/docs/versions index 7771cabc308..265e01a0bfe 100644 --- a/docs/versions +++ b/docs/versions @@ -1,5 +1,19 @@ +release/v6.1.x v6.1.0 +release/v6.0.x v6.0.0 +release/v5.2.x v5.2.0 +release/v5.1.x v5.1.0 +release/v5.0.x v5.0.0 +release/v4.3.x v4.3.0 +release/v4.2.x v4.2.0 +release/v4.1.x v4.1.0 +release/v4.0.x v4.0.0 +release/v3.4.x v3.4.0 +release/v3.3.x v3.3.0 +release/v3.2.x v3.2.0 release/v3.1.x v3.1.0 release/v3.0.x v3.0.0 +release/v2.5.x v2.5.0 +release/v2.4.x v2.4.0 release/v2.3.x v2.3.0 release/v2.2.x v2.2.0 release/v2.1.x v2.1.0 diff --git a/e2e/Makefile b/e2e/Makefile index 95a0fa5b6a2..0b9802d06e1 100644 --- a/e2e/Makefile +++ b/e2e/Makefile @@ -8,6 +8,9 @@ cleanup-ibc-test-containers: done e2e-test: cleanup-ibc-test-containers - ./scripts/run-e2e.sh $(suite) $(test) + ./scripts/run-e2e.sh $(entrypoint) $(test) -.PHONY: cleanup-ibc-test-containers e2e-test +compatibility-tests: + ./scripts/run-compatibility-tests.sh $(release_branch) + +.PHONY: cleanup-ibc-test-containers e2e-test compatibility-tests diff --git a/e2e/README.md b/e2e/README.md new file mode 100644 index 00000000000..1080f6a41a4 --- /dev/null +++ b/e2e/README.md @@ -0,0 +1,354 @@ +# Table of Contents + +1. [How to write tests](#how-to-write-tests) + - a. [Adding a new test](#adding-a-new-test) + - b. [Running the tests with custom images](#running-tests-with-custom-images) + - b. [Code samples](#code-samples) + - [Setup](#setup) + - [Creating test users](#creating-test-users) + - [Waiting](#waiting) + - [Query wallet balances](#query-wallet-balances) + - [Broadcasting messages](#broadcasting-messages) + - [Starting the relayer](#starting-the-relayer) + - [Arbitrary commands](#arbitrary-commands) + - [IBC transfer](#ibc-transfer) +2. [Test design](#test-design) + - a. [interchaintest](#interchaintest) + - b. [CI configuration](#ci-configuration) +3. [Github Workflows](#github-workflows) +4. [Running Compatibility Tests](#running-compatibility-tests) +5. [Troubleshooting](#troubleshooting) + +# How to write tests + +## Adding a new test + +All tests should go under the [e2e](https://github.com/cosmos/ibc-go/tree/main/e2e) directory. When adding a new test, either add a new test function +to an existing test suite **_in the same file_**, or create a new test suite in a new file and add test functions there. +New test files should follow the convention of `module_name_test.go`. + +New test suites should be composed of `testsuite.E2ETestSuite`. This type has lots of useful helper functionality that will +be quite common in most tests. + +> Note: see [here](#how-tests-are-run) for details about these requirements. + +## Running tests with custom images + +Tests can be run using a Makefile target under the e2e directory. `e2e/Makefile` + +There are several envinronment variables that alter the behaviour of the make target. + +| Environment Variable | Description | Default Value | +|----------------------|-------------------------------------------|---------------| +| CHAIN_IMAGE | The image that will be used for the chain | ibc-go-simd | +| CHAIN_A_TAG | The tag used for chain B | latest | +| CHAIN_B_TAG | The tag used for chain A | latest | +| CHAIN_BINARY | The binary used in the container | simd | +| RELAYER_TAG | The tag used for the relayer | main | +| RELAYER_TYPE | The type of relayer to use (rly/hermes) | rly | + +> Note: when running tests locally, **no images are pushed** to the `ghcr.io/cosmos/ibc-go-simd` registry. +The images which are used only exist on your machine. + +These environment variables allow us to run tests with arbitrary verions (from branches or released) of simd +and the go relayer. + +Every time changes are pushed to a branch or to `main`, a new `simd` image is built and pushed [here](https://github.com/cosmos/ibc-go/pkgs/container/ibc-go-simd). + +### Example Command + +```sh +export CHAIN_IMAGE="ghcr.io/cosmos/ibc-go-simd" +export CHAIN_A_TAG="main" +export CHAIN_BINARY="simd" + +# We can also specify different values for the chains if needed. +# they will default to the same as chain a. +# export CHAIN_B_TAG="main" +# export CHAIN_BINARY="icad" + +export RELAYER_TAG="v2.0.0" +make e2e-test entrypoint=TestInterchainAccountsTestSuite test=TestMsgSubmitTx_SuccessfulTransfer +``` + +> Note: sometimes it can be useful to make changes to [ibctest](https://github.com/strangelove-ventures/interchaintest) when running tests locally. In order to do this, add the following line to +e2e/go.mod + +`replace github.com/strangelove-ventures/interchaintest => ../ibctest` + +Or point it to any local checkout you have. + +### Running tests in CI + +To run tests in CI, you can checkout the ibc-go repo and provide these environment variables +to the CI task. + +[This repo](https://github.com/chatton/ibc-go-e2e-demo) contains an example of how to do this with Github Actions. + +## Code samples + +### Setup + +Every standard test will start with this. This creates two chains and a relayer, +initializes relayer accounts on both chains, establishes a connection and a channel +between the chains. + +Both chains have started, but the relayer is not yet started. + +The relayer should be started as part of the test if required. See [Starting the Relayer](#starting-the-relayer) + +```go +relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) +chainA, chainB := s.GetChains() +``` + +### Creating test users + +There are helper functions to easily create users on both chains. + +```go +chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) +chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) +``` + +### Waiting + +We can wait for some number of blocks on the specified chains if required. + +```go +chainA, chainB := s.GetChains() +err := test.WaitForBlocks(ctx, 1, chainA, chainB) +s.Require().NoError(err) +``` + +### Query wallet balances + +We can fetch balances of wallets on specific chains. + +```go +chainABalance, err := s.GetChainANativeBalance(ctx, chainAWallet) +s.Require().NoError(err) +``` + +### Broadcasting messages + +We can broadcast arbitrary messages which are signed on behalf of users created in the test. + +This example shows a multi message transaction being broadcast on chainA and signed on behalf of chainAWallet. + +```go +relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) +chainA, chainB := s.GetChains() + +chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) +chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + +t.Run("broadcast multi message transaction", func(t *testing.T){ + payPacketFeeMsg := feetypes.NewMsgPayPacketFee(testFee, channelA.PortID, channelA.ChannelID, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), nil) + transferMsg := transfertypes.NewMsgTransfer(channelA.PortID, channelA.ChannelID, transferAmount, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), chainBWallet.Bech32Address(chainB.Config().Bech32Prefix), clienttypes.NewHeight(1, 1000), 0) + resp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, payPacketFeeMsg, transferMsg) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) +}) +``` + +### Starting the relayer + +The relayer can be started with the following. + +```go +t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) +}) +``` + +### Arbitrary commands + +Arbitrary commands can be executed on a given chain. + +> Note: these commands will be fully configured to run on the chain executed on (home directory, ports configured etc.) + +However, it is preferable to [broadcast messages](#broadcasting-messages) or use a gRPC query if possible. + +```go +stdout, stderr, err := chainA.Exec(ctx, []string{"tx", "..."}, nil) +``` + +### IBC transfer + +It is possible to send an IBC transfer in two ways. + +Use the ibctest `Chain` interface (this ultimately does a docker exec) + +```go +t.Run("send IBC transfer", func(t *testing.T) { + chainATx, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName, walletAmount, nil) + s.Require().NoError(err) + s.Require().NoError(chainATx.Validate(), "chain-a ibc transfer tx is invalid") +}) +``` + +Broadcast a `MsgTransfer`. + +```go +t.Run("send IBC transfer", func(t *testing.T){ + transferMsg := transfertypes.NewMsgTransfer(channelA.PortID, channelA.ChannelID, transferAmount, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), chainBWallet.Bech32Address(chainB.Config().Bech32Prefix), clienttypes.NewHeight(1, 1000), 0) + resp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, transferMsg) + s.AssertValidTxResponse(resp) + s.Require().NoError(err) +}) +``` + +## Test design + +### interchaintest + +These E2E tests use the [interchaintest framework](https://github.com/strangelove-ventures/interchaintest). This framework creates chains and relayers in containers and allows for arbitrary commands to be executed in the chain containers, +as well as allowing us to broadcast arbitrary messages which are signed on behalf of a user created in the test. + +### CI configuration + +There are two main github actions for e2e tests. + +[e2e.yaml](https://github.com/cosmos/ibc-go/blob/main/.github/workflows/e2e.yaml) which runs when collaborators create branches. + +[e2e-fork.yaml](https://github.com/cosmos/ibc-go/blob/main/.github/workflows/e2e-fork.yml) which runs when forks are created. + +In `e2e.yaml`, the `simd` image is built and pushed to [a registry](https://github.com/cosmos/ibc-go/pkgs/container/ibc-go-simd) and every test +that is run uses the image that was built. + +In `e2e-fork.yaml`, images are not pushed to this registry, but instead remain local to the host runner. + +## How tests are run + +The tests use the `matrix` feature of Github Actions. The matrix is +dynamically generated using [this command](https://github.com/cosmos/ibc-go/blob/main/cmd/build_test_matrix/main.go). + +> Note: there is currently a limitation that all tests belonging to a test suite must be in the same file. +In order to support test functions spread in different files, we would either need to manually maintain a matrix +or update the script to account for this. The script assumes there is a single test suite per test file to avoid an overly complex +generation process. + +Which looks under the `e2e` directory, and creates a task for each test suite function. + +### Example + +```go +// e2e/file_one_test.go +package e2e + +func TestFeeMiddlewareTestSuite(t *testing.T) { + suite.Run(t, new(FeeMiddlewareTestSuite)) +} + +type FeeMiddlewareTestSuite struct { + testsuite.E2ETestSuite +} + +func (s *FeeMiddlewareTestSuite) TestA() {} +func (s *FeeMiddlewareTestSuite) TestB() {} +func (s *FeeMiddlewareTestSuite) TestC() {} + +``` + +```go +// e2e/file_two_test.go +package e2e + +func TestTransferTestSuite(t *testing.T) { + suite.Run(t, new(TransferTestSuite)) +} + +type TransferTestSuite struct { + testsuite.E2ETestSuite +} + +func (s *TransferTestSuite) TestD() {} +func (s *TransferTestSuite) TestE() {} +func (s *TransferTestSuite) TestF() {} + +``` + +In the above example, the following would be generated. + +```json +{ + "include": [ + { + "entrypoint": "TestFeeMiddlewareTestSuite", + "test": "TestA" + }, + { + "entrypoint": "TestFeeMiddlewareTestSuite", + "test": "TestB" + }, + { + "entrypoint": "TestFeeMiddlewareTestSuite", + "test": "TestC" + }, + { + "entrypoint": "TestTransferTestSuite", + "test": "TestD" + }, + { + "entrypoint": "TestTransferTestSuite", + "test": "TestE" + }, + { + "entrypoint": "TestTransferTestSuite", + "test": "TestF" + } + ] +} +``` + +This string is used to generate a test matrix in the Github Action that runs the E2E tests. + +All tests will be run on different hosts. + +### Misceleneous: + +## GitHub Workflows + +### Building and pushing a `simd` image + +If we ever need to manually build and push an image, we can do so with the [Build Simd Image](../.github/workflows/build-simd-image-from-tag.yml) GitHub workflow. + +This can be triggered manually from the UI by navigating to + +`Actions` -> `Build Simd Image` -> `Run Workflow` + +And providing the git tag. + +Alternatively, the [gh](https://cli.github.com/) CLI tool can be used to trigger this workflow. + +```bash +gh workflow run "Build Simd Image" -f tag=v3.0.0 +``` + +## Running Compatibility Tests + +To trigger the compatibility tests for a release branch, you can use the following command. + +```bash +make compatibility-tests release_branch=release/v5.0.x +``` + +This will build an image from the tip of the release branch and run all tests specified in the corresponding +json matrix files under .github/compatibility-test-matrices and is equivalent to going to the Github UI and navigating to + +`Actions` -> `Compatibility E2E` -> `Run Workflow` -> `release/v5.0.x` + +## Troubleshooting + +- On Mac, after running a lot of tests, it can happen that containers start failing. To fix this, you can try clearing existing containers and restarting the docker daemon. + + This generally manifests itself as relayer or simd containers timing out during setup stages of the test. This doesn't happen in CI. + + ```bash + # delete all images + docker system prune -af + ``` + + This issue doesn't seem to occur on other operating systems. diff --git a/e2e/fee_middleware_test.go b/e2e/fee_middleware_test.go deleted file mode 100644 index e6207f5d729..00000000000 --- a/e2e/fee_middleware_test.go +++ /dev/null @@ -1,439 +0,0 @@ -package e2e - -import ( - "context" - "testing" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/strangelove-ventures/ibctest/broadcast" - "github.com/strangelove-ventures/ibctest/chain/cosmos" - "github.com/strangelove-ventures/ibctest/ibc" - "github.com/strangelove-ventures/ibctest/test" - "github.com/stretchr/testify/suite" - - "e2e/testsuite" - "e2e/testvalues" - - feetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" -) - -func TestFeeMiddlewareTestSuite(t *testing.T) { - suite.Run(t, new(FeeMiddlewareTestSuite)) -} - -type FeeMiddlewareTestSuite struct { - testsuite.E2ETestSuite -} - -// RegisterCounterPartyPayee broadcasts a MsgRegisterCounterpartyPayee message. -func (s *FeeMiddlewareTestSuite) RegisterCounterPartyPayee(ctx context.Context, chain *cosmos.CosmosChain, - user broadcast.User, portID, channelID, relayerAddr, counterpartyPayeeAddr string) (sdk.TxResponse, error) { - msg := feetypes.NewMsgRegisterCounterpartyPayee(portID, channelID, relayerAddr, counterpartyPayeeAddr) - return s.BroadcastMessages(ctx, chain, user, msg) -} - -// QueryCounterPartyPayee queries the counterparty payee of the given chain and relayer address on the specified channel. -func (s *FeeMiddlewareTestSuite) QueryCounterPartyPayee(ctx context.Context, chain ibc.Chain, relayerAddress, channelID string) (string, error) { - queryClient := s.GetChainGRCPClients(chain).FeeQueryClient - res, err := queryClient.CounterpartyPayee(ctx, &feetypes.QueryCounterpartyPayeeRequest{ - ChannelId: channelID, - Relayer: relayerAddress, - }) - - if err != nil { - return "", err - } - return res.CounterpartyPayee, nil -} - -// PayPacketFeeAsync broadcasts a MsgPayPacketFeeAsync message. -func (s *FeeMiddlewareTestSuite) PayPacketFeeAsync( - ctx context.Context, - chain *cosmos.CosmosChain, - user broadcast.User, - packetID channeltypes.PacketId, - packetFee feetypes.PacketFee, -) (sdk.TxResponse, error) { - msg := feetypes.NewMsgPayPacketFeeAsync(packetID, packetFee) - return s.BroadcastMessages(ctx, chain, user, msg) -} - -// QueryIncentivizedPacketsForChannel queries the incentivized packets on the specified channel. -func (s *FeeMiddlewareTestSuite) QueryIncentivizedPacketsForChannel( - ctx context.Context, - chain *cosmos.CosmosChain, - portId, - channelId string, -) ([]*feetypes.IdentifiedPacketFees, error) { - queryClient := s.GetChainGRCPClients(chain).FeeQueryClient - res, err := queryClient.IncentivizedPacketsForChannel(ctx, &feetypes.QueryIncentivizedPacketsForChannelRequest{ - PortId: portId, - ChannelId: channelId, - }) - if err != nil { - return nil, err - } - return res.IncentivizedPackets, err -} - -func (s *FeeMiddlewareTestSuite) TestMsgPayPacketFee_AsyncSingleSender_Succeeds() { - t := s.T() - ctx := context.TODO() - - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) - chainA, chainB := s.GetChains() - - var ( - chainADenom = chainA.Config().Denom - testFee = testvalues.DefaultFee(chainADenom) - chainATx ibc.Tx - payPacketFeeTxResp sdk.TxResponse - ) - - chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) - - t.Run("relayer wallets recovered", func(t *testing.T) { - err := s.RecoverRelayerWallets(ctx, relayer) - s.Require().NoError(err) - }) - - chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) - t.Run("relayer wallets fetched", func(t *testing.T) { - s.Require().NoError(err) - }) - - s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") - - _, chainBRelayerUser := s.GetRelayerUsers(ctx) - - t.Run("register counter party payee", func(t *testing.T) { - resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.Address, chainARelayerWallet.Address) - s.Require().NoError(err) - s.AssertValidTxResponse(resp) - }) - - t.Run("verify counter party payee", func(t *testing.T) { - address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.Address, channelA.Counterparty.ChannelID) - s.Require().NoError(err) - s.Require().Equal(chainARelayerWallet.Address, address) - }) - - walletAmount := ibc.WalletAmount{ - Address: chainAWallet.Bech32Address(chainB.Config().Bech32Prefix), // destination address - Denom: chainADenom, - Amount: testvalues.IBCTransferAmount, - } - - t.Run("send IBC transfer", func(t *testing.T) { - chainATx, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName, walletAmount, nil) - s.Require().NoError(err) - s.Require().NoError(chainATx.Validate(), "chain-a ibc transfer tx is invalid") - }) - - t.Run("tokens are escrowed", func(t *testing.T) { - actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - walletAmount.Amount - s.Require().Equal(expected, actualBalance) - }) - - t.Run("pay packet fee", func(t *testing.T) { - t.Run("no incentivized packets", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Empty(packets) - }) - - packetId := channeltypes.NewPacketId(channelA.PortID, channelA.ChannelID, 1) - packetFee := feetypes.NewPacketFee(testFee, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), nil) - - t.Run("should succeed", func(t *testing.T) { - payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet, packetId, packetFee) - s.Require().NoError(err) - s.AssertValidTxResponse(payPacketFeeTxResp) - }) - - t.Run("there should be incentivized packets", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Len(packets, 1) - actualFee := packets[0].PacketFees[0].Fee - - s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) - s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) - s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) - }) - - t.Run("balance should be lowered by sum of recv ack and timeout", func(t *testing.T) { - // The balance should be lowered by the sum of the recv, ack and timeout fees. - actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - walletAmount.Amount - testFee.Total().AmountOf(chainADenom).Int64() - s.Require().Equal(expected, actualBalance) - }) - }) - - t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) - }) - - t.Run("packets are relayed", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Empty(packets) - }) - - t.Run("timeout fee is refunded", func(t *testing.T) { - actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) - s.Require().NoError(err) - - // once the relayer has relayed the packets, the timeout fee should be refunded. - expected := testvalues.StartingTokenAmount - walletAmount.Amount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() - s.Require().Equal(expected, actualBalance) - }) -} - -func (s *FeeMiddlewareTestSuite) TestMultiMsg_MsgPayPacketFeeSingleSender() { - t := s.T() - ctx := context.TODO() - - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) - - chainA, chainB := s.GetChains() - - var ( - chainADenom = chainA.Config().Denom - testFee = testvalues.DefaultFee(chainADenom) - multiMsgTxResponse sdk.TxResponse - ) - - transferAmount := testvalues.DefaultTransferAmount(chainA.Config().Denom) - - chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) - chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) - - t.Run("relayer wallets recovered", func(t *testing.T) { - err := s.RecoverRelayerWallets(ctx, relayer) - s.Require().NoError(err) - }) - - chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) - t.Run("relayer wallets fetched", func(t *testing.T) { - s.Require().NoError(err) - }) - - s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") - - chainARelayerUser, chainBRelayerUser := s.GetRelayerUsers(ctx) - - relayerAStartingBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) - s.Require().NoError(err) - t.Logf("relayer A user starting with balance: %d", relayerAStartingBalance) - - t.Run("register counter party payee", func(t *testing.T) { - multiMsgTxResponse, err = s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.Address, chainARelayerWallet.Address) - s.Require().NoError(err) - s.AssertValidTxResponse(multiMsgTxResponse) - }) - - t.Run("verify counter party payee", func(t *testing.T) { - address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.Address, channelA.Counterparty.ChannelID) - s.Require().NoError(err) - s.Require().Equal(chainARelayerWallet.Address, address) - }) - - t.Run("no incentivized packets", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Empty(packets) - }) - - payPacketFeeMsg := feetypes.NewMsgPayPacketFee(testFee, channelA.PortID, channelA.ChannelID, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), nil) - transferMsg := transfertypes.NewMsgTransfer(channelA.PortID, channelA.ChannelID, transferAmount, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), chainBWallet.Bech32Address(chainB.Config().Bech32Prefix), clienttypes.NewHeight(1, 1000), 0) - resp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, payPacketFeeMsg, transferMsg) - - t.Run("transfer successful", func(t *testing.T) { - s.AssertValidTxResponse(resp) - s.Require().NoError(err) - }) - - t.Run("there should be incentivized packets", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Len(packets, 1) - actualFee := packets[0].PacketFees[0].Fee - - s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) - s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) - s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) - }) - - t.Run("balance should be lowered by sum of recv ack and timeout", func(t *testing.T) { - // The balance should be lowered by the sum of the recv, ack and timeout fees. - actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount - testFee.Total().AmountOf(chainADenom).Int64() - s.Require().Equal(expected, actualBalance) - }) - - t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) - }) - - t.Run("packets are relayed", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Empty(packets) - }) - - t.Run("timeout fee is refunded", func(t *testing.T) { - actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) - s.Require().NoError(err) - - // once the relayer has relayed the packets, the timeout fee should be refunded. - expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() - s.Require().Equal(expected, actualBalance) - }) - - t.Run("relayerA is paid ack and recv fee", func(t *testing.T) { - actualBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) - s.Require().NoError(err) - expected := relayerAStartingBalance + testFee.AckFee.AmountOf(chainADenom).Int64() + testFee.RecvFee.AmountOf(chainADenom).Int64() - s.Require().Equal(expected, actualBalance) - }) -} - -func (s *FeeMiddlewareTestSuite) TestMsgPayPacketFee_SingleSender_TimesOut() { - t := s.T() - ctx := context.TODO() - - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) - chainA, chainB := s.GetChains() - - var ( - chainADenom = chainA.Config().Denom - testFee = testvalues.DefaultFee(chainADenom) - chainATx ibc.Tx - payPacketFeeTxResp sdk.TxResponse - ) - - chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) - chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) - - t.Run("relayer wallets recovered", func(t *testing.T) { - s.Require().NoError(s.RecoverRelayerWallets(ctx, relayer)) - }) - - chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) - t.Run("relayer wallets fetched", func(t *testing.T) { - s.Require().NoError(err) - }) - - _, chainBRelayerUser := s.GetRelayerUsers(ctx) - - t.Run("register counter party payee", func(t *testing.T) { - resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.Address, chainARelayerWallet.Address) - s.Require().NoError(err) - s.AssertValidTxResponse(resp) - }) - - t.Run("verify counter party payee", func(t *testing.T) { - address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.Address, channelA.Counterparty.ChannelID) - s.Require().NoError(err) - s.Require().Equal(chainARelayerWallet.Address, address) - }) - - chainBWalletAmount := ibc.WalletAmount{ - Address: chainBWallet.Bech32Address(chainB.Config().Bech32Prefix), // destination address - Denom: chainA.Config().Denom, - Amount: testvalues.IBCTransferAmount, - } - - t.Run("Send IBC transfer", func(t *testing.T) { - chainATx, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName, chainBWalletAmount, testvalues.ImmediatelyTimeout()) - s.Require().NoError(err) - s.Require().NoError(chainATx.Validate(), "source ibc transfer tx is invalid") - time.Sleep(time.Nanosecond * 1) // want it to timeout immediately - }) - - t.Run("tokens are escrowed", func(t *testing.T) { - actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount - s.Require().Equal(expected, actualBalance) - }) - - t.Run("pay packet fee", func(t *testing.T) { - - packetId := channeltypes.NewPacketId(channelA.PortID, channelA.ChannelID, 1) - packetFee := feetypes.NewPacketFee(testFee, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), nil) - - t.Run("no incentivized packets", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Empty(packets) - }) - - t.Run("should succeed", func(t *testing.T) { - payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet, packetId, packetFee) - s.Require().NoError(err) - s.AssertValidTxResponse(payPacketFeeTxResp) - }) - - t.Run("there should be incentivized packets", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Len(packets, 1) - actualFee := packets[0].PacketFees[0].Fee - - s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) - s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) - s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) - }) - - t.Run("balance should be lowered by sum of recv ack and timeout", func(t *testing.T) { - // The balance should be lowered by the sum of the recv, ack and timeout fees. - actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount - testFee.Total().AmountOf(chainADenom).Int64() - s.Require().Equal(expected, actualBalance) - }) - - }) - - t.Run("start relayer", func(t *testing.T) { - s.StartRelayer(relayer) - }) - - t.Run("packets are relayed", func(t *testing.T) { - packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) - s.Require().NoError(err) - s.Require().Empty(packets) - }) - - t.Run("recv and ack should be refunded", func(t *testing.T) { - actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) - s.Require().NoError(err) - - expected := testvalues.StartingTokenAmount - testFee.TimeoutFee.AmountOf(chainADenom).Int64() - s.Require().Equal(expected, actualBalance) - }) -} - -// feeMiddlewareChannelOptions configures both of the chains to have fee middleware enabled. -func feeMiddlewareChannelOptions() func(options *ibc.CreateChannelOptions) { - return func(opts *ibc.CreateChannelOptions) { - opts.Version = "{\"fee_version\":\"ics29-1\",\"app_version\":\"ics20-1\"}" - opts.DestPortName = "transfer" - opts.SourcePortName = "transfer" - } -} diff --git a/e2e/go.mod b/e2e/go.mod index feb8f7f43c1..cb2b3872974 100644 --- a/e2e/go.mod +++ b/e2e/go.mod @@ -1,61 +1,104 @@ -module e2e +module github.com/cosmos/ibc-go/e2e -go 1.18 - -replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +go 1.19 require ( - github.com/cosmos/cosmos-sdk v0.45.6 - github.com/cosmos/ibc-go/v4 v4.0.0-rc0 - github.com/docker/docker v20.10.17+incompatible - github.com/strangelove-ventures/ibctest v0.0.0-20220713213153-930886d8db30 - github.com/stretchr/testify v1.8.0 - go.uber.org/zap v1.21.0 - google.golang.org/grpc v1.47.0 + github.com/cosmos/cosmos-sdk v0.47.0-rc2 + github.com/cosmos/gogoproto v1.4.6 + github.com/cosmos/ibc-go/v7 v7.0.0-20230120105519-ae96bf3d5ee9 + github.com/cosmos/interchain-accounts v0.4.1-0.20230116203650-08d2a4529a5d + github.com/docker/docker v20.10.19+incompatible + github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230201060741-e0e4e0f9283b + github.com/stretchr/testify v1.8.2 + github.com/tendermint/tendermint v0.37.0-rc2 + go.uber.org/zap v1.23.0 + golang.org/x/mod v0.8.0 + google.golang.org/grpc v1.53.0 ) require ( - filippo.io/edwards25519 v1.0.0-beta.2 // indirect - github.com/99designs/keyring v1.1.6 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect - github.com/DataDog/zstd v1.4.5 // indirect - github.com/Microsoft/go-winio v0.5.1 // indirect - github.com/armon/go-metrics v0.4.0 // indirect + cloud.google.com/go v0.107.0 // indirect + cloud.google.com/go/compute v1.15.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v0.8.0 // indirect + cloud.google.com/go/storage v1.27.0 // indirect + cosmossdk.io/api v0.3.1 // indirect + cosmossdk.io/core v0.3.2 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + cosmossdk.io/errors v1.0.0-beta.7 // indirect + cosmossdk.io/math v1.0.0-beta.6 // indirect + cosmossdk.io/tools/rosetta v0.2.0 // indirect + filippo.io/edwards25519 v1.0.0-rc.1 // indirect + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.1 // indirect + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect + github.com/ChainSafe/go-schnorrkel/1 v0.0.0-00010101000000-000000000000 // indirect + github.com/Microsoft/go-winio v0.6.0 // indirect + github.com/StirlingMarketingGroup/go-namecase v1.0.0 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/avast/retry-go/v4 v4.0.4 // indirect - github.com/benbjohnson/clock v1.1.0 // indirect + github.com/aws/aws-sdk-go v1.40.45 // indirect + github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/speakeasy v0.1.0 // indirect - github.com/btcsuite/btcd v0.22.0-beta // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect + github.com/btcsuite/btcd v0.22.3 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.10 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/confio/ics23/go v0.7.0 // indirect - github.com/cosmos/btcutil v1.0.4 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/confio/ics23/go v0.9.0 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect - github.com/cosmos/iavl v0.17.3 // indirect - github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect - github.com/cosmos/ledger-go v0.9.2 // indirect - github.com/danieljoos/wincred v1.0.2 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/gorocksdb v1.2.0 // indirect + github.com/cosmos/iavl v0.19.5-rc.1 // indirect + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab // indirect + github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/rosetta-sdk-go v0.9.0 // indirect + github.com/creachadair/taskgroup v0.3.2 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgraph-io/badger/v2 v2.2007.2 // indirect - github.com/dgraph-io/ristretto v0.0.3 // indirect + github.com/deckarep/golang-set v1.8.0 // indirect + github.com/decred/base58 v1.0.4 // indirect + github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect - github.com/docker/go-units v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect - github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b // indirect - github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/ethereum/go-ethereum v1.10.21 // indirect + github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-kit/kit v0.12.0 // indirect - github.com/go-kit/log v0.2.0 // indirect + github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect + github.com/go-stack/stack v1.8.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/gogo/gateway v1.1.0 // indirect + github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869 // indirect github.com/gogo/protobuf v1.3.3 // indirect + github.com/golang/glog v1.0.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.3 // indirect - github.com/google/btree v1.0.0 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/orderedcode v0.0.1 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -64,71 +107,107 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.6.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/ipfs/go-cid v0.0.7 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect - github.com/libp2p/go-buffer-pool v0.0.2 // indirect - github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/klauspost/compress v1.15.12 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/lib/pq v1.10.7 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-libp2p-core v0.15.1 // indirect + github.com/libp2p/go-openssl v0.0.7 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect - github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect + github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect + github.com/multiformats/go-base32 v0.0.3 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multiaddr v0.4.1 // indirect + github.com/multiformats/go-multibase v0.0.3 // indirect + github.com/multiformats/go-multicodec v0.4.1 // indirect + github.com/multiformats/go-multihash v0.1.0 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/opencontainers/image-spec v1.1.0-rc2 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/pierrec/xxHash v0.1.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect github.com/rakyll/statik v0.1.7 // indirect - github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect - github.com/regen-network/cosmos-proto v0.3.1 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect - github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect - github.com/sirupsen/logrus v1.8.1 // indirect - github.com/spf13/afero v1.8.2 // indirect + github.com/rs/cors v1.8.2 // indirect + github.com/rs/zerolog v1.28.0 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.5.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.12.0 // indirect - github.com/subosito/gotenv v1.3.0 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect - github.com/tendermint/btcd v0.1.1 // indirect - github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect + github.com/spf13/viper v1.15.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tendermint/tendermint v0.34.19 // indirect - github.com/tendermint/tm-db v0.6.6 // indirect - github.com/zondax/hid v0.9.0 // indirect + github.com/tendermint/tm-db v0.6.7 // indirect + github.com/tidwall/btree v1.5.2 // indirect + github.com/ulikunitz/xz v0.5.8 // indirect + github.com/vedhavyas/go-subkey v1.0.3 // indirect + github.com/zondax/hid v0.9.1 // indirect + github.com/zondax/ledger-go v0.14.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.7.0 // indirect - golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect - golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect - golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect - golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.10 // indirect - golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect - google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect - google.golang.org/protobuf v1.28.0 // indirect - gopkg.in/ini.v1 v1.66.4 // indirect + go.opencensus.io v0.24.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + golang.org/x/crypto v0.4.0 // indirect + golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 // indirect + golang.org/x/net v0.6.0 // indirect + golang.org/x/oauth2 v0.4.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect + golang.org/x/tools v0.6.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.107.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 // indirect + google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + lukechampine.com/blake3 v1.1.6 // indirect lukechampine.com/uint128 v1.1.1 // indirect modernc.org/cc/v3 v3.36.0 // indirect modernc.org/ccgo/v3 v3.16.6 // indirect @@ -139,4 +218,19 @@ require ( modernc.org/sqlite v1.17.3 // indirect modernc.org/strutil v1.1.1 // indirect modernc.org/token v1.0.0 // indirect + nhooyr.io/websocket v1.8.6 // indirect + pgregory.net/rapid v0.5.5 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) + +// TODO: using version v1.0.0 causes a build failure. This is the previous version which compiles successfully. +replace ( + github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d + github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0 + github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 ) + +// uncomment to use the local version of ibc-go, you will need to run `go mod tidy` in e2e directory. +replace github.com/cosmos/ibc-go/v7 => ../ + +replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/e2e/go.sum b/e2e/go.sum index 6d00db2a409..f6490f008d2 100644 --- a/e2e/go.sum +++ b/e2e/go.sum @@ -1,4 +1,3 @@ -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -18,27 +17,23 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/iam v0.8.0 h1:E2osAkZzxI/+8pZcxVLcDtAQx/u+hZXVryUaYQ5O0Kk= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -49,49 +44,53 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= +cosmossdk.io/core v0.3.2 h1:KlQIufpJHJvOs7YLGTZsZcCo1WlkencDXepsr8STKZQ= +cosmossdk.io/core v0.3.2/go.mod h1:CO7vbe+evrBvHc0setFHL/u7nlY7HJGzdRSBkT/sirc= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= +cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/math v1.0.0-beta.6 h1:WF29SiFYNde5eYvqO2kdOM9nYbDb44j3YW5B8M1m9KE= +cosmossdk.io/math v1.0.0-beta.6/go.mod h1:gUVtWwIzfSXqcOT+lBVz2jyjfua8DoBdzRsIyaUAT/8= +cosmossdk.io/tools/rosetta v0.2.0 h1:Ae499UiZ9yPNCXvjOBO/R9I1pksCJfxoqWauEZgA/gs= +cosmossdk.io/tools/rosetta v0.2.0/go.mod h1:3mn8QuE2wLUdTi77/gbDXdFqXZdBdiBJhgAWUTSXPv8= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI= -filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o= -github.com/99designs/keyring v1.1.6 h1:kVDC2uCgVwecxCk+9zoCt2uEL6dt+dfVzMvGgnVcIuM= -github.com/99designs/keyring v1.1.6/go.mod h1:16e0ds7LGQQcT59QqkTg72Hh5ShM51Byv5PEmW6uoRU= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= +filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= +github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= +github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= +github.com/StirlingMarketingGroup/go-namecase v1.0.0 h1:2CzaNtCzc4iNHirR+5ru9OzGg8rQp860gqLBFqRI02Y= +github.com/StirlingMarketingGroup/go-namecase v1.0.0/go.mod h1:ZsoSKcafcAzuBx+sndbxHu/RjDcDTrEdT4UvhniHfio= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= -github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= -github.com/adlio/schema v1.1.13/go.mod h1:L5Z7tw+7lRK1Fnpi/LT/ooCP1elkXn0krMWBQHUhEDE= -github.com/adlio/schema v1.3.0/go.mod h1:51QzxkpeFs6lRY11kPye26IaFPOV+HqEj01t5aXXKfs= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -103,157 +102,159 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.4.0 h1:yCQqn7dwca4ITXb+CbubHmedzaQYHhNhrEXLYUeEe8Q= -github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/avast/retry-go/v4 v4.0.4 h1:38hLf0DsRXh+hOF6HbTni0+5QGTNdw9zbaMD7KAO830= github.com/avast/retry-go/v4 v4.0.4/go.mod h1:HqmLvS2VLdStPCGDFjSuZ9pzlTqVRldCI4w2dO4m1Ms= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.40.45 h1:QN1nsY27ssD/JmW4s83qmSb+uL6DG4GmCDzjmJB4xUI= github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o= -github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= -github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= -github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/btcsuite/btcd v0.22.3 h1:kYNaWFvOw6xvqP0vR20RP1Zq1DVMBxEO8QN5d1/EfNg= +github.com/btcsuite/btcd v0.22.3/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.10 h1:HW3XP9G3mXr0gYPfxCAQLD29u+Ys0uIeotv9RWfnhrM= +github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.10/go.mod h1:5g1oM4Zu3BOaLpsKQ+O8PAv2kNuq+kPcA1VzFbsSqxE= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= -github.com/confio/ics23/go v0.6.6/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= -github.com/confio/ics23/go v0.7.0 h1:00d2kukk7sPoHWL4zZBZwzxnpA2pec1NPdwbSokJ5w8= -github.com/confio/ics23/go v0.7.0/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= -github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.2.1/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= +github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= -github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= -github.com/cosmos/cosmos-sdk v0.45.6 h1:bnYLOcDp0cKWMLeUTTJIttq6xxRep52ulPxXC3BCfuQ= -github.com/cosmos/cosmos-sdk v0.45.6/go.mod h1:bPeeVMEtVvH3y3xAGHVbK+/CZlpaazzh77hG8ZrcJpI= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= +github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.47.0-rc2 h1:BwQC41zQXG/pN9DdLaWzYJrC911St5lYOQIoW4Hf5wQ= +github.com/cosmos/cosmos-sdk v0.47.0-rc2/go.mod h1:e0ZEpY/nhVoXAkijdHPdFOJNOXCddfvyFrFLp2QmCCY= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= -github.com/cosmos/iavl v0.17.3 h1:s2N819a2olOmiauVa0WAhoIJq9EhSXE9HDBAoR9k+8Y= -github.com/cosmos/iavl v0.17.3/go.mod h1:prJoErZFABYZGDHka1R6Oay4z9PrNeFFiMKHDAMOi4w= -github.com/cosmos/ibc-go/v4 v4.0.0-rc0 h1:zeMr6PNE7L300AcGkrMwRvtp62/RpGc7qU1LwhUcPKc= -github.com/cosmos/ibc-go/v4 v4.0.0-rc0/go.mod h1:4LK+uPycPhebJrJ8ebIqvsMEZ0lVRVNTiEyeI9zfB0U= -github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= -github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= -github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= -github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= +github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= +github.com/cosmos/gogoproto v1.4.6 h1:Ee7z15dWJaGlgM2rWrK8N2IX7PQcuccu8oG68jp5RL4= +github.com/cosmos/gogoproto v1.4.6/go.mod h1:VS/ASYmPgv6zkPKLjR9EB91lwbLHOzaGCirmKKhncfI= +github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= +github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= +github.com/cosmos/iavl v0.19.5-rc.1 h1:4PjF2PdScyPbN1WbXpiQU21YtyonnrMU31xN74g8Rkg= +github.com/cosmos/iavl v0.19.5-rc.1/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +github.com/cosmos/interchain-accounts v0.4.1-0.20230116203650-08d2a4529a5d h1:YR8OGEZKf0xveWZ2B/3+r9Q0dbtypXmwwAcolFNY8Fw= +github.com/cosmos/interchain-accounts v0.4.1-0.20230116203650-08d2a4529a5d/go.mod h1:O4DXede5LGQ7ycy4JLjAksuiku6PsFbP2K/x0KgAcuk= +github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= +github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/rosetta-sdk-go v0.9.0 h1:3mj2naR+GUhUXabtb96WWSsPFZDCYkdtp6r0jffgugg= +github.com/cosmos/rosetta-sdk-go v0.9.0/go.mod h1:2v41yXL25xxAXrczVSnbDHcQH9CgildruDlGQGKW/JU= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= +github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= -github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= +github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= +github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/decred/base58 v1.0.4 h1:QJC6B0E0rXOPA8U/kw2rP+qiRJsUaE2Er+pYb3siUeA= +github.com/decred/base58 v1.0.4/go.mod h1:jJswKPEdvpFpvf7dsDvFZyLT22xZ9lWqEByX38oGd9E= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 h1:3GIJYXQDAKpLEFriGFN8SbSffak10UXHGdIcFaMPykY= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0/go.mod h1:3s92l0paYkZoIHuj4X93Teg/HB7eGM9x/zokGw+u4mY= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= -github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= -github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= -github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= -github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= +github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b h1:HBah4D48ypg3J7Np4N+HY/ZR76fx3HEUGxDU6Uk39oQ= -github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= @@ -264,39 +265,32 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= -github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/ethereum/go-ethereum v1.10.21 h1:5lqsEx92ZaZzRyOqBEXux4/UR06m296RGzN3ol3teJY= +github.com/ethereum/go-ethereum v1.10.21/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= -github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -306,34 +300,48 @@ github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgO github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= -github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869 h1:kRpU4zq+Pzh4feET49aEWPOzwQy3U2SsbZEQ7QEcif0= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -342,7 +350,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -361,16 +368,16 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -383,14 +390,16 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -403,20 +412,18 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -427,18 +434,14 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -449,194 +452,210 @@ github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-getter v1.6.2 h1:7jX7xcB+uVCliddZgeKyNxv0xoT7qL5KDtH7rU4IqIk= +github.com/hashicorp/go-getter v1.6.2/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM= -github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg= +github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU= +github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845 h1:H+uM0Bv88eur3ZSsd2NGKg3YIiuXxwxtlN7HjE66UTU= +github.com/icza/dyno v0.0.0-20220812133438-f0b6f8a18845/go.mod h1:c1tRKs5Tx7E2+uHGSyyncziFjvGpgv4H2HrqXeUQ/Uk= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= +github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= -github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= -github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-libp2p-core v0.15.1 h1:0RY+Mi/ARK9DgG1g9xVQLb8dDaaU8tCePMtGALEfBnM= +github.com/libp2p/go-libp2p-core v0.15.1/go.mod h1:agSaboYM4hzB1cWekgVReqV5M4g5M+2eNNejV+1EEhs= +github.com/libp2p/go-openssl v0.0.7 h1:eCAzdLejcNVBzP/iZM9vqHnQm+XyCEbSSIheIPRGNsw= +github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b h1:QrHweqAtyJ9EwCaGHBu1fghwxIPiopAHV06JlXrMHjk= +github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b/go.mod h1:xxLb2ip6sSUts3g1irPVHyk/DGslwQsNOo9I7smJfNU= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= +github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.4.1 h1:Pq37uLx3hsyNlTDir7FZyU8+cFCTqd5y1KiM2IzOutI= +github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= +github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= +github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= +github.com/multiformats/go-multicodec v0.4.1 h1:BSJbf+zpghcZMZrwTYBGwy0CPcVZGWiC72Cp8bBd4R4= +github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA= +github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/jwt v1.2.2/go.mod h1:/xX356yQA6LuXI9xWW7mZNpxgF2mBmGecH+Fj34sP5Q= -github.com/nats-io/jwt/v2 v2.0.3/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nats.go v1.12.1/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s= -github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -644,124 +663,104 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= -github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= -github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/xxHash v0.1.5 h1:n/jBpwTHiER4xYvK3/CdPVnLDPchj8eTJFFLUb4QHBo= +github.com/pierrec/xxHash v0.1.5/go.mod h1:w2waW5Zoa/Wc4Yqe0wgrIYAGKqRMf7czn2HNKXmuL+I= github.com/pierrre/gotestcover v0.0.0-20160517101806-924dca7d15f0/go.mod h1:4xpMLz7RBWyB+ElzHu8Llua96TRCB3YwX+l5EP1wmHk= -github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= -github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= @@ -770,53 +769,48 @@ github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= +github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa h1:0U2s5loxrTy6/VgfVoLuVLFJcURKLH49ie0zSch7gh4= -github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= +github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= +github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -825,24 +819,20 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/strangelove-ventures/ibctest v0.0.0-20220713213153-930886d8db30 h1:pMhrxU1tY220nxDu6t/gb0H30NG+WYiSJFS5OrcxLFs= -github.com/strangelove-ventures/ibctest v0.0.0-20220713213153-930886d8db30/go.mod h1:aWBeEKU4lGfvJ9qO543zJbQGtB2fK2ffrJh6jbtowEM= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/strangelove-ventures/go-subkey v1.0.7 h1:cOP/Lajg3uxV/tvspu0m6+0Cu+DJgygkEAbx/s+f35I= +github.com/strangelove-ventures/go-subkey v1.0.7/go.mod h1:E34izOIEm+sZ1YmYawYRquqBQWeZBjVB4pF7bMuhc1c= +github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230201060741-e0e4e0f9283b h1:TPt4lyXM0XJUrgaO5ufBsAx9jbrNuwvSZvnIBL/5ui0= +github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230201060741-e0e4e0f9283b/go.mod h1:xABocejOFzpH8VR9Se92KE02IqR3cLhzGnl4SHV36Qw= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -850,40 +840,36 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= -github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= -github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= -github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= -github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= -github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= +github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.14/go.mod h1:FrwVm3TvsVicI9Z7FlucHV6Znfd5KBc/Lpp69cCwtk0= -github.com/tendermint/tendermint v0.34.19 h1:y0P1qI5wSa9IRuhKnTDA6IUcOrLi1hXJuALR+R7HFEk= -github.com/tendermint/tendermint v0.34.19/go.mod h1:R5+wgIwSxMdKQcmOaeudL0Cjkr3HDkhpcdum6VeU3R4= -github.com/tendermint/tm-db v0.6.4/go.mod h1:dptYhIpJ2M5kUuenLr+Yyf3zQOv1SgBZcl8/BmWlMBw= -github.com/tendermint/tm-db v0.6.6 h1:EzhaOfR0bdKyATqcd5PNeyeq8r+V4bRPHBfyFdD9kGM= -github.com/tendermint/tm-db v0.6.6/go.mod h1:wP8d49A85B7/erz/r4YbKssKw6ylsO/hKtFk7E1aWZI= -github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= +github.com/tendermint/tendermint v0.37.0-rc2 h1:2n1em+jfbhSv6QnBj8F6KHCpbIzZCB8KgcjidJUQNlY= +github.com/tendermint/tendermint v0.37.0-rc2/go.mod h1:uYQO9DRNPeZROa9X3hJOZpYcVREDC2/HST+EiU5g2+A= +github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= +github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= +github.com/tidwall/btree v1.5.2 h1:5eA83Gfki799V3d3bJo9sWk+yL2LRoTEah3O/SA6/8w= +github.com/tidwall/btree v1.5.2/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= +github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -892,21 +878,14 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= -github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= +github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.0 h1:dlMC7aO8Wss1CxBq2I96kZ69Nh1ligzbs8UWOtq/AsA= +github.com/zondax/ledger-go v0.14.0/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -915,60 +894,43 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= @@ -978,7 +940,9 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE= +golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -992,7 +956,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1004,10 +967,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1022,14 +983,12 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1037,6 +996,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1044,30 +1004,23 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211208012354-db4efeb81f4b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1077,14 +1030,10 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1096,8 +1045,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4= -golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1109,102 +1058,82 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1213,20 +1142,17 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1239,12 +1165,10 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1273,7 +1197,6 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1284,23 +1207,16 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1321,19 +1237,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.107.0 h1:I2SlFjD8ZWabaIFOfeEDg3pf0BHJDh6iYQ1ic3Yu/UU= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1341,6 +1246,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1378,44 +1284,17 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 h1:vArvWooPH749rNHpBGgVl+U9B9dATjiEhJzcWGlovNs= +google.golang.org/genproto v0.0.0-20230202175211-008b39050e57/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1432,26 +1311,16 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1465,23 +1334,24 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1500,9 +1370,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1511,6 +1379,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= +lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.36.0 h1:0kmRkTmqNidmu3c7BNDSdVHCxXCkWLmWmCIVX4LUboo= @@ -1547,10 +1417,13 @@ modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/e2e/relayer/relayer.go b/e2e/relayer/relayer.go new file mode 100644 index 00000000000..7467a9f47f3 --- /dev/null +++ b/e2e/relayer/relayer.go @@ -0,0 +1,58 @@ +package relayer + +import ( + "fmt" + "testing" + + dockerclient "github.com/docker/docker/client" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/relayer" + "go.uber.org/zap" +) + +const ( + Rly = "rly" + Hermes = "hermes" + + cosmosRelayerRepository = "ghcr.io/cosmos/relayer" + cosmosRelayerUser = "100:1000" // docker run -it --rm --entrypoint echo ghcr.io/cosmos/relayer "$(id -u):$(id -g)" +) + +// Config holds configuration values for the relayer used in the tests. +type Config struct { + // Tag is the tag used for the relayer image. + Tag string + // Type specifies the type of relayer that this is. + Type string +} + +// New returns an implementation of ibc.Relayer depending on the provided RelayerType. +func New(t *testing.T, cfg Config, logger *zap.Logger, dockerClient *dockerclient.Client, network string) ibc.Relayer { + switch cfg.Type { + case Rly: + return newCosmosRelayer(t, cfg.Tag, logger, dockerClient, network) + case Hermes: + return newHermesRelayer() + default: + panic(fmt.Sprintf("unknown relayer specified: %s", cfg.Type)) + } +} + +// newCosmosRelayer returns an instance of the go relayer. +// Options are used to allow for relayer version selection and specifying the default processing option. +func newCosmosRelayer(t *testing.T, tag string, logger *zap.Logger, dockerClient *dockerclient.Client, network string) ibc.Relayer { + customImageOption := relayer.CustomDockerImage(cosmosRelayerRepository, tag, cosmosRelayerUser) + relayerProcessingOption := relayer.StartupFlags("-p", "events") // relayer processes via events + + relayerFactory := interchaintest.NewBuiltinRelayerFactory(ibc.CosmosRly, logger, customImageOption, relayerProcessingOption) + + return relayerFactory.Build( + t, dockerClient, network, + ) +} + +// newHermesRelayer returns an instance of the hermes relayer. +func newHermesRelayer() ibc.Relayer { + panic("hermes relayer not yet implemented for interchaintest") +} diff --git a/e2e/scripts/run-compatibility-tests.sh b/e2e/scripts/run-compatibility-tests.sh new file mode 100755 index 00000000000..76ef12a5e5d --- /dev/null +++ b/e2e/scripts/run-compatibility-tests.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -Eeou pipefail + +function run_full_compatibility_suite(){ + local release_branch="${1}" + gh workflow run e2e-compatibility.yaml -f release-branch=${release_branch} + sleep 5 # can take some time for the workflow to appear + run_id="$(gh run list "--workflow=e2e-compatibility.yaml" | grep workflow_dispatch | grep -Eo "[0-9]{9,11}" | head -n 1)" + gh run view ${run_id} --web +} + +RELEASE_BRANCH="${1}" +run_full_compatibility_suite "${RELEASE_BRANCH}" diff --git a/e2e/scripts/run-e2e.sh b/e2e/scripts/run-e2e.sh index 1e0875c099f..e280be0ddee 100755 --- a/e2e/scripts/run-e2e.sh +++ b/e2e/scripts/run-e2e.sh @@ -2,16 +2,11 @@ set -euo pipefail -SUITE="${1}" +ENTRY_POINT="${1}" TEST="${2}" -export SIMD_TAG="${SIMD_TAG:-latest}" -export SIMD_IMAGE="${SIMD_IMAGE:-ibc-go-simd-e2e}" -# In CI, the docker images will be built separately. -# context for building the image is one directory up. -if [ "${CI:-}" != "true" ] -then - (cd ..; docker build . -t "${SIMD_IMAGE}:${SIMD_TAG}") -fi +export CHAIN_A_TAG="${CHAIN_A_TAG:-latest}" +export CHAIN_IMAGE="${CHAIN_IMAGE:-ibc-go-simd}" +export CHAIN_BINARY="${CHAIN_BINARY:-simd}" -go test -v ./ --run ${SUITE} -testify.m ^${TEST}$ +go test -v ./tests/... --run ${ENTRY_POINT} -testify.m ^${TEST}$ diff --git a/e2e/semverutil/semver.go b/e2e/semverutil/semver.go new file mode 100644 index 00000000000..a210289bad4 --- /dev/null +++ b/e2e/semverutil/semver.go @@ -0,0 +1,61 @@ +package semverutil + +import ( + "strings" + + "golang.org/x/mod/semver" +) + +// FeatureReleases contains the combination of versions the feature was released in. +type FeatureReleases struct { + // MajorVersion is the major version in the format including the v. E.g. "v6" + MajorVersion string + // MinorVersions contains a slice of versions including the v and excluding the patch version. E.g. v2.5 + MinorVersions []string +} + +// IsSupported returns whether the version contains the feature. +// This is true if the version is greater than or equal to the major version it was released in +// or is greater than or equal to the list of minor releases it was included in. +func (fr FeatureReleases) IsSupported(versionStr string) bool { + + // in our compatibility tests, our images are in the format of "release-v1.0.x". We want to actually look at + // the "1.0.x" part but we also need this to be a valid version. We can change it to "1.0.0" + // TODO: change the way we provide the ibc-go version. This should be done in a more flexible way such + // as docker labels/metadata instead of the tag, as this will only work for our versioning scheme. + const releasePrefix = "release-" + if strings.HasPrefix(versionStr, releasePrefix) { + versionStr = versionStr[len(releasePrefix):] + versionStr = strings.ReplaceAll(versionStr, "x", "0") + } + + // assume any non-semantic version formatted version supports the feature + // this will be useful during development of the e2e test with the new feature + if !semver.IsValid(versionStr) { + return true + } + + if semverGTE(versionStr, fr.MajorVersion) { + return true + } + + for _, mv := range fr.MinorVersions { + mvMajor, versionStrMajor := semver.Major(mv), semver.Major(versionStr) + + if semverEqual(mvMajor, versionStrMajor) { + return semverGTE(versionStr, mv) + } + } + + return false +} + +// semverGTE returns true if versionA is greater than or equal to versionB. +func semverGTE(versionA, versionB string) bool { + return semver.Compare(versionA, versionB) >= 0 +} + +// semverEqual returns true if versionA is equal to versionB. +func semverEqual(versionA, versionB string) bool { + return semver.Compare(versionA, versionB) == 0 +} diff --git a/e2e/semverutil/semver_test.go b/e2e/semverutil/semver_test.go new file mode 100644 index 00000000000..b2b44f1d318 --- /dev/null +++ b/e2e/semverutil/semver_test.go @@ -0,0 +1,53 @@ +package semverutil_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/ibc-go/e2e/semverutil" +) + +func TestIsSupported(t *testing.T) { + releases := semverutil.FeatureReleases{ + MajorVersion: "v6", + MinorVersions: []string{ + "v2.5", + "v3.4", + "v4.2", + "v5.1", + }, + } + + testCases := []struct { + name string + version string + expSupported bool + }{ + {"non semantic version", "main", true}, + {"non semantic version starts with v", "v", true}, + {"non semantic version", "pr-155", true}, + {"non semantic version", "major.5.1", true}, + {"non semantic version", "1.minor.1", true}, + {"supported semantic version", "v2.5.0", true}, + {"supported semantic version", "v3.4.0", true}, + {"supported semantic version", "v4.2.0", true}, + {"supported semantic version", "v5.1.0", true}, + {"supported semantic version", "v6.0.0", true}, + {"supported semantic version", "v6.1.0", true}, + {"supported semantic version", "v7.1.0", true}, + {"supported semantic version", "v22.5.1", true}, + {"supported semantic version without v", "2.5.0", true}, + {"unsupported semantic version", "v1.5.0", false}, + {"unsupported semantic version", "v2.4.5", false}, + {"unsupported semantic version", "v3.1.0", false}, + {"unsupported semantic version", "v4.1.0", false}, + {"unsupported semantic version", "v5.0.0", false}, + {"unsupported semantic version on partially supported major line", "v2.4.0", false}, + } + + for _, tc := range testCases { + supported := releases.IsSupported(tc.version) + require.Equal(t, tc.expSupported, supported, tc.name) + } +} diff --git a/e2e/testconfig/testconfig.go b/e2e/testconfig/testconfig.go index 46be84e1e58..4cadcee57e2 100644 --- a/e2e/testconfig/testconfig.go +++ b/e2e/testconfig/testconfig.go @@ -1,50 +1,175 @@ package testconfig import ( + "encoding/json" "fmt" "os" + "strings" - "github.com/strangelove-ventures/ibctest/ibc" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module/testutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + tmjson "github.com/tendermint/tendermint/libs/json" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/ibc-go/e2e/relayer" + "github.com/cosmos/ibc-go/e2e/semverutil" + "github.com/cosmos/ibc-go/e2e/testvalues" ) const ( - DefaultSimdImage = "ghcr.io/cosmos/ibc-go-simd-e2e" - SimdImageEnv = "SIMD_IMAGE" - SimdTagEnv = "SIMD_TAG" - GoRelayerTag = "RLY_TAG" + // ChainImageEnv specifies the image that the chains will use. If left unspecified, it will + // default to being determined based on the specified binary. E.g. ghcr.io/cosmos/ibc-go-simd + ChainImageEnv = "CHAIN_IMAGE" + // ChainATagEnv specifies the tag that Chain A will use. + ChainATagEnv = "CHAIN_A_TAG" + // ChainBTagEnv specifies the tag that Chain B will use. If unspecified + // the value will default to the same value as Chain A. + ChainBTagEnv = "CHAIN_B_TAG" + // RelayerTagEnv specifies the relayer version. Defaults to "main" + RelayerTagEnv = "RELAYER_TAG" + // RelayerTypeEnv specifies the type of relayer that should be used. + RelayerTypeEnv = "RELAYER_TYPE" + // ChainBinaryEnv binary is the binary that will be used for both chains. + ChainBinaryEnv = "CHAIN_BINARY" + // ChainUpgradeTagEnv specifies the upgrade version tag + ChainUpgradeTagEnv = "CHAIN_UPGRADE_TAG" + // ChainUpgradePlanEnv specifies the upgrade plan name + ChainUpgradePlanEnv = "CHAIN_UPGRADE_PLAN" - defaultRlyTag = "main" + // defaultBinary is the default binary that will be used by the chains. + defaultBinary = "simd" + // defaultRlyTag is the tag that will be used if no relayer tag is specified. + // all images are here https://github.com/cosmos/relayer/pkgs/container/relayer/versions + defaultRlyTag = "andrew-tendermint_v0.37" // "v2.2.0" + // defaultChainTag is the tag that will be used for the chains if none is specified. + defaultChainTag = "main" + // defaultRelayerType is the default relayer that will be used if none is specified. + defaultRelayerType = relayer.Rly ) +func getChainImage(binary string) string { + if binary == "" { + binary = defaultBinary + } + return fmt.Sprintf("ghcr.io/cosmos/ibc-go-%s", binary) +} + // TestConfig holds various fields used in the E2E tests. type TestConfig struct { - SimdImage string - SimdTag string - RlyTag string + ChainAConfig ChainConfig + ChainBConfig ChainConfig + RelayerConfig relayer.Config + UpgradeTag string + UpgradePlanName string +} + +// ChainConfig holds information about an individual chain used in the tests. +type ChainConfig struct { + Image string + Tag string + Binary string } // FromEnv returns a TestConfig constructed from environment variables. func FromEnv() TestConfig { - simdImage, ok := os.LookupEnv(SimdImageEnv) + chainBinary, ok := os.LookupEnv(ChainBinaryEnv) + if !ok { + chainBinary = defaultBinary + } + + chainATag, ok := os.LookupEnv(ChainATagEnv) + if !ok { + chainATag = defaultChainTag + } + + chainBTag, ok := os.LookupEnv(ChainBTagEnv) if !ok { - simdImage = DefaultSimdImage + chainBTag = chainATag } - simdTag, ok := os.LookupEnv(SimdTagEnv) + chainAImage := getChainImage(chainBinary) + specifiedChainImage, ok := os.LookupEnv(ChainImageEnv) + if ok { + chainAImage = specifiedChainImage + } + chainBImage := chainAImage + + upgradeTag, ok := os.LookupEnv(ChainUpgradeTagEnv) if !ok { - panic(fmt.Sprintf("must specify simd version for test with environment variable [%s]", SimdTagEnv)) + upgradeTag = "" } - rlyTag, ok := os.LookupEnv(GoRelayerTag) + upgradePlan, ok := os.LookupEnv(ChainUpgradePlanEnv) if !ok { - rlyTag = defaultRlyTag + upgradePlan = "" } return TestConfig{ - SimdImage: simdImage, - SimdTag: simdTag, - RlyTag: rlyTag, + ChainAConfig: ChainConfig{ + Image: chainAImage, + Tag: chainATag, + Binary: chainBinary, + }, + ChainBConfig: ChainConfig{ + Image: chainBImage, + Tag: chainBTag, + Binary: chainBinary, + }, + UpgradeTag: upgradeTag, + UpgradePlanName: upgradePlan, + RelayerConfig: GetRelayerConfigFromEnv(), + } +} + +// GetRelayerConfigFromEnv returns the RelayerConfig from present environment variables. +func GetRelayerConfigFromEnv() relayer.Config { + relayerType := strings.TrimSpace(os.Getenv(RelayerTypeEnv)) + if relayerType == "" { + relayerType = defaultRelayerType + } + + rlyTag := strings.TrimSpace(os.Getenv(RelayerTagEnv)) + if rlyTag == "" { + if relayerType == relayer.Rly { + rlyTag = defaultRlyTag + } + if relayerType == relayer.Hermes { + // TODO: set default hermes version + } + } + return relayer.Config{ + Tag: rlyTag, + Type: relayerType, + } +} + +func GetChainATag() string { + chainATag, ok := os.LookupEnv(ChainATagEnv) + if !ok { + panic(fmt.Sprintf("no environment variable specified for %s", ChainATagEnv)) + } + return chainATag +} + +func GetChainBTag() string { + chainBTag, ok := os.LookupEnv(ChainBTagEnv) + if !ok { + return GetChainATag() } + return chainBTag +} + +// IsCI returns true if the tests are running in CI, false is returned +// if the tests are running locally. +// Note: github actions passes a CI env value of true by default to all runners. +func IsCI() bool { + return strings.ToLower(os.Getenv("CI")) == "true" } // ChainOptions stores chain configurations for the chains that will be @@ -62,8 +187,8 @@ type ChainOptionConfiguration func(options *ChainOptions) // These options can be configured by passing configuration functions to E2ETestSuite.GetChains. func DefaultChainOptions() ChainOptions { tc := FromEnv() - chainACfg := newDefaultSimappConfig(tc, "simapp-a", "chain-a", "atoma") - chainBCfg := newDefaultSimappConfig(tc, "simapp-b", "chain-b", "atomb") + chainACfg := newDefaultSimappConfig(tc.ChainAConfig, "simapp-a", "chain-a", "atoma") + chainBCfg := newDefaultSimappConfig(tc.ChainBConfig, "simapp-b", "chain-b", "atomb") return ChainOptions{ ChainAConfig: &chainACfg, ChainBConfig: &chainBCfg, @@ -71,23 +196,175 @@ func DefaultChainOptions() ChainOptions { } // newDefaultSimappConfig creates an ibc configuration for simd. -func newDefaultSimappConfig(tc TestConfig, name, chainID, denom string) ibc.ChainConfig { +func newDefaultSimappConfig(cc ChainConfig, name, chainID, denom string) ibc.ChainConfig { + return ibc.ChainConfig{ Type: "cosmos", Name: name, ChainID: chainID, Images: []ibc.DockerImage{ { - Repository: tc.SimdImage, - Version: tc.SimdTag, + Repository: cc.Image, + Version: cc.Tag, }, }, - Bin: "simd", + Bin: cc.Binary, Bech32Prefix: "cosmos", + CoinType: fmt.Sprint(sdk.GetConfig().GetCoinType()), Denom: denom, GasPrices: fmt.Sprintf("0.00%s", denom), GasAdjustment: 1.3, TrustingPeriod: "508h", NoHostMount: false, + ModifyGenesis: getGenesisModificationFunction(cc), + } +} + +// getGenesisModificationFunction returns a genesis modification function that handles the GenesisState type +// correctly depending on if the govv1beta1 gov module is used or if govv1 is being used. +func getGenesisModificationFunction(cc ChainConfig) func(ibc.ChainConfig, []byte) ([]byte, error) { + version := cc.Tag + + if govGenesisFeatureReleases.IsSupported(version) { + return defaultGovv1ModifyGenesis() + } + + return defaultGovv1Beta1ModifyGenesis() +} + +// govGenesisFeatureReleases represents the releases the governance module genesis +// was upgraded from v1beta1 to v1. +var govGenesisFeatureReleases = semverutil.FeatureReleases{ + MajorVersion: "v7", +} + +// defaultGovv1ModifyGenesis will only modify governance params to ensure the voting period and minimum deposit +// are functional for e2e testing purposes. +func defaultGovv1ModifyGenesis() func(ibc.ChainConfig, []byte) ([]byte, error) { + return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { + genDoc, err := tmtypes.GenesisDocFromJSON(genbz) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into genesis doc: %w", err) + } + + var appState genutiltypes.AppMap + if err := json.Unmarshal(genDoc.AppState, &appState); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into app state: %w", err) + } + + govGenBz, err := modifyGovAppState(chainConfig, appState[govtypes.ModuleName]) + if err != nil { + return nil, err + } + + appState[govtypes.ModuleName] = govGenBz + + genDoc.AppState, err = json.Marshal(appState) + if err != nil { + return nil, err + } + + bz, err := tmjson.MarshalIndent(genDoc, "", " ") + if err != nil { + return nil, err + } + + return bz, nil + } +} + +// defaultGovv1Beta1ModifyGenesis will only modify governance params to ensure the voting period and minimum deposit +// // are functional for e2e testing purposes. +func defaultGovv1Beta1ModifyGenesis() func(ibc.ChainConfig, []byte) ([]byte, error) { + const appStateKey = "app_state" + return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { + genesisDocMap := map[string]interface{}{} + err := json.Unmarshal(genbz, &genesisDocMap) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into genesis doc: %w", err) + } + + appStateMap, ok := genesisDocMap[appStateKey].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("failed to extract to app_state") + } + + govModuleBytes, err := json.Marshal(appStateMap[govtypes.ModuleName]) + if err != nil { + return nil, fmt.Errorf("failed to extract gov genesis bytes: %s", err) + } + + govModuleGenesisBytes, err := modifyGovv1Beta1AppState(chainConfig, govModuleBytes) + if err != nil { + return nil, err + } + + govModuleGenesisMap := map[string]interface{}{} + err = json.Unmarshal(govModuleGenesisBytes, &govModuleGenesisMap) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal gov genesis bytes into map: %w", err) + } + + appStateMap[govtypes.ModuleName] = govModuleGenesisMap + genesisDocMap[appStateKey] = appStateMap + + finalGenesisDocBytes, err := json.MarshalIndent(genesisDocMap, "", " ") + if err != nil { + return nil, err + } + + return finalGenesisDocBytes, nil + } +} + +// modifyGovAppState takes the existing gov app state and marshals it to a govv1 GenesisState. +func modifyGovAppState(chainConfig ibc.ChainConfig, govAppState []byte) ([]byte, error) { + cfg := testutil.MakeTestEncodingConfig() + + cdc := codec.NewProtoCodec(cfg.InterfaceRegistry) + govv1.RegisterInterfaces(cfg.InterfaceRegistry) + + govGenesisState := &govv1.GenesisState{} + + if err := cdc.UnmarshalJSON(govAppState, govGenesisState); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into gov genesis state: %w", err) + } + + if govGenesisState.Params == nil { + govGenesisState.Params = &govv1.Params{} + } + + govGenesisState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(chainConfig.Denom, govv1beta1.DefaultMinDepositTokens)) + vp := testvalues.VotingPeriod + govGenesisState.Params.VotingPeriod = &vp + + govGenBz, err := cdc.MarshalJSON(govGenesisState) + if err != nil { + return nil, fmt.Errorf("failed to marshal gov genesis state: %w", err) } + + return govGenBz, nil +} + +// modifyGovv1Beta1AppState takes the existing gov app state and marshals it to a govv1beta1 GenesisState. +func modifyGovv1Beta1AppState(chainConfig ibc.ChainConfig, govAppState []byte) ([]byte, error) { + cfg := testutil.MakeTestEncodingConfig() + + cdc := codec.NewProtoCodec(cfg.InterfaceRegistry) + govv1beta1.RegisterInterfaces(cfg.InterfaceRegistry) + + govGenesisState := &govv1beta1.GenesisState{} + if err := cdc.UnmarshalJSON(govAppState, govGenesisState); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into govv1beta1 genesis state: %w", err) + } + + govGenesisState.DepositParams.MinDeposit = sdk.NewCoins(sdk.NewCoin(chainConfig.Denom, govv1beta1.DefaultMinDepositTokens)) + govGenesisState.VotingParams.VotingPeriod = testvalues.VotingPeriod + + govGenBz, err := cdc.MarshalJSON(govGenesisState) + if err != nil { + return nil, fmt.Errorf("failed to marshal gov genesis state: %w", err) + } + + return govGenBz, nil } diff --git a/e2e/tests/core/03-connection/connection_test.go b/e2e/tests/core/03-connection/connection_test.go new file mode 100644 index 00000000000..1694bc2e0ce --- /dev/null +++ b/e2e/tests/core/03-connection/connection_test.go @@ -0,0 +1,132 @@ +package connection + +import ( + "context" + "fmt" + "strconv" + "strings" + "testing" + "time" + + paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestConnectionTestSuite(t *testing.T) { + suite.Run(t, new(ConnectionTestSuite)) +} + +type ConnectionTestSuite struct { + testsuite.E2ETestSuite +} + +// QueryMaxExpectedTimePerBlockParam queries the on-chain max expected time per block param for 03-connection +func (s *ConnectionTestSuite) QueryMaxExpectedTimePerBlockParam(ctx context.Context, chain ibc.Chain) uint64 { + queryClient := s.GetChainGRCPClients(chain).ParamsQueryClient + res, err := queryClient.Params(ctx, ¶msproposaltypes.QueryParamsRequest{ + Subspace: ibcexported.ModuleName, + Key: string(connectiontypes.KeyMaxExpectedTimePerBlock), + }) + s.Require().NoError(err) + + // removing additional strings that are used for amino + delay := strings.ReplaceAll(res.Param.Value, "\"", "") + time, err := strconv.ParseUint(delay, 10, 64) + s.Require().NoError(err) + + return time +} + +// TestMaxExpectedTimePerBlockParam tests changing the MaxExpectedTimePerBlock param using a governance proposal +func (s *ConnectionTestSuite) TestMaxExpectedTimePerBlockParam() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, chainB := s.GetChains() + + chainBDenom := chainB.Config().Denom + chainAIBCToken := testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("ensure delay is set to the default of 30 seconds", func(t *testing.T) { + expectedDelay := uint64(30 * time.Second) + delay := s.QueryMaxExpectedTimePerBlockParam(ctx, chainA) + s.Require().Equal(expectedDelay, delay) + }) + + t.Run("change the delay to 60 seconds", func(t *testing.T) { + delay := fmt.Sprintf(`"%d"`, 1*time.Minute) + changes := []paramsproposaltypes.ParamChange{ + paramsproposaltypes.NewParamChange(ibcexported.ModuleName, string(connectiontypes.KeyMaxExpectedTimePerBlock), delay), + } + + proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes) + s.ExecuteGovProposal(ctx, chainA, chainAWallet, proposal) + }) + + t.Run("validate the param was successfully changed", func(t *testing.T) { + expectedDelay := uint64(1 * time.Minute) + delay := s.QueryMaxExpectedTimePerBlockParam(ctx, chainA) + s.Require().Equal(expectedDelay, delay) + }) + + t.Run("ensure packets can be received, send from chainB to chainA", func(t *testing.T) { + t.Run("send tokens from chainB to chainA", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferAmount(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) + + actualBalance, err := chainA.GetBalance(ctx, chainAAddress, chainAIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("stop relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + }) + }) +} + +// transferChannelOptions configures both of the chains to have non-incentivized transfer channels. +func transferChannelOptions() func(options *ibc.CreateChannelOptions) { + return func(opts *ibc.CreateChannelOptions) { + opts.Version = transfertypes.Version + opts.SourcePortName = transfertypes.PortID + opts.DestPortName = transfertypes.PortID + } +} diff --git a/e2e/tests/core/client_test.go b/e2e/tests/core/client_test.go new file mode 100644 index 00000000000..03b1b9566cd --- /dev/null +++ b/e2e/tests/core/client_test.go @@ -0,0 +1,121 @@ +package e2e + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestClientTestSuite(t *testing.T) { + suite.Run(t, new(ClientTestSuite)) +} + +type ClientTestSuite struct { + testsuite.E2ETestSuite +} + +// Status queries the current status of the client +func (s *ClientTestSuite) Status(ctx context.Context, chain ibc.Chain, clientID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.ClientStatus(ctx, &clienttypes.QueryClientStatusRequest{ + ClientId: clientID, + }) + if err != nil { + return "", err + } + + return res.Status, nil +} + +func (s *ClientTestSuite) TestClientUpdateProposal_Succeeds() { + t := s.T() + ctx := context.TODO() + + var ( + pathName string + relayer ibc.Relayer + subjectClientID string + substituteClientID string + badTrustingPeriod = time.Duration(time.Second) + ) + + t.Run("create substitute client with correct trusting period", func(t *testing.T) { + relayer, _ = s.SetupChainsRelayerAndChannel(ctx) + + // TODO: update when client identifier created is accessible + // currently assumes first client is 07-tendermint-0 + substituteClientID = clienttypes.FormatClientIdentifier(ibcexported.Tendermint, 0) + + // TODO: replace with better handling of path names + pathName = fmt.Sprintf("%s-path-%d", s.T().Name(), 0) + pathName = strings.ReplaceAll(pathName, "/", "-") + }) + + chainA, chainB := s.GetChains() + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + t.Run("create subject client with bad trusting period", func(t *testing.T) { + createClientOptions := ibc.CreateClientOptions{ + TrustingPeriod: badTrustingPeriod.String(), + } + + s.SetupClients(ctx, relayer, createClientOptions) + + // TODO: update when client identifier created is accessible + // currently assumes second client is 07-tendermint-1 + subjectClientID = clienttypes.FormatClientIdentifier(ibcexported.Tendermint, 1) + }) + + time.Sleep(badTrustingPeriod) + + t.Run("update substitute client", func(t *testing.T) { + s.UpdateClients(ctx, relayer, pathName) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("check status of each client", func(t *testing.T) { + t.Run("substitute should be active", func(t *testing.T) { + status, err := s.Status(ctx, chainA, substituteClientID) + s.Require().NoError(err) + s.Require().Equal(ibcexported.Active.String(), status) + }) + + t.Run("subject should be expired", func(t *testing.T) { + status, err := s.Status(ctx, chainA, subjectClientID) + s.Require().NoError(err) + s.Require().Equal(ibcexported.Expired.String(), status) + }) + }) + + t.Run("pass client update proposal", func(t *testing.T) { + proposal := clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subjectClientID, substituteClientID) + s.ExecuteGovProposal(ctx, chainA, chainAWallet, proposal) + }) + + t.Run("check status of each client", func(t *testing.T) { + t.Run("substitute should be active", func(t *testing.T) { + status, err := s.Status(ctx, chainA, substituteClientID) + s.Require().NoError(err) + s.Require().Equal(ibcexported.Active.String(), status) + }) + + t.Run("subject should be active", func(t *testing.T) { + status, err := s.Status(ctx, chainA, subjectClientID) + s.Require().NoError(err) + s.Require().Equal(ibcexported.Active.String(), status) + }) + }) +} diff --git a/e2e/tests/interchain_accounts/base_test.go b/e2e/tests/interchain_accounts/base_test.go new file mode 100644 index 00000000000..53c5384be31 --- /dev/null +++ b/e2e/tests/interchain_accounts/base_test.go @@ -0,0 +1,421 @@ +package interchain_accounts + +import ( + "context" + "testing" + "time" + + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + "golang.org/x/mod/semver" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/gogoproto/proto" + + "github.com/cosmos/ibc-go/e2e/testconfig" + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestInterchainAccountsTestSuite(t *testing.T) { + suite.Run(t, new(InterchainAccountsTestSuite)) +} + +type InterchainAccountsTestSuite struct { + testsuite.E2ETestSuite +} + +// getICAVersion returns the version which should be used in the MsgRegisterAccount broadcast from the +// controller chain. +func getICAVersion(chainAVersion, chainBVersion string) string { + chainBIsGreaterThanOrEqualToChainA := semver.Compare(chainAVersion, chainBVersion) <= 0 + if chainBIsGreaterThanOrEqualToChainA { + // allow version to be specified by the controller chain + return "" + } + // explicitly set the version string because the host chain might not yet support incentivized channels. + return icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) +} + +// RegisterInterchainAccount will attempt to register an interchain account on the counterparty chain. +func (s *InterchainAccountsTestSuite) RegisterInterchainAccount(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, msgRegisterAccount *controllertypes.MsgRegisterInterchainAccount) { + txResp, err := s.BroadcastMessages(ctx, chain, user, msgRegisterAccount) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) +} + +func (s *InterchainAccountsTestSuite) TestMsgSendTx_SuccessfulTransfer() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + // setup 2 accounts: controller account on chain A, a second chain B account. + // host account will be created when the ICA is registered + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + controllerAddress := controllerAccount.FormattedAddress() + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + var hostAccount string + + t.Run("broadcast MsgRegisterInterchainAccount", func(t *testing.T) { + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, controllerAddress, version) + + txResp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("verify interchain account", func(t *testing.T) { + var err error + hostAccount, err = s.QueryInterchainAccount(ctx, chainA, controllerAddress, ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(hostAccount)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + }) + + t.Run("interchain account executes a bank transfer on behalf of the corresponding owner account", func(t *testing.T) { + t.Run("fund interchain account wallet", func(t *testing.T) { + // fund the host account so it has some $$ to send + err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: hostAccount, + Amount: testvalues.StartingTokenAmount, + Denom: chainB.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("broadcast MsgSendTx", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + msgSend := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + cdc := testsuite.Codec() + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData) + + resp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + msgSendTx, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + }) +} + +func (s *InterchainAccountsTestSuite) TestMsgSendTx_FailedTransfer_InsufficientFunds() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + // setup 2 accounts: controller account on chain A, a second chain B account. + // host account will be created when the ICA is registered + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + controllerAddress := controllerAccount.FormattedAddress() + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + var hostAccount string + + t.Run("broadcast MsgRegisterInterchainAccount", func(t *testing.T) { + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, controllerAddress, version) + + txResp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("verify interchain account", func(t *testing.T) { + var err error + hostAccount, err = s.QueryInterchainAccount(ctx, chainA, controllerAddress, ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(hostAccount)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + }) + + t.Run("fail to execute bank transfer over ICA", func(t *testing.T) { + t.Run("verify empty host wallet", func(t *testing.T) { + hostAccountBalance, err := chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) + s.Require().NoError(err) + s.Require().Zero(hostAccountBalance) + }) + + t.Run("broadcast MsgSendTx", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + msgSend := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + cdc := testsuite.Codec() + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(controllerAddress, ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData) + + txResp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + msgSendTx, + ) + + s.AssertValidTxResponse(txResp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) + }) + + t.Run("verify balance is the same", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + }) +} + +func (s *InterchainAccountsTestSuite) TestMsgSubmitTx_SuccessfulTransfer_AfterReopeningICA() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + // setup 2 accounts: controller account on chain A, a second chain B account. + // host account will be created when the ICA is registered + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + controllerAddress := controllerAccount.FormattedAddress() + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + var ( + portID string + hostAccount string + + initialChannelID = "channel-1" + channelIDAfterReopening = "channel-2" + ) + + t.Run("register interchain account", func(t *testing.T) { + var err error + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterInterchainAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, controllerAddress, version) + s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterInterchainAccount) + portID, err = icatypes.NewControllerPortID(controllerAddress) + s.Require().NoError(err) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("verify interchain account", func(t *testing.T) { + var err error + hostAccount, err = s.QueryInterchainAccount(ctx, chainA, controllerAddress, ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(hostAccount)) + + _, err = s.QueryChannel(ctx, chainA, portID, initialChannelID) + s.Require().NoError(err) + }) + + // stop the relayer to let the submit tx message time out + t.Run("stop relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + }) + + t.Run("submit tx message with bank transfer message times out", func(t *testing.T) { + t.Run("fund interchain account wallet", func(t *testing.T) { + // fund the host account account so it has some $$ to send + err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: hostAccount, + Amount: testvalues.StartingTokenAmount, + Denom: chainB.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("broadcast MsgSendTx", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + msgSend := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + cdc := testsuite.Codec() + + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(controllerAddress, ibctesting.FirstConnectionID, uint64(1), packetData) + + resp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + msgSendTx, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + // this sleep is to allow the packet to timeout + time.Sleep(1 * time.Second) + }) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("verify channel is closed due to timeout on ordered channel", func(t *testing.T) { + channel, err := s.QueryChannel(ctx, chainA, portID, initialChannelID) + s.Require().NoError(err) + + s.Require().Equal(channeltypes.CLOSED, channel.State, "the channel was not in an expected state") + }) + + t.Run("verify tokens not transferred", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + + // re-register interchain account to reopen the channel now that it has been closed due to timeout + // on an ordered channel + t.Run("register interchain account", func(t *testing.T) { + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterInterchainAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, controllerAddress, version) + s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterInterchainAccount) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) + }) + + t.Run("verify new channel is now open and interchain account has been reregistered with the same portID", func(t *testing.T) { + channel, err := s.QueryChannel(ctx, chainA, portID, channelIDAfterReopening) + s.Require().NoError(err) + + s.Require().Equal(channeltypes.OPEN, channel.State, "the channel was not in an expected state") + }) + + t.Run("broadcast MsgSendTx", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + msgSend := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + cdc := testsuite.Codec() + + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(controllerAddress, ibctesting.FirstConnectionID, uint64(5*time.Minute), packetData) + + resp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + msgSendTx, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + // time for the packet to be relayed + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB)) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) +} diff --git a/e2e/tests/interchain_accounts/gov_test.go b/e2e/tests/interchain_accounts/gov_test.go new file mode 100644 index 00000000000..2f572c35596 --- /dev/null +++ b/e2e/tests/interchain_accounts/gov_test.go @@ -0,0 +1,117 @@ +package interchain_accounts + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/gogoproto/proto" + + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestInterchainAccountsGovTestSuite(t *testing.T) { + suite.Run(t, new(InterchainAccountsGovTestSuite)) +} + +type InterchainAccountsGovTestSuite struct { + testsuite.E2ETestSuite +} + +func (s *InterchainAccountsGovTestSuite) TestInterchainAccountsGovIntegration() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBAccount.FormattedAddress() + + govModuleAddress, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, chainA) + s.Require().NoError(err) + s.Require().NotNil(govModuleAddress) + + t.Run("execute proposal for MsgRegisterInterchainAccount", func(t *testing.T) { + version := icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, govModuleAddress.String(), version) + s.ExecuteGovProposalV1(ctx, msgRegisterAccount, chainA, controllerAccount, 1) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) + + var interchainAccAddr string + t.Run("verify interchain account registration success", func(t *testing.T) { + var err error + interchainAccAddr, err = s.QueryInterchainAccount(ctx, chainA, govModuleAddress.String(), ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAccAddr)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + }) + + t.Run("interchain account executes a bank transfer on behalf of the corresponding owner account", func(t *testing.T) { + t.Run("fund interchain account wallet", func(t *testing.T) { + // fund the host account, so it has some $$ to send + err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: interchainAccAddr, + Amount: testvalues.StartingTokenAmount, + Denom: chainB.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("execute proposal for MsgSendTx", func(t *testing.T) { + msgBankSend := &banktypes.MsgSend{ + FromAddress: interchainAccAddr, + ToAddress: chainBAddress, + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + cdc := testsuite.Codec() + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgBankSend}) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(govModuleAddress.String(), ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData) + s.ExecuteGovProposalV1(ctx, msgSendTx, chainA, controllerAccount, 2) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, interchainAccAddr, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + }) +} diff --git a/e2e/tests/interchain_accounts/groups_test.go b/e2e/tests/interchain_accounts/groups_test.go new file mode 100644 index 00000000000..7e7ad72324d --- /dev/null +++ b/e2e/tests/interchain_accounts/groups_test.go @@ -0,0 +1,214 @@ +package interchain_accounts + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + grouptypes "github.com/cosmos/cosmos-sdk/x/group" + "github.com/cosmos/gogoproto/proto" + interchaintest "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +const ( + // DefaultGroupMemberWeight is the members voting weight. + // A group members weight is used in the sum of `YES` votes required to meet a decision policy threshold. + DefaultGroupMemberWeight = "1" + + // DefaultGroupThreshold is the minimum weighted sum of `YES` votes that must be met or + // exceeded for a proposal to succeed. + DefaultGroupThreshold = "1" + + // DefaultMetadata defines a resusable metadata string for testing purposes + DefaultMetadata = "custom metadata" + + // DefaultMinExecutionPeriod is the minimum duration after the proposal submission + // where members can start sending MsgExec. This means that the window for + // sending a MsgExec transaction is: + // `[ submission + min_execution_period ; submission + voting_period + max_execution_period]` + // where max_execution_period is a app-specific config, defined in the keeper. + // If not set, min_execution_period will default to 0. + DefaultMinExecutionPeriod = time.Duration(0) + + // DefaultVotingPeriod is the duration from submission of a proposal to the end of voting period + // Within this times votes can be submitted with MsgVote. + DefaultVotingPeriod = time.Minute + + // InitialGroupID is the first group ID generated by x/group + InitialGroupID = 1 + + // InitialProposalID is the first group proposal ID generated by x/group + InitialProposalID = 1 +) + +func TestInterchainAccountsGroupsTestSuite(t *testing.T) { + suite.Run(t, new(InterchainAccountsGroupsTestSuite)) +} + +type InterchainAccountsGroupsTestSuite struct { + testsuite.E2ETestSuite +} + +func (s *InterchainAccountsGroupsTestSuite) QueryGroupPolicyAddress(ctx context.Context, chain ibc.Chain) string { + queryClient := s.GetChainGRCPClients(chain).GroupsQueryClient + res, err := queryClient.GroupPoliciesByGroup(ctx, &grouptypes.QueryGroupPoliciesByGroupRequest{ + GroupId: InitialGroupID, // always use the initial group id + }) + s.Require().NoError(err) + + return res.GroupPolicies[0].Address +} + +func (s *InterchainAccountsGroupsTestSuite) TestInterchainAccountsGroupsIntegration() { + t := s.T() + ctx := context.TODO() + + var ( + groupPolicyAddr string + interchainAccAddr string + err error + ) + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + t.Run("create group with new threshold decision policy", func(t *testing.T) { + members := []grouptypes.MemberRequest{ + { + Address: chainAAddress, + Weight: DefaultGroupMemberWeight, + }, + } + + decisionPolicy := grouptypes.NewThresholdDecisionPolicy(DefaultGroupThreshold, DefaultVotingPeriod, DefaultMinExecutionPeriod) + msgCreateGroupWithPolicy, err := grouptypes.NewMsgCreateGroupWithPolicy(chainAAddress, members, DefaultMetadata, DefaultMetadata, true, decisionPolicy) + s.Require().NoError(err) + + txResp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, msgCreateGroupWithPolicy) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("submit proposal for MsgRegisterInterchainAccount", func(t *testing.T) { + groupPolicyAddr = s.QueryGroupPolicyAddress(ctx, chainA) + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, groupPolicyAddr, icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID)) + + msgSubmitProposal, err := grouptypes.NewMsgSubmitProposal(groupPolicyAddr, []string{chainAAddress}, []sdk.Msg{msgRegisterAccount}, DefaultMetadata, grouptypes.Exec_EXEC_UNSPECIFIED, "e2e groups proposal: for MsgRegisterInterchainAccount", "e2e groups proposal: for MsgRegisterInterchainAccount") + s.Require().NoError(err) + + txResp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, msgSubmitProposal) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("vote and exec proposal", func(t *testing.T) { + msgVote := &grouptypes.MsgVote{ + ProposalId: InitialProposalID, + Voter: chainAAddress, + Option: grouptypes.VOTE_OPTION_YES, + Exec: grouptypes.Exec_EXEC_TRY, + } + + txResp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, msgVote) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("verify interchain account registration success", func(t *testing.T) { + interchainAccAddr, err = s.QueryInterchainAccount(ctx, chainA, groupPolicyAddr, ibctesting.FirstConnectionID) + s.Require().NotEmpty(interchainAccAddr) + s.Require().NoError(err) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) // 1 transfer (created by default), 1 interchain-accounts + }) + + t.Run("fund interchain account wallet", func(t *testing.T) { + err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: interchainAccAddr, + Amount: testvalues.StartingTokenAmount, + Denom: chainB.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("submit proposal for MsgSendTx", func(t *testing.T) { + msgBankSend := &banktypes.MsgSend{ + FromAddress: interchainAccAddr, + ToAddress: chainBAddress, + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + cdc := testsuite.Codec() + + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgBankSend}) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSubmitTx := controllertypes.NewMsgSendTx(groupPolicyAddr, ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData) + msgSubmitProposal, err := grouptypes.NewMsgSubmitProposal(groupPolicyAddr, []string{chainAAddress}, []sdk.Msg{msgSubmitTx}, DefaultMetadata, grouptypes.Exec_EXEC_UNSPECIFIED, "e2e groups proposal: for MsgRegisterInterchainAccount", "e2e groups proposal: for MsgRegisterInterchainAccount") + s.Require().NoError(err) + + txResp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, msgSubmitProposal) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("vote and exec proposal", func(t *testing.T) { + msgVote := &grouptypes.MsgVote{ + ProposalId: InitialProposalID + 1, + Voter: chainAAddress, + Option: grouptypes.VOTE_OPTION_YES, + Exec: grouptypes.Exec_EXEC_TRY, + } + + txResp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, msgVote) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") + + balance, err := chainB.GetBalance(ctx, chainBAddress, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + + balance, err = chainB.GetBalance(ctx, interchainAccAddr, chainB.Config().Denom) + s.Require().NoError(err) + + expected = testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, balance) + }) +} diff --git a/e2e/tests/interchain_accounts/incentivized_test.go b/e2e/tests/interchain_accounts/incentivized_test.go new file mode 100644 index 00000000000..e91f52eb439 --- /dev/null +++ b/e2e/tests/interchain_accounts/incentivized_test.go @@ -0,0 +1,393 @@ +package interchain_accounts + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/gogoproto/proto" + interchaintest "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/testconfig" + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestIncentivizedInterchainAccountsTestSuite(t *testing.T) { + suite.Run(t, new(IncentivizedInterchainAccountsTestSuite)) +} + +type IncentivizedInterchainAccountsTestSuite struct { + InterchainAccountsTestSuite +} + +// RegisterCounterPartyPayee broadcasts a MsgRegisterCounterpartyPayee message. +func (s *IncentivizedInterchainAccountsTestSuite) RegisterCounterPartyPayee(ctx context.Context, chain *cosmos.CosmosChain, + user ibc.Wallet, portID, channelID, relayerAddr, counterpartyPayeeAddr string, +) (sdk.TxResponse, error) { + msg := feetypes.NewMsgRegisterCounterpartyPayee(portID, channelID, relayerAddr, counterpartyPayeeAddr) + return s.BroadcastMessages(ctx, chain, user, msg) +} + +func (s *IncentivizedInterchainAccountsTestSuite) TestMsgSendTx_SuccessfulBankSend_Incentivized() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + interchainAcc = "" + testFee = testvalues.DefaultFee(chainADenom) + ) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + t.Run("relayer wallets fetched", func(t *testing.T) { + s.Require().NoError(err) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + chainARelayerUser, chainBRelayerUser := s.GetRelayerUsers(ctx) + relayerAStartingBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + t.Logf("relayer A user starting with balance: %d", relayerAStartingBalance) + + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + t.Run("broadcast MsgRegisterInterchainAccount", func(t *testing.T) { + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, controllerAccount.FormattedAddress(), version) + + txResp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + var channelOutput ibc.ChannelOutput + t.Run("verify interchain account", func(t *testing.T) { + var err error + interchainAcc, err = s.QueryInterchainAccount(ctx, chainA, controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAcc)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + + // interchain accounts channel at index: 0 + channelOutput = channels[0] + + s.Require().NoError(test.WaitForBlocks(ctx, 2, chainA, chainB)) + }) + + t.Run("execute interchain account bank send through controller", func(t *testing.T) { + t.Run("fund interchain account wallet on host chainB", func(t *testing.T) { + // fund the interchain account so it has some $$ to send + err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: interchainAcc, + Amount: testvalues.StartingTokenAmount, + Denom: chainB.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("register counterparty payee", func(t *testing.T) { + resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelOutput.Counterparty.PortID, channelOutput.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(resp) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelOutput.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("stop relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + }) + + t.Run("broadcast incentivized MsgSendTx", func(t *testing.T) { + msgPayPacketFee := &feetypes.MsgPayPacketFee{ + Fee: testvalues.DefaultFee(chainADenom), + SourcePortId: channelOutput.PortID, + SourceChannelId: channelOutput.ChannelID, + Signer: controllerAccount.FormattedAddress(), + } + + msgSend := &banktypes.MsgSend{ + FromAddress: interchainAcc, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + cdc := testsuite.Codec() + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData) + + resp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgPayPacketFee, msgSendTx) + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB)) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("verify interchain account sent tokens", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, interchainAcc, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + + t.Run("timeout fee is refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, controllerAccount) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + + t.Run("relayerA is paid ack and recv fee", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + + expected := relayerAStartingBalance + testFee.AckFee.AmountOf(chainADenom).Int64() + testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + }) +} + +func (s *IncentivizedInterchainAccountsTestSuite) TestMsgSendTx_FailedBankSend_Incentivized() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + interchainAcc = "" + testFee = testvalues.DefaultFee(chainADenom) + ) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + t.Run("relayer wallets fetched", func(t *testing.T) { + s.Require().NoError(err) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + chainARelayerUser, chainBRelayerUser := s.GetRelayerUsers(ctx) + relayerAStartingBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + t.Logf("relayer A user starting with balance: %d", relayerAStartingBalance) + + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + t.Run("broadcast MsgRegisterInterchainAccount", func(t *testing.T) { + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, controllerAccount.FormattedAddress(), version) + + txResp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + var channelOutput ibc.ChannelOutput + t.Run("verify interchain account", func(t *testing.T) { + var err error + interchainAcc, err = s.QueryInterchainAccount(ctx, chainA, controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAcc)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + + // interchain accounts channel at index: 0 + channelOutput = channels[0] + + s.Require().NoError(test.WaitForBlocks(ctx, 2, chainA, chainB)) + }) + + t.Run("execute interchain account bank send through controller", func(t *testing.T) { + t.Run("register counterparty payee", func(t *testing.T) { + resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelOutput.Counterparty.PortID, channelOutput.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(resp) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelOutput.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("stop relayer", func(t *testing.T) { + err := relayer.StopRelayer(ctx, s.GetRelayerExecReporter()) + s.Require().NoError(err) + }) + + t.Run("broadcast incentivized MsgSendTx", func(t *testing.T) { + msgPayPacketFee := &feetypes.MsgPayPacketFee{ + Fee: testvalues.DefaultFee(chainADenom), + SourcePortId: channelOutput.PortID, + SourceChannelId: channelOutput.ChannelID, + Signer: controllerAccount.FormattedAddress(), + } + + msgSend := &banktypes.MsgSend{ + FromAddress: interchainAcc, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + cdc := testsuite.Codec() + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData) + + resp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgPayPacketFee, msgSendTx) + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB)) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("verify interchain account did not send tokens", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, interchainAcc, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, balance, "tokens should not have been sent as interchain account was not funded") + }) + + t.Run("timeout fee is refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, controllerAccount) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + + t.Run("relayerA is paid ack and recv fee", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + + expected := relayerAStartingBalance + testFee.AckFee.AmountOf(chainADenom).Int64() + testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + }) +} diff --git a/e2e/tests/interchain_accounts/intertx_incentivized_test.go b/e2e/tests/interchain_accounts/intertx_incentivized_test.go new file mode 100644 index 00000000000..a76ae1a990c --- /dev/null +++ b/e2e/tests/interchain_accounts/intertx_incentivized_test.go @@ -0,0 +1,355 @@ +package interchain_accounts + +import ( + "context" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types" + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/testvalues" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestIncentivizedInterTxTestSuite(t *testing.T) { + suite.Run(t, new(IncentivizedInterTxTestSuite)) +} + +type IncentivizedInterTxTestSuite struct { + InterTxTestSuite +} + +func (s *IncentivizedInterTxTestSuite) TestMsgSubmitTx_SuccessfulBankSend_Incentivized() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + interchainAcc = "" + testFee = testvalues.DefaultFee(chainADenom) + ) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + t.Run("relayer wallets fetched", func(t *testing.T) { + s.Require().NoError(err) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + chainARelayerUser, chainBRelayerUser := s.GetRelayerUsers(ctx) + relayerAStartingBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + t.Logf("relayer A user starting with balance: %d", relayerAStartingBalance) + + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + t.Run("register interchain account", func(t *testing.T) { + version := "" // allow app to handle the version as appropriate. + msgRegisterAccount := intertxtypes.NewMsgRegisterAccount(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, version) + err := s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + var channelOutput ibc.ChannelOutput + t.Run("verify interchain account", func(t *testing.T) { + var err error + interchainAcc, err = s.QueryInterchainAccountLegacy(ctx, chainA, controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAcc)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + + // interchain accounts channel at index: 0 + channelOutput = channels[0] + }) + + t.Run("execute interchain account bank send through controller", func(t *testing.T) { + t.Run("fund interchain account wallet on host chainB", func(t *testing.T) { + // fund the interchain account so it has some $$ to send + err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: interchainAcc, + Amount: testvalues.StartingTokenAmount, + Denom: chainB.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("register counterparty payee", func(t *testing.T) { + resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelOutput.Counterparty.PortID, channelOutput.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(resp) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelOutput.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("stop relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + }) + + t.Run("broadcast incentivized MsgSubmitTx", func(t *testing.T) { + msgPayPacketFee := &feetypes.MsgPayPacketFee{ + Fee: testvalues.DefaultFee(chainADenom), + SourcePortId: channelOutput.PortID, + SourceChannelId: channelOutput.ChannelID, + Signer: controllerAccount.FormattedAddress(), + } + + msgSend := &banktypes.MsgSend{ + FromAddress: interchainAcc, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + msgSubmitTx, err := intertxtypes.NewMsgSubmitTx(msgSend, ibctesting.FirstConnectionID, controllerAccount.FormattedAddress()) + s.Require().NoError(err) + + resp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgPayPacketFee, msgSubmitTx) + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB)) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("verify interchain account sent tokens", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, interchainAcc, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + + t.Run("timeout fee is refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, controllerAccount) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + + t.Run("relayerA is paid ack and recv fee", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + + expected := relayerAStartingBalance + testFee.AckFee.AmountOf(chainADenom).Int64() + testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + }) +} + +func (s *IncentivizedInterTxTestSuite) TestMsgSubmitTx_FailedBankSend_Incentivized() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + interchainAcc = "" + testFee = testvalues.DefaultFee(chainADenom) + ) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + t.Run("relayer wallets fetched", func(t *testing.T) { + s.Require().NoError(err) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + chainARelayerUser, chainBRelayerUser := s.GetRelayerUsers(ctx) + relayerAStartingBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + t.Logf("relayer A user starting with balance: %d", relayerAStartingBalance) + + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + t.Run("register interchain account", func(t *testing.T) { + version := "" // allow app to handle the version as appropriate. + msgRegisterAccount := intertxtypes.NewMsgRegisterAccount(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, version) + err := s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + var channelOutput ibc.ChannelOutput + t.Run("verify interchain account", func(t *testing.T) { + var err error + interchainAcc, err = s.QueryInterchainAccountLegacy(ctx, chainA, controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAcc)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + + // interchain accounts channel at index: 0 + channelOutput = channels[0] + + s.Require().NoError(test.WaitForBlocks(ctx, 2, chainA, chainB)) + }) + + t.Run("execute interchain account bank send through controller", func(t *testing.T) { + t.Run("register counterparty payee", func(t *testing.T) { + resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelOutput.Counterparty.PortID, channelOutput.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(resp) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelOutput.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("stop relayer", func(t *testing.T) { + err := relayer.StopRelayer(ctx, s.GetRelayerExecReporter()) + s.Require().NoError(err) + }) + + t.Run("broadcast incentivized MsgSubmitTx", func(t *testing.T) { + msgPayPacketFee := &feetypes.MsgPayPacketFee{ + Fee: testvalues.DefaultFee(chainADenom), + SourcePortId: channelOutput.PortID, + SourceChannelId: channelOutput.ChannelID, + Signer: controllerAccount.FormattedAddress(), + } + + msgSend := &banktypes.MsgSend{ + FromAddress: interchainAcc, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + msgSubmitTx, err := intertxtypes.NewMsgSubmitTx(msgSend, ibctesting.FirstConnectionID, controllerAccount.FormattedAddress()) + s.Require().NoError(err) + + resp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgPayPacketFee, msgSubmitTx) + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB)) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelOutput.PortID, channelOutput.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("verify interchain account did not send tokens", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, interchainAcc, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, balance, "tokens should not have been sent as interchain account was not funded") + }) + + t.Run("timeout fee is refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, controllerAccount) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + + t.Run("relayerA is paid ack and recv fee", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + + expected := relayerAStartingBalance + testFee.AckFee.AmountOf(chainADenom).Int64() + testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + }) +} diff --git a/e2e/tests/interchain_accounts/intertx_test.go b/e2e/tests/interchain_accounts/intertx_test.go new file mode 100644 index 00000000000..b70d539a55b --- /dev/null +++ b/e2e/tests/interchain_accounts/intertx_test.go @@ -0,0 +1,215 @@ +package interchain_accounts + +import ( + "context" + "testing" + + "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types" + + "github.com/cosmos/ibc-go/e2e/testconfig" + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestInterTxTestSuite(t *testing.T) { + suite.Run(t, new(InterTxTestSuite)) +} + +type InterTxTestSuite struct { + testsuite.E2ETestSuite +} + +// RegisterInterchainAccount will attempt to register an interchain account on the counterparty chain. +func (s *InterTxTestSuite) RegisterInterchainAccount(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, msgRegisterAccount *intertxtypes.MsgRegisterAccount) error { + txResp, err := s.BroadcastMessages(ctx, chain, user, msgRegisterAccount) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + return err +} + +func (s *InterTxTestSuite) TestMsgSubmitTx_SuccessfulTransfer() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + // setup 2 accounts: controller account on chain A, a second chain B account. + // host account will be created when the ICA is registered + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + var hostAccount string + + t.Run("register interchain account", func(t *testing.T) { + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterAccount := intertxtypes.NewMsgRegisterAccount(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, version) + err := s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("verify interchain account", func(t *testing.T) { + var err error + hostAccount, err = s.QueryInterchainAccountLegacy(ctx, chainA, controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(hostAccount)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + }) + + t.Run("interchain account executes a bank transfer on behalf of the corresponding owner account", func(t *testing.T) { + t.Run("fund interchain account wallet", func(t *testing.T) { + // fund the host account account so it has some $$ to send + err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: hostAccount, + Amount: testvalues.StartingTokenAmount, + Denom: chainB.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("broadcast MsgSubmitTx", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + msgSend := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + // assemble submitMessage tx for intertx + msgSubmitTx, err := intertxtypes.NewMsgSubmitTx( + msgSend, + ibctesting.FirstConnectionID, + controllerAccount.FormattedAddress(), + ) + s.Require().NoError(err) + + // broadcast submitMessage tx from controller account on chain A + // this message should trigger the sending of an ICA packet over channel-1 (channel created between controller and host) + // this ICA packet contains the assembled bank transfer message from above, which will be executed by the host account on the host chain. + resp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + msgSubmitTx, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + }) +} + +func (s *InterTxTestSuite) TestMsgSubmitTx_FailedTransfer_InsufficientFunds() { + t := s.T() + ctx := context.TODO() + + // setup relayers and connection-0 between two chains + // channel-0 is a transfer channel but it will not be used in this test case + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + // setup 2 accounts: controller account on chain A, a second chain B account. + // host account will be created when the ICA is registered + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + var hostAccount string + + t.Run("register interchain account", func(t *testing.T) { + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterAccount := intertxtypes.NewMsgRegisterAccount(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, version) + err := s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("verify interchain account", func(t *testing.T) { + var err error + hostAccount, err = s.QueryInterchainAccountLegacy(ctx, chainA, controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(hostAccount)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + }) + + t.Run("fail to execute bank transfer over ICA", func(t *testing.T) { + t.Run("verify empty host wallet", func(t *testing.T) { + hostAccountBalance, err := chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) + s.Require().NoError(err) + s.Require().Zero(hostAccountBalance) + }) + + t.Run("broadcast MsgSubmitTx", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + transferMsg := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + // assemble submitMessage tx for intertx + submitMsg, err := intertxtypes.NewMsgSubmitTx( + transferMsg, + ibctesting.FirstConnectionID, + controllerAccount.FormattedAddress(), + ) + s.Require().NoError(err) + + // broadcast submitMessage tx from controller account on chain A + // this message should trigger the sending of an ICA packet over channel-1 (channel created between controller and host) + // this ICA packet contains the assembled bank transfer message from above, which will be executed by the host account on the host chain. + resp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + submitMsg, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + }) + + t.Run("verify balance is the same", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + }) +} diff --git a/e2e/tests/transfer/authz_test.go b/e2e/tests/transfer/authz_test.go new file mode 100644 index 00000000000..2906122d0d0 --- /dev/null +++ b/e2e/tests/transfer/authz_test.go @@ -0,0 +1,329 @@ +package transfer + +import ( + "context" + "testing" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/authz" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" +) + +func TestAuthzTransferTestSuite(t *testing.T) { + suite.Run(t, new(AuthzTransferTestSuite)) +} + +type AuthzTransferTestSuite struct { + testsuite.E2ETestSuite +} + +func (suite *AuthzTransferTestSuite) TestAuthz_MsgTransfer_Succeeds() { + t := suite.T() + ctx := context.TODO() + + relayer, channelA := suite.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, chainB := suite.GetChains() + + chainADenom := chainA.Config().Denom + + granterWallet := suite.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + granterAddress := granterWallet.FormattedAddress() + + granteeWallet := suite.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + granteeAddress := granteeWallet.FormattedAddress() + + receiverWallet := suite.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + receiverWalletAddress := receiverWallet.FormattedAddress() + + t.Run("start relayer", func(t *testing.T) { + suite.StartRelayer(relayer) + }) + + // createMsgGrantFn initializes a TransferAuthorization and broadcasts a MsgGrant message. + createMsgGrantFn := func(t *testing.T) { + transferAuth := transfertypes.TransferAuthorization{ + Allocations: []transfertypes.Allocation{ + { + SourcePort: channelA.PortID, + SourceChannel: channelA.ChannelID, + SpendLimit: sdk.NewCoins(sdk.NewCoin(chainADenom, sdk.NewInt(testvalues.StartingTokenAmount))), + AllowList: []string{receiverWalletAddress}, + }, + }, + } + + protoAny, err := codectypes.NewAnyWithValue(&transferAuth) + suite.Require().NoError(err) + + msgGrant := &authz.MsgGrant{ + Granter: granterAddress, + Grantee: granteeAddress, + Grant: authz.Grant{ + Authorization: protoAny, + // no expiration + Expiration: nil, + }, + } + + resp, err := suite.BroadcastMessages(context.TODO(), chainA, granterWallet, msgGrant) + suite.AssertValidTxResponse(resp) + suite.Require().NoError(err) + } + + // verifyGrantFn returns a test function which asserts chainA has a grant authorization + // with the given spend limit. + verifyGrantFn := func(expectedLimit int64) func(t *testing.T) { + return func(t *testing.T) { + grantAuths, err := suite.QueryGranterGrants(ctx, chainA, granterAddress) + + suite.Require().NoError(err) + suite.Require().Len(grantAuths, 1) + grantAuthorization := grantAuths[0] + + transferAuth := suite.extractTransferAuthorizationFromGrantAuthorization(grantAuthorization) + expectedSpendLimit := sdk.NewCoins(sdk.NewCoin(chainADenom, sdk.NewInt(expectedLimit))) + suite.Require().Equal(expectedSpendLimit, transferAuth.Allocations[0].SpendLimit) + } + } + + t.Run("broadcast MsgGrant", createMsgGrantFn) + + t.Run("broadcast MsgExec for ibc MsgTransfer", func(t *testing.T) { + transferMsg := transfertypes.MsgTransfer{ + SourcePort: channelA.PortID, + SourceChannel: channelA.ChannelID, + Token: testvalues.DefaultTransferAmount(chainADenom), + Sender: granterAddress, + Receiver: receiverWalletAddress, + TimeoutHeight: suite.GetTimeoutHeight(ctx, chainB), + } + + protoAny, err := codectypes.NewAnyWithValue(&transferMsg) + suite.Require().NoError(err) + + msgExec := &authz.MsgExec{ + Grantee: granteeAddress, + Msgs: []*codectypes.Any{protoAny}, + } + + resp, err := suite.BroadcastMessages(context.TODO(), chainA, granteeWallet, msgExec) + suite.AssertValidTxResponse(resp) + suite.Require().NoError(err) + }) + + t.Run("verify granter wallet amount", func(t *testing.T) { + actualBalance, err := suite.GetChainANativeBalance(ctx, granterWallet) + suite.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + suite.Require().Equal(expected, actualBalance) + }) + + suite.Require().NoError(test.WaitForBlocks(context.TODO(), 10, chainB)) + + t.Run("verify receiver wallet amount", func(t *testing.T) { + chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) + actualBalance, err := chainB.GetBalance(ctx, receiverWalletAddress, chainBIBCToken.IBCDenom()) + suite.Require().NoError(err) + suite.Require().Equal(testvalues.IBCTransferAmount, actualBalance) + }) + + t.Run("granter grant spend limit reduced", verifyGrantFn(testvalues.StartingTokenAmount-testvalues.IBCTransferAmount)) + + t.Run("re-initialize MsgGrant", createMsgGrantFn) + + t.Run("granter grant was reinitialized", verifyGrantFn(testvalues.StartingTokenAmount)) + + t.Run("revoke access", func(t *testing.T) { + msgRevoke := authz.MsgRevoke{ + Granter: granterAddress, + Grantee: granteeAddress, + MsgTypeUrl: transfertypes.TransferAuthorization{}.MsgTypeURL(), + } + + resp, err := suite.BroadcastMessages(context.TODO(), chainA, granterWallet, &msgRevoke) + suite.AssertValidTxResponse(resp) + suite.Require().NoError(err) + }) + + t.Run("exec unauthorized MsgTransfer", func(t *testing.T) { + transferMsg := transfertypes.MsgTransfer{ + SourcePort: channelA.PortID, + SourceChannel: channelA.ChannelID, + Token: testvalues.DefaultTransferAmount(chainADenom), + Sender: granterAddress, + Receiver: receiverWalletAddress, + TimeoutHeight: suite.GetTimeoutHeight(ctx, chainB), + } + + protoAny, err := codectypes.NewAnyWithValue(&transferMsg) + suite.Require().NoError(err) + + msgExec := &authz.MsgExec{ + Grantee: granteeAddress, + Msgs: []*codectypes.Any{protoAny}, + } + + resp, err := suite.BroadcastMessages(context.TODO(), chainA, granteeWallet, msgExec) + suite.Require().NotEqual(0, resp.Code) + suite.Require().Contains(resp.RawLog, authz.ErrNoAuthorizationFound.Error()) + suite.Require().NoError(err) + }) +} + +func (suite *AuthzTransferTestSuite) TestAuthz_InvalidTransferAuthorizations() { + t := suite.T() + ctx := context.TODO() + + relayer, channelA := suite.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, chainB := suite.GetChains() + + chainADenom := chainA.Config().Denom + + granterWallet := suite.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + granterAddress := granterWallet.FormattedAddress() + + granteeWallet := suite.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + granteeAddress := granteeWallet.FormattedAddress() + + receiverWallet := suite.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + receiverWalletAddress := receiverWallet.FormattedAddress() + + t.Run("start relayer", func(t *testing.T) { + suite.StartRelayer(relayer) + }) + + const spendLimit = 1000 + + t.Run("broadcast MsgGrant", func(t *testing.T) { + transferAuth := transfertypes.TransferAuthorization{ + Allocations: []transfertypes.Allocation{ + { + SourcePort: channelA.PortID, + SourceChannel: channelA.ChannelID, + SpendLimit: sdk.NewCoins(sdk.NewCoin(chainADenom, sdk.NewInt(spendLimit))), + AllowList: []string{receiverWalletAddress}, + }, + }, + } + + protoAny, err := codectypes.NewAnyWithValue(&transferAuth) + suite.Require().NoError(err) + + msgGrant := &authz.MsgGrant{ + Granter: granterAddress, + Grantee: granteeAddress, + Grant: authz.Grant{ + Authorization: protoAny, + // no expiration + Expiration: nil, + }, + } + + resp, err := suite.BroadcastMessages(context.TODO(), chainA, granterWallet, msgGrant) + suite.AssertValidTxResponse(resp) + suite.Require().NoError(err) + }) + + t.Run("exceed spend limit", func(t *testing.T) { + const invalidSpendAmount = spendLimit + 1 + + t.Run("broadcast MsgExec for ibc MsgTransfer", func(t *testing.T) { + transferMsg := transfertypes.MsgTransfer{ + SourcePort: channelA.PortID, + SourceChannel: channelA.ChannelID, + Token: sdk.Coin{Denom: chainADenom, Amount: sdk.NewInt(invalidSpendAmount)}, + Sender: granterAddress, + Receiver: receiverWalletAddress, + TimeoutHeight: suite.GetTimeoutHeight(ctx, chainB), + } + + protoAny, err := codectypes.NewAnyWithValue(&transferMsg) + suite.Require().NoError(err) + + msgExec := &authz.MsgExec{ + Grantee: granteeAddress, + Msgs: []*codectypes.Any{protoAny}, + } + + resp, err := suite.BroadcastMessages(context.TODO(), chainA, granteeWallet, msgExec) + suite.Require().NotEqual(0, resp.Code) + suite.Require().Contains(resp.RawLog, sdkerrors.ErrInsufficientFunds.Error()) + suite.Require().NoError(err) + }) + + t.Run("verify granter wallet amount", func(t *testing.T) { + actualBalance, err := suite.GetChainANativeBalance(ctx, granterWallet) + suite.Require().NoError(err) + suite.Require().Equal(testvalues.StartingTokenAmount, actualBalance) + }) + + t.Run("verify receiver wallet amount", func(t *testing.T) { + chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) + actualBalance, err := chainB.GetBalance(ctx, receiverWalletAddress, chainBIBCToken.IBCDenom()) + suite.Require().NoError(err) + suite.Require().Equal(int64(0), actualBalance) + }) + + t.Run("granter grant spend limit unchanged", func(t *testing.T) { + grantAuths, err := suite.QueryGranterGrants(ctx, chainA, granterAddress) + + suite.Require().NoError(err) + suite.Require().Len(grantAuths, 1) + grantAuthorization := grantAuths[0] + + transferAuth := suite.extractTransferAuthorizationFromGrantAuthorization(grantAuthorization) + expectedSpendLimit := sdk.NewCoins(sdk.NewCoin(chainADenom, sdk.NewInt(spendLimit))) + suite.Require().Equal(expectedSpendLimit, transferAuth.Allocations[0].SpendLimit) + }) + }) + + t.Run("send funds to invalid address", func(t *testing.T) { + invalidWallet := suite.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + invalidWalletAddress := invalidWallet.FormattedAddress() + + t.Run("broadcast MsgExec for ibc MsgTransfer", func(t *testing.T) { + transferMsg := transfertypes.MsgTransfer{ + SourcePort: channelA.PortID, + SourceChannel: channelA.ChannelID, + Token: sdk.Coin{Denom: chainADenom, Amount: sdk.NewInt(spendLimit)}, + Sender: granterAddress, + Receiver: invalidWalletAddress, + TimeoutHeight: suite.GetTimeoutHeight(ctx, chainB), + } + + protoAny, err := codectypes.NewAnyWithValue(&transferMsg) + suite.Require().NoError(err) + + msgExec := &authz.MsgExec{ + Grantee: granteeAddress, + Msgs: []*codectypes.Any{protoAny}, + } + + resp, err := suite.BroadcastMessages(context.TODO(), chainA, granteeWallet, msgExec) + suite.Require().NotEqual(0, resp.Code) + suite.Require().Contains(resp.RawLog, sdkerrors.ErrInvalidAddress.Error()) + suite.Require().NoError(err) + }) + }) +} + +// extractTransferAuthorizationFromGrantAuthorization extracts a TransferAuthorization from the given +// GrantAuthorization. +func (suite *AuthzTransferTestSuite) extractTransferAuthorizationFromGrantAuthorization(grantAuth *authz.GrantAuthorization) *transfertypes.TransferAuthorization { + cfg := testsuite.EncodingConfig() + var authorization authz.Authorization + err := cfg.InterfaceRegistry.UnpackAny(grantAuth.Authorization, &authorization) + suite.Require().NoError(err) + + transferAuth, ok := authorization.(*transfertypes.TransferAuthorization) + suite.Require().True(ok) + return transferAuth +} diff --git a/e2e/tests/transfer/base_test.go b/e2e/tests/transfer/base_test.go new file mode 100644 index 00000000000..d858bc04058 --- /dev/null +++ b/e2e/tests/transfer/base_test.go @@ -0,0 +1,472 @@ +package transfer + +import ( + "context" + "strconv" + "testing" + "time" + + paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/semverutil" + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestTransferTestSuite(t *testing.T) { + suite.Run(t, new(TransferTestSuite)) +} + +type TransferTestSuite struct { + testsuite.E2ETestSuite +} + +// QueryTransferSendEnabledParam queries the on-chain send enabled param for the transfer module +func (s *TransferTestSuite) QueryTransferSendEnabledParam(ctx context.Context, chain ibc.Chain) bool { + queryClient := s.GetChainGRCPClients(chain).ParamsQueryClient + res, err := queryClient.Params(ctx, ¶msproposaltypes.QueryParamsRequest{ + Subspace: transfertypes.StoreKey, + Key: string(transfertypes.KeySendEnabled), + }) + s.Require().NoError(err) + + enabled, err := strconv.ParseBool(res.Param.Value) + s.Require().NoError(err) + + return enabled +} + +// QueryTransferReceiveEnabledParam queries the on-chain receive enabled param for the transfer module +func (s *TransferTestSuite) QueryTransferReceiveEnabledParam(ctx context.Context, chain ibc.Chain) bool { + queryClient := s.GetChainGRCPClients(chain).ParamsQueryClient + res, err := queryClient.Params(ctx, ¶msproposaltypes.QueryParamsRequest{ + Subspace: transfertypes.StoreKey, + Key: string(transfertypes.KeyReceiveEnabled), + }) + s.Require().NoError(err) + + enabled, err := strconv.ParseBool(res.Param.Value) + s.Require().NoError(err) + + return enabled +} + +// TestMsgTransfer_Succeeds_Nonincentivized will test sending successful IBC transfers from chainA to chainB. +// The transfer will occur over a basic transfer channel (non incentivized) and both native and non-native tokens +// will be sent forwards and backwards in the IBC transfer timeline (both chains will act as source and receiver chains). +func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, chainB := s.GetChains() + + chainADenom := chainA.Config().Denom + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("non-native IBC token transfer from chainB to chainA, receiver is source of tokens", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferAmount(chainBIBCToken.IBCDenom()), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + s.Require().Equal(int64(0), actualBalance) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainB, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) + + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, actualBalance) + }) +} + +// TestMsgTransfer_Fails_InvalidAddress attempts to send an IBC transfer to an invalid address and ensures +// that the tokens on the sending chain are unescrowed. +func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, chainB := s.GetChains() + + chainADenom := chainA.Config().Denom + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("native IBC token transfer from chainA to invalid address", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, testvalues.InvalidAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + }) + + t.Run("token transfer amount unescrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, actualBalance) + }) +} + +func (s *TransferTestSuite) TestMsgTransfer_Timeout_Nonincentivized() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, _ := s.GetChains() + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + chainBWalletAmount := ibc.WalletAmount{ + Address: chainBWallet.FormattedAddress(), // destination address + Denom: chainA.Config().Denom, + Amount: testvalues.IBCTransferAmount, + } + + t.Run("IBC transfer packet timesout", func(t *testing.T) { + tx, err := chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName(), chainBWalletAmount, ibc.TransferOptions{Timeout: testvalues.ImmediatelyTimeout()}) + s.Require().NoError(err) + s.Require().NoError(tx.Validate(), "source ibc transfer tx is invalid") + time.Sleep(time.Nanosecond * 1) // want it to timeout immediately + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("ensure escrowed tokens have been refunded to sender due to timeout", func(t *testing.T) { + // ensure destination address did not receive any tokens + bal, err := s.GetChainBNativeBalance(ctx, chainBWallet) + s.Require().NoError(err) + s.Require().Equal(testvalues.StartingTokenAmount, bal) + + // ensure that the sender address has been successfully refunded the full amount + bal, err = s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + s.Require().Equal(testvalues.StartingTokenAmount, bal) + }) +} + +// TestSendEnabledParam tests changing ics20 SendEnabled parameter +func (s *TransferTestSuite) TestSendEnabledParam() { + t := s.T() + ctx := context.TODO() + + _, channelA := s.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, chainB := s.GetChains() + + chainADenom := chainA.Config().Denom + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("ensure transfer sending is enabled", func(t *testing.T) { + enabled := s.QueryTransferSendEnabledParam(ctx, chainA) + s.Require().True(enabled) + }) + + t.Run("ensure packets can be sent", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("change send enabled parameter to disabled", func(t *testing.T) { + changes := []paramsproposaltypes.ParamChange{ + paramsproposaltypes.NewParamChange(transfertypes.StoreKey, string(transfertypes.KeySendEnabled), "false"), + } + + proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes) + s.ExecuteGovProposal(ctx, chainA, chainAWallet, proposal) + }) + + t.Run("ensure transfer params are disabled", func(t *testing.T) { + enabled := s.QueryTransferSendEnabledParam(ctx, chainA) + s.Require().False(enabled) + }) + + t.Run("ensure ics20 transfer fails", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.Require().NoError(err) + s.Require().Equal(transfertypes.ErrSendDisabled.ABCICode(), transferTxResp.Code) + }) +} + +// TestReceiveEnabledParam tests changing ics20 ReceiveEnabled parameter +func (s *TransferTestSuite) TestReceiveEnabledParam() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, chainB := s.GetChains() + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + var ( + chainBDenom = chainB.Config().Denom + chainAIBCToken = testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) // IBC token sent to chainA + + chainAAddress = chainAWallet.FormattedAddress() + chainBAddress = chainBWallet.FormattedAddress() + ) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("ensure transfer receive is enabled", func(t *testing.T) { + enabled := s.QueryTransferReceiveEnabledParam(ctx, chainA) + s.Require().True(enabled) + }) + + t.Run("ensure packets can be received, send from chainB to chainA", func(t *testing.T) { + t.Run("send from chainB to chainA", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferAmount(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) + + actualBalance, err := chainA.GetBalance(ctx, chainAAddress, chainAIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("stop relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + }) + }) + + t.Run("change receive enabled parameter to disabled ", func(t *testing.T) { + changes := []paramsproposaltypes.ParamChange{ + paramsproposaltypes.NewParamChange(transfertypes.StoreKey, string(transfertypes.KeyReceiveEnabled), "false"), + } + + proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes) + s.ExecuteGovProposal(ctx, chainA, chainAWallet, proposal) + }) + + t.Run("ensure transfer params are disabled", func(t *testing.T) { + enabled := s.QueryTransferReceiveEnabledParam(ctx, chainA) + s.Require().False(enabled) + }) + + t.Run("ensure ics20 transfer fails", func(t *testing.T) { + t.Run("send from chainB to chainA", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferAmount(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - (testvalues.IBCTransferAmount * 2) // second send + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("tokens are unescrowed in failed acknowledgement", func(t *testing.T) { + actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount // only first send marked + s.Require().Equal(expected, actualBalance) + }) + }) +} + +// memoFeatureReleases represents the releases the memo field was released in. +var memoFeatureReleases = semverutil.FeatureReleases{ + MajorVersion: "v6", + MinorVersions: []string{ + "v2.5", + "v3.4", + "v4.2", + "v5.1", + }, +} + +// This can be used to test sending with a transfer packet with a memo given different combinations of +// ibc-go versions. +// +// TestMsgTransfer_WithMemo will test sending IBC transfers from chainA to chainB +// If the chains contain a version of FungibleTokenPacketData with memo, both send and receive should succeed. +// If one of the chains contains a version of FungibleTokenPacketData without memo, then receiving a packet with +// memo should fail in that chain +func (s *TransferTestSuite) TestMsgTransfer_WithMemo() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, transferChannelOptions()) + chainA, chainB := s.GetChains() + + chainADenom := chainA.Config().Denom + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + chainAVersion := chainA.Config().Images[0].Version + chainBVersion := chainB.Config().Images[0].Version + + t.Run("IBC token transfer with memo from chainA to chainB", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "memo") + s.Require().NoError(err) + + if memoFeatureReleases.IsSupported(chainAVersion) { + s.AssertValidTxResponse(transferTxResp) + } else { + s.Require().Equal(uint32(2), transferTxResp.Code) + s.Require().Contains(transferTxResp.RawLog, "errUnknownField") + } + }) + + if !memoFeatureReleases.IsSupported(chainAVersion) { + // transfer not sent, end test + return + } + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) + + t.Run("packets relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + if memoFeatureReleases.IsSupported(chainBVersion) { + s.Require().Equal(testvalues.IBCTransferAmount, actualBalance) + } else { + s.Require().Equal(int64(0), actualBalance) + } + }) +} + +// transferChannelOptions configures both of the chains to have non-incentivized transfer channels. +func transferChannelOptions() func(options *ibc.CreateChannelOptions) { + return func(opts *ibc.CreateChannelOptions) { + opts.Version = transfertypes.Version + opts.SourcePortName = transfertypes.PortID + opts.DestPortName = transfertypes.PortID + } +} diff --git a/e2e/tests/transfer/incentivized_test.go b/e2e/tests/transfer/incentivized_test.go new file mode 100644 index 00000000000..7da6e7b5c5d --- /dev/null +++ b/e2e/tests/transfer/incentivized_test.go @@ -0,0 +1,742 @@ +package transfer + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/ibc-go/e2e/testvalues" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" +) + +type IncentivizedTransferTestSuite struct { + TransferTestSuite +} + +func TestIncentivizedTransferTestSuite(t *testing.T) { + suite.Run(t, new(IncentivizedTransferTestSuite)) +} + +func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_AsyncSingleSender_Succeeds() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + testFee = testvalues.DefaultFee(chainADenom) + chainATx ibc.Tx + payPacketFeeTxResp sdk.TxResponse + ) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + t.Run("relayer wallets fetched", func(t *testing.T) { + s.Require().NoError(err) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + _, chainBRelayerUser := s.GetRelayerUsers(ctx) + + t.Run("register counterparty payee", func(t *testing.T) { + resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(resp) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelA.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + walletAmount := ibc.WalletAmount{ + Address: chainAWallet.FormattedAddress(), // destination address + Denom: chainADenom, + Amount: testvalues.IBCTransferAmount, + } + + t.Run("send IBC transfer", func(t *testing.T) { + chainATx, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName(), walletAmount, ibc.TransferOptions{}) + s.Require().NoError(err) + s.Require().NoError(chainATx.Validate(), "chain-a ibc transfer tx is invalid") + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - walletAmount.Amount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("pay packet fee", func(t *testing.T) { + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + packetId := channeltypes.NewPacketID(channelA.PortID, channelA.ChannelID, chainATx.Packet.Sequence) + packetFee := feetypes.NewPacketFee(testFee, chainAWallet.FormattedAddress(), nil) + + t.Run("should succeed", func(t *testing.T) { + payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet, packetId, packetFee) + s.Require().NoError(err) + s.AssertValidTxResponse(payPacketFeeTxResp) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("balance should be lowered by sum of recv ack and timeout", func(t *testing.T) { + // The balance should be lowered by the sum of the recv, ack and timeout fees. + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - walletAmount.Amount - testFee.Total().AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("timeout fee is refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + // once the relayer has relayed the packets, the timeout fee should be refunded. + expected := testvalues.StartingTokenAmount - walletAmount.Amount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) +} + +func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_InvalidReceiverAccount() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + testFee = testvalues.DefaultFee(chainADenom) + payPacketFeeTxResp sdk.TxResponse + ) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + t.Run("relayer wallets fetched", func(t *testing.T) { + s.Require().NoError(err) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + _, chainBRelayerUser := s.GetRelayerUsers(ctx) + + t.Run("register counterparty payee", func(t *testing.T) { + resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(resp) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelA.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + transferAmount := testvalues.DefaultTransferAmount(chainADenom) + + t.Run("send IBC transfer", func(t *testing.T) { + transferMsg := transfertypes.NewMsgTransfer(channelA.PortID, channelA.ChannelID, transferAmount, chainAWallet.FormattedAddress(), testvalues.InvalidAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + txResp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, transferMsg) + // this message should be successful, as receiver account is not validated on the sending chain. + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - transferAmount.Amount.Int64() + s.Require().Equal(expected, actualBalance) + }) + + t.Run("pay packet fee", func(t *testing.T) { + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + packetId := channeltypes.NewPacketID(channelA.PortID, channelA.ChannelID, 1) + packetFee := feetypes.NewPacketFee(testFee, chainAWallet.FormattedAddress(), nil) + + t.Run("should succeed", func(t *testing.T) { + payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet, packetId, packetFee) + s.Require().NoError(err) + s.AssertValidTxResponse(payPacketFeeTxResp) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("balance should be lowered by sum of recv, ack and timeout", func(t *testing.T) { + // The balance should be lowered by the sum of the recv, ack and timeout fees. + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - transferAmount.Amount.Int64() - testFee.Total().AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + t.Run("timeout fee and transfer amount refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + // once the relayer has relayed the packets, the timeout fee should be refunded. + // the address was invalid so the amount sent should be unescrowed. + expected := testvalues.StartingTokenAmount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance, "the amount sent and timeout fee should have been refunded as there was an invalid receiver address provided") + }) +} + +func (s *IncentivizedTransferTestSuite) TestMultiMsg_MsgPayPacketFeeSingleSender() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) + + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + testFee = testvalues.DefaultFee(chainADenom) + multiMsgTxResponse sdk.TxResponse + ) + + transferAmount := testvalues.DefaultTransferAmount(chainA.Config().Denom) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + t.Run("relayer wallets fetched", func(t *testing.T) { + s.Require().NoError(err) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + chainARelayerUser, chainBRelayerUser := s.GetRelayerUsers(ctx) + + relayerAStartingBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + t.Logf("relayer A user starting with balance: %d", relayerAStartingBalance) + + t.Run("register counterparty payee", func(t *testing.T) { + multiMsgTxResponse, err = s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(multiMsgTxResponse) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelA.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + payPacketFeeMsg := feetypes.NewMsgPayPacketFee(testFee, channelA.PortID, channelA.ChannelID, chainAWallet.FormattedAddress(), nil) + transferMsg := transfertypes.NewMsgTransfer(channelA.PortID, channelA.ChannelID, transferAmount, chainAWallet.FormattedAddress(), chainBWallet.FormattedAddress(), s.GetTimeoutHeight(ctx, chainB), 0, "") + resp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, payPacketFeeMsg, transferMsg) + + t.Run("transfer successful", func(t *testing.T) { + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("balance should be lowered by sum of recv ack and timeout", func(t *testing.T) { + // The balance should be lowered by the sum of the recv, ack and timeout fees. + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount - testFee.Total().AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("timeout fee is refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + // once the relayer has relayed the packets, the timeout fee should be refunded. + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + + t.Run("relayerA is paid ack and recv fee", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainARelayerUser) + s.Require().NoError(err) + expected := relayerAStartingBalance + testFee.AckFee.AmountOf(chainADenom).Int64() + testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) +} + +func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_SingleSender_TimesOut() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + testFee = testvalues.DefaultFee(chainADenom) + chainATx ibc.Tx + payPacketFeeTxResp sdk.TxResponse + ) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + t.Run("relayer wallets recovered", func(t *testing.T) { + s.Require().NoError(s.RecoverRelayerWallets(ctx, relayer)) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + t.Run("relayer wallets fetched", func(t *testing.T) { + s.Require().NoError(err) + }) + + _, chainBRelayerUser := s.GetRelayerUsers(ctx) + + t.Run("register counterparty payee", func(t *testing.T) { + resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(resp) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelA.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + chainBWalletAmount := ibc.WalletAmount{ + Address: chainBWallet.FormattedAddress(), // destination address + Denom: chainA.Config().Denom, + Amount: testvalues.IBCTransferAmount, + } + + t.Run("Send IBC transfer", func(t *testing.T) { + chainATx, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName(), chainBWalletAmount, ibc.TransferOptions{Timeout: testvalues.ImmediatelyTimeout()}) + s.Require().NoError(err) + s.Require().NoError(chainATx.Validate(), "source ibc transfer tx is invalid") + time.Sleep(time.Nanosecond * 1) // want it to timeout immediately + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("pay packet fee", func(t *testing.T) { + packetId := channeltypes.NewPacketID(channelA.PortID, channelA.ChannelID, chainATx.Packet.Sequence) + packetFee := feetypes.NewPacketFee(testFee, chainAWallet.FormattedAddress(), nil) + + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("should succeed", func(t *testing.T) { + payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet, packetId, packetFee) + s.Require().NoError(err) + s.AssertValidTxResponse(payPacketFeeTxResp) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("balance should be lowered by sum of recv ack and timeout", func(t *testing.T) { + // The balance should be lowered by the sum of the recv, ack and timeout fees. + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount - testFee.Total().AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("recv and ack should be refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testFee.TimeoutFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) +} + +func (s *IncentivizedTransferTestSuite) TestPayPacketFeeAsync_SingleSender_NoCounterPartyAddress() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) + chainA, _ := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + testFee = testvalues.DefaultFee(chainADenom) + chainATx ibc.Tx + payPacketFeeTxResp sdk.TxResponse + ) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainBWalletAmount := ibc.WalletAmount{ + Address: chainAWallet.FormattedAddress(), // destination address + Denom: chainADenom, + Amount: testvalues.IBCTransferAmount, + } + + t.Run("send IBC transfer", func(t *testing.T) { + var err error + chainATx, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName(), chainBWalletAmount, ibc.TransferOptions{}) + s.Require().NoError(err) + s.Require().NoError(chainATx.Validate(), "source ibc transfer tx is invalid") + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("pay packet fee", func(t *testing.T) { + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + packetId := channeltypes.NewPacketID(channelA.PortID, channelA.ChannelID, chainATx.Packet.Sequence) + packetFee := feetypes.NewPacketFee(testFee, chainAWallet.FormattedAddress(), nil) + + t.Run("should succeed", func(t *testing.T) { + var err error + payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet, packetId, packetFee) + s.Require().NoError(err) + s.AssertValidTxResponse(payPacketFeeTxResp) + }) + + t.Run("should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee := packets[0].PacketFees[0].Fee + + s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + }) + + t.Run("balance should be lowered by sum of recv, ack and timeout", func(t *testing.T) { + // The balance should be lowered by the sum of the recv, ack and timeout fees. + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount - testFee.Total().AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("with no counterparty address", func(t *testing.T) { + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("timeout and recv fee are refunded", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + // once the relayer has relayed the packets, the timeout and recv fee should be refunded. + expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount - testFee.AckFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected, actualBalance) + }) + }) +} + +func (s *IncentivizedTransferTestSuite) TestMsgPayPacketFee_AsyncMultipleSenders_Succeeds() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions()) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + testFee = testvalues.DefaultFee(chainADenom) + chainATx ibc.Tx + payPacketFeeTxResp sdk.TxResponse + ) + + chainAWallet1 := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAWallet2 := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + t.Run("relayer wallets recovered", func(t *testing.T) { + err := s.RecoverRelayerWallets(ctx, relayer) + s.Require().NoError(err) + }) + + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer) + s.Require().NoError(err) + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + _, chainBRelayerUser := s.GetRelayerUsers(ctx) + + t.Run("register counterparty payee", func(t *testing.T) { + resp, err := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress()) + s.Require().NoError(err) + s.AssertValidTxResponse(resp) + }) + + t.Run("verify counterparty payee", func(t *testing.T) { + address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelA.Counterparty.ChannelID) + s.Require().NoError(err) + s.Require().Equal(chainARelayerWallet.FormattedAddress(), address) + }) + + walletAmount1 := ibc.WalletAmount{ + Address: chainAWallet1.FormattedAddress(), // destination address + Denom: chainADenom, + Amount: testvalues.IBCTransferAmount, + } + + t.Run("send IBC transfer", func(t *testing.T) { + chainATx, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet1.KeyName(), walletAmount1, ibc.TransferOptions{}) + s.Require().NoError(err) + s.Require().NoError(chainATx.Validate(), "chain-a ibc transfer tx is invalid") + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet1) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - walletAmount1.Amount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("pay packet fee", func(t *testing.T) { + t.Run("no incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + packetId := channeltypes.NewPacketID(channelA.PortID, channelA.ChannelID, chainATx.Packet.Sequence) + packetFee1 := feetypes.NewPacketFee(testFee, chainAWallet1.FormattedAddress(), nil) + packetFee2 := feetypes.NewPacketFee(testFee, chainAWallet2.FormattedAddress(), nil) + + t.Run("paying packetFee1 should succeed", func(t *testing.T) { + payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet1, packetId, packetFee1) + s.Require().NoError(err) + s.AssertValidTxResponse(payPacketFeeTxResp) + }) + t.Run("paying packetFee2 should succeed", func(t *testing.T) { + payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet2, packetId, packetFee2) + s.Require().NoError(err) + s.AssertValidTxResponse(payPacketFeeTxResp) + }) + + t.Run("there should be incentivized packets", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Len(packets, 1) + actualFee1 := packets[0].PacketFees[0].Fee + actualFee2 := packets[0].PacketFees[1].Fee + s.Require().Len(packets[0].PacketFees, 2) + + s.Require().True(actualFee1.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee1.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee1.TimeoutFee.IsEqual(testFee.TimeoutFee)) + + s.Require().True(actualFee2.RecvFee.IsEqual(testFee.RecvFee)) + s.Require().True(actualFee2.AckFee.IsEqual(testFee.AckFee)) + s.Require().True(actualFee2.TimeoutFee.IsEqual(testFee.TimeoutFee)) + }) + + t.Run("balance of chainAWallet1 should be lowered by sum of recv ack and timeout", func(t *testing.T) { + actualBalance1, err := s.GetChainANativeBalance(ctx, chainAWallet1) + s.Require().NoError(err) + + expected1 := testvalues.StartingTokenAmount - walletAmount1.Amount - testFee.Total().AmountOf(chainADenom).Int64() + s.Require().Equal(expected1, actualBalance1) + }) + + t.Run("balance of chainAWallet2 should be lowered by sum of recv ack and timeout", func(t *testing.T) { + actualBalance2, err := s.GetChainANativeBalance(ctx, chainAWallet2) + s.Require().NoError(err) + + expected2 := testvalues.StartingTokenAmount - testFee.Total().AmountOf(chainADenom).Int64() + s.Require().Equal(expected2, actualBalance2) + }) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Empty(packets) + }) + + t.Run("timeout fee is refunded", func(t *testing.T) { + actualBalance1, err := s.GetChainANativeBalance(ctx, chainAWallet1) + s.Require().NoError(err) + + // once the relayer has relayed the packets, the timeout fee should be refunded. + expected1 := testvalues.StartingTokenAmount - walletAmount1.Amount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected1, actualBalance1) + + actualBalance2, err := s.GetChainANativeBalance(ctx, chainAWallet2) + s.Require().NoError(err) + + // once the relayer has relayed the packets, the timeout fee should be refunded. + expected2 := testvalues.StartingTokenAmount - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64() + s.Require().Equal(expected2, actualBalance2) + }) +} + +// feeMiddlewareChannelOptions configures both of the chains to have fee middleware enabled. +func feeMiddlewareChannelOptions() func(options *ibc.CreateChannelOptions) { + return func(opts *ibc.CreateChannelOptions) { + opts.Version = "{\"fee_version\":\"ics29-1\",\"app_version\":\"ics20-1\"}" + opts.DestPortName = "transfer" + opts.SourcePortName = "transfer" + } +} diff --git a/e2e/tests/upgrades/upgrade_test.go b/e2e/tests/upgrades/upgrade_test.go new file mode 100644 index 00000000000..c8500e830dc --- /dev/null +++ b/e2e/tests/upgrades/upgrade_test.go @@ -0,0 +1,638 @@ +package upgrades + +import ( + "context" + "fmt" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/cosmos/gogoproto/proto" + intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types" + interchaintest "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" + "github.com/stretchr/testify/suite" + "golang.org/x/mod/semver" + + "github.com/cosmos/ibc-go/e2e/testconfig" + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + v7migrations "github.com/cosmos/ibc-go/v7/modules/core/02-client/migrations/v7" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +const ( + haltHeight = uint64(100) + blocksAfterUpgrade = uint64(10) +) + +func TestUpgradeTestSuite(t *testing.T) { + testCfg := testconfig.FromEnv() + if testCfg.UpgradeTag == "" || testCfg.UpgradePlanName == "" { + t.Fatal("upgrade tag and upgrade plan name must be provided in test configuration") + } + + suite.Run(t, new(UpgradeTestSuite)) +} + +type UpgradeTestSuite struct { + testsuite.E2ETestSuite +} + +// UpgradeChain upgrades a chain to a specific version using the planName provided. +// The software upgrade proposal is broadcast by the provided wallet. +func (s *UpgradeTestSuite) UpgradeChain(ctx context.Context, chain *cosmos.CosmosChain, wallet ibc.Wallet, planName, currentVersion, upgradeVersion string) { + plan := upgradetypes.Plan{ + Name: planName, + Height: int64(haltHeight), + Info: fmt.Sprintf("upgrade version test from %s to %s", currentVersion, upgradeVersion), + } + + upgradeProposal := upgradetypes.NewSoftwareUpgradeProposal(fmt.Sprintf("upgrade from %s to %s", currentVersion, upgradeVersion), "upgrade chain E2E test", plan) + s.ExecuteGovProposal(ctx, chain, wallet, upgradeProposal) + + height, err := chain.Height(ctx) + s.Require().NoError(err, "error fetching height before upgrade") + + timeoutCtx, timeoutCtxCancel := context.WithTimeout(ctx, time.Minute*2) + defer timeoutCtxCancel() + + err = test.WaitForBlocks(timeoutCtx, int(haltHeight-height)+1, chain) + s.Require().Error(err, "chain did not halt at halt height") + + err = chain.StopAllNodes(ctx) + s.Require().NoError(err, "error stopping node(s)") + + chain.UpgradeVersion(ctx, s.DockerClient, upgradeVersion) + + err = chain.StartAllNodes(ctx) + s.Require().NoError(err, "error starting upgraded node(s)") + + // we are reinitializing the clients because we need to update the hostGRPCAddress after + // the upgrade and subsequent restarting of nodes + s.InitGRPCClients(chain) + + timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Minute*2) + defer timeoutCtxCancel() + + err = test.WaitForBlocks(timeoutCtx, int(blocksAfterUpgrade), chain) + s.Require().NoError(err, "chain did not produce blocks after upgrade") + + height, err = chain.Height(ctx) + s.Require().NoError(err, "error fetching height after upgrade") + + s.Require().Greater(height, haltHeight, "height did not increment after upgrade") +} + +func (s *UpgradeTestSuite) TestIBCChainUpgrade() { + t := s.T() + testCfg := testconfig.FromEnv() + + ctx := context.Background() + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + chainBIBCToken = testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) // IBC token sent to chainB + + chainBDenom = chainB.Config().Denom + chainAIBCToken = testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) // IBC token sent to chainA + ) + + // create separate user specifically for the upgrade proposal to more easily verify starting + // and end balances of the chainA users. + chainAUpgradeProposalWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + t.Run("upgrade chainA", func(t *testing.T) { + s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradePlanName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag) + }) + + t.Run("restart relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + s.StartRelayer(relayer) + }) + + t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 2) + + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount * 2 + s.Require().Equal(expected, actualBalance) + }) + + t.Run("ensure packets can be received, send from chainB to chainA", func(t *testing.T) { + t.Run("send from chainB to chainA", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferAmount(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) + + actualBalance, err := chainA.GetBalance(ctx, chainAAddress, chainAIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + }) +} + +func (s *UpgradeTestSuite) TestChainUpgrade() { + t := s.T() + + ctx := context.Background() + chain := s.SetupSingleChain(ctx) + + userWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + userWalletAddr := userWallet.FormattedAddress() + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chain), "failed to wait for blocks") + + t.Run("send funds to test wallet", func(t *testing.T) { + err := chain.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: userWalletAddr, + Amount: testvalues.StartingTokenAmount, + Denom: chain.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("verify tokens sent", func(t *testing.T) { + balance, err := chain.GetBalance(ctx, userWalletAddr, chain.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount * 2 + s.Require().Equal(expected, balance) + }) + + t.Run("upgrade chain", func(t *testing.T) { + testCfg := testconfig.FromEnv() + proposerWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + s.UpgradeChain(ctx, chain, proposerWallet, testCfg.UpgradePlanName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag) + }) + + t.Run("send funds to test wallet", func(t *testing.T) { + err := chain.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: userWalletAddr, + Amount: testvalues.StartingTokenAmount, + Denom: chain.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("verify tokens sent", func(t *testing.T) { + balance, err := chain.GetBalance(ctx, userWalletAddr, chain.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount * 3 + s.Require().Equal(expected, balance) + }) +} + +func (s *UpgradeTestSuite) TestV5ToV6ChainUpgrade() { + t := s.T() + testCfg := testconfig.FromEnv() + + ctx := context.Background() + relayer, _ := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + // create separate user specifically for the upgrade proposal to more easily verify starting + // and end balances of the chainA users. + chainAUpgradeProposalWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + // setup 2 accounts: controller account on chain A, a second chain B account. + // host account will be created when the ICA is registered + controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + var hostAccount string + + t.Run("register interchain account", func(t *testing.T) { + version := getICAVersion(testconfig.GetChainATag(), testconfig.GetChainBTag()) + msgRegisterAccount := intertxtypes.NewMsgRegisterAccount(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, version) + err := s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterAccount) + s.Require().NoError(err) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("verify interchain account", func(t *testing.T) { + var err error + hostAccount, err = s.QueryInterchainAccount(ctx, chainA, controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(hostAccount)) + + channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + s.Require().Equal(len(channels), 2) + }) + + t.Run("interchain account executes a bank transfer on behalf of the corresponding owner account", func(t *testing.T) { + t.Run("fund interchain account wallet", func(t *testing.T) { + // fund the host account, so it has some $$ to send + err := chainB.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{ + Address: hostAccount, + Amount: testvalues.StartingTokenAmount, + Denom: chainB.Config().Denom, + }) + s.Require().NoError(err) + }) + + t.Run("broadcast MsgSubmitTx (legacy)", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + msgSend := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + // assemble submitMessage tx for intertx + msgSubmitTx, err := intertxtypes.NewMsgSubmitTx( + msgSend, + ibctesting.FirstConnectionID, + controllerAccount.FormattedAddress(), + ) + s.Require().NoError(err) + + // broadcast submitMessage tx from controller account on chain A + // this message should trigger the sending of an ICA packet over channel-1 (channel created between controller and host) + // this ICA packet contains the assembled bank transfer message from above, which will be executed by the host account on the host chain. + resp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + msgSubmitTx, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + t.Run("upgrade chainA", func(t *testing.T) { + s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradePlanName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag) + }) + + t.Run("restart relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + s.StartRelayer(relayer) + }) + + t.Run("broadcast MsgSubmitTx (legacy)", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + msgSend := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + // assemble submitMessage tx for intertx + msgSubmitTx, err := intertxtypes.NewMsgSubmitTx( + msgSend, + ibctesting.FirstConnectionID, + controllerAccount.FormattedAddress(), + ) + s.Require().NoError(err) + + // broadcast submitMessage tx from controller account on chain A + // this message should trigger the sending of an ICA packet over channel-1 (channel created between controller and host) + // this ICA packet contains the assembled bank transfer message from above, which will be executed by the host account on the host chain. + resp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + msgSubmitTx, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) + s.Require().NoError(err) + + expected := (testvalues.IBCTransferAmount * 2) + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) + + t.Run("broadcast MsgSendTx (MsgServer)", func(t *testing.T) { + // assemble bank transfer message from host account to user account on host chain + msgSend := &banktypes.MsgSend{ + FromAddress: hostAccount, + ToAddress: chainBAccount.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), + } + + data, err := icatypes.SerializeCosmosTx(testsuite.Codec(), []proto.Message{msgSend}) + s.Require().NoError(err) + + icaPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + } + + relativeTimeoutTimestamp := uint64(time.Hour.Nanoseconds()) + msgSendTx := controllertypes.NewMsgSendTx(controllerAccount.FormattedAddress(), ibctesting.FirstConnectionID, relativeTimeoutTimestamp, icaPacketData) + + // broadcast MsgSendTx tx from controller account on chain A + // this message should trigger the sending of an ICA packet over channel-1 (channel created between controller and host) + // this ICA packet contains the assembled bank transfer message from above, which will be executed by the host account on the host chain. + resp, err := s.BroadcastMessages( + ctx, + chainA, + controllerAccount, + msgSendTx, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + balance, err := chainB.GetBalance(ctx, chainBAccount.FormattedAddress(), chainB.Config().Denom) + s.Require().NoError(err) + + _, err = chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) + s.Require().NoError(err) + + expected := (testvalues.IBCTransferAmount * 3) + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance) + }) +} + +// TestV6ToV7ChainUpgrade will test that an upgrade from a v6 ibc-go binary to a v7 ibc-go binary is successful +// and that the automatic migrations associated with the 02-client module are performed. Namely that the solo machine +// proto definition is migrated in state from the v2 to v3 definition. This is checked by creating a solo machine client +// before the upgrade and asserting that its TypeURL has been changed after the upgrade. The test also ensure packets +// can be sent before and after the upgrade without issue +func (s *UpgradeTestSuite) TestV6ToV7ChainUpgrade() { + t := s.T() + testCfg := testconfig.FromEnv() + + ctx := context.Background() + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() + + var ( + chainADenom = chainA.Config().Denom + chainBIBCToken = testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) // IBC token sent to chainB + ) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + // create second tendermint client + createClientOptions := ibc.CreateClientOptions{ + TrustingPeriod: ibctesting.TrustingPeriod.String(), + } + + s.SetupClients(ctx, relayer, createClientOptions) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("check that both tendermint clients are active", func(t *testing.T) { + status, err := s.QueryClientStatus(ctx, chainA, testvalues.TendermintClientID(0)) + s.Require().NoError(err) + s.Require().Equal(exported.Active.String(), status) + + status, err = s.QueryClientStatus(ctx, chainA, testvalues.TendermintClientID(1)) + s.Require().NoError(err) + s.Require().Equal(exported.Active.String(), status) + }) + + // create solo machine client using the solomachine implementation from ibctesting + // TODO: the solomachine clientID should be updated when after fix of this issue: https://github.com/cosmos/ibc-go/issues/2907 + solo := ibctesting.NewSolomachine(t, testsuite.Codec(), "solomachine", "testing", 1) + + legacyConsensusState := &v7migrations.ConsensusState{ + PublicKey: solo.ConsensusState().PublicKey, + Diversifier: solo.ConsensusState().Diversifier, + Timestamp: solo.ConsensusState().Timestamp, + } + + legacyClientState := &v7migrations.ClientState{ + Sequence: solo.ClientState().Sequence, + IsFrozen: solo.ClientState().IsFrozen, + ConsensusState: legacyConsensusState, + AllowUpdateAfterProposal: true, + } + + msgCreateSoloMachineClient, err := clienttypes.NewMsgCreateClient(legacyClientState, legacyConsensusState, chainAAddress) + s.Require().NoError(err) + + resp, err := s.BroadcastMessages( + ctx, + chainA, + chainAWallet, + msgCreateSoloMachineClient, + ) + + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + t.Run("check that the solomachine is now active and that the clientstate is a pre-upgrade v2 solomachine clientstate", func(t *testing.T) { + status, err := s.QueryClientStatus(ctx, chainA, testvalues.SolomachineClientID(2)) + s.Require().NoError(err) + s.Require().Equal(exported.Active.String(), status) + + res, err := s.ClientState(ctx, chainA, testvalues.SolomachineClientID(2)) + s.Require().NoError(err) + s.Require().Equal(fmt.Sprint("/", proto.MessageName(&v7migrations.ClientState{})), res.ClientState.TypeUrl) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + // create separate user specifically for the upgrade proposal to more easily verify starting + // and end balances of the chainA users. + chainAUpgradeProposalWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + t.Run("upgrade chainA", func(t *testing.T) { + s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, testCfg.UpgradePlanName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag) + }) + + t.Run("check that the tendermint clients are active again after upgrade", func(t *testing.T) { + status, err := s.QueryClientStatus(ctx, chainA, testvalues.TendermintClientID(0)) + s.Require().NoError(err) + s.Require().Equal(exported.Active.String(), status) + + status, err = s.QueryClientStatus(ctx, chainA, testvalues.TendermintClientID(1)) + s.Require().NoError(err) + s.Require().Equal(exported.Active.String(), status) + }) + + t.Run("IBC token transfer from chainA to chainB, to make sure the upgrade did not break the packet flow", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount * 2 + s.Require().Equal(expected, actualBalance) + }) + + t.Run("check that the v2 solo machine clientstate has been updated to the v3 solo machine clientstate", func(t *testing.T) { + res, err := s.ClientState(ctx, chainA, testvalues.SolomachineClientID(2)) + s.Require().NoError(err) + s.Require().Equal(fmt.Sprint("/", proto.MessageName(&solomachine.ClientState{})), res.ClientState.TypeUrl) + }) +} + +// RegisterInterchainAccount will attempt to register an interchain account on the counterparty chain. +func (s *UpgradeTestSuite) RegisterInterchainAccount(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, msgRegisterAccount *intertxtypes.MsgRegisterAccount) error { + txResp, err := s.BroadcastMessages(ctx, chain, user, msgRegisterAccount) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + return err +} + +// getICAVersion returns the version which should be used in the MsgRegisterAccount broadcast from the +// controller chain. +func getICAVersion(chainAVersion, chainBVersion string) string { + chainBIsGreaterThanOrEqualToChainA := semver.Compare(chainAVersion, chainBVersion) <= 0 + if chainBIsGreaterThanOrEqualToChainA { + // allow version to be specified by the controller chain + return "" + } + // explicitly set the version string because the host chain might not yet support incentivized channels. + return icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) +} + +// ClientState queries the current ClientState by clientID +func (s *UpgradeTestSuite) ClientState(ctx context.Context, chain ibc.Chain, clientID string) (*clienttypes.QueryClientStateResponse, error) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.ClientState(ctx, &clienttypes.QueryClientStateRequest{ + ClientId: clientID, + }) + if err != nil { + return res, err + } + + return res, nil +} diff --git a/e2e/testsuite/codec.go b/e2e/testsuite/codec.go new file mode 100644 index 00000000000..5ad4a78febe --- /dev/null +++ b/e2e/testsuite/codec.go @@ -0,0 +1,66 @@ +package testsuite + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdkcodec "github.com/cosmos/cosmos-sdk/crypto/codec" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/authz" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + grouptypes "github.com/cosmos/cosmos-sdk/x/group" + proposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types" + + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + v7migrations "github.com/cosmos/ibc-go/v7/modules/core/02-client/migrations/v7" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + simappparams "github.com/cosmos/ibc-go/v7/testing/simapp/params" +) + +func Codec() *codec.ProtoCodec { + cdc, _ := codecAndEncodingConfig() + return cdc +} + +func EncodingConfig() simappparams.EncodingConfig { + _, cfg := codecAndEncodingConfig() + return cfg +} + +func codecAndEncodingConfig() (*codec.ProtoCodec, simappparams.EncodingConfig) { + cfg := simappparams.MakeTestEncodingConfig() + + // ibc types + icacontrollertypes.RegisterInterfaces(cfg.InterfaceRegistry) + feetypes.RegisterInterfaces(cfg.InterfaceRegistry) + intertxtypes.RegisterInterfaces(cfg.InterfaceRegistry) + solomachine.RegisterInterfaces(cfg.InterfaceRegistry) + v7migrations.RegisterInterfaces(cfg.InterfaceRegistry) + transfertypes.RegisterInterfaces(cfg.InterfaceRegistry) + clienttypes.RegisterInterfaces(cfg.InterfaceRegistry) + channeltypes.RegisterInterfaces(cfg.InterfaceRegistry) + connectiontypes.RegisterInterfaces(cfg.InterfaceRegistry) + ibctmtypes.RegisterInterfaces(cfg.InterfaceRegistry) + + // all other types + upgradetypes.RegisterInterfaces(cfg.InterfaceRegistry) + banktypes.RegisterInterfaces(cfg.InterfaceRegistry) + govv1beta1.RegisterInterfaces(cfg.InterfaceRegistry) + govv1.RegisterInterfaces(cfg.InterfaceRegistry) + authtypes.RegisterInterfaces(cfg.InterfaceRegistry) + sdkcodec.RegisterInterfaces(cfg.InterfaceRegistry) + grouptypes.RegisterInterfaces(cfg.InterfaceRegistry) + proposaltypes.RegisterInterfaces(cfg.InterfaceRegistry) + authz.RegisterInterfaces(cfg.InterfaceRegistry) + + cdc := codec.NewProtoCodec(cfg.InterfaceRegistry) + return cdc, cfg +} diff --git a/e2e/testsuite/grpc_query.go b/e2e/testsuite/grpc_query.go new file mode 100644 index 00000000000..ff38ae0f09e --- /dev/null +++ b/e2e/testsuite/grpc_query.go @@ -0,0 +1,159 @@ +package testsuite + +import ( + "context" + + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govtypesbeta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// QueryClientState queries the client state on the given chain for the provided clientID. +func (s *E2ETestSuite) QueryClientState(ctx context.Context, chain ibc.Chain, clientID string) (ibcexported.ClientState, error) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.ClientState(ctx, &clienttypes.QueryClientStateRequest{ + ClientId: clientID, + }) + if err != nil { + return nil, err + } + + clientState, err := clienttypes.UnpackClientState(res.ClientState) + if err != nil { + return nil, err + } + + return clientState, nil +} + +// QueryClientStatus queries the status of the client by clientID +func (s *E2ETestSuite) QueryClientStatus(ctx context.Context, chain ibc.Chain, clientID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.ClientStatus(ctx, &clienttypes.QueryClientStatusRequest{ + ClientId: clientID, + }) + if err != nil { + return "", err + } + + return res.Status, nil +} + +// QueryChannel queries the channel on a given chain for the provided portID and channelID +func (s *E2ETestSuite) QueryChannel(ctx context.Context, chain ibc.Chain, portID, channelID string) (channeltypes.Channel, error) { + queryClient := s.GetChainGRCPClients(chain).ChannelQueryClient + res, err := queryClient.Channel(ctx, &channeltypes.QueryChannelRequest{ + PortId: portID, + ChannelId: channelID, + }) + if err != nil { + return channeltypes.Channel{}, err + } + + return *res.Channel, nil +} + +// QueryPacketCommitment queries the packet commitment on the given chain for the provided channel and sequence. +func (s *E2ETestSuite) QueryPacketCommitment(ctx context.Context, chain ibc.Chain, portID, channelID string, sequence uint64) ([]byte, error) { + queryClient := s.GetChainGRCPClients(chain).ChannelQueryClient + res, err := queryClient.PacketCommitment(ctx, &channeltypes.QueryPacketCommitmentRequest{ + PortId: portID, + ChannelId: channelID, + Sequence: sequence, + }) + if err != nil { + return nil, err + } + return res.Commitment, nil +} + +// QueryInterchainAccount queries the interchain account for the given owner and connectionID. +func (s *E2ETestSuite) QueryInterchainAccount(ctx context.Context, chain ibc.Chain, owner, connectionID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).ICAQueryClient + res, err := queryClient.InterchainAccount(ctx, &controllertypes.QueryInterchainAccountRequest{ + Owner: owner, + ConnectionId: connectionID, + }) + if err != nil { + return "", err + } + return res.Address, nil +} + +// QueryInterchainAccountLegacy queries the interchain account for the given owner and connectionID using the intertx module. +func (s *E2ETestSuite) QueryInterchainAccountLegacy(ctx context.Context, chain ibc.Chain, owner, connectionID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).InterTxQueryClient + res, err := queryClient.InterchainAccount(ctx, &intertxtypes.QueryInterchainAccountRequest{ + Owner: owner, + ConnectionId: connectionID, + }) + if err != nil { + return "", err + } + + return res.InterchainAccountAddress, nil +} + +// QueryIncentivizedPacketsForChannel queries the incentivized packets on the specified channel. +func (s *E2ETestSuite) QueryIncentivizedPacketsForChannel( + ctx context.Context, + chain *cosmos.CosmosChain, + portId, + channelId string, +) ([]*feetypes.IdentifiedPacketFees, error) { + queryClient := s.GetChainGRCPClients(chain).FeeQueryClient + res, err := queryClient.IncentivizedPacketsForChannel(ctx, &feetypes.QueryIncentivizedPacketsForChannelRequest{ + PortId: portId, + ChannelId: channelId, + }) + if err != nil { + return nil, err + } + return res.IncentivizedPackets, err +} + +// QueryCounterPartyPayee queries the counterparty payee of the given chain and relayer address on the specified channel. +func (s *E2ETestSuite) QueryCounterPartyPayee(ctx context.Context, chain ibc.Chain, relayerAddress, channelID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).FeeQueryClient + res, err := queryClient.CounterpartyPayee(ctx, &feetypes.QueryCounterpartyPayeeRequest{ + ChannelId: channelID, + Relayer: relayerAddress, + }) + if err != nil { + return "", err + } + return res.CounterpartyPayee, nil +} + +// QueryProposal queries the governance proposal on the given chain with the given proposal ID. +func (s *E2ETestSuite) QueryProposal(ctx context.Context, chain ibc.Chain, proposalID uint64) (govtypesbeta1.Proposal, error) { + queryClient := s.GetChainGRCPClients(chain).GovQueryClient + res, err := queryClient.Proposal(ctx, &govtypesbeta1.QueryProposalRequest{ + ProposalId: proposalID, + }) + if err != nil { + return govtypesbeta1.Proposal{}, err + } + + return res.Proposal, nil +} + +func (s *E2ETestSuite) QueryProposalV1(ctx context.Context, chain ibc.Chain, proposalID uint64) (govtypesv1.Proposal, error) { + queryClient := s.GetChainGRCPClients(chain).GovQueryClientV1 + res, err := queryClient.Proposal(ctx, &govtypesv1.QueryProposalRequest{ + ProposalId: proposalID, + }) + if err != nil { + return govtypesv1.Proposal{}, err + } + + return *res.Proposal, nil +} diff --git a/e2e/testsuite/relayer.go b/e2e/testsuite/relayer.go deleted file mode 100644 index 123a54465d1..00000000000 --- a/e2e/testsuite/relayer.go +++ /dev/null @@ -1,24 +0,0 @@ -package testsuite - -import ( - "testing" - - "e2e/testconfig" - - dockerclient "github.com/docker/docker/client" - "github.com/strangelove-ventures/ibctest" - "github.com/strangelove-ventures/ibctest/ibc" - "github.com/strangelove-ventures/ibctest/relayer" - "go.uber.org/zap" -) - -const ( - cosmosRelayerRepository = "ghcr.io/cosmos/relayer" -) - -// newCosmosRelayer returns an instance of the go relayer. -func newCosmosRelayer(t *testing.T, tc testconfig.TestConfig, logger *zap.Logger, dockerClient *dockerclient.Client, network string) ibc.Relayer { - return ibctest.NewBuiltinRelayerFactory(ibc.CosmosRly, logger, relayer.CustomDockerImage(cosmosRelayerRepository, tc.RlyTag)).Build( - t, dockerClient, network, - ) -} diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index 7874f956639..edd4642dcb5 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -2,28 +2,45 @@ package testsuite import ( "context" + "errors" "fmt" - "io/ioutil" + "strconv" "strings" "time" - "e2e/testconfig" - + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/authz" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + grouptypes "github.com/cosmos/cosmos-sdk/x/group" + paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types" dockerclient "github.com/docker/docker/client" - "github.com/strangelove-ventures/ibctest" - "github.com/strangelove-ventures/ibctest/broadcast" - "github.com/strangelove-ventures/ibctest/chain/cosmos" - "github.com/strangelove-ventures/ibctest/ibc" - "github.com/strangelove-ventures/ibctest/test" - "github.com/strangelove-ventures/ibctest/testreporter" + interchaintest "github.com/strangelove-ventures/interchaintest/v7" + "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v7/ibc" + "github.com/strangelove-ventures/interchaintest/v7/testreporter" + test "github.com/strangelove-ventures/interchaintest/v7/testutil" "github.com/stretchr/testify/suite" "go.uber.org/zap" "go.uber.org/zap/zaptest" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - feetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + "github.com/cosmos/ibc-go/e2e/relayer" + "github.com/cosmos/ibc-go/e2e/semverutil" + "github.com/cosmos/ibc-go/e2e/testconfig" + "github.com/cosmos/ibc-go/e2e/testvalues" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" ) const ( @@ -31,6 +48,8 @@ const ( ChainARelayerName = "rlyA" // ChainBRelayerName is the name given to the relayer wallet on ChainB ChainBRelayerName = "rlyB" + // DefaultGasValue is the default gas value used to configure tx.Factory + DefaultGasValue = 500000 ) // E2ETestSuite has methods and functionality which can be shared among all test suites. @@ -43,13 +62,28 @@ type E2ETestSuite struct { DockerClient *dockerclient.Client network string startRelayerFn func(relayer ibc.Relayer) + + // pathNameIndex is the latest index to be used for generating paths + pathNameIndex uint64 } // GRPCClients holds a reference to any GRPC clients that are needed by the tests. // These should typically be used for query clients only. If we need to make changes, we should // use E2ETestSuite.BroadcastMessages to broadcast transactions instead. type GRPCClients struct { - FeeQueryClient feetypes.QueryClient + ClientQueryClient clienttypes.QueryClient + ChannelQueryClient channeltypes.QueryClient + FeeQueryClient feetypes.QueryClient + ICAQueryClient controllertypes.QueryClient + InterTxQueryClient intertxtypes.QueryClient + + // SDK query clients + GovQueryClient govtypesv1beta1.QueryClient + GovQueryClientV1 govtypesv1.QueryClient + GroupsQueryClient grouptypes.QueryClient + ParamsQueryClient paramsproposaltypes.QueryClient + AuthQueryClient authtypes.QueryClient + AuthZQueryClient authz.QueryClient } // path is a pairing of two chains which will be used in a test. @@ -65,9 +99,9 @@ func newPath(chainA, chainB *cosmos.CosmosChain) path { } } -// GetRelayerUsers returns two ibctest.User instances which can be used for the relayer users +// GetRelayerUsers returns two ibc.Wallet instances which can be used for the relayer users // on the two chains. -func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...testconfig.ChainOptionConfiguration) (*ibctest.User, *ibctest.User) { +func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...testconfig.ChainOptionConfiguration) (ibc.Wallet, ibc.Wallet) { chainA, chainB := s.GetChains(chainOpts...) chainAAccountBytes, err := chainA.GetAddress(ctx, ChainARelayerName) s.Require().NoError(err) @@ -75,16 +109,10 @@ func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...testcon chainBAccountBytes, err := chainB.GetAddress(ctx, ChainBRelayerName) s.Require().NoError(err) - chainARelayerUser := ibctest.User{ - Address: chainAAccountBytes, - KeyName: ChainARelayerName, - } + chainARelayerUser := cosmos.NewWallet(ChainARelayerName, chainAAccountBytes, "", chainA.Config()) + chainBRelayerUser := cosmos.NewWallet(ChainBRelayerName, chainBAccountBytes, "", chainB.Config()) - chainBRelayerUser := ibctest.User{ - Address: chainBAccountBytes, - KeyName: ChainBRelayerName, - } - return &chainARelayerUser, &chainBRelayerUser + return chainARelayerUser, chainBRelayerUser } // SetupChainsRelayerAndChannel create two chains, a relayer, establishes a connection and creates a channel @@ -93,37 +121,33 @@ func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...testcon // This should be called at the start of every test, unless fine grained control is required. func (s *E2ETestSuite) SetupChainsRelayerAndChannel(ctx context.Context, channelOpts ...func(*ibc.CreateChannelOptions)) (ibc.Relayer, ibc.ChannelOutput) { chainA, chainB := s.GetChains() - home, err := ioutil.TempDir("", "") - s.Require().NoError(err) - r := newCosmosRelayer(s.T(), testconfig.FromEnv(), s.logger, s.DockerClient, s.network) + r := relayer.New(s.T(), testconfig.FromEnv().RelayerConfig, s.logger, s.DockerClient, s.network) - pathName := fmt.Sprintf("%s-path", s.T().Name()) - pathName = strings.ReplaceAll(pathName, "/", "-") - - ic := ibctest.NewInterchain(). - AddChain(chainA). - AddChain(chainB). - AddRelayer(r, "r"). - AddLink(ibctest.InterchainLink{ - Chain1: chainA, - Chain2: chainB, - Relayer: r, - Path: pathName, - }) + pathName := s.generatePathName() channelOptions := ibc.DefaultChannelOpts() for _, opt := range channelOpts { opt(&channelOptions) } - eRep := s.getRelayerExecReporter() - s.Require().NoError(ic.Build(ctx, eRep, ibctest.InterchainBuildOptions{ - TestName: s.T().Name(), - HomeDir: home, - Client: s.DockerClient, - NetworkID: s.network, - CreateChannelOpts: channelOptions, + ic := interchaintest.NewInterchain(). + AddChain(chainA). + AddChain(chainB). + AddRelayer(r, "r"). + AddLink(interchaintest.InterchainLink{ + Chain1: chainA, + Chain2: chainB, + Relayer: r, + Path: pathName, + CreateChannelOpts: channelOptions, + }) + + eRep := s.GetRelayerExecReporter() + s.Require().NoError(ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ + TestName: s.T().Name(), + Client: s.DockerClient, + NetworkID: s.network, })) s.startRelayerFn = func(relayer ibc.Relayer) { @@ -140,14 +164,70 @@ func (s *E2ETestSuite) SetupChainsRelayerAndChannel(ctx context.Context, channel time.Sleep(time.Second * 10) } - s.initGRPCClients(chainA) - s.initGRPCClients(chainB) + s.InitGRPCClients(chainA) + s.InitGRPCClients(chainB) chainAChannels, err := r.GetChannels(ctx, eRep, chainA.Config().ChainID) s.Require().NoError(err) return r, chainAChannels[len(chainAChannels)-1] } +// SetupSingleChain creates and returns a single CosmosChain for usage in e2e tests. +// This is useful for testing single chain functionality when performing coordinated upgrades as well as testing localhost ibc client functionality. +// TODO: Actually setup a single chain. Seeing panic: runtime error: index out of range [0] with length 0 when using a single chain. +// issue: https://github.com/strangelove-ventures/interchaintest/issues/401 +func (s *E2ETestSuite) SetupSingleChain(ctx context.Context) *cosmos.CosmosChain { + chainA, chainB := s.GetChains() + + ic := interchaintest.NewInterchain().AddChain(chainA).AddChain(chainB) + + eRep := s.GetRelayerExecReporter() + s.Require().NoError(ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ + TestName: s.T().Name(), + Client: s.DockerClient, + NetworkID: s.network, + SkipPathCreation: true, + })) + + s.InitGRPCClients(chainA) + s.InitGRPCClients(chainB) + + return chainA +} + +// generatePathName generates the path name using the test suites name +func (s *E2ETestSuite) generatePathName() string { + pathName := fmt.Sprintf("%s-path-%d", s.T().Name(), s.pathNameIndex) + s.pathNameIndex++ + return strings.ReplaceAll(pathName, "/", "-") +} + +// generatePath generates the path name using the test suites name +func (s *E2ETestSuite) generatePath(ctx context.Context, relayer ibc.Relayer) string { + chainA, chainB := s.GetChains() + chainAID := chainA.Config().ChainID + chainBID := chainB.Config().ChainID + + pathName := s.generatePathName() + err := relayer.GeneratePath(ctx, s.GetRelayerExecReporter(), chainAID, chainBID, pathName) + s.Require().NoError(err) + + return pathName +} + +// SetupClients creates clients on chainA and chainB using the provided create client options +func (s *E2ETestSuite) SetupClients(ctx context.Context, relayer ibc.Relayer, opts ibc.CreateClientOptions) { + pathName := s.generatePath(ctx, relayer) + err := relayer.CreateClients(ctx, s.GetRelayerExecReporter(), pathName, opts) + s.Require().NoError(err) +} + +// UpdateClients updates clients on chainA and chainB +func (s *E2ETestSuite) UpdateClients(ctx context.Context, relayer ibc.Relayer, pathName string) { + err := relayer.UpdateClients(ctx, s.GetRelayerExecReporter(), pathName) + s.Require().NoError(err) +} + // GetChains returns two chains that can be used in a test. The pair returned // is unique to the current test being run. Note: this function does not create containers. func (s *E2ETestSuite) GetChains(chainOpts ...testconfig.ChainOptionConfiguration) (*cosmos.CosmosChain, *cosmos.CosmosChain) { @@ -174,9 +254,21 @@ func (s *E2ETestSuite) GetChains(chainOpts ...testconfig.ChainOptionConfiguratio // BroadcastMessages broadcasts the provided messages to the given chain and signs them on behalf of the provided user. // Once the broadcast response is returned, we wait for a few blocks to be created on both chain A and chain B. -func (s *E2ETestSuite) BroadcastMessages(ctx context.Context, chain *cosmos.CosmosChain, user broadcast.User, msgs ...sdk.Msg) (sdk.TxResponse, error) { +func (s *E2ETestSuite) BroadcastMessages(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, msgs ...sdk.Msg) (sdk.TxResponse, error) { broadcaster := cosmos.NewBroadcaster(s.T(), chain) - resp, err := ibctest.BroadcastTx(ctx, broadcaster, user, msgs...) + + broadcaster.ConfigureClientContextOptions(func(clientContext client.Context) client.Context { + // use a codec with all the types our tests care about registered. + // BroadcastTx will deserialize the response and will not be able to otherwise. + cdc := Codec() + return clientContext.WithCodec(cdc).WithTxConfig(authtx.NewTxConfig(cdc, []signingtypes.SignMode{signingtypes.SignMode_SIGN_MODE_DIRECT})) + }) + + broadcaster.ConfigureFactoryOptions(func(factory tx.Factory) tx.Factory { + return factory.WithGas(DefaultGasValue) + }) + + resp, err := cosmos.BroadcastTx(ctx, broadcaster, user, msgs...) if err != nil { return sdk.TxResponse{}, err } @@ -186,17 +278,37 @@ func (s *E2ETestSuite) BroadcastMessages(ctx context.Context, chain *cosmos.Cosm return resp, err } +// RegisterCounterPartyPayee broadcasts a MsgRegisterCounterpartyPayee message. +func (s *E2ETestSuite) RegisterCounterPartyPayee(ctx context.Context, chain *cosmos.CosmosChain, + user ibc.Wallet, portID, channelID, relayerAddr, counterpartyPayeeAddr string, +) (sdk.TxResponse, error) { + msg := feetypes.NewMsgRegisterCounterpartyPayee(portID, channelID, relayerAddr, counterpartyPayeeAddr) + return s.BroadcastMessages(ctx, chain, user, msg) +} + +// PayPacketFeeAsync broadcasts a MsgPayPacketFeeAsync message. +func (s *E2ETestSuite) PayPacketFeeAsync( + ctx context.Context, + chain *cosmos.CosmosChain, + user ibc.Wallet, + packetID channeltypes.PacketId, + packetFee feetypes.PacketFee, +) (sdk.TxResponse, error) { + msg := feetypes.NewMsgPayPacketFeeAsync(packetID, packetFee) + return s.BroadcastMessages(ctx, chain, user, msg) +} + // GetRelayerWallets returns the relayer wallets associated with the chains. -func (s *E2ETestSuite) GetRelayerWallets(relayer ibc.Relayer) (ibc.RelayerWallet, ibc.RelayerWallet, error) { +func (s *E2ETestSuite) GetRelayerWallets(relayer ibc.Relayer) (ibc.Wallet, ibc.Wallet, error) { chainA, chainB := s.GetChains() chainARelayerWallet, ok := relayer.GetWallet(chainA.Config().ChainID) if !ok { - return ibc.RelayerWallet{}, ibc.RelayerWallet{}, fmt.Errorf("unable to find chain A relayer wallet") + return nil, nil, fmt.Errorf("unable to find chain A relayer wallet") } chainBRelayerWallet, ok := relayer.GetWallet(chainB.Config().ChainID) if !ok { - return ibc.RelayerWallet{}, ibc.RelayerWallet{}, fmt.Errorf("unable to find chain B relayer wallet") + return nil, nil, fmt.Errorf("unable to find chain B relayer wallet") } return chainARelayerWallet, chainBRelayerWallet, nil } @@ -211,15 +323,23 @@ func (s *E2ETestSuite) RecoverRelayerWallets(ctx context.Context, relayer ibc.Re chainA, chainB := s.GetChains() - if err := chainA.RecoverKey(ctx, ChainARelayerName, chainARelayerWallet.Mnemonic); err != nil { + if err := chainA.RecoverKey(ctx, ChainARelayerName, chainARelayerWallet.Mnemonic()); err != nil { return fmt.Errorf("could not recover relayer wallet on chain A: %s", err) } - if err := chainB.RecoverKey(ctx, ChainBRelayerName, chainBRelayerWallet.Mnemonic); err != nil { + if err := chainB.RecoverKey(ctx, ChainBRelayerName, chainBRelayerWallet.Mnemonic()); err != nil { return fmt.Errorf("could not recover relayer wallet on chain B: %s", err) } return nil } +// Transfer broadcasts a MsgTransfer message. +func (s *E2ETestSuite) Transfer(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, + portID, channelID string, token sdk.Coin, sender, receiver string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, memo string, +) (sdk.TxResponse, error) { + msg := transfertypes.NewMsgTransfer(portID, channelID, token, sender, receiver, timeoutHeight, timeoutTimestamp, memo) + return s.BroadcastMessages(ctx, chain, user, msg) +} + // StartRelayer starts the given relayer. func (s *E2ETestSuite) StartRelayer(relayer ibc.Relayer) { if s.startRelayerFn == nil { @@ -229,26 +349,32 @@ func (s *E2ETestSuite) StartRelayer(relayer ibc.Relayer) { s.startRelayerFn(relayer) } +// StopRelayer stops the given relayer. +func (s *E2ETestSuite) StopRelayer(ctx context.Context, relayer ibc.Relayer) { + err := relayer.StopRelayer(ctx, s.GetRelayerExecReporter()) + s.Require().NoError(err) +} + // CreateUserOnChainA creates a user with the given amount of funds on chain A. -func (s *E2ETestSuite) CreateUserOnChainA(ctx context.Context, amount int64) *ibctest.User { +func (s *E2ETestSuite) CreateUserOnChainA(ctx context.Context, amount int64) ibc.Wallet { chainA, _ := s.GetChains() - return ibctest.GetAndFundTestUsers(s.T(), ctx, strings.ReplaceAll(s.T().Name(), " ", "-"), amount, chainA)[0] + return interchaintest.GetAndFundTestUsers(s.T(), ctx, strings.ReplaceAll(s.T().Name(), " ", "-"), amount, chainA)[0] } // CreateUserOnChainB creates a user with the given amount of funds on chain B. -func (s *E2ETestSuite) CreateUserOnChainB(ctx context.Context, amount int64) *ibctest.User { +func (s *E2ETestSuite) CreateUserOnChainB(ctx context.Context, amount int64) ibc.Wallet { _, chainB := s.GetChains() - return ibctest.GetAndFundTestUsers(s.T(), ctx, strings.ReplaceAll(s.T().Name(), " ", "-"), amount, chainB)[0] + return interchaintest.GetAndFundTestUsers(s.T(), ctx, strings.ReplaceAll(s.T().Name(), " ", "-"), amount, chainB)[0] } // GetChainANativeBalance gets the balance of a given user on chain A. -func (s *E2ETestSuite) GetChainANativeBalance(ctx context.Context, user *ibctest.User) (int64, error) { +func (s *E2ETestSuite) GetChainANativeBalance(ctx context.Context, user ibc.Wallet) (int64, error) { chainA, _ := s.GetChains() return GetNativeChainBalance(ctx, chainA, user) } // GetChainBNativeBalance gets the balance of a given user on chain B. -func (s *E2ETestSuite) GetChainBNativeBalance(ctx context.Context, user *ibctest.User) (int64, error) { +func (s *E2ETestSuite) GetChainBNativeBalance(ctx context.Context, user ibc.Wallet) (int64, error) { _, chainB := s.GetChains() return GetNativeChainBalance(ctx, chainB, user) } @@ -260,9 +386,9 @@ func (s *E2ETestSuite) GetChainGRCPClients(chain ibc.Chain) GRPCClients { return cs } -// initGRPCClients establishes GRPC clients with the given chain. +// InitGRPCClients establishes GRPC clients with the given chain. // The created GRPCClients can be retrieved with GetChainGRCPClients. -func (s *E2ETestSuite) initGRPCClients(chain *cosmos.CosmosChain) { +func (s *E2ETestSuite) InitGRPCClients(chain *cosmos.CosmosChain) { // Create a connection to the gRPC server. grpcConn, err := grpc.Dial( chain.GetHostGRPCAddress(), @@ -280,25 +406,42 @@ func (s *E2ETestSuite) initGRPCClients(chain *cosmos.CosmosChain) { } s.grpcClients[chain.Config().ChainID] = GRPCClients{ - FeeQueryClient: feetypes.NewQueryClient(grpcConn), + ClientQueryClient: clienttypes.NewQueryClient(grpcConn), + ChannelQueryClient: channeltypes.NewQueryClient(grpcConn), + FeeQueryClient: feetypes.NewQueryClient(grpcConn), + ICAQueryClient: controllertypes.NewQueryClient(grpcConn), + InterTxQueryClient: intertxtypes.NewQueryClient(grpcConn), + GovQueryClient: govtypesv1beta1.NewQueryClient(grpcConn), + GovQueryClientV1: govtypesv1.NewQueryClient(grpcConn), + GroupsQueryClient: grouptypes.NewQueryClient(grpcConn), + ParamsQueryClient: paramsproposaltypes.NewQueryClient(grpcConn), + AuthQueryClient: authtypes.NewQueryClient(grpcConn), + AuthZQueryClient: authz.NewQueryClient(grpcConn), } } // AssertValidTxResponse verifies that an sdk.TxResponse // has non-empty values. func (s *E2ETestSuite) AssertValidTxResponse(resp sdk.TxResponse) { - respLogsMsg := resp.Logs.String() - s.Require().NotEqual(int64(0), resp.GasUsed, respLogsMsg) - s.Require().NotEqual(int64(0), resp.GasWanted, respLogsMsg) - s.Require().NotEmpty(resp.Events, respLogsMsg) - s.Require().NotEmpty(resp.Data, respLogsMsg) + errorMsg := fmt.Sprintf("%+v", resp) + s.Require().NotEmpty(resp.TxHash, errorMsg) + s.Require().NotEqual(int64(0), resp.GasUsed, errorMsg) + s.Require().NotEqual(int64(0), resp.GasWanted, errorMsg) + s.Require().NotEmpty(resp.Events, errorMsg) + s.Require().NotEmpty(resp.Data, errorMsg) +} + +// AssertPacketRelayed asserts that the packet commitment does not exist on the sending chain. +// The packet commitment will be deleted upon a packet acknowledgement or timeout. +func (s *E2ETestSuite) AssertPacketRelayed(ctx context.Context, chain *cosmos.CosmosChain, portID, channelID string, sequence uint64) { + commitment, _ := s.QueryPacketCommitment(ctx, chain, portID, channelID, sequence) + s.Require().Empty(commitment) } // createCosmosChains creates two separate chains in docker containers. // test and can be retrieved with GetChains. func (s *E2ETestSuite) createCosmosChains(chainOptions testconfig.ChainOptions) (*cosmos.CosmosChain, *cosmos.CosmosChain) { - ctx := context.Background() - client, network := ibctest.DockerSetup(s.T()) + client, network := interchaintest.DockerSetup(s.T()) s.logger = zap.NewExample() s.DockerClient = client @@ -306,35 +449,156 @@ func (s *E2ETestSuite) createCosmosChains(chainOptions testconfig.ChainOptions) logger := zaptest.NewLogger(s.T()) - // TODO(chatton): allow for controller over number of validators and full nodes. - chainA := cosmos.NewCosmosChain(s.T().Name(), *chainOptions.ChainAConfig, 1, 0, logger) - chainB := cosmos.NewCosmosChain(s.T().Name(), *chainOptions.ChainBConfig, 1, 0, logger) - - s.T().Cleanup(func() { - if !s.T().Failed() { - for _, c := range []*cosmos.CosmosChain{chainA, chainB} { - if err := c.Cleanup(ctx); err != nil { - s.T().Logf("Chain cleanup for %s failed: %v", c.Config().ChainID, err) - } - } - } - }) + numValidators, numFullNodes := getValidatorsAndFullNodes() + chainA := cosmos.NewCosmosChain(s.T().Name(), *chainOptions.ChainAConfig, numValidators, numFullNodes, logger) + chainB := cosmos.NewCosmosChain(s.T().Name(), *chainOptions.ChainBConfig, numValidators, numFullNodes, logger) return chainA, chainB } -// getRelayerExecReporter returns a testreporter.RelayerExecReporter instances +// GetRelayerExecReporter returns a testreporter.RelayerExecReporter instances // using the current test's testing.T. -func (s *E2ETestSuite) getRelayerExecReporter() *testreporter.RelayerExecReporter { +func (s *E2ETestSuite) GetRelayerExecReporter() *testreporter.RelayerExecReporter { rep := testreporter.NewNopReporter() return rep.RelayerExecReporter(s.T()) } +// GetTimeoutHeight returns a timeout height of 1000 blocks above the current block height. +// This function should be used when the timeout is never expected to be reached +func (s *E2ETestSuite) GetTimeoutHeight(ctx context.Context, chain *cosmos.CosmosChain) clienttypes.Height { + height, err := chain.Height(ctx) + s.Require().NoError(err) + return clienttypes.NewHeight(clienttypes.ParseChainID(chain.Config().ChainID), uint64(height)+1000) +} + // GetNativeChainBalance returns the balance of a specific user on a chain using the native denom. -func GetNativeChainBalance(ctx context.Context, chain ibc.Chain, user *ibctest.User) (int64, error) { - bal, err := chain.GetBalance(ctx, user.Bech32Address(chain.Config().Bech32Prefix), chain.Config().Denom) +func GetNativeChainBalance(ctx context.Context, chain ibc.Chain, user ibc.Wallet) (int64, error) { + bal, err := chain.GetBalance(ctx, user.FormattedAddress(), chain.Config().Denom) if err != nil { return -1, err } return bal, nil } + +// ExecuteGovProposal submits the given governance proposal using the provided user and uses all validators to vote yes on the proposal. +// It ensures the proposal successfully passes. +func (s *E2ETestSuite) ExecuteGovProposal(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, content govtypesv1beta1.Content) { + sender, err := sdk.AccAddressFromBech32(user.FormattedAddress()) + s.Require().NoError(err) + + msgSubmitProposal, err := govtypesv1beta1.NewMsgSubmitProposal(content, sdk.NewCoins(sdk.NewCoin(chain.Config().Denom, govtypesv1beta1.DefaultMinDepositTokens)), sender) + s.Require().NoError(err) + + txResp, err := s.BroadcastMessages(ctx, chain, user, msgSubmitProposal) + s.Require().NoError(err) + s.AssertValidTxResponse(txResp) + + // TODO: replace with parsed proposal ID from MsgSubmitProposalResponse + // https://github.com/cosmos/ibc-go/issues/2122 + + proposal, err := s.QueryProposal(ctx, chain, 1) + s.Require().NoError(err) + s.Require().Equal(govtypesv1beta1.StatusVotingPeriod, proposal.Status) + + err = chain.VoteOnProposalAllValidators(ctx, "1", cosmos.ProposalVoteYes) + s.Require().NoError(err) + + // ensure voting period has not passed before validators finished voting + proposal, err = s.QueryProposal(ctx, chain, 1) + s.Require().NoError(err) + s.Require().Equal(govtypesv1beta1.StatusVotingPeriod, proposal.Status) + + time.Sleep(testvalues.VotingPeriod) // pass proposal + + proposal, err = s.QueryProposal(ctx, chain, 1) + s.Require().NoError(err) + s.Require().Equal(govtypesv1beta1.StatusPassed, proposal.Status) +} + +// govv1ProposalTitleAndSummary represents the releases that support the new title and summary fields. +var govv1ProposalTitleAndSummary = semverutil.FeatureReleases{ + MajorVersion: "v7", +} + +// ExecuteGovProposalV1 submits a governance proposal using the provided user and message and uses all validators +// to vote yes on the proposal. It ensures the proposal successfully passes. +func (s *E2ETestSuite) ExecuteGovProposalV1(ctx context.Context, msg sdk.Msg, chain *cosmos.CosmosChain, user ibc.Wallet, proposalID uint64) { + sender, err := sdk.AccAddressFromBech32(user.FormattedAddress()) + s.Require().NoError(err) + + msgs := []sdk.Msg{msg} + msgSubmitProposal, err := govtypesv1.NewMsgSubmitProposal(msgs, sdk.NewCoins(sdk.NewCoin(chain.Config().Denom, govtypesv1.DefaultMinDepositTokens)), sender.String(), "", fmt.Sprintf("e2e gov proposal: %d", proposalID), fmt.Sprintf("executing gov proposal %d", proposalID)) + s.Require().NoError(err) + + if !govv1ProposalTitleAndSummary.IsSupported(chain.Nodes()[0].Image.Version) { + msgSubmitProposal.Title = "" + msgSubmitProposal.Summary = "" + } + + resp, err := s.BroadcastMessages(ctx, chain, user, msgSubmitProposal) + s.AssertValidTxResponse(resp) + s.Require().NoError(err) + + s.Require().NoError(chain.VoteOnProposalAllValidators(ctx, strconv.Itoa(int(proposalID)), cosmos.ProposalVoteYes)) + + time.Sleep(testvalues.VotingPeriod) + + proposal, err := s.QueryProposalV1(ctx, chain, proposalID) + s.Require().NoError(err) + s.Require().Equal(govtypesv1.StatusPassed, proposal.Status) +} + +// QueryModuleAccountAddress returns the sdk.AccAddress of a given module name. +func (s *E2ETestSuite) QueryModuleAccountAddress(ctx context.Context, moduleName string, chain *cosmos.CosmosChain) (sdk.AccAddress, error) { + authClient := s.GetChainGRCPClients(chain).AuthQueryClient + + resp, err := authClient.ModuleAccountByName(ctx, &authtypes.QueryModuleAccountByNameRequest{ + Name: moduleName, + }) + if err != nil { + return nil, err + } + + cfg := EncodingConfig() + + var account authtypes.AccountI + if err := cfg.InterfaceRegistry.UnpackAny(resp.Account, &account); err != nil { + return nil, err + } + moduleAccount, ok := account.(authtypes.ModuleAccountI) + if !ok { + return nil, errors.New(fmt.Sprintf("failed to cast account: %T as ModuleAccount", moduleAccount)) + } + + return moduleAccount.GetAddress(), nil +} + +// QueryGranterGrants returns all GrantAuthorizations for the given granterAddress. +func (s *E2ETestSuite) QueryGranterGrants(ctx context.Context, chain *cosmos.CosmosChain, granterAddress string) ([]*authz.GrantAuthorization, error) { + authzClient := s.GetChainGRCPClients(chain).AuthZQueryClient + queryRequest := &authz.QueryGranterGrantsRequest{ + Granter: granterAddress, + } + + grants, err := authzClient.GranterGrants(ctx, queryRequest) + if err != nil { + return nil, err + } + + return grants.Grants, nil +} + +// GetIBCToken returns the denomination of the full token denom sent to the receiving channel +func GetIBCToken(fullTokenDenom string, portID, channelID string) transfertypes.DenomTrace { + return transfertypes.ParseDenomTrace(fmt.Sprintf("%s/%s/%s", portID, channelID, fullTokenDenom)) +} + +// getValidatorsAndFullNodes returns the number of validators and full nodes respectively that should be used for +// the test. If the test is running in CI, more nodes are used, when running locally a single node is used to +// use less resources and allow the tests to run faster. +func getValidatorsAndFullNodes() (int, int) { + if testconfig.IsCI() { + return 4, 1 + } + return 1, 0 +} diff --git a/e2e/testvalues/values.go b/e2e/testvalues/values.go index ce11c09bc98..c4c09e68781 100644 --- a/e2e/testvalues/values.go +++ b/e2e/testvalues/values.go @@ -1,15 +1,20 @@ package testvalues import ( + "fmt" + "time" + sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/strangelove-ventures/ibctest/ibc" + "github.com/strangelove-ventures/interchaintest/v7/ibc" - feetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ) const ( - StartingTokenAmount int64 = 10_000_000 - IBCTransferAmount int64 = 10_000 + StartingTokenAmount int64 = 100_000_000 + IBCTransferAmount int64 = 10_000 + InvalidAddress string = "" + VotingPeriod time.Duration = time.Second * 30 ) // ImmediatelyTimeout returns an ibc.IBCTimeout which will cause an IBC transfer to timeout immediately. @@ -30,3 +35,11 @@ func DefaultFee(denom string) feetypes.Fee { func DefaultTransferAmount(denom string) sdk.Coin { return sdk.Coin{Denom: denom, Amount: sdk.NewInt(IBCTransferAmount)} } + +func TendermintClientID(id int) string { + return fmt.Sprintf("07-tendermint-%d", id) +} + +func SolomachineClientID(id int) string { + return fmt.Sprintf("06-solomachine-%d", id) +} diff --git a/go.mod b/go.mod index 7ca10a06af4..bce5260d10e 100644 --- a/go.mod +++ b/go.mod @@ -1,124 +1,162 @@ -go 1.18 +go 1.19 -module github.com/cosmos/ibc-go/v4 - -replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 +module github.com/cosmos/ibc-go/v7 require ( - github.com/armon/go-metrics v0.4.0 - github.com/confio/ics23/go v0.7.0 - github.com/cosmos/cosmos-sdk v0.45.6 - github.com/gogo/protobuf v1.3.3 + cosmossdk.io/api v0.3.1 + cosmossdk.io/errors v1.0.0-beta.7 + cosmossdk.io/math v1.0.0-beta.6 + cosmossdk.io/simapp v0.0.0-20221216140705-ee8890cf30e7 + cosmossdk.io/tools/rosetta v0.2.0 + github.com/armon/go-metrics v0.4.1 + github.com/cosmos/cosmos-proto v1.0.0-beta.2 + github.com/cosmos/cosmos-sdk v0.47.0-rc2 + github.com/cosmos/gogoproto v1.4.6 + github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab github.com/golang/protobuf v1.5.2 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/rakyll/statik v0.1.7 - github.com/regen-network/cosmos-proto v0.3.1 github.com/spf13/cast v1.5.0 - github.com/spf13/cobra v1.5.0 - github.com/spf13/viper v1.12.0 - github.com/stretchr/testify v1.8.0 - github.com/tendermint/tendermint v0.34.19 - github.com/tendermint/tm-db v0.6.6 - google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd - google.golang.org/grpc v1.48.0 - google.golang.org/protobuf v1.28.0 + github.com/spf13/cobra v1.6.1 + github.com/spf13/viper v1.15.0 + github.com/stretchr/testify v1.8.2 + github.com/tendermint/tendermint v0.37.0-rc2 + github.com/tendermint/tm-db v0.6.7 + google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 + google.golang.org/grpc v1.53.0 + google.golang.org/protobuf v1.28.1 gopkg.in/yaml.v2 v2.4.0 ) -require github.com/gin-gonic/gin v1.7.0 // indirect - require ( - filippo.io/edwards25519 v1.0.0-beta.2 // indirect - github.com/99designs/keyring v1.1.6 // indirect + cloud.google.com/go v0.107.0 // indirect + cloud.google.com/go/compute v1.15.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v0.8.0 // indirect + cloud.google.com/go/storage v1.27.0 // indirect + cosmossdk.io/core v0.3.2 // indirect + cosmossdk.io/depinject v1.0.0-alpha.3 // indirect + filippo.io/edwards25519 v1.0.0-rc.1 // indirect + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect - github.com/DataDog/zstd v1.4.5 // indirect - github.com/Workiva/go-datastructures v1.0.53 // indirect + github.com/aws/aws-sdk-go v1.40.45 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/speakeasy v0.1.0 // indirect - github.com/btcsuite/btcd v0.22.0-beta // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect - github.com/cosmos/btcutil v1.0.4 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/confio/ics23/go v0.9.0 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect - github.com/cosmos/iavl v0.17.3 // indirect - github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect - github.com/cosmos/ledger-go v0.9.2 // indirect - github.com/danieljoos/wincred v1.0.2 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/gorocksdb v1.2.0 // indirect + github.com/cosmos/iavl v0.19.5-rc.1 // indirect + github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect + github.com/cosmos/rosetta-sdk-go v0.9.0 // indirect + github.com/creachadair/taskgroup v0.3.2 // indirect + github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v2 v2.2007.2 // indirect - github.com/dgraph-io/ristretto v0.0.3 // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.0 // indirect - github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b // indirect - github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-kit/kit v0.12.0 // indirect - github.com/go-kit/log v0.2.0 // indirect + github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/gogo/gateway v1.1.0 // indirect - github.com/golang/snappy v0.0.3 // indirect - github.com/google/btree v1.0.0 // indirect + github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v1.0.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/orderedcode v0.0.1 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.6.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect - github.com/improbable-eng/grpc-web v0.14.1 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect - github.com/klauspost/compress v1.13.6 // indirect - github.com/lib/pq v1.10.4 // indirect - github.com/libp2p/go-buffer-pool v0.0.2 // indirect - github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/klauspost/compress v1.15.12 // indirect + github.com/lib/pq v1.10.7 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect - github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect + github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect - github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/cors v1.8.2 // indirect - github.com/rs/zerolog v1.26.1 // indirect - github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect - github.com/spf13/afero v1.8.2 // indirect + github.com/rs/zerolog v1.28.0 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + 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/subosito/gotenv v1.3.0 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect - github.com/tendermint/btcd v0.1.1 // indirect - github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/zondax/hid v0.9.0 // indirect + github.com/tidwall/btree v1.5.2 // indirect + github.com/ulikunitz/xz v0.5.8 // indirect + github.com/zondax/hid v0.9.1 // indirect + github.com/zondax/ledger-go v0.14.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect - golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect - golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/ini.v1 v1.66.4 // indirect + go.opencensus.io v0.24.0 // indirect + golang.org/x/crypto v0.4.0 // indirect + golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 // indirect + golang.org/x/net v0.6.0 // indirect + golang.org/x/oauth2 v0.4.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.107.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.6 // indirect + pgregory.net/rapid v0.5.5 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 01f587eac52..bcc0cb0255c 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -18,27 +17,23 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/iam v0.8.0 h1:E2osAkZzxI/+8pZcxVLcDtAQx/u+hZXVryUaYQ5O0Kk= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -49,241 +44,188 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= +cosmossdk.io/core v0.3.2 h1:KlQIufpJHJvOs7YLGTZsZcCo1WlkencDXepsr8STKZQ= +cosmossdk.io/core v0.3.2/go.mod h1:CO7vbe+evrBvHc0setFHL/u7nlY7HJGzdRSBkT/sirc= +cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw= +cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU= +cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= +cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= +cosmossdk.io/math v1.0.0-beta.6 h1:WF29SiFYNde5eYvqO2kdOM9nYbDb44j3YW5B8M1m9KE= +cosmossdk.io/math v1.0.0-beta.6/go.mod h1:gUVtWwIzfSXqcOT+lBVz2jyjfua8DoBdzRsIyaUAT/8= +cosmossdk.io/simapp v0.0.0-20221216140705-ee8890cf30e7 h1:8uwZLyQ6NMZNT0janUI86Q4vF1sIIquSUsijmOkgmp8= +cosmossdk.io/simapp v0.0.0-20221216140705-ee8890cf30e7/go.mod h1:zvJ3aFHDzqQ6NvkCcCHyolr5Wh2BJ9Rg4qVcN1T6Re0= +cosmossdk.io/tools/rosetta v0.2.0 h1:Ae499UiZ9yPNCXvjOBO/R9I1pksCJfxoqWauEZgA/gs= +cosmossdk.io/tools/rosetta v0.2.0/go.mod h1:3mn8QuE2wLUdTi77/gbDXdFqXZdBdiBJhgAWUTSXPv8= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-beta.2 h1:/BZRNzm8N4K4eWfK28dL4yescorxtO7YG1yun8fy+pI= -filippo.io/edwards25519 v1.0.0-beta.2/go.mod h1:X+pm78QAUPtFLi1z9PYIlS/bdDnvbCOGKtZ+ACWEf7o= -github.com/99designs/keyring v1.1.6 h1:kVDC2uCgVwecxCk+9zoCt2uEL6dt+dfVzMvGgnVcIuM= -github.com/99designs/keyring v1.1.6/go.mod h1:16e0ds7LGQQcT59QqkTg72Hh5ShM51Byv5PEmW6uoRU= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= -github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= +filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= +github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= -github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= -github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= -github.com/adlio/schema v1.1.13/go.mod h1:L5Z7tw+7lRK1Fnpi/LT/ooCP1elkXn0krMWBQHUhEDE= -github.com/adlio/schema v1.3.0 h1:eSVYLxYWbm/6ReZBCkLw4Fz7uqC+ZNoPvA39bOwi52A= -github.com/adlio/schema v1.3.0/go.mod h1:51QzxkpeFs6lRY11kPye26IaFPOV+HqEj01t5aXXKfs= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.4.0 h1:yCQqn7dwca4ITXb+CbubHmedzaQYHhNhrEXLYUeEe8Q= -github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.40.45 h1:QN1nsY27ssD/JmW4s83qmSb+uL6DG4GmCDzjmJB4xUI= github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o= -github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= -github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= -github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= -github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= -github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= +github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/rosetta-sdk-go v0.7.0 h1:lmTO/JEpCvZgpbkOITL95rA80CPKb5CtMzLaqF2mCNg= -github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq3yftRmpsy29coWE= -github.com/confio/ics23/go v0.6.6/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= -github.com/confio/ics23/go v0.7.0 h1:00d2kukk7sPoHWL4zZBZwzxnpA2pec1NPdwbSokJ5w8= -github.com/confio/ics23/go v0.7.0/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= -github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.2.1 h1:/EeEo2EtN3umhbbgCveyjifoMYg0pS+nMMEemaYw634= -github.com/containerd/continuity v0.2.1/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= +github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cosmos/btcutil v1.0.4 h1:n7C2ngKXo7UC9gNyMNLbzqz7Asuf+7Qv4gnX/rOdQ44= -github.com/cosmos/btcutil v1.0.4/go.mod h1:Ffqc8Hn6TJUdDgHBwIZLtrLQC1KdJ9jGJl/TvgUaxbU= -github.com/cosmos/cosmos-sdk v0.45.6 h1:bnYLOcDp0cKWMLeUTTJIttq6xxRep52ulPxXC3BCfuQ= -github.com/cosmos/cosmos-sdk v0.45.6/go.mod h1:bPeeVMEtVvH3y3xAGHVbK+/CZlpaazzh77hG8ZrcJpI= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= +github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= +github.com/cosmos/cosmos-sdk v0.47.0-rc2 h1:BwQC41zQXG/pN9DdLaWzYJrC911St5lYOQIoW4Hf5wQ= +github.com/cosmos/cosmos-sdk v0.47.0-rc2/go.mod h1:e0ZEpY/nhVoXAkijdHPdFOJNOXCddfvyFrFLp2QmCCY= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= -github.com/cosmos/iavl v0.17.3 h1:s2N819a2olOmiauVa0WAhoIJq9EhSXE9HDBAoR9k+8Y= -github.com/cosmos/iavl v0.17.3/go.mod h1:prJoErZFABYZGDHka1R6Oay4z9PrNeFFiMKHDAMOi4w= -github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4= -github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= -github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= -github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= +github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= +github.com/cosmos/gogoproto v1.4.6 h1:Ee7z15dWJaGlgM2rWrK8N2IX7PQcuccu8oG68jp5RL4= +github.com/cosmos/gogoproto v1.4.6/go.mod h1:VS/ASYmPgv6zkPKLjR9EB91lwbLHOzaGCirmKKhncfI= +github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= +github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= +github.com/cosmos/iavl v0.19.5-rc.1 h1:4PjF2PdScyPbN1WbXpiQU21YtyonnrMU31xN74g8Rkg= +github.com/cosmos/iavl v0.19.5-rc.1/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab h1:I9ialKTQo7248V827Bba4OuKPmk+FPzmTVHsLXaIJWw= +github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2CwqasX5dSD7Hbp/9b6lhK6BwoBDCBldx7gPKRukR60= +github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w= +github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g= +github.com/cosmos/rosetta-sdk-go v0.9.0 h1:3mj2naR+GUhUXabtb96WWSsPFZDCYkdtp6r0jffgugg= +github.com/cosmos/rosetta-sdk-go v0.9.0/go.mod h1:2v41yXL25xxAXrczVSnbDHcQH9CgildruDlGQGKW/JU= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= +github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= -github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= -github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= -github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b h1:HBah4D48ypg3J7Np4N+HY/ZR76fx3HEUGxDU6Uk39oQ= -github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -291,49 +233,29 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= -github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= -github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= -github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= -github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -343,28 +265,23 @@ github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgO github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= @@ -374,19 +291,24 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= -github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869 h1:kRpU4zq+Pzh4feET49aEWPOzwQy3U2SsbZEQ7QEcif0= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -395,7 +317,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -414,17 +335,16 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -437,15 +357,16 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -458,19 +379,17 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -481,22 +400,14 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -507,83 +418,71 @@ github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-getter v1.6.2 h1:7jX7xcB+uVCliddZgeKyNxv0xoT7qL5KDtH7rU4IqIk= +github.com/hashicorp/go-getter v1.6.2/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 h1:uUjLpLt6bVvZ72SQc/B4dXcPBw4Vgd7soowdRl52qEM= -github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87/go.mod h1:XGsKKeXxeRr95aEOgipvluMPlgjr7dGlk9ZTWOjcUcg= -github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU= +github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= -github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/improbable-eng/grpc-web v0.14.1 h1:NrN4PY71A6tAz2sKDvC5JCauENWp0ykG8Oq1H3cpFvw= -github.com/improbable-eng/grpc-web v0.14.1/go.mod h1:zEjGHa8DAlkoOXmswrNvhUGEYQA9UI7DhrGeHR1DMGU= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.9.0 h1:npqHz788dryJiR/l6K/RUQAyh2SwV91+d1dnh4RjO9w= +github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -595,101 +494,74 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= -github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= -github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -697,220 +569,154 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/jwt v1.2.2/go.mod h1:/xX356yQA6LuXI9xWW7mZNpxgF2mBmGecH+Fj34sP5Q= -github.com/nats-io/jwt/v2 v2.0.3/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nats.go v1.12.1/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s= -github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neilotoole/errgroup v0.1.5/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runc v1.0.3 h1:1hbqejyQWCJBvtKAfdO0b1FmaEf2z/bxnjqbARass5k= -github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= -github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= -github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= -github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= -github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGnWA97M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= -github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= +github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa h1:0U2s5loxrTy6/VgfVoLuVLFJcURKLH49ie0zSch7gh4= -github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= +github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= +github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -919,25 +725,16 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -945,77 +742,48 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= -github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= -github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= -github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= -github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= -github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.14/go.mod h1:FrwVm3TvsVicI9Z7FlucHV6Znfd5KBc/Lpp69cCwtk0= -github.com/tendermint/tendermint v0.34.19 h1:y0P1qI5wSa9IRuhKnTDA6IUcOrLi1hXJuALR+R7HFEk= -github.com/tendermint/tendermint v0.34.19/go.mod h1:R5+wgIwSxMdKQcmOaeudL0Cjkr3HDkhpcdum6VeU3R4= -github.com/tendermint/tm-db v0.6.4/go.mod h1:dptYhIpJ2M5kUuenLr+Yyf3zQOv1SgBZcl8/BmWlMBw= -github.com/tendermint/tm-db v0.6.6 h1:EzhaOfR0bdKyATqcd5PNeyeq8r+V4bRPHBfyFdD9kGM= -github.com/tendermint/tm-db v0.6.6/go.mod h1:wP8d49A85B7/erz/r4YbKssKw6ylsO/hKtFk7E1aWZI= -github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= -github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/sjson v1.1.4/go.mod h1:wXpKXu8CtDjKAZ+3DrKY5ROCorDFahq8l0tey/Lx1fg= -github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= +github.com/tendermint/tendermint v0.37.0-rc2 h1:2n1em+jfbhSv6QnBj8F6KHCpbIzZCB8KgcjidJUQNlY= +github.com/tendermint/tendermint v0.37.0-rc2/go.mod h1:uYQO9DRNPeZROa9X3hJOZpYcVREDC2/HST+EiU5g2+A= +github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= +github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= +github.com/tidwall/btree v1.5.2 h1:5eA83Gfki799V3d3bJo9sWk+yL2LRoTEah3O/SA6/8w= +github.com/tidwall/btree v1.5.2/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= +github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vmihailenco/msgpack/v5 v5.1.4/go.mod h1:C5gboKD0TJPqWDTVTtrQNfRbiBwHZGo8UTqP/9/XvLI= -github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= -github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= +github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.0 h1:dlMC7aO8Wss1CxBq2I96kZ69Nh1ligzbs8UWOtq/AsA= +github.com/zondax/ledger-go v0.14.0/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1024,61 +792,35 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= @@ -1087,7 +829,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE= +golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1101,26 +844,20 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1132,14 +869,12 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1157,29 +892,20 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211208012354-db4efeb81f4b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1189,14 +915,10 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1219,37 +941,28 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1266,56 +979,38 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1324,19 +1019,18 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1349,12 +1043,10 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1363,7 +1055,6 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1384,29 +1075,20 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1427,19 +1109,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.107.0 h1:I2SlFjD8ZWabaIFOfeEDg3pf0BHJDh6iYQ1ic3Yu/UU= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1447,6 +1118,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1470,7 +1142,6 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1484,45 +1155,17 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 h1:vArvWooPH749rNHpBGgVl+U9B9dATjiEhJzcWGlovNs= +google.golang.org/genproto v0.0.0-20230202175211-008b39050e57/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1545,21 +1188,10 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1573,30 +1205,24 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1612,7 +1238,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1623,10 +1249,12 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= +pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/go.work.example b/go.work.example new file mode 100644 index 00000000000..5481cb3c915 --- /dev/null +++ b/go.work.example @@ -0,0 +1,6 @@ +go 1.19 + +use ( + ./ + ./e2e +) diff --git a/internal/errors/errors.go b/internal/errors/errors.go new file mode 100644 index 00000000000..79b96856a87 --- /dev/null +++ b/internal/errors/errors.go @@ -0,0 +1,63 @@ +package errors + +import ( + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +const codespace = exported.ModuleName + +var ( + // ErrInvalidSequence is used the sequence number (nonce) is incorrect + // for the signature. + ErrInvalidSequence = errorsmod.Register(codespace, 1, "invalid sequence") + + // ErrUnauthorized is used whenever a request without sufficient + // authorization is handled. + ErrUnauthorized = errorsmod.Register(codespace, 2, "unauthorized") + + // ErrInsufficientFunds is used when the account cannot pay requested amount. + ErrInsufficientFunds = errorsmod.Register(codespace, 3, "insufficient funds") + + // ErrUnknownRequest is used when the request body. + ErrUnknownRequest = errorsmod.Register(codespace, 4, "unknown request") + + // ErrInvalidAddress is used when an address is found to be invalid. + ErrInvalidAddress = errorsmod.Register(codespace, 5, "invalid address") + + // ErrInvalidCoins is used when sdk.Coins are invalid. + ErrInvalidCoins = errorsmod.Register(codespace, 6, "invalid coins") + + // ErrOutOfGas is used when there is not enough gas. + ErrOutOfGas = errorsmod.Register(codespace, 7, "out of gas") + + // ErrInvalidRequest defines an ABCI typed error where the request contains + // invalid data. + ErrInvalidRequest = errorsmod.Register(codespace, 8, "invalid request") + + // ErrInvalidHeight defines an error for an invalid height + ErrInvalidHeight = errorsmod.Register(codespace, 9, "invalid height") + + // ErrInvalidVersion defines a general error for an invalid version + ErrInvalidVersion = errorsmod.Register(codespace, 10, "invalid version") + + // ErrInvalidChainID defines an error when the chain-id is invalid. + ErrInvalidChainID = errorsmod.Register(codespace, 11, "invalid chain-id") + + // ErrInvalidType defines an error an invalid type. + ErrInvalidType = errorsmod.Register(codespace, 12, "invalid type") + + // ErrPackAny defines an error when packing a protobuf message to Any fails. + ErrPackAny = errorsmod.Register(codespace, 13, "failed packing protobuf message to Any") + + // ErrUnpackAny defines an error when unpacking a protobuf message from Any fails. + ErrUnpackAny = errorsmod.Register(codespace, 14, "failed unpacking protobuf message from Any") + + // ErrLogic defines an internal logic error, e.g. an invariant or assertion + // that is violated. It is a programmer error, not a user-facing error. + ErrLogic = errorsmod.Register(codespace, 15, "internal logic error") + + // ErrNotFound defines an error when requested entity doesn't exist in the state. + ErrNotFound = errorsmod.Register(codespace, 16, "not found") +) diff --git a/internal/logging/logging.go b/internal/logging/logging.go new file mode 100644 index 00000000000..03a326a7d45 --- /dev/null +++ b/internal/logging/logging.go @@ -0,0 +1,23 @@ +package logging + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SdkEventsToLogArguments converts a given sdk.Events and returns a slice of strings that provide human +// readable values for the event attributes. +func SdkEventsToLogArguments(events sdk.Events) []string { + logArgs := []string{"events"} + for _, e := range events { + logArgs = append(logArgs, fmt.Sprintf("type=%s", e.Type)) + for _, attr := range e.Attributes { + if len(attr.Value) == 0 { + continue + } + logArgs = append(logArgs, fmt.Sprintf("%s=%s", attr.Key, attr.Value)) + } + } + return logArgs +} diff --git a/maintainership.png b/maintainership.png new file mode 100644 index 00000000000..4dd79a8f0dd Binary files /dev/null and b/maintainership.png differ diff --git a/modules/apps/27-interchain-accounts/client/cli/cli.go b/modules/apps/27-interchain-accounts/client/cli/cli.go index 92dbb031255..e36c3c8bd80 100644 --- a/modules/apps/27-interchain-accounts/client/cli/cli.go +++ b/modules/apps/27-interchain-accounts/client/cli/cli.go @@ -3,8 +3,8 @@ package cli import ( "github.com/spf13/cobra" - controllercli "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/client/cli" - hostcli "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/client/cli" + controllercli "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/client/cli" + hostcli "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/client/cli" ) // GetQueryCmd returns the query commands for the interchain-accounts submodule @@ -12,7 +12,7 @@ func GetQueryCmd() *cobra.Command { icaQueryCmd := &cobra.Command{ Use: "interchain-accounts", Aliases: []string{"ica"}, - Short: "interchain-accounts subcommands", + Short: "IBC interchain accounts query subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, } @@ -24,3 +24,21 @@ func GetQueryCmd() *cobra.Command { return icaQueryCmd } + +// NewTxCmd returns the tx commands for the interchain-accounts submodule +func NewTxCmd() *cobra.Command { + icaTxCmd := &cobra.Command{ + Use: "interchain-accounts", + Aliases: []string{"ica"}, + Short: "IBC interchain accounts transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + } + + icaTxCmd.AddCommand( + controllercli.NewTxCmd(), + hostcli.NewTxCmd(), + ) + + return icaTxCmd +} diff --git a/modules/apps/27-interchain-accounts/controller/client/cli/cli.go b/modules/apps/27-interchain-accounts/controller/client/cli/cli.go index 0d2f54bd59b..a863649c901 100644 --- a/modules/apps/27-interchain-accounts/controller/client/cli/cli.go +++ b/modules/apps/27-interchain-accounts/controller/client/cli/cli.go @@ -2,20 +2,41 @@ package cli import ( "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" ) // GetQueryCmd returns the query commands for the ICA controller submodule func GetQueryCmd() *cobra.Command { queryCmd := &cobra.Command{ Use: "controller", - Short: "interchain-accounts controller subcommands", + Short: "IBC interchain accounts controller query subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, } queryCmd.AddCommand( + GetCmdQueryInterchainAccount(), GetCmdParams(), ) return queryCmd } + +// NewTxCmd creates and returns the tx command +func NewTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "controller", + Short: "IBC interchain accounts controller transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + newRegisterInterchainAccountCmd(), + newSendTxCmd(), + ) + + return cmd +} diff --git a/modules/apps/27-interchain-accounts/controller/client/cli/query.go b/modules/apps/27-interchain-accounts/controller/client/cli/query.go index b7636715c7d..ca71a96652a 100644 --- a/modules/apps/27-interchain-accounts/controller/client/cli/query.go +++ b/modules/apps/27-interchain-accounts/controller/client/cli/query.go @@ -8,9 +8,43 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ) +// GetCmdQueryInterchainAccount returns the command handler for the controller submodule parameter querying. +func GetCmdQueryInterchainAccount() *cobra.Command { + cmd := &cobra.Command{ + Use: "interchain-account [owner] [connection-id]", + Short: "Query the interchain account address for a given owner on a particular connection", + Long: "Query the controller submodule for the interchain account address for a given owner on a particular connection", + Args: cobra.ExactArgs(2), + Example: fmt.Sprintf("%s query interchain-accounts controller interchain-account cosmos1layxcsmyye0dc0har9sdfzwckaz8sjwlfsj8zs connection-0", version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + req := &types.QueryInterchainAccountRequest{ + Owner: args[0], + ConnectionId: args[1], + } + + res, err := queryClient.InterchainAccount(cmd.Context(), req) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + // GetCmdParams returns the command handler for the controller submodule parameter querying. func GetCmdParams() *cobra.Command { cmd := &cobra.Command{ diff --git a/modules/apps/27-interchain-accounts/controller/client/cli/tx.go b/modules/apps/27-interchain-accounts/controller/client/cli/tx.go new file mode 100644 index 00000000000..44094f7b152 --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/client/cli/tx.go @@ -0,0 +1,109 @@ +package cli + +import ( + "fmt" + "os" + "strings" + + "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/codec" + "github.com/spf13/cobra" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" +) + +const ( + // The controller chain channel version + flagVersion = "version" + flagRelativePacketTimeout = "relative-packet-timeout" +) + +func newRegisterInterchainAccountCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "register [connection-id]", + Short: "Register an interchain account on the provided connection.", + Long: strings.TrimSpace(`Register an account on the counterparty chain via the +connection id from the source chain. Connection identifier should be for the source chain +and the interchain account will be created on the counterparty chain. Callers are expected to +provide the appropriate application version string via {version} flag. Generates a new +port identifier using the provided owner string, binds to the port identifier and claims +the associated capability.`), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + connectionID := args[0] + owner := clientCtx.GetFromAddress().String() + version, err := cmd.Flags().GetString(flagVersion) + if err != nil { + return err + } + + msg := types.NewMsgRegisterInterchainAccount(connectionID, owner, version) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String(flagVersion, "", "Controller chain channel version") + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +func newSendTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "send-tx [connection-id] [path/to/packet_msg.json]", + Short: "Send an interchain account tx on the provided connection.", + Long: strings.TrimSpace(`Submits pre-built packet data containing messages to be executed on the host chain +and attempts to send the packet. Packet data is provided as json, file or string. An +appropriate relative timeoutTimestamp must be provided with flag {relative-packet-timeout}`), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) + + connectionID := args[0] + owner := clientCtx.GetFromAddress().String() + + // attempt to unmarshal ica msg data argument + var icaMsgData icatypes.InterchainAccountPacketData + msgContentOrFileName := args[1] + if err := cdc.UnmarshalJSON([]byte(msgContentOrFileName), &icaMsgData); err != nil { + + // check for file path if JSON input is not provided + contents, err := os.ReadFile(msgContentOrFileName) + if err != nil { + return fmt.Errorf("neither JSON input nor path to .json file for packet data with messages were provided: %w", err) + } + + if err := cdc.UnmarshalJSON(contents, &icaMsgData); err != nil { + return fmt.Errorf("error unmarshalling packet data with messages file: %w", err) + } + } + + relativeTimeoutTimestamp, err := cmd.Flags().GetUint64(flagRelativePacketTimeout) + if err != nil { + return err + } + + msg := types.NewMsgSendTx(owner, connectionID, relativeTimeoutTimestamp, icaMsgData) + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().Uint64(flagRelativePacketTimeout, icatypes.DefaultRelativePacketTimeoutTimestamp, "Relative packet timeout in nanoseconds from now. Default is 10 minutes.") + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/modules/apps/27-interchain-accounts/controller/ibc_middleware.go b/modules/apps/27-interchain-accounts/controller/ibc_middleware.go index 53adf6a090e..56a0d529a8a 100644 --- a/modules/apps/27-interchain-accounts/controller/ibc_middleware.go +++ b/modules/apps/27-interchain-accounts/controller/ibc_middleware.go @@ -1,16 +1,19 @@ package controller import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/keeper" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/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" + 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" ) var _ porttypes.Middleware = &IBCMiddleware{} @@ -22,7 +25,7 @@ type IBCMiddleware struct { keeper keeper.Keeper } -// IBCMiddleware creates a new IBCMiddleware given the associated keeper and underlying application +// NewIBCMiddleware creates a new IBCMiddleware given the associated keeper and underlying application func NewIBCMiddleware(app porttypes.IBCModule, k keeper.Keeper) IBCMiddleware { return IBCMiddleware{ app: app, @@ -55,11 +58,17 @@ func (im IBCMiddleware) OnChanOpenInit( return "", err } + if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return "", err + } + // call underlying app's OnChanOpenInit callback with the passed in version // the version returned is discarded as the ica-auth module does not have permission to edit the version string. // ics27 will always return the version string containing the Metadata struct which is created during the `RegisterInterchainAccount` call. - if _, err := im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version); err != nil { - return "", err + if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, portID, connectionHops[0]) { + if _, err := im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, nil, counterparty, version); err != nil { + return "", err + } } return version, nil @@ -76,7 +85,7 @@ func (im IBCMiddleware) OnChanOpenTry( counterparty channeltypes.Counterparty, counterpartyVersion string, ) (string, error) { - return "", sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") + return "", errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") } // OnChanOpenAck implements the IBCMiddleware interface @@ -100,17 +109,26 @@ func (im IBCMiddleware) OnChanOpenAck( return err } + connectionID, err := im.keeper.GetConnectionID(ctx, portID, channelID) + if err != nil { + return err + } + // call underlying app's OnChanOpenAck callback with the counterparty app version. - return im.app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) + if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, portID, connectionID) { + return im.app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) + } + + return nil } -// OnChanOpenAck implements the IBCMiddleware interface +// OnChanOpenConfirm implements the IBCMiddleware interface func (im IBCMiddleware) OnChanOpenConfirm( ctx sdk.Context, portID, channelID string, ) error { - return sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") + return errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") } // OnChanCloseInit implements the IBCMiddleware interface @@ -120,7 +138,7 @@ func (im IBCMiddleware) OnChanCloseInit( channelID string, ) error { // Disallow user-initiated channel closing for interchain account channels - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") + return errorsmod.Wrap(ibcerrors.ErrInvalidRequest, "user cannot close channel") } // OnChanCloseConfirm implements the IBCMiddleware interface @@ -129,7 +147,20 @@ func (im IBCMiddleware) OnChanCloseConfirm( portID, channelID string, ) error { - return im.keeper.OnChanCloseConfirm(ctx, portID, channelID) + if err := im.keeper.OnChanCloseConfirm(ctx, portID, channelID); err != nil { + return err + } + + connectionID, err := im.keeper.GetConnectionID(ctx, portID, channelID) + if err != nil { + return err + } + + if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, portID, connectionID) { + return im.app.OnChanCloseConfirm(ctx, portID, channelID) + } + + return nil } // OnRecvPacket implements the IBCMiddleware interface @@ -138,7 +169,7 @@ func (im IBCMiddleware) OnRecvPacket( packet channeltypes.Packet, _ sdk.AccAddress, ) ibcexported.Acknowledgement { - err := sdkerrors.Wrapf(icatypes.ErrInvalidChannelFlow, "cannot receive packet on controller chain") + err := errorsmod.Wrapf(icatypes.ErrInvalidChannelFlow, "cannot receive packet on controller chain") ack := channeltypes.NewErrorAcknowledgement(err) keeper.EmitAcknowledgementEvent(ctx, packet, ack, err) return ack @@ -155,8 +186,17 @@ func (im IBCMiddleware) OnAcknowledgementPacket( return types.ErrControllerSubModuleDisabled } + connectionID, err := im.keeper.GetConnectionID(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if err != nil { + return err + } + // call underlying app's OnAcknowledgementPacket callback. - return im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) + if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, packet.GetSourcePort(), connectionID) { + return im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) + } + + return nil } // OnTimeoutPacket implements the IBCMiddleware interface @@ -173,15 +213,28 @@ func (im IBCMiddleware) OnTimeoutPacket( return err } - return im.app.OnTimeoutPacket(ctx, packet, relayer) + connectionID, err := im.keeper.GetConnectionID(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if err != nil { + return err + } + + if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, packet.GetSourcePort(), connectionID) { + return im.app.OnTimeoutPacket(ctx, packet, relayer) + } + + return nil } // SendPacket implements the ICS4 Wrapper interface func (im IBCMiddleware) SendPacket( ctx sdk.Context, chanCap *capabilitytypes.Capability, - packet ibcexported.PacketI, -) error { + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, +) (uint64, error) { panic("SendPacket not supported for ICA controller module. Please use SendTx") } diff --git a/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go b/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go index b326c0bb71f..3826dea0c79 100644 --- a/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go +++ b/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go @@ -7,31 +7,26 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/stretchr/testify/suite" - "github.com/tendermint/tendermint/crypto" - - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - fee "github.com/cosmos/ibc-go/v4/modules/apps/29-fee" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller" + controllerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + fee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" + 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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) var ( - // TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module() - // https://github.com/cosmos/cosmos-sdk/issues/10225 - // - // TestAccAddress defines a resuable bech32 address for testing purposes - TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), ibctesting.FirstConnectionID, TestPortID) - // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" - // TestPortID defines a resuable port identifier for testing purposes + // TestPortID defines a reusable port identifier for testing purposes TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) - // TestVersion defines a resuable interchainaccounts version string for testing purposes + // TestVersion defines a reusable interchainaccounts version string for testing purposes TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ Version: icatypes.Version, ControllerConnectionId: ibctesting.FirstConnectionID, @@ -65,8 +60,8 @@ func (suite *InterchainAccountsTestSuite) SetupTest() { func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) - path.EndpointA.ChannelConfig.PortID = icatypes.PortID - path.EndpointB.ChannelConfig.PortID = icatypes.PortID + path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED path.EndpointA.ChannelConfig.Version = TestVersion @@ -120,7 +115,11 @@ func SetupICAPath(path *ibctesting.Path, owner string) error { } func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { - var channel *channeltypes.Channel + var ( + channel *channeltypes.Channel + isNilApp bool + path *ibctesting.Path + ) testCases := []struct { name string @@ -130,6 +129,20 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { { "success", func() {}, true, }, + { + "ICA auth module does not claim channel capability", func() { + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanOpenInit = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string, + portID, channelID string, chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, version string, + ) (string, error) { + if chanCap != nil { + return "", fmt.Errorf("channel capability should be nil") + } + + return version, nil + } + }, true, + }, { "ICA auth module modification of channel version is ignored", func() { // NOTE: explicitly modify the channel version via the auth module callback, @@ -162,6 +175,23 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { } }, false, }, + { + "nil underlying app", func() { + isNilApp = true + }, true, + }, + { + "middleware disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.DeleteMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanOpenInit = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string, + portID, channelID string, chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, version string, + ) (string, error) { + return "", fmt.Errorf("error should be unreachable") + } + }, true, + }, } for _, tc := range testCases { @@ -169,8 +199,9 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { suite.Run(tc.name, func() { suite.SetupTest() // reset + isNilApp = false - path := NewICAPath(suite.chainA, suite.chainB) + path = NewICAPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) // mock init interchain account @@ -178,11 +209,13 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { suite.Require().NoError(err) portCap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) - suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) + suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) //nolint:errcheck // checking this error isn't needed for the test path.EndpointA.ChannelConfig.PortID = portID path.EndpointA.ChannelID = ibctesting.FirstChannelID + suite.chainA.GetSimApp().ICAControllerKeeper.SetMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + // default values counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) channel = &channeltypes.Channel{ @@ -207,6 +240,10 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) suite.Require().True(ok) + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.GetVersion(), ) @@ -239,12 +276,14 @@ func (suite *InterchainAccountsTestSuite) TestChanOpenTry() { err = RegisterInterchainAccount(path.EndpointB, TestOwnerAddress) suite.Require().NoError(err) - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + channelKey := host.ChannelKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) proofInit, proofHeight := path.EndpointB.Chain.QueryProof(channelKey) // use chainA (controller) for ChanOpenTry - msg := channeltypes.NewMsgChannelOpenTry(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, TestVersion, channeltypes.ORDERED, []string{path.EndpointA.ConnectionID}, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, TestVersion, proofInit, proofHeight, icatypes.ModuleName) + msg := channeltypes.NewMsgChannelOpenTry(path.EndpointA.ChannelConfig.PortID, TestVersion, channeltypes.ORDERED, []string{path.EndpointA.ConnectionID}, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, TestVersion, proofInit, proofHeight, icatypes.ModuleName) handler := suite.chainA.GetSimApp().MsgServiceRouter().Handler(msg) _, err = handler(suite.chainA.GetContext(), msg) @@ -271,7 +310,10 @@ func (suite *InterchainAccountsTestSuite) TestChanOpenTry() { } func (suite *InterchainAccountsTestSuite) TestOnChanOpenAck() { - var path *ibctesting.Path + var ( + path *ibctesting.Path + isNilApp bool + ) testCases := []struct { name string @@ -300,6 +342,22 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenAck() { } }, false, }, + { + "nil underlying app", func() { + isNilApp = true + }, true, + }, + { + "middleware disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.DeleteMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanOpenAck = func( + ctx sdk.Context, portID, channelID string, counterpartyChannelID string, counterpartyVersion string, + ) error { + return fmt.Errorf("error should be unreachable") + } + }, true, + }, } for _, tc := range testCases { @@ -307,6 +365,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenAck() { suite.Run(tc.name, func() { suite.SetupTest() // reset + isNilApp = false path = NewICAPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) @@ -327,6 +386,10 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenAck() { err = cbs.OnChanOpenAck(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelID, path.EndpointB.ChannelConfig.Version) + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + if tc.expPass { suite.Require().NoError(err) } else { @@ -359,7 +422,8 @@ func (suite *InterchainAccountsTestSuite) TestChanOpenConfirm() { // commit state changes so proof can be created suite.chainB.NextBlock() - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) // query proof from ChainB channelKey := host.ChannelKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) @@ -407,7 +471,10 @@ func (suite *InterchainAccountsTestSuite) TestOnChanCloseInit() { } func (suite *InterchainAccountsTestSuite) TestOnChanCloseConfirm() { - var path *ibctesting.Path + var ( + path *ibctesting.Path + isNilApp bool + ) testCases := []struct { name string @@ -417,11 +484,17 @@ func (suite *InterchainAccountsTestSuite) TestOnChanCloseConfirm() { { "success", func() {}, true, }, + { + "nil underlying app", func() { + isNilApp = true + }, true, + }, } for _, tc := range testCases { suite.Run(tc.name, func() { suite.SetupTest() // reset + isNilApp = false path = NewICAPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) @@ -436,6 +509,10 @@ func (suite *InterchainAccountsTestSuite) TestOnChanCloseConfirm() { cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) suite.Require().True(ok) + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + err = cbs.OnChanCloseConfirm( suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) @@ -490,14 +567,17 @@ func (suite *InterchainAccountsTestSuite) TestOnRecvPacket() { 0, ) - ack := cbs.OnRecvPacket(suite.chainA.GetContext(), packet, TestAccAddress) + ack := cbs.OnRecvPacket(suite.chainA.GetContext(), packet, nil) suite.Require().Equal(tc.expPass, ack.Success()) }) } } func (suite *InterchainAccountsTestSuite) TestOnAcknowledgementPacket() { - var path *ibctesting.Path + var ( + path *ibctesting.Path + isNilApp bool + ) testCases := []struct { msg string @@ -523,11 +603,28 @@ func (suite *InterchainAccountsTestSuite) TestOnAcknowledgementPacket() { } }, false, }, + { + "nil underlying app", func() { + isNilApp = true + }, true, + }, + { + "middleware disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.DeleteMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnAcknowledgementPacket = func( + ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress, + ) error { + return fmt.Errorf("error should be unreachable") + } + }, true, + }, } for _, tc := range testCases { suite.Run(tc.msg, func() { suite.SetupTest() // reset + isNilApp = false path = NewICAPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) @@ -554,6 +651,10 @@ func (suite *InterchainAccountsTestSuite) TestOnAcknowledgementPacket() { cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) suite.Require().True(ok) + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + err = cbs.OnAcknowledgementPacket(suite.chainA.GetContext(), packet, []byte("ack"), nil) if tc.expPass { @@ -566,7 +667,10 @@ func (suite *InterchainAccountsTestSuite) TestOnAcknowledgementPacket() { } func (suite *InterchainAccountsTestSuite) TestOnTimeoutPacket() { - var path *ibctesting.Path + var ( + path *ibctesting.Path + isNilApp bool + ) testCases := []struct { msg string @@ -592,11 +696,28 @@ func (suite *InterchainAccountsTestSuite) TestOnTimeoutPacket() { } }, false, }, + { + "nil underlying app", func() { + isNilApp = true + }, true, + }, + { + "middleware disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.DeleteMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnTimeoutPacket = func( + ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress, + ) error { + return fmt.Errorf("error should be unreachable") + } + }, true, + }, } for _, tc := range testCases { suite.Run(tc.msg, func() { suite.SetupTest() // reset + isNilApp = false path = NewICAPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) @@ -623,6 +744,10 @@ func (suite *InterchainAccountsTestSuite) TestOnTimeoutPacket() { cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) suite.Require().True(ok) + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + err = cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, nil) if tc.expPass { @@ -719,3 +844,80 @@ func (suite *InterchainAccountsTestSuite) TestGetAppVersion() { suite.Require().True(found) suite.Require().Equal(path.EndpointA.ChannelConfig.Version, appVersion) } + +func (suite *InterchainAccountsTestSuite) TestInFlightHandshakeRespectsGoAPICaller() { + path := NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + // initiate a channel handshake such that channel.State == INIT + err := RegisterInterchainAccount(path.EndpointA, suite.chainA.SenderAccount.GetAddress().String()) + suite.Require().NoError(err) + + // attempt to start a second handshake via the controller msg server + msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), TestVersion) + + res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) + suite.Require().Error(err) + suite.Require().Nil(res) +} + +func (suite *InterchainAccountsTestSuite) TestInFlightHandshakeRespectsMsgServerCaller() { + path := NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + // initiate a channel handshake such that channel.State == INIT + msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), TestVersion) + + res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) + suite.Require().NotNil(res) + suite.Require().NoError(err) + + // attempt to start a second handshake via the legacy Go API + err = RegisterInterchainAccount(path.EndpointA, suite.chainA.SenderAccount.GetAddress().String()) + suite.Require().Error(err) +} + +func (suite *InterchainAccountsTestSuite) TestClosedChannelReopensWithMsgServer() { + path := NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, suite.chainA.SenderAccount.GetAddress().String()) + suite.Require().NoError(err) + + // set the channel state to closed + err = path.EndpointA.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) + err = path.EndpointB.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) + + // reset endpoint channel ids + path.EndpointA.ChannelID = "" + path.EndpointB.ChannelID = "" + + // fetch the next channel sequence before reinitiating the channel handshake + channelSeq := suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(suite.chainA.GetContext()) + + // route a new MsgRegisterInterchainAccount in order to reopen the + msgServer := controllerkeeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + msgRegisterInterchainAccount := types.NewMsgRegisterInterchainAccount(path.EndpointA.ConnectionID, suite.chainA.SenderAccount.GetAddress().String(), path.EndpointA.ChannelConfig.Version) + + res, err := msgServer.RegisterInterchainAccount(suite.chainA.GetContext(), msgRegisterInterchainAccount) + suite.Require().NoError(err) + suite.Require().Equal(channeltypes.FormatChannelIdentifier(channelSeq), res.ChannelId) + + // assign the channel sequence to endpointA before generating proofs and initiating the TRY step + path.EndpointA.ChannelID = channeltypes.FormatChannelIdentifier(channelSeq) + + path.EndpointA.Chain.NextBlock() + + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanOpenAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanOpenConfirm() + suite.Require().NoError(err) +} diff --git a/modules/apps/27-interchain-accounts/controller/keeper/account.go b/modules/apps/27-interchain-accounts/controller/keeper/account.go index e16f2d0874d..5044e50b962 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account.go @@ -1,12 +1,15 @@ package keeper import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/internal/logging" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // RegisterInterchainAccount is the entry point to registering an interchain account: @@ -16,38 +19,72 @@ import ( // - A new MsgChannelOpenInit is routed through the MsgServiceRouter, executing the OnOpenChanInit callback stack as configured. // - An error is returned if the port identifier is already in use. Gaining access to interchain accounts whose channels // have closed cannot be done with this function. A regular MsgChannelOpenInit must be used. +// +// Deprecated: this is a legacy API that is only intended to function correctly in workflows where an underlying authentication application has been set. +// Calling this API will result in all packet callbacks being routed to the underlying application. + +// Please use MsgRegisterInterchainAccount for use cases which do not need to route to an underlying application. + +// Prior to v6.x.x of ibc-go, the controller module was only functional as middleware, with authentication performed +// by the underlying application. For a full summary of the changes in v6.x.x, please see ADR009. +// This API will be removed in later releases. func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, connectionID, owner, version string) error { portID, err := icatypes.NewControllerPortID(owner) if err != nil { return err } + if k.IsMiddlewareDisabled(ctx, portID, connectionID) && !k.IsActiveChannelClosed(ctx, connectionID, portID) { + return errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel is already active or a handshake is in flight") + } + + k.SetMiddlewareEnabled(ctx, portID, connectionID) + + _, err = k.registerInterchainAccount(ctx, connectionID, portID, version) + if err != nil { + return err + } + + return nil +} + +// registerInterchainAccount registers an interchain account, returning the channel id of the MsgChannelOpenInitResponse +// and an error if one occurred. +func (k Keeper) registerInterchainAccount(ctx sdk.Context, connectionID, portID, version string) (string, error) { // if there is an active channel for this portID / connectionID return an error activeChannelID, found := k.GetOpenActiveChannel(ctx, connectionID, portID) if found { - return sdkerrors.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s on connection %s for owner %s", activeChannelID, portID, connectionID, owner) + return "", errorsmod.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s on connection %s", activeChannelID, portID, connectionID) } switch { case k.portKeeper.IsBound(ctx, portID) && !k.IsBound(ctx, portID): - return sdkerrors.Wrapf(icatypes.ErrPortAlreadyBound, "another module has claimed capability for and bound port with portID: %s", portID) + return "", errorsmod.Wrapf(icatypes.ErrPortAlreadyBound, "another module has claimed capability for and bound port with portID: %s", portID) case !k.portKeeper.IsBound(ctx, portID): cap := k.BindPort(ctx, portID) if err := k.ClaimCapability(ctx, cap, host.PortPath(portID)); err != nil { - return sdkerrors.Wrapf(err, "unable to bind to newly generated portID: %s", portID) + return "", errorsmod.Wrapf(err, "unable to bind to newly generated portID: %s", portID) } } - msg := channeltypes.NewMsgChannelOpenInit(portID, version, channeltypes.ORDERED, []string{connectionID}, icatypes.PortID, icatypes.ModuleName) + msg := channeltypes.NewMsgChannelOpenInit(portID, version, channeltypes.ORDERED, []string{connectionID}, icatypes.HostPortID, authtypes.NewModuleAddress(icatypes.ModuleName).String()) handler := k.msgRouter.Handler(msg) - res, err := handler(ctx, msg) if err != nil { - return err + return "", err } + events := res.GetEvents() + k.Logger(ctx).Debug("emitting interchain account registration events", logging.SdkEventsToLogArguments(events)) + // NOTE: The sdk msg handler creates a new EventManager, so events must be correctly propagated back to the current context - ctx.EventManager().EmitEvents(res.GetEvents()) + ctx.EventManager().EmitEvents(events) - return nil + firstMsgResponse := res.MsgResponses[0] + channelOpenInitResponse, ok := firstMsgResponse.GetCachedValue().(*channeltypes.MsgChannelOpenInitResponse) + if !ok { + return "", errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to covert %T message response to %T", firstMsgResponse.GetCachedValue(), &channeltypes.MsgChannelOpenInitResponse{}) + } + + return channelOpenInitResponse.ChannelId, nil } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/account_test.go b/modules/apps/27-interchain-accounts/controller/keeper/account_test.go index 5d8854eea59..33ec4d6448f 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account_test.go @@ -1,10 +1,10 @@ package keeper_test import ( - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { diff --git a/modules/apps/27-interchain-accounts/controller/keeper/events.go b/modules/apps/27-interchain-accounts/controller/keeper/events.go index 8381fe7bec7..d712409785a 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/events.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/events.go @@ -5,8 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // EmitAcknowledgementEvent emits an event signalling a successful or failed acknowledgement and including the error diff --git a/modules/apps/27-interchain-accounts/controller/keeper/genesis.go b/modules/apps/27-interchain-accounts/controller/keeper/genesis.go index 88ca396b93b..ea5cbd822cd 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/genesis.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/genesis.go @@ -5,12 +5,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // InitGenesis initializes the interchain accounts controller application state from a provided genesis state -func InitGenesis(ctx sdk.Context, keeper Keeper, state icatypes.ControllerGenesisState) { +func InitGenesis(ctx sdk.Context, keeper Keeper, state genesistypes.ControllerGenesisState) { for _, portID := range state.Ports { if !keeper.IsBound(ctx, portID) { cap := keeper.BindPort(ctx, portID) @@ -22,6 +22,12 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, state icatypes.ControllerGenesi for _, ch := range state.ActiveChannels { keeper.SetActiveChannelID(ctx, ch.ConnectionId, ch.PortId, ch.ChannelId) + + if ch.IsMiddlewareEnabled { + keeper.SetMiddlewareEnabled(ctx, ch.PortId, ch.ConnectionId) + } else { + keeper.SetMiddlewareDisabled(ctx, ch.PortId, ch.ConnectionId) + } } for _, acc := range state.InterchainAccounts { @@ -32,8 +38,8 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, state icatypes.ControllerGenesi } // ExportGenesis returns the interchain accounts controller exported genesis -func ExportGenesis(ctx sdk.Context, keeper Keeper) icatypes.ControllerGenesisState { - return icatypes.NewControllerGenesisState( +func ExportGenesis(ctx sdk.Context, keeper Keeper) genesistypes.ControllerGenesisState { + return genesistypes.NewControllerGenesisState( keeper.GetAllActiveChannels(ctx), keeper.GetAllInterchainAccounts(ctx), keeper.GetAllPorts(ctx), diff --git a/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go b/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go index 348294fbc8a..a44ea5dc3d9 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/genesis_test.go @@ -1,28 +1,37 @@ package keeper_test import ( - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/keeper" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestInitGenesis() { suite.SetupTest() - genesisState := icatypes.ControllerGenesisState{ - ActiveChannels: []icatypes.ActiveChannel{ + interchainAccAddr := icatypes.GenerateAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, TestPortID) + genesisState := genesistypes.ControllerGenesisState{ + ActiveChannels: []genesistypes.ActiveChannel{ { - ConnectionId: ibctesting.FirstConnectionID, - PortId: TestPortID, - ChannelId: ibctesting.FirstChannelID, + ConnectionId: ibctesting.FirstConnectionID, + PortId: TestPortID, + ChannelId: ibctesting.FirstChannelID, + IsMiddlewareEnabled: true, + }, + { + ConnectionId: "connection-1", + PortId: "test-port-1", + ChannelId: "channel-1", + IsMiddlewareEnabled: false, }, }, - InterchainAccounts: []icatypes.RegisteredInterchainAccount{ + InterchainAccounts: []genesistypes.RegisteredInterchainAccount{ { ConnectionId: ibctesting.FirstConnectionID, PortId: TestPortID, - AccountAddress: TestAccAddress.String(), + AccountAddress: interchainAccAddr.String(), }, }, Ports: []string{TestPortID}, @@ -34,9 +43,15 @@ func (suite *KeeperTestSuite) TestInitGenesis() { suite.Require().True(found) suite.Require().Equal(ibctesting.FirstChannelID, channelID) + isMiddlewareEnabled := suite.chainA.GetSimApp().ICAControllerKeeper.IsMiddlewareEnabled(suite.chainA.GetContext(), TestPortID, ibctesting.FirstConnectionID) + suite.Require().True(isMiddlewareEnabled) + + isMiddlewareDisabled := suite.chainA.GetSimApp().ICAControllerKeeper.IsMiddlewareDisabled(suite.chainA.GetContext(), "test-port-1", "connection-1") + suite.Require().True(isMiddlewareDisabled) + accountAdrr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, TestPortID) suite.Require().True(found) - suite.Require().Equal(TestAccAddress.String(), accountAdrr) + suite.Require().Equal(interchainAccAddr.String(), accountAdrr) expParams := types.NewParams(false) params := suite.chainA.GetSimApp().ICAControllerKeeper.GetParams(suite.chainA.GetContext()) @@ -52,12 +67,16 @@ func (suite *KeeperTestSuite) TestExportGenesis() { err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) + genesisState := keeper.ExportGenesis(suite.chainA.GetContext(), suite.chainA.GetSimApp().ICAControllerKeeper) suite.Require().Equal(path.EndpointA.ChannelID, genesisState.ActiveChannels[0].ChannelId) suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.ActiveChannels[0].PortId) + suite.Require().True(genesisState.ActiveChannels[0].IsMiddlewareEnabled) - suite.Require().Equal(TestAccAddress.String(), genesisState.InterchainAccounts[0].AccountAddress) + suite.Require().Equal(interchainAccAddr, genesisState.InterchainAccounts[0].AccountAddress) suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.InterchainAccounts[0].PortId) suite.Require().Equal([]string{TestPortID}, genesisState.GetPorts()) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/grpc_query.go b/modules/apps/27-interchain-accounts/controller/keeper/grpc_query.go index e23edc5017e..a00b4854d59 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/grpc_query.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/grpc_query.go @@ -4,16 +4,41 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ) var _ types.QueryServer = Keeper{} +// InterchainAccount implements the Query/InterchainAccount gRPC method +func (k Keeper) InterchainAccount(goCtx context.Context, req *types.QueryInterchainAccountRequest) (*types.QueryInterchainAccountResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + portID, err := icatypes.NewControllerPortID(req.Owner) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "failed to generate portID from owner address: %s", err) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + addr, found := k.GetInterchainAccountAddress(ctx, req.ConnectionId, portID) + if !found { + return nil, status.Errorf(codes.NotFound, "failed to retrieve account address for %s on connection %s", portID, req.ConnectionId) + } + + return &types.QueryInterchainAccountResponse{ + Address: addr, + }, nil +} + // Params implements the Query/Params gRPC method -func (q Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { +func (k Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { ctx := sdk.UnwrapSDKContext(c) - params := q.GetParams(ctx) + params := k.GetParams(ctx) return &types.QueryParamsResponse{ Params: ¶ms, diff --git a/modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go b/modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go index ba54ce876bc..f1f6355f272 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/grpc_query_test.go @@ -3,9 +3,78 @@ package keeper_test import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) +func (suite *KeeperTestSuite) TestQueryInterchainAccount() { + var req *types.QueryInterchainAccountRequest + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "empty request", + func() { + req = nil + }, + false, + }, + { + "empty owner address", + func() { + req.Owner = "" + }, + false, + }, + { + "invalid connection, account address not found", + func() { + req.ConnectionId = "invalid-connection-id" + }, + false, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + suite.SetupTest() + + path := NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, ibctesting.TestAccAddress) + suite.Require().NoError(err) + + req = &types.QueryInterchainAccountRequest{ + ConnectionId: ibctesting.FirstConnectionID, + Owner: ibctesting.TestAccAddress, + } + + tc.malleate() + + res, err := suite.chainA.GetSimApp().ICAControllerKeeper.InterchainAccount(sdk.WrapSDKContext(suite.chainA.GetContext()), req) + + if tc.expPass { + expAddress, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) + + suite.Require().NoError(err) + suite.Require().Equal(expAddress, res.Address) + } else { + suite.Require().Error(err) + } + }) + } +} + func (suite *KeeperTestSuite) TestQueryParams() { ctx := sdk.WrapSDKContext(suite.chainA.GetContext()) expParams := types.DefaultParams() diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index 337610f4a3b..916f32382f2 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -4,12 +4,12 @@ import ( "fmt" "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // OnChanOpenInit performs basic validation of channel initialization. @@ -30,15 +30,15 @@ func (k Keeper) OnChanOpenInit( version string, ) (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) } - if !strings.HasPrefix(portID, icatypes.PortPrefix) { - return "", sdkerrors.Wrapf(icatypes.ErrInvalidControllerPort, "expected %s{owner-account-address}, got %s", icatypes.PortPrefix, portID) + if !strings.HasPrefix(portID, icatypes.ControllerPortPrefix) { + return "", errorsmod.Wrapf(icatypes.ErrInvalidControllerPort, "expected %s{owner-account-address}, got %s", icatypes.ControllerPortPrefix, portID) } - if counterparty.PortId != icatypes.PortID { - return "", sdkerrors.Wrapf(icatypes.ErrInvalidHostPort, "expected %s, got %s", icatypes.PortID, counterparty.PortId) + if counterparty.PortId != icatypes.HostPortID { + return "", errorsmod.Wrapf(icatypes.ErrInvalidHostPort, "expected %s, got %s", icatypes.HostPortID, counterparty.PortId) } var metadata icatypes.Metadata @@ -51,7 +51,7 @@ func (k Keeper) OnChanOpenInit( metadata = icatypes.NewDefaultMetadata(connectionHops[0], connection.GetCounterparty().GetConnectionID()) } else { if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(version), &metadata); err != nil { - return "", sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") + return "", errorsmod.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") } } @@ -67,11 +67,16 @@ func (k Keeper) OnChanOpenInit( } if channel.State == channeltypes.OPEN { - return "", sdkerrors.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s is already OPEN", activeChannelID, portID) + return "", errorsmod.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s is already OPEN", activeChannelID, portID) } - if !icatypes.IsPreviousMetadataEqual(channel.Version, metadata) { - return "", sdkerrors.Wrap(icatypes.ErrInvalidVersion, "previous active channel metadata does not match provided version") + appVersion, found := k.GetAppVersion(ctx, portID, activeChannelID) + if !found { + panic(fmt.Sprintf("active channel mapping set for %s, but channel does not exist in channel store", activeChannelID)) + } + + if !icatypes.IsPreviousMetadataEqual(appVersion, metadata) { + return "", errorsmod.Wrap(icatypes.ErrInvalidVersion, "previous active channel metadata does not match provided version") } } @@ -86,26 +91,26 @@ func (k Keeper) OnChanOpenAck( channelID string, counterpartyVersion string, ) error { - if portID == icatypes.PortID { - return sdkerrors.Wrapf(icatypes.ErrInvalidControllerPort, "portID cannot be host chain port ID: %s", icatypes.PortID) + if portID == icatypes.HostPortID { + return errorsmod.Wrapf(icatypes.ErrInvalidControllerPort, "portID cannot be host chain port ID: %s", icatypes.HostPortID) } - if !strings.HasPrefix(portID, icatypes.PortPrefix) { - return sdkerrors.Wrapf(icatypes.ErrInvalidControllerPort, "expected %s{owner-account-address}, got %s", icatypes.PortPrefix, portID) + if !strings.HasPrefix(portID, icatypes.ControllerPortPrefix) { + return errorsmod.Wrapf(icatypes.ErrInvalidControllerPort, "expected %s{owner-account-address}, got %s", icatypes.ControllerPortPrefix, portID) } var metadata icatypes.Metadata if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &metadata); err != nil { - return sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") + return errorsmod.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") } if activeChannelID, found := k.GetOpenActiveChannel(ctx, metadata.ControllerConnectionId, portID); found { - return sdkerrors.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s", activeChannelID, portID) + return errorsmod.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s", activeChannelID, portID) } channel, found := k.channelKeeper.GetChannel(ctx, portID, channelID) if !found { - return sdkerrors.Wrapf(channeltypes.ErrChannelNotFound, "failed to retrieve channel %s on port %s", channelID, portID) + return errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "failed to retrieve channel %s on port %s", channelID, portID) } if err := icatypes.ValidateControllerMetadata(ctx, k.channelKeeper, channel.ConnectionHops, metadata); err != nil { @@ -113,7 +118,7 @@ func (k Keeper) OnChanOpenAck( } if strings.TrimSpace(metadata.Address) == "" { - return sdkerrors.Wrap(icatypes.ErrInvalidAccountAddress, "interchain account address cannot be empty") + return errorsmod.Wrap(icatypes.ErrInvalidAccountAddress, "interchain account address cannot be empty") } k.SetActiveChannelID(ctx, metadata.ControllerConnectionId, portID, channelID) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go index 87338812aba..79df5aadad6 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -3,10 +3,10 @@ package keeper_test import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestOnChanOpenInit() { @@ -24,9 +24,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { }{ { "success", - func() { - path.EndpointA.SetChannel(*channel) - }, + func() {}, true, }, { @@ -54,30 +52,44 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { }, true, }, + { + "success: channel reopening", + func() { + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + err = path.EndpointA.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) + + err = path.EndpointB.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) + + path.EndpointA.ChannelID = "" + path.EndpointB.ChannelID = "" + }, + true, + }, { "invalid metadata - previous metadata is different", func() { // set active channel to closed suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + // attempt to downgrade version by reinitializing channel with version 1, but setting channel to version 2 + metadata.Version = "ics27-2" + + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) closedChannel := channeltypes.Channel{ State: channeltypes.CLOSED, Ordering: channeltypes.ORDERED, Counterparty: counterparty, ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: TestVersion, + Version: string(versionBytes), } - path.EndpointA.SetChannel(closedChannel) - - // modify metadata - metadata.Version = "ics27-2" - - versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) - suite.Require().NoError(err) - - channel.Version = string(versionBytes) }, false, }, @@ -91,7 +103,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { { "invalid port ID", func() { - path.EndpointA.ChannelConfig.PortID = "invalid-port-id" + path.EndpointA.ChannelConfig.PortID = "invalid-port-id" //nolint:goconst }, false, }, @@ -225,7 +237,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { suite.Require().NoError(err) portCap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) - suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) + suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) //nolint:errcheck // this error check isn't needed for tests path.EndpointA.ChannelConfig.PortID = portID // default values @@ -278,7 +290,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { { "invalid port ID - host chain", func() { - path.EndpointA.ChannelConfig.PortID = icatypes.PortID + path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID }, false, }, @@ -384,7 +396,10 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { err = path.EndpointB.ChanOpenTry() suite.Require().NoError(err) - metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, TestAccAddress.String(), icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) + + metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, interchainAccAddr, icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/keeper.go b/modules/apps/27-interchain-accounts/controller/keeper/keeper.go index 3ecdb169197..061a20a233c 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/keeper.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/keeper.go @@ -1,43 +1,47 @@ package keeper import ( + "bytes" "fmt" "strings" - baseapp "github.com/cosmos/cosmos-sdk/baseapp" + 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" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/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" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // Keeper defines the IBC interchain accounts controller keeper type Keeper struct { - storeKey sdk.StoreKey + storeKey storetypes.StoreKey cdc codec.BinaryCodec paramSpace paramtypes.Subspace - ics4Wrapper icatypes.ICS4Wrapper + ics4Wrapper porttypes.ICS4Wrapper channelKeeper icatypes.ChannelKeeper portKeeper icatypes.PortKeeper - scopedKeeper capabilitykeeper.ScopedKeeper + scopedKeeper exported.ScopedKeeper - msgRouter *baseapp.MsgServiceRouter + msgRouter icatypes.MessageRouter } // NewKeeper creates a new interchain accounts controller Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Subspace, - ics4Wrapper icatypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, - scopedKeeper capabilitykeeper.ScopedKeeper, msgRouter *baseapp.MsgServiceRouter, + cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, + ics4Wrapper porttypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, + scopedKeeper exported.ScopedKeeper, msgRouter icatypes.MessageRouter, ) Keeper { // set KeyTable if it has not already been set if !paramSpace.HasKeyTable() { @@ -58,14 +62,23 @@ func NewKeeper( // Logger returns the application logger, scoped to the associated module func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", fmt.Sprintf("x/%s-%s", host.ModuleName, icatypes.ModuleName)) + return ctx.Logger().With("module", fmt.Sprintf("x/%s-%s", exported.ModuleName, icatypes.ModuleName)) +} + +// GetConnectionID returns the connection id for the given port and channelIDs. +func (k Keeper) GetConnectionID(ctx sdk.Context, portID, channelID string) (string, error) { + channel, found := k.channelKeeper.GetChannel(ctx, portID, channelID) + if !found { + return "", errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + return channel.ConnectionHops[0], nil } // GetAllPorts returns all ports to which the interchain accounts controller module is bound. Used in ExportGenesis func (k Keeper) GetAllPorts(ctx sdk.Context) []string { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(icatypes.PortKeyPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) var ports []string for ; iterator.Valid(); iterator.Next() { @@ -134,20 +147,36 @@ func (k Keeper) GetOpenActiveChannel(ctx sdk.Context, connectionID, portID strin return "", false } +// IsActiveChannelClosed retrieves the active channel from the store and returns true if the channel state is CLOSED, otherwise false +func (k Keeper) IsActiveChannelClosed(ctx sdk.Context, connectionID, portID string) bool { + channelID, found := k.GetActiveChannelID(ctx, connectionID, portID) + if !found { + return false + } + + channel, found := k.channelKeeper.GetChannel(ctx, portID, channelID) + return found && channel.State == channeltypes.CLOSED +} + // GetAllActiveChannels returns a list of all active interchain accounts controller channels and their associated connection and port identifiers -func (k Keeper) GetAllActiveChannels(ctx sdk.Context) []icatypes.ActiveChannel { +func (k Keeper) GetAllActiveChannels(ctx sdk.Context) []genesistypes.ActiveChannel { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(icatypes.ActiveChannelKeyPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) - var activeChannels []icatypes.ActiveChannel + var activeChannels []genesistypes.ActiveChannel for ; iterator.Valid(); iterator.Next() { keySplit := strings.Split(string(iterator.Key()), "/") - ch := icatypes.ActiveChannel{ - ConnectionId: keySplit[2], - PortId: keySplit[1], - ChannelId: string(iterator.Value()), + portID := keySplit[1] + connectionID := keySplit[2] + channelID := string(iterator.Value()) + + ch := genesistypes.ActiveChannel{ + ConnectionId: connectionID, + PortId: portID, + ChannelId: channelID, + IsMiddlewareEnabled: k.IsMiddlewareEnabled(ctx, portID, connectionID), } activeChannels = append(activeChannels, ch) @@ -181,15 +210,15 @@ func (k Keeper) GetInterchainAccountAddress(ctx sdk.Context, connectionID, portI } // GetAllInterchainAccounts returns a list of all registered interchain account addresses and their associated connection and controller port identifiers -func (k Keeper) GetAllInterchainAccounts(ctx sdk.Context) []icatypes.RegisteredInterchainAccount { +func (k Keeper) GetAllInterchainAccounts(ctx sdk.Context) []genesistypes.RegisteredInterchainAccount { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(icatypes.OwnerKeyPrefix)) - var interchainAccounts []icatypes.RegisteredInterchainAccount + var interchainAccounts []genesistypes.RegisteredInterchainAccount for ; iterator.Valid(); iterator.Next() { keySplit := strings.Split(string(iterator.Key()), "/") - acc := icatypes.RegisteredInterchainAccount{ + acc := genesistypes.RegisteredInterchainAccount{ ConnectionId: keySplit[2], PortId: keySplit[1], AccountAddress: string(iterator.Value()), @@ -206,3 +235,33 @@ func (k Keeper) SetInterchainAccountAddress(ctx sdk.Context, connectionID, portI store := ctx.KVStore(k.storeKey) store.Set(icatypes.KeyOwnerAccount(portID, connectionID), []byte(address)) } + +// IsMiddlewareEnabled returns true if the underlying application callbacks are enabled for given port and connection identifier pair, otherwise false +func (k Keeper) IsMiddlewareEnabled(ctx sdk.Context, portID, connectionID string) bool { + store := ctx.KVStore(k.storeKey) + return bytes.Equal(icatypes.MiddlewareEnabled, store.Get(icatypes.KeyIsMiddlewareEnabled(portID, connectionID))) +} + +// IsMiddlewareDisabled returns true if the underlying application callbacks are disabled for the given port and connection identifier pair, otherwise false +func (k Keeper) IsMiddlewareDisabled(ctx sdk.Context, portID, connectionID string) bool { + store := ctx.KVStore(k.storeKey) + return bytes.Equal(icatypes.MiddlewareDisabled, store.Get(icatypes.KeyIsMiddlewareEnabled(portID, connectionID))) +} + +// SetMiddlewareEnabled stores a flag to indicate that the underlying application callbacks should be enabled for the given port and connection identifier pair +func (k Keeper) SetMiddlewareEnabled(ctx sdk.Context, portID, connectionID string) { + store := ctx.KVStore(k.storeKey) + store.Set(icatypes.KeyIsMiddlewareEnabled(portID, connectionID), icatypes.MiddlewareEnabled) +} + +// SetMiddlewareDisabled stores a flag to indicate that the underlying application callbacks should be disabled for the given port and connection identifier pair +func (k Keeper) SetMiddlewareDisabled(ctx sdk.Context, portID, connectionID string) { + store := ctx.KVStore(k.storeKey) + store.Set(icatypes.KeyIsMiddlewareEnabled(portID, connectionID), icatypes.MiddlewareDisabled) +} + +// DeleteMiddlewareEnabled deletes the middleware enabled flag stored in state +func (k Keeper) DeleteMiddlewareEnabled(ctx sdk.Context, portID, connectionID string) { + store := ctx.KVStore(k.storeKey) + store.Delete(icatypes.KeyIsMiddlewareEnabled(portID, connectionID)) +} diff --git a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go index 602cb69426f..0583912165b 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go @@ -3,29 +3,22 @@ package keeper_test import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" - "github.com/tendermint/tendermint/crypto" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) var ( - // TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module() - // https://github.com/cosmos/cosmos-sdk/issues/10225 - // - // TestAccAddress defines a resuable bech32 address for testing purposes - TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), ibctesting.FirstConnectionID, TestPortID) - // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" - // TestPortID defines a resuable port identifier for testing purposes + // TestPortID defines a reusable port identifier for testing purposes TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) - // TestVersion defines a resuable interchainaccounts version string for testing purposes + // TestVersion defines a reusable interchainaccounts version string for testing purposes TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ Version: icatypes.Version, ControllerConnectionId: ibctesting.FirstConnectionID, @@ -55,8 +48,8 @@ func (suite *KeeperTestSuite) SetupTest() { func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) - path.EndpointA.ChannelConfig.PortID = icatypes.PortID - path.EndpointB.ChannelConfig.PortID = icatypes.PortID + path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED path.EndpointA.ChannelConfig.Version = TestVersion @@ -152,11 +145,10 @@ func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() { suite.Require().NoError(err) counterpartyPortID := path.EndpointA.ChannelConfig.PortID - expectedAddr := icatypes.GenerateAddress(suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(icatypes.ModuleName), ibctesting.FirstConnectionID, counterpartyPortID) retrievedAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, counterpartyPortID) suite.Require().True(found) - suite.Require().Equal(expectedAddr.String(), retrievedAddr) + suite.Require().NotEmpty(retrievedAddr) retrievedAddr, found = suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), "invalid conn", "invalid port") suite.Require().False(found) @@ -165,8 +157,8 @@ func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() { func (suite *KeeperTestSuite) TestGetAllActiveChannels() { var ( - expectedChannelID string = "test-channel" - expectedPortID string = "test-port" + expectedChannelID = "test-channel" + expectedPortID = "test-port" ) suite.SetupTest() @@ -179,16 +171,18 @@ func (suite *KeeperTestSuite) TestGetAllActiveChannels() { suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedChannelID) - expectedChannels := []icatypes.ActiveChannel{ + expectedChannels := []genesistypes.ActiveChannel{ { - ConnectionId: ibctesting.FirstConnectionID, - PortId: TestPortID, - ChannelId: path.EndpointA.ChannelID, + ConnectionId: ibctesting.FirstConnectionID, + PortId: TestPortID, + ChannelId: path.EndpointA.ChannelID, + IsMiddlewareEnabled: true, }, { - ConnectionId: ibctesting.FirstConnectionID, - PortId: expectedPortID, - ChannelId: expectedChannelID, + ConnectionId: ibctesting.FirstConnectionID, + PortId: expectedPortID, + ChannelId: expectedChannelID, + IsMiddlewareEnabled: false, }, } @@ -199,8 +193,8 @@ func (suite *KeeperTestSuite) TestGetAllActiveChannels() { func (suite *KeeperTestSuite) TestGetAllInterchainAccounts() { var ( - expectedAccAddr string = "test-acc-addr" - expectedPortID string = "test-port" + expectedAccAddr = "test-acc-addr" + expectedPortID = "test-port" ) suite.SetupTest() @@ -211,13 +205,16 @@ func (suite *KeeperTestSuite) TestGetAllInterchainAccounts() { err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) + suite.chainA.GetSimApp().ICAControllerKeeper.SetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr) - expectedAccounts := []icatypes.RegisteredInterchainAccount{ + expectedAccounts := []genesistypes.RegisteredInterchainAccount{ { ConnectionId: ibctesting.FirstConnectionID, PortId: TestPortID, - AccountAddress: TestAccAddress.String(), + AccountAddress: interchainAccAddr, }, { ConnectionId: ibctesting.FirstConnectionID, @@ -248,8 +245,8 @@ func (suite *KeeperTestSuite) TestIsActiveChannel() { func (suite *KeeperTestSuite) TestSetInterchainAccountAddress() { var ( - expectedAccAddr string = "test-acc-addr" - expectedPortID string = "test-port" + expectedAccAddr = "test-acc-addr" + expectedPortID = "test-port" ) suite.chainA.GetSimApp().ICAControllerKeeper.SetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/migrations.go b/modules/apps/27-interchain-accounts/controller/keeper/migrations.go new file mode 100644 index 00000000000..92a3a21d8e3 --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/keeper/migrations.go @@ -0,0 +1,50 @@ +package keeper + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" +) + +// Migrator is a struct for handling in-place store migrations. +type Migrator struct { + keeper *Keeper +} + +// NewMigrator returns a new Migrator. +func NewMigrator(keeper *Keeper) Migrator { + return Migrator{keeper: keeper} +} + +// AssertChannelCapabilityMigrations checks that all channel capabilities generated using the interchain accounts controller port prefix +// are owned by the controller submodule and ibc. +func (m Migrator) AssertChannelCapabilityMigrations(ctx sdk.Context) error { + if m.keeper != nil { + logger := m.keeper.Logger(ctx) + filteredChannels := m.keeper.channelKeeper.GetAllChannelsWithPortPrefix(ctx, icatypes.ControllerPortPrefix) + for _, ch := range filteredChannels { + name := host.ChannelCapabilityPath(ch.PortId, ch.ChannelId) + capability, found := m.keeper.scopedKeeper.GetCapability(ctx, name) + if !found { + logger.Error(fmt.Sprintf("failed to find capability: %s", name)) + return errorsmod.Wrapf(capabilitytypes.ErrCapabilityNotFound, "failed to find capability: %s", name) + } + + isAuthenticated := m.keeper.scopedKeeper.AuthenticateCapability(ctx, capability, name) + if !isAuthenticated { + logger.Error(fmt.Sprintf("expected capability owner: %s", controllertypes.SubModuleName)) + return errorsmod.Wrapf(capabilitytypes.ErrCapabilityNotOwned, "expected capability owner: %s", controllertypes.SubModuleName) + } + + m.keeper.SetMiddlewareEnabled(ctx, ch.PortId, ch.ConnectionHops[0]) + logger.Info("successfully migrated channel capability", "name", name) + } + } + return nil +} diff --git a/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go b/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go new file mode 100644 index 00000000000..00ef1fc8279 --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/keeper/migrations_test.go @@ -0,0 +1,75 @@ +package keeper_test + +import ( + "fmt" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func (suite *KeeperTestSuite) TestAssertChannelCapabilityMigrations() { + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "channel with different port is filtered out", + func() { + portIDWithOutPrefix := ibctesting.MockPort + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), portIDWithOutPrefix, ibctesting.FirstChannelID, channeltypes.Channel{ + ConnectionHops: []string{ibctesting.FirstConnectionID}, + }) + }, + true, + }, + { + "capability not found", + func() { + portIDWithPrefix := fmt.Sprintf("%s%s", icatypes.ControllerPortPrefix, "port-without-capability") + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), portIDWithPrefix, ibctesting.FirstChannelID, channeltypes.Channel{ + ConnectionHops: []string{ibctesting.FirstConnectionID}, + }) + }, + false, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + suite.SetupTest() + + path := NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, ibctesting.TestAccAddress) + suite.Require().NoError(err) + + tc.malleate() + + migrator := keeper.NewMigrator(&suite.chainA.GetSimApp().ICAControllerKeeper) + err = migrator.AssertChannelCapabilityMigrations(suite.chainA.GetContext()) + + if tc.expPass { + suite.Require().NoError(err) + + isMiddlewareEnabled := suite.chainA.GetSimApp().ICAControllerKeeper.IsMiddlewareEnabled( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ConnectionID, + ) + + suite.Require().True(isMiddlewareEnabled) + } else { + suite.Require().Error(err) + } + }) + } +} diff --git a/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go b/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go new file mode 100644 index 00000000000..0495d0490b6 --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/keeper/msg_server.go @@ -0,0 +1,72 @@ +package keeper + +import ( + "context" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" +) + +var _ types.MsgServer = msgServer{} + +type msgServer struct { + *Keeper +} + +// NewMsgServerImpl returns an implementation of the ICS27 MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper *Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +// RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount +func (s msgServer) RegisterInterchainAccount(goCtx context.Context, msg *types.MsgRegisterInterchainAccount) (*types.MsgRegisterInterchainAccountResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + portID, err := icatypes.NewControllerPortID(msg.Owner) + if err != nil { + return nil, err + } + + if s.IsMiddlewareEnabled(ctx, portID, msg.ConnectionId) && !s.IsActiveChannelClosed(ctx, msg.ConnectionId, portID) { + return nil, errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel is already active or a handshake is in flight") + } + + s.SetMiddlewareDisabled(ctx, portID, msg.ConnectionId) + + channelID, err := s.registerInterchainAccount(ctx, msg.ConnectionId, portID, msg.Version) + if err != nil { + s.Logger(ctx).Error("error registering interchain account", "error", err.Error()) + return nil, err + } + + s.Logger(ctx).Info("successfully registered interchain account", "channel-id", channelID) + + return &types.MsgRegisterInterchainAccountResponse{ + ChannelId: channelID, + PortId: portID, + }, nil +} + +// SendTx defines a rpc handler for MsgSendTx +func (s msgServer) SendTx(goCtx context.Context, msg *types.MsgSendTx) (*types.MsgSendTxResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + portID, err := icatypes.NewControllerPortID(msg.Owner) + if err != nil { + return nil, err + } + + // the absolute timeout value is calculated using the controller chain block time + the relative timeout value + // this assumes time synchrony to a certain degree between the controller and counterparty host chain + absoluteTimeout := uint64(ctx.BlockTime().UnixNano()) + msg.RelativeTimeout + seq, err := s.sendTx(ctx, msg.ConnectionId, portID, msg.PacketData, absoluteTimeout) + if err != nil { + return nil, err + } + + return &types.MsgSendTxResponse{Sequence: seq}, nil +} diff --git a/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go b/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go new file mode 100644 index 00000000000..44585b2eea4 --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go @@ -0,0 +1,200 @@ +package keeper_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/gogoproto/proto" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func (suite *KeeperTestSuite) TestRegisterInterchainAccount_MsgServer() { + var ( + msg *types.MsgRegisterInterchainAccount + expectedChannelID = "channel-0" + ) + + testCases := []struct { + name string + expPass bool + malleate func() + }{ + { + "success", + true, + func() {}, + }, + { + "invalid connection id", + false, + func() { + msg.ConnectionId = "connection-100" + }, + }, + { + "non-empty owner address is valid", + true, + func() { + msg.Owner = "" + }, + }, + { + "empty address invalid", + false, + func() { + msg.Owner = "" + }, + }, + { + "port is already bound for owner but capability is claimed by another module", + false, + func() { + capability := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), TestPortID) + err := suite.chainA.GetSimApp().TransferKeeper.ClaimCapability(suite.chainA.GetContext(), capability, host.PortPath(TestPortID)) + suite.Require().NoError(err) + }, + }, + } + + for _, tc := range testCases { + suite.SetupTest() + + path := NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + msg = types.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, ibctesting.TestAccAddress, "") + + tc.malleate() + + ctx := suite.chainA.GetContext() + msgServer := keeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + res, err := msgServer.RegisterInterchainAccount(ctx, msg) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(expectedChannelID, res.ChannelId) + + events := ctx.EventManager().Events() + suite.Require().Len(events, 2) + suite.Require().Equal(events[0].Type, channeltypes.EventTypeChannelOpenInit) + suite.Require().Equal(events[1].Type, sdk.EventTypeMessage) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + } + } +} + +func (suite *KeeperTestSuite) TestSubmitTx() { + var ( + path *ibctesting.Path + msg *types.MsgSendTx + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", func() { + }, + true, + }, + { + "failure - owner address is empty", func() { + msg.Owner = "" + }, + false, + }, + { + "failure - active channel does not exist for connection ID", func() { + msg.Owner = TestOwnerAddress + msg.ConnectionId = "connection-100" + }, + false, + }, + { + "failure - active channel does not exist for port ID", func() { + msg.Owner = "invalid-owner" + }, + false, + }, + { + "failure - controller module does not own capability for this channel", func() { + msg.Owner = "invalid-owner" + portID, err := icatypes.NewControllerPortID(msg.Owner) + suite.Require().NoError(err) + + // set the active channel with the incorrect portID in order to reach the capability check + suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), path.EndpointA.ConnectionID, portID, path.EndpointA.ChannelID) + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() + + owner := TestOwnerAddress + path = NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, owner) + suite.Require().NoError(err) + + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + suite.Require().NoError(err) + + // get the address of the interchain account stored in state during handshake step + interchainAccountAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), path.EndpointA.ConnectionID, portID) + suite.Require().True(found) + + // create bank transfer message that will execute on the host chain + icaMsg := &banktypes.MsgSend{ + FromAddress: interchainAccountAddr, + ToAddress: suite.chainB.SenderAccount.GetAddress().String(), + Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), + } + + data, err := icatypes.SerializeCosmosTx(suite.chainA.Codec, []proto.Message{icaMsg}) + suite.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + Memo: "memo", + } + + timeoutTimestamp := uint64(suite.chainA.GetContext().BlockTime().Add(time.Minute).UnixNano()) + connectionID := path.EndpointA.ConnectionID + + msg = types.NewMsgSendTx(owner, connectionID, timeoutTimestamp, packetData) + + tc.malleate() // malleate mutates test data + + ctx := suite.chainA.GetContext() + msgServer := keeper.NewMsgServerImpl(&suite.chainA.GetSimApp().ICAControllerKeeper) + res, err := msgServer.SendTx(ctx, msg) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + } + }) + } +} diff --git a/modules/apps/27-interchain-accounts/controller/keeper/params.go b/modules/apps/27-interchain-accounts/controller/keeper/params.go index 38e82a27c80..8e18cd80095 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/params.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/params.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ) // IsControllerEnabled retrieves the controller enabled boolean from the paramstore. diff --git a/modules/apps/27-interchain-accounts/controller/keeper/params_test.go b/modules/apps/27-interchain-accounts/controller/keeper/params_test.go index 4e4d8703e40..7b19883af14 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/params_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/params_test.go @@ -1,6 +1,6 @@ package keeper_test -import "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" +import "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" func (suite *KeeperTestSuite) TestParams() { expParams := types.DefaultParams() diff --git a/modules/apps/27-interchain-accounts/controller/keeper/relay.go b/modules/apps/27-interchain-accounts/controller/keeper/relay.go index 6d197aadca2..b8a5996a5a0 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/relay.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/relay.go @@ -1,13 +1,14 @@ package keeper import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/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" ) // SendTx takes pre-built packet data containing messages to be executed on the host chain from an authentication module and attempts to send the packet. @@ -15,63 +16,40 @@ import ( // If the base application has the capability to send on the provided portID. An appropriate // absolute timeoutTimestamp must be provided. If the packet is timed out, the channel will be closed. // In the case of channel closure, a new channel may be reopened to reconnect to the host chain. -func (k Keeper) SendTx(ctx sdk.Context, chanCap *capabilitytypes.Capability, connectionID, portID string, icaPacketData icatypes.InterchainAccountPacketData, timeoutTimestamp uint64) (uint64, error) { +// +// Deprecated: this is a legacy API that is only intended to function correctly in workflows where an underlying application has been set. +// Prior to to v6.x.x of ibc-go, the controller module was only functional as middleware, with authentication performed +// by the underlying application. For a full summary of the changes in v6.x.x, please see ADR009. +// This API will be removed in later releases. +func (k Keeper) SendTx(ctx sdk.Context, _ *capabilitytypes.Capability, connectionID, portID string, icaPacketData icatypes.InterchainAccountPacketData, timeoutTimestamp uint64) (uint64, error) { + return k.sendTx(ctx, connectionID, portID, icaPacketData, timeoutTimestamp) +} + +func (k Keeper) sendTx(ctx sdk.Context, connectionID, portID string, icaPacketData icatypes.InterchainAccountPacketData, timeoutTimestamp uint64) (uint64, error) { activeChannelID, found := k.GetOpenActiveChannel(ctx, connectionID, portID) if !found { - return 0, sdkerrors.Wrapf(icatypes.ErrActiveChannelNotFound, "failed to retrieve active channel on connection %s for port %s", connectionID, portID) + return 0, errorsmod.Wrapf(icatypes.ErrActiveChannelNotFound, "failed to retrieve active channel on connection %s for port %s", connectionID, portID) } - sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, portID, activeChannelID) + chanCap, found := k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, activeChannelID)) if !found { - return 0, sdkerrors.Wrap(channeltypes.ErrChannelNotFound, activeChannelID) + return 0, errorsmod.Wrapf(capabilitytypes.ErrCapabilityNotFound, "failed to find capability: %s", host.ChannelCapabilityPath(portID, activeChannelID)) } - destinationPort := sourceChannelEnd.GetCounterparty().GetPortID() - destinationChannel := sourceChannelEnd.GetCounterparty().GetChannelID() - if uint64(ctx.BlockTime().UnixNano()) >= timeoutTimestamp { return 0, icatypes.ErrInvalidTimeoutTimestamp } - return k.createOutgoingPacket(ctx, portID, activeChannelID, destinationPort, destinationChannel, chanCap, icaPacketData, timeoutTimestamp) -} - -func (k Keeper) createOutgoingPacket( - ctx sdk.Context, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel string, - chanCap *capabilitytypes.Capability, - icaPacketData icatypes.InterchainAccountPacketData, - timeoutTimestamp uint64, -) (uint64, error) { if err := icaPacketData.ValidateBasic(); err != nil { - return 0, sdkerrors.Wrap(err, "invalid interchain account packet data") + return 0, errorsmod.Wrap(err, "invalid interchain account packet data") } - // get the next sequence - sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) - if !found { - return 0, sdkerrors.Wrapf(channeltypes.ErrSequenceSendNotFound, "failed to retrieve next sequence send for channel %s on port %s", sourceChannel, sourcePort) - } - - packet := channeltypes.NewPacket( - icaPacketData.GetBytes(), - sequence, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel, - clienttypes.ZeroHeight(), - timeoutTimestamp, - ) - - if err := k.ics4Wrapper.SendPacket(ctx, chanCap, packet); err != nil { + sequence, err := k.ics4Wrapper.SendPacket(ctx, chanCap, portID, activeChannelID, clienttypes.ZeroHeight(), timeoutTimestamp, icaPacketData.GetBytes()) + if err != nil { return 0, err } - return packet.Sequence, nil + return sequence, nil } // OnTimeoutPacket removes the active channel associated with the provided packet, the underlying channel end is closed diff --git a/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go b/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go index a980d3f953d..c16af788923 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/relay_test.go @@ -3,20 +3,18 @@ package keeper_test import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + "github.com/cosmos/gogoproto/proto" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestSendTx() { var ( path *ibctesting.Path packetData icatypes.InterchainAccountPacketData - chanCap *capabilitytypes.Capability timeoutTimestamp uint64 ) @@ -37,7 +35,7 @@ func (suite *KeeperTestSuite) TestSendTx() { Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), } - data, err := icatypes.SerializeCosmosTx(suite.chainB.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainB.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) packetData = icatypes.InterchainAccountPacketData{ @@ -53,7 +51,7 @@ func (suite *KeeperTestSuite) TestSendTx() { interchainAccountAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) suite.Require().True(found) - msgsBankSend := []sdk.Msg{ + msgsBankSend := []proto.Message{ &banktypes.MsgSend{ FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), @@ -93,13 +91,6 @@ func (suite *KeeperTestSuite) TestSendTx() { }, false, }, - { - "channel does not exist", - func() { - suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, "channel-100") - }, - false, - }, { "channel in INIT state - optimistic packet sends fail", func() { @@ -114,18 +105,11 @@ func (suite *KeeperTestSuite) TestSendTx() { { "sendPacket fails - channel closed", func() { - err := path.EndpointA.SetChannelClosed() + err := path.EndpointA.SetChannelState(channeltypes.CLOSED) suite.Require().NoError(err) }, false, }, - { - "invalid channel capability provided", - func() { - chanCap = nil - }, - false, - }, { "timeout timestamp is not in the future", func() { @@ -138,7 +122,7 @@ func (suite *KeeperTestSuite) TestSendTx() { Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), } - data, err := icatypes.SerializeCosmosTx(suite.chainB.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainB.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) packetData = icatypes.InterchainAccountPacketData{ @@ -165,13 +149,10 @@ func (suite *KeeperTestSuite) TestSendTx() { err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) - var ok bool - chanCap, ok = suite.chainA.GetSimApp().ScopedICAMockKeeper.GetCapability(path.EndpointA.Chain.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) - suite.Require().True(ok) - tc.malleate() // malleate mutates test data - _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), chanCap, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, packetData, timeoutTimestamp) + //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) + _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, packetData, timeoutTimestamp) if tc.expPass { suite.Require().NoError(err) diff --git a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations.go b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations.go new file mode 100644 index 00000000000..4b7406f044c --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations.go @@ -0,0 +1,77 @@ +package v6 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// MigrateICS27ChannelCapability performs a search on a prefix store using the provided store key and module name. +// It retrieves the associated channel capability index and reassigns ownership to the ICS27 controller submodule. +func MigrateICS27ChannelCapability( + ctx sdk.Context, + cdc codec.BinaryCodec, + capabilityStoreKey storetypes.StoreKey, + capabilityKeeper *capabilitykeeper.Keeper, + module string, // the name of the scoped keeper for the underlying app module +) error { + // construct a prefix store using the x/capability index prefix: index->capability owners + prefixStore := prefix.NewStore(ctx.KVStore(capabilityStoreKey), capabilitytypes.KeyPrefixIndexCapability) + iterator := sdk.KVStorePrefixIterator(prefixStore, nil) + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) + + for ; iterator.Valid(); iterator.Next() { + // unmarshal the capability index value and set of owners + index := capabilitytypes.IndexFromKey(iterator.Key()) + + var owners capabilitytypes.CapabilityOwners + cdc.MustUnmarshal(iterator.Value(), &owners) + + if !hasIBCOwner(owners.GetOwners()) { + continue + } + + for _, owner := range owners.GetOwners() { + if owner.Module == module { + // remove the owner from the set + owners.Remove(owner) + + // reassign the owner module to icacontroller + owner.Module = controllertypes.SubModuleName + + // add the controller submodule to the set of owners + if err := owners.Set(owner); err != nil { + return err + } + + // set the new owners for the current capability index + capabilityKeeper.SetOwners(ctx, index, owners) + } + } + } + + // initialise the x/capability memstore + capabilityKeeper.InitMemStore(ctx) + + return nil +} + +func hasIBCOwner(owners []capabilitytypes.Owner) bool { + if len(owners) != 2 { + return false + } + + for _, owner := range owners { + if owner.Module == ibcexported.ModuleName { + return true + } + } + + return false +} diff --git a/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go new file mode 100644 index 00000000000..934db7395a3 --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/migrations/v6/migrations_test.go @@ -0,0 +1,200 @@ +package v6_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + "github.com/stretchr/testify/suite" + + v6 "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/migrations/v6" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" +) + +type MigrationsTestSuite struct { + suite.Suite + + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain + + coordinator *ibctesting.Coordinator + path *ibctesting.Path +} + +func (suite *MigrationsTestSuite) SetupTest() { + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) + + suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) + suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) + + suite.path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID + suite.path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID + suite.path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED + suite.path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED + suite.path.EndpointA.ChannelConfig.Version = icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) + suite.path.EndpointB.ChannelConfig.Version = icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) +} + +func (suite *MigrationsTestSuite) SetupPath() error { + if err := suite.RegisterInterchainAccount(suite.path.EndpointA, ibctesting.TestAccAddress); err != nil { + return err + } + + if err := suite.path.EndpointB.ChanOpenTry(); err != nil { + return err + } + + if err := suite.path.EndpointA.ChanOpenAck(); err != nil { + return err + } + + if err := suite.path.EndpointB.ChanOpenConfirm(); err != nil { + return err + } + + return nil +} + +func (suite *MigrationsTestSuite) RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { + portID, err := icatypes.NewControllerPortID(owner) + if err != nil { + return err + } + + channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) + + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version); err != nil { + return err + } + + // commit state changes for proof verification + endpoint.Chain.NextBlock() + + // update port/channel ids + endpoint.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) + endpoint.ChannelConfig.PortID = portID + + return nil +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(MigrationsTestSuite)) +} + +func (suite *MigrationsTestSuite) TestMigrateICS27ChannelCapability() { + suite.SetupTest() + suite.coordinator.SetupConnections(suite.path) + + err := suite.SetupPath() + suite.Require().NoError(err) + + // create additional capabilities to cover edge cases + suite.CreateMockCapabilities() + + // create and claim a new capability with ibc/mock for "channel-1" + // note: suite.SetupPath() now claims the chanel capability using icacontroller for "channel-0" + capName := host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, channeltypes.FormatChannelIdentifier(1)) + + cap, err := suite.chainA.GetSimApp().ScopedIBCKeeper.NewCapability(suite.chainA.GetContext(), capName) + suite.Require().NoError(err) + + err = suite.chainA.GetSimApp().ScopedICAMockKeeper.ClaimCapability(suite.chainA.GetContext(), cap, capName) + suite.Require().NoError(err) + + // assert the capability is owned by the mock module + cap, found := suite.chainA.GetSimApp().ScopedICAMockKeeper.GetCapability(suite.chainA.GetContext(), capName) + suite.Require().NotNil(cap) + suite.Require().True(found) + + isAuthenticated := suite.chainA.GetSimApp().ScopedICAMockKeeper.AuthenticateCapability(suite.chainA.GetContext(), cap, capName) + suite.Require().True(isAuthenticated) + + cap, found = suite.chainA.GetSimApp().ScopedICAControllerKeeper.GetCapability(suite.chainA.GetContext(), capName) + suite.Require().Nil(cap) + suite.Require().False(found) + + suite.ResetMemStore() // empty the x/capability in-memory store + + err = v6.MigrateICS27ChannelCapability( + suite.chainA.GetContext(), + suite.chainA.Codec, + suite.chainA.GetSimApp().GetKey(capabilitytypes.StoreKey), + suite.chainA.GetSimApp().CapabilityKeeper, + ibcmock.ModuleName+types.SubModuleName, + ) + + suite.Require().NoError(err) + + // assert the capability is now owned by the ICS27 controller submodule + cap, found = suite.chainA.GetSimApp().ScopedICAControllerKeeper.GetCapability(suite.chainA.GetContext(), capName) + suite.Require().NotNil(cap) + suite.Require().True(found) + + isAuthenticated = suite.chainA.GetSimApp().ScopedICAControllerKeeper.AuthenticateCapability(suite.chainA.GetContext(), cap, capName) + suite.Require().True(isAuthenticated) + + cap, found = suite.chainA.GetSimApp().ScopedICAMockKeeper.GetCapability(suite.chainA.GetContext(), capName) + suite.Require().Nil(cap) + suite.Require().False(found) + + // ensure channel capability for "channel-0" is still owned by the controller + capName = host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID) + cap, found = suite.chainA.GetSimApp().ScopedICAControllerKeeper.GetCapability(suite.chainA.GetContext(), capName) + suite.Require().NotNil(cap) + suite.Require().True(found) + + isAuthenticated = suite.chainA.GetSimApp().ScopedICAControllerKeeper.AuthenticateCapability(suite.chainA.GetContext(), cap, capName) + suite.Require().True(isAuthenticated) + + suite.AssertMockCapabiltiesUnchanged() +} + +// CreateMockCapabilities creates an additional two capabilities used for testing purposes: +// 1. A capability with a single owner +// 2. A capability with two owners, neither of which is "ibc" +func (suite *MigrationsTestSuite) CreateMockCapabilities() { + cap, err := suite.chainA.GetSimApp().ScopedIBCMockKeeper.NewCapability(suite.chainA.GetContext(), "mock_one") + suite.Require().NoError(err) + suite.Require().NotNil(cap) + + cap, err = suite.chainA.GetSimApp().ScopedICAMockKeeper.NewCapability(suite.chainA.GetContext(), "mock_two") + suite.Require().NoError(err) + suite.Require().NotNil(cap) + + err = suite.chainA.GetSimApp().ScopedIBCMockKeeper.ClaimCapability(suite.chainA.GetContext(), cap, "mock_two") + suite.Require().NoError(err) +} + +// AssertMockCapabiltiesUnchanged authenticates the mock capabilities created at the start of the test to ensure they remain unchanged +func (suite *MigrationsTestSuite) AssertMockCapabiltiesUnchanged() { + cap, found := suite.chainA.GetSimApp().ScopedIBCMockKeeper.GetCapability(suite.chainA.GetContext(), "mock_one") + suite.Require().True(found) + suite.Require().NotNil(cap) + + cap, found = suite.chainA.GetSimApp().ScopedIBCMockKeeper.GetCapability(suite.chainA.GetContext(), "mock_two") + suite.Require().True(found) + suite.Require().NotNil(cap) + + isAuthenticated := suite.chainA.GetSimApp().ScopedICAMockKeeper.AuthenticateCapability(suite.chainA.GetContext(), cap, "mock_two") + suite.Require().True(isAuthenticated) +} + +// ResetMemstore removes all existing fwd and rev capability kv pairs and deletes `KeyMemInitialised` from the x/capability memstore. +// This effectively mocks a new chain binary being started. Migration code is run against persisted state only and allows the memstore to be reinitialised. +func (suite *MigrationsTestSuite) ResetMemStore() { + memStore := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetMemKey(capabilitytypes.MemStoreKey)) + memStore.Delete(capabilitytypes.KeyMemInitialized) + + iterator := memStore.Iterator(nil, nil) + defer sdk.LogDeferred(suite.chainA.GetContext().Logger(), func() error { return iterator.Close() }) + + for ; iterator.Valid(); iterator.Next() { + memStore.Delete(iterator.Key()) + } +} diff --git a/modules/apps/27-interchain-accounts/controller/types/codec.go b/modules/apps/27-interchain-accounts/controller/types/codec.go new file mode 100644 index 00000000000..6b684cf4618 --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/types/codec.go @@ -0,0 +1,15 @@ +package types + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// RegisterInterfaces registers the interchain accounts controller message types using the provided InterfaceRegistry +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgRegisterInterchainAccount{}, + &MsgSendTx{}, + ) +} diff --git a/modules/apps/27-interchain-accounts/controller/types/controller.pb.go b/modules/apps/27-interchain-accounts/controller/types/controller.pb.go index 8aa795abab6..7d8badd96e1 100644 --- a/modules/apps/27-interchain-accounts/controller/types/controller.pb.go +++ b/modules/apps/27-interchain-accounts/controller/types/controller.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -93,9 +93,9 @@ var fileDescriptor_177fd0fec5eb3400 = []byte{ 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x15, 0x90, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, 0x9c, 0x5f, 0x9c, 0x9b, 0x5f, 0xac, 0x9f, 0x99, 0x94, 0xac, 0x9b, 0x9e, 0xaf, 0x5f, 0x66, - 0xa2, 0x9f, 0x9b, 0x9f, 0x52, 0x9a, 0x93, 0x5a, 0x0c, 0x0a, 0xa0, 0x62, 0x7d, 0x23, 0x73, 0x5d, + 0xae, 0x9f, 0x9b, 0x9f, 0x52, 0x9a, 0x93, 0x5a, 0x0c, 0x0a, 0xa0, 0x62, 0x7d, 0x23, 0x73, 0x5d, 0x84, 0xb7, 0x74, 0xb1, 0x85, 0x4d, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x2b, 0xc6, - 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x36, 0xd4, 0x5d, 0xad, 0x5b, 0x01, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xf2, 0x00, 0xac, 0x5b, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/27-interchain-accounts/controller/types/errors.go b/modules/apps/27-interchain-accounts/controller/types/errors.go index 3a0ade00fe1..2f2d5595e21 100644 --- a/modules/apps/27-interchain-accounts/controller/types/errors.go +++ b/modules/apps/27-interchain-accounts/controller/types/errors.go @@ -1,10 +1,10 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // ICA Controller sentinel errors var ( - ErrControllerSubModuleDisabled = sdkerrors.Register(SubModuleName, 2, "controller submodule is disabled") + ErrControllerSubModuleDisabled = errorsmod.Register(SubModuleName, 2, "controller submodule is disabled") ) diff --git a/modules/apps/27-interchain-accounts/controller/types/msgs.go b/modules/apps/27-interchain-accounts/controller/types/msgs.go new file mode 100644 index 00000000000..5837b76a01b --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/types/msgs.go @@ -0,0 +1,87 @@ +package types + +import ( + "strings" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" +) + +var _ sdk.Msg = &MsgRegisterInterchainAccount{} + +// NewMsgRegisterInterchainAccount creates a new instance of MsgRegisterInterchainAccount +func NewMsgRegisterInterchainAccount(connectionID, owner, version string) *MsgRegisterInterchainAccount { + return &MsgRegisterInterchainAccount{ + ConnectionId: connectionID, + Owner: owner, + Version: version, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgRegisterInterchainAccount) ValidateBasic() error { + if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { + return errorsmod.Wrap(err, "invalid connection ID") + } + + if strings.TrimSpace(msg.Owner) == "" { + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "owner address cannot be empty") + } + + return nil +} + +// GetSigners implements sdk.Msg +func (msg MsgRegisterInterchainAccount) GetSigners() []sdk.AccAddress { + accAddr, err := sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{accAddr} +} + +// NewMsgSendTx creates a new instance of MsgSendTx +func NewMsgSendTx(owner, connectionID string, relativeTimeoutTimestamp uint64, packetData icatypes.InterchainAccountPacketData) *MsgSendTx { + return &MsgSendTx{ + ConnectionId: connectionID, + Owner: owner, + RelativeTimeout: relativeTimeoutTimestamp, + PacketData: packetData, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgSendTx) ValidateBasic() error { + if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { + return errorsmod.Wrap(err, "invalid connection ID") + } + + if strings.TrimSpace(msg.Owner) == "" { + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "owner address cannot be empty") + } + + if err := msg.PacketData.ValidateBasic(); err != nil { + return errorsmod.Wrap(err, "invalid interchain account packet data") + } + + if msg.RelativeTimeout == 0 { + return errorsmod.Wrap(ibcerrors.ErrInvalidRequest, "relative timeout cannot be zero") + } + + return nil +} + +// GetSigners implements sdk.Msg +func (msg MsgSendTx) GetSigners() []sdk.AccAddress { + accAddr, err := sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + panic(err) + } + + return []sdk.AccAddress{accAddr} +} diff --git a/modules/apps/27-interchain-accounts/controller/types/msgs_test.go b/modules/apps/27-interchain-accounts/controller/types/msgs_test.go new file mode 100644 index 00000000000..e5afa00c93e --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/types/msgs_test.go @@ -0,0 +1,196 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/gogoproto/proto" + "github.com/stretchr/testify/require" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/cosmos/ibc-go/v7/testing/simapp" +) + +func TestMsgRegisterInterchainAccountValidateBasic(t *testing.T) { + var msg *types.MsgRegisterInterchainAccount + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "success: with empty channel version", + func() { + msg.Version = "" + }, + true, + }, + { + "success: with fee enabled channel version", + func() { + feeMetadata := feetypes.Metadata{ + FeeVersion: feetypes.Version, + AppVersion: icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID), + } + + bz := feetypes.ModuleCdc.MustMarshalJSON(&feeMetadata) + msg.Version = string(bz) + }, + true, + }, + { + "connection id is invalid", + func() { + msg.ConnectionId = "" + }, + false, + }, + { + "owner address is empty", + func() { + msg.Owner = "" + }, + false, + }, + } + + for i, tc := range testCases { + + msg = types.NewMsgRegisterInterchainAccount( + ibctesting.FirstConnectionID, + ibctesting.TestAccAddress, + icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID), + ) + + tc.malleate() + + err := msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) + } else { + require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func TestMsgRegisterInterchainAccountGetSigners(t *testing.T) { + expSigner, err := sdk.AccAddressFromBech32(ibctesting.TestAccAddress) + require.NoError(t, err) + + msg := types.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, ibctesting.TestAccAddress, "") + require.Equal(t, []sdk.AccAddress{expSigner}, msg.GetSigners()) +} + +func TestMsgSendTxValidateBasic(t *testing.T) { + var msg *types.MsgSendTx + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "connection id is invalid", + func() { + msg.ConnectionId = "" + }, + false, + }, + { + "owner address is empty", + func() { + msg.Owner = "" + }, + false, + }, + { + "relative timeout is not set", + func() { + msg.RelativeTimeout = 0 + }, + false, + }, + { + "messages array is empty", + func() { + msg.PacketData = icatypes.InterchainAccountPacketData{} + }, + false, + }, + } + + for i, tc := range testCases { + + msgBankSend := &banktypes.MsgSend{ + FromAddress: ibctesting.TestAccAddress, + ToAddress: ibctesting.TestAccAddress, + Amount: ibctesting.TestCoins, + } + + data, err := icatypes.SerializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, []proto.Message{msgBankSend}) + require.NoError(t, err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + } + + msg = types.NewMsgSendTx( + ibctesting.TestAccAddress, + ibctesting.FirstConnectionID, + 100000, + packetData, + ) + + tc.malleate() + + err = msg.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) + } else { + require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + +func TestMsgSendTxGetSigners(t *testing.T) { + expSigner, err := sdk.AccAddressFromBech32(ibctesting.TestAccAddress) + require.NoError(t, err) + + msgBankSend := &banktypes.MsgSend{ + FromAddress: ibctesting.TestAccAddress, + ToAddress: ibctesting.TestAccAddress, + Amount: ibctesting.TestCoins, + } + + data, err := icatypes.SerializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, []proto.Message{msgBankSend}) + require.NoError(t, err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + } + + msg := types.NewMsgSendTx( + ibctesting.TestAccAddress, + ibctesting.FirstConnectionID, + 100000, + packetData, + ) + require.Equal(t, []sdk.AccAddress{expSigner}, msg.GetSigners()) +} diff --git a/modules/apps/27-interchain-accounts/controller/types/params.go b/modules/apps/27-interchain-accounts/controller/types/params.go index d7b9cc83874..5baaaa8b1df 100644 --- a/modules/apps/27-interchain-accounts/controller/types/params.go +++ b/modules/apps/27-interchain-accounts/controller/types/params.go @@ -33,7 +33,7 @@ func DefaultParams() Params { // Validate validates all controller submodule parameters func (p Params) Validate() error { - if err := validateEnabled(p.ControllerEnabled); err != nil { + if err := validateEnabledType(p.ControllerEnabled); err != nil { return err } @@ -43,11 +43,11 @@ func (p Params) Validate() error { // ParamSetPairs implements params.ParamSet func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(KeyControllerEnabled, p.ControllerEnabled, validateEnabled), + paramtypes.NewParamSetPair(KeyControllerEnabled, p.ControllerEnabled, validateEnabledType), } } -func validateEnabled(i interface{}) error { +func validateEnabledType(i interface{}) error { _, ok := i.(bool) if !ok { return fmt.Errorf("invalid parameter type: %T", i) diff --git a/modules/apps/27-interchain-accounts/controller/types/params_test.go b/modules/apps/27-interchain-accounts/controller/types/params_test.go index df3927e22d3..e2f653b741e 100644 --- a/modules/apps/27-interchain-accounts/controller/types/params_test.go +++ b/modules/apps/27-interchain-accounts/controller/types/params_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" ) func TestValidateParams(t *testing.T) { diff --git a/modules/apps/27-interchain-accounts/controller/types/query.pb.go b/modules/apps/27-interchain-accounts/controller/types/query.pb.go index 82a755409f4..c1900bbc179 100644 --- a/modules/apps/27-interchain-accounts/controller/types/query.pb.go +++ b/modules/apps/27-interchain-accounts/controller/types/query.pb.go @@ -6,8 +6,9 @@ package types import ( context "context" fmt "fmt" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -28,6 +29,104 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// QueryInterchainAccountRequest is the request type for the Query/InterchainAccount RPC method. +type QueryInterchainAccountRequest struct { + Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"` + ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` +} + +func (m *QueryInterchainAccountRequest) Reset() { *m = QueryInterchainAccountRequest{} } +func (m *QueryInterchainAccountRequest) String() string { return proto.CompactTextString(m) } +func (*QueryInterchainAccountRequest) ProtoMessage() {} +func (*QueryInterchainAccountRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_df0d8b259d72854e, []int{0} +} +func (m *QueryInterchainAccountRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryInterchainAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryInterchainAccountRequest.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 *QueryInterchainAccountRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryInterchainAccountRequest.Merge(m, src) +} +func (m *QueryInterchainAccountRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryInterchainAccountRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryInterchainAccountRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryInterchainAccountRequest proto.InternalMessageInfo + +func (m *QueryInterchainAccountRequest) GetOwner() string { + if m != nil { + return m.Owner + } + return "" +} + +func (m *QueryInterchainAccountRequest) GetConnectionId() string { + if m != nil { + return m.ConnectionId + } + return "" +} + +// QueryInterchainAccountResponse the response type for the Query/InterchainAccount RPC method. +type QueryInterchainAccountResponse struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *QueryInterchainAccountResponse) Reset() { *m = QueryInterchainAccountResponse{} } +func (m *QueryInterchainAccountResponse) String() string { return proto.CompactTextString(m) } +func (*QueryInterchainAccountResponse) ProtoMessage() {} +func (*QueryInterchainAccountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_df0d8b259d72854e, []int{1} +} +func (m *QueryInterchainAccountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryInterchainAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryInterchainAccountResponse.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 *QueryInterchainAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryInterchainAccountResponse.Merge(m, src) +} +func (m *QueryInterchainAccountResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryInterchainAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryInterchainAccountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryInterchainAccountResponse proto.InternalMessageInfo + +func (m *QueryInterchainAccountResponse) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + // QueryParamsRequest is the request type for the Query/Params RPC method. type QueryParamsRequest struct { } @@ -36,7 +135,7 @@ func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryParamsRequest) ProtoMessage() {} func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_df0d8b259d72854e, []int{0} + return fileDescriptor_df0d8b259d72854e, []int{2} } func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,7 +174,7 @@ func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryParamsResponse) ProtoMessage() {} func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_df0d8b259d72854e, []int{1} + return fileDescriptor_df0d8b259d72854e, []int{3} } func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -112,6 +211,8 @@ func (m *QueryParamsResponse) GetParams() *Params { } func init() { + proto.RegisterType((*QueryInterchainAccountRequest)(nil), "ibc.applications.interchain_accounts.controller.v1.QueryInterchainAccountRequest") + proto.RegisterType((*QueryInterchainAccountResponse)(nil), "ibc.applications.interchain_accounts.controller.v1.QueryInterchainAccountResponse") proto.RegisterType((*QueryParamsRequest)(nil), "ibc.applications.interchain_accounts.controller.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "ibc.applications.interchain_accounts.controller.v1.QueryParamsResponse") } @@ -121,27 +222,37 @@ func init() { } var fileDescriptor_df0d8b259d72854e = []byte{ - // 315 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x91, 0x31, 0x4b, 0x33, 0x31, - 0x1c, 0xc6, 0x9b, 0x17, 0xde, 0x0e, 0x71, 0x8b, 0x0e, 0x52, 0x24, 0x48, 0x27, 0x97, 0x26, 0xf4, - 0x2c, 0x08, 0x1d, 0x1c, 0x14, 0x74, 0xad, 0x1d, 0x5d, 0x24, 0x17, 0xc3, 0x35, 0x72, 0x97, 0x7f, - 0x9a, 0xe4, 0x0a, 0x5d, 0xfd, 0x04, 0x82, 0x5f, 0xca, 0xb1, 0x20, 0x82, 0x9b, 0x72, 0xe7, 0x07, - 0x91, 0xde, 0x1d, 0xb4, 0x62, 0x07, 0xad, 0x6b, 0xfe, 0x3c, 0xbf, 0x5f, 0x1e, 0x1e, 0x7c, 0xaa, - 0x63, 0xc9, 0x85, 0xb5, 0xa9, 0x96, 0x22, 0x68, 0x30, 0x9e, 0x6b, 0x13, 0x94, 0x93, 0x13, 0xa1, - 0xcd, 0x8d, 0x90, 0x12, 0x72, 0x13, 0x3c, 0x97, 0x60, 0x82, 0x83, 0x34, 0x55, 0x8e, 0xcf, 0xfa, - 0x7c, 0x9a, 0x2b, 0x37, 0x67, 0xd6, 0x41, 0x00, 0x12, 0xe9, 0x58, 0xb2, 0xf5, 0x3c, 0xdb, 0x90, - 0x67, 0xab, 0x3c, 0x9b, 0xf5, 0x3b, 0xe7, 0x5b, 0x38, 0xd7, 0x08, 0x95, 0xb8, 0x73, 0x90, 0x00, - 0x24, 0xa9, 0xe2, 0xc2, 0x6a, 0x2e, 0x8c, 0x81, 0xd0, 0xe8, 0xab, 0x6b, 0x77, 0x0f, 0x93, 0xab, - 0xe5, 0x2f, 0x47, 0xc2, 0x89, 0xcc, 0x8f, 0xd5, 0x34, 0x57, 0x3e, 0x74, 0x35, 0xde, 0xfd, 0xf2, - 0xea, 0x2d, 0x18, 0xaf, 0xc8, 0x18, 0xb7, 0x6d, 0xf5, 0xb2, 0x8f, 0x0e, 0xd1, 0xd1, 0x4e, 0x34, - 0x64, 0xbf, 0x2f, 0xc5, 0x1a, 0x66, 0x43, 0x8a, 0xde, 0x10, 0xfe, 0x5f, 0xb9, 0xc8, 0x0b, 0xc2, - 0xed, 0xfa, 0x48, 0x2e, 0xb6, 0x01, 0x7f, 0xef, 0xd1, 0xb9, 0xfc, 0x33, 0xa7, 0x6e, 0xde, 0x1d, - 0xde, 0x3f, 0x7f, 0x3c, 0xfe, 0x1b, 0x90, 0x88, 0x37, 0x93, 0xfc, 0x64, 0x8a, 0xba, 0xe1, 0xd9, - 0xdd, 0x53, 0x41, 0xd1, 0xa2, 0xa0, 0xe8, 0xbd, 0xa0, 0xe8, 0xa1, 0xa4, 0xad, 0x45, 0x49, 0x5b, - 0xaf, 0x25, 0x6d, 0x5d, 0x8f, 0x12, 0x1d, 0x26, 0x79, 0xcc, 0x24, 0x64, 0x5c, 0x82, 0xcf, 0xc0, - 0x2f, 0xf1, 0xbd, 0x04, 0xf8, 0x6c, 0xc0, 0x33, 0xb8, 0xcd, 0x53, 0xe5, 0x6b, 0x59, 0x74, 0xd2, - 0x5b, 0xf9, 0x7a, 0x9b, 0x7c, 0x61, 0x6e, 0x95, 0x8f, 0xdb, 0xd5, 0xaa, 0xc7, 0x9f, 0x01, 0x00, - 0x00, 0xff, 0xff, 0x9b, 0x4f, 0xc0, 0x9d, 0xae, 0x02, 0x00, 0x00, + // 465 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x41, 0x6b, 0x14, 0x31, + 0x14, 0xc7, 0x77, 0x56, 0xba, 0x62, 0xd4, 0x83, 0x71, 0x0f, 0xcb, 0xa2, 0xa3, 0xcc, 0xc9, 0xcb, + 0x26, 0x74, 0x14, 0x0a, 0x0b, 0x0a, 0x56, 0x50, 0x7a, 0x6b, 0xe7, 0x20, 0xe2, 0xc1, 0x92, 0xcd, + 0x84, 0x69, 0x64, 0x26, 0x6f, 0x9a, 0x64, 0x56, 0x96, 0xd2, 0x8b, 0x9f, 0x40, 0xf0, 0xe6, 0x27, + 0xf2, 0x58, 0x10, 0xc1, 0x93, 0xc8, 0xae, 0x9f, 0xc0, 0xb3, 0x07, 0x99, 0x4c, 0x74, 0x3b, 0x58, + 0xc5, 0x5d, 0x7b, 0x9a, 0xbc, 0xf7, 0x78, 0xff, 0xdf, 0x7b, 0xf9, 0x67, 0xd0, 0x03, 0x39, 0xe1, + 0x94, 0x95, 0x65, 0x2e, 0x39, 0xb3, 0x12, 0x94, 0xa1, 0x52, 0x59, 0xa1, 0xf9, 0x01, 0x93, 0x6a, + 0x9f, 0x71, 0x0e, 0x95, 0xb2, 0x86, 0x72, 0x50, 0x56, 0x43, 0x9e, 0x0b, 0x4d, 0xa7, 0x9b, 0xf4, + 0xb0, 0x12, 0x7a, 0x46, 0x4a, 0x0d, 0x16, 0x70, 0x2c, 0x27, 0x9c, 0x9c, 0xee, 0x27, 0x67, 0xf4, + 0x93, 0x65, 0x3f, 0x99, 0x6e, 0x0e, 0x1f, 0xad, 0xc1, 0x3c, 0xa5, 0xe0, 0xc0, 0xc3, 0x7e, 0x06, + 0x19, 0xb8, 0x23, 0xad, 0x4f, 0x3e, 0x7b, 0x23, 0x03, 0xc8, 0x72, 0x41, 0x59, 0x29, 0x29, 0x53, + 0x0a, 0xac, 0x1f, 0xca, 0x55, 0x23, 0x8b, 0x6e, 0xee, 0xd5, 0xb3, 0xef, 0xfc, 0xc2, 0x3d, 0x6c, + 0x68, 0x89, 0x38, 0xac, 0x84, 0xb1, 0xb8, 0x8f, 0x36, 0xe0, 0x95, 0x12, 0x7a, 0x10, 0xdc, 0x0e, + 0xee, 0x5c, 0x4a, 0x9a, 0x00, 0xdf, 0x47, 0x57, 0x39, 0x28, 0x25, 0x78, 0xad, 0xb5, 0x2f, 0xd3, + 0x41, 0xb7, 0xae, 0x6e, 0x0f, 0xbe, 0x7d, 0xbe, 0xd5, 0x9f, 0xb1, 0x22, 0x1f, 0x47, 0xad, 0x72, + 0x94, 0x5c, 0x59, 0xc6, 0x3b, 0x69, 0x34, 0x46, 0xe1, 0x9f, 0xa8, 0xa6, 0x04, 0x65, 0x04, 0x1e, + 0xa0, 0x8b, 0x2c, 0x4d, 0xb5, 0x30, 0xc6, 0x83, 0x7f, 0x86, 0x51, 0x1f, 0x61, 0xd7, 0xbb, 0xcb, + 0x34, 0x2b, 0x8c, 0x1f, 0x33, 0x92, 0xe8, 0x7a, 0x2b, 0xeb, 0x65, 0x12, 0xd4, 0x2b, 0x5d, 0xc6, + 0xa9, 0x5c, 0x8e, 0xc7, 0x64, 0x75, 0x73, 0x88, 0xd7, 0xf4, 0x4a, 0xf1, 0xf7, 0x0b, 0x68, 0xc3, + 0xb1, 0xf0, 0xbb, 0x2e, 0xba, 0xf6, 0xdb, 0x0a, 0x78, 0x6f, 0x1d, 0xc6, 0x5f, 0x4d, 0x18, 0x26, + 0xe7, 0x29, 0xd9, 0x5c, 0x4d, 0xf4, 0xe2, 0xf5, 0x87, 0xaf, 0x6f, 0xbb, 0xcf, 0xf0, 0x53, 0xea, + 0xdf, 0xde, 0xbf, 0xbc, 0x39, 0xe7, 0xbe, 0xa1, 0x47, 0xee, 0x7b, 0x4c, 0x97, 0xa6, 0x1a, 0x7a, + 0xd4, 0x72, 0xfc, 0x18, 0x7f, 0x0c, 0x50, 0xaf, 0xb9, 0x39, 0xfc, 0x78, 0xed, 0xf1, 0x5b, 0x26, + 0x0f, 0x9f, 0xfc, 0xb7, 0x8e, 0xdf, 0x7d, 0xec, 0x76, 0xbf, 0x87, 0xe3, 0x55, 0x76, 0x6f, 0xec, + 0xdf, 0x7e, 0xf9, 0x7e, 0x1e, 0x06, 0x27, 0xf3, 0x30, 0xf8, 0x32, 0x0f, 0x83, 0x37, 0x8b, 0xb0, + 0x73, 0xb2, 0x08, 0x3b, 0x9f, 0x16, 0x61, 0xe7, 0xf9, 0x6e, 0x26, 0xed, 0x41, 0x35, 0x21, 0x1c, + 0x0a, 0xca, 0xc1, 0x14, 0x60, 0x6a, 0xf9, 0x51, 0x06, 0x74, 0xba, 0x45, 0x0b, 0x48, 0xab, 0x5c, + 0x98, 0x06, 0x16, 0x6f, 0x8d, 0x96, 0xbc, 0xd1, 0x59, 0x3c, 0x3b, 0x2b, 0x85, 0x99, 0xf4, 0xdc, + 0x4f, 0x7a, 0xf7, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x23, 0x39, 0x1f, 0x93, 0x04, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -156,6 +267,8 @@ 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 QueryClient interface { + // InterchainAccount returns the interchain account address for a given owner address on a given connection + InterchainAccount(ctx context.Context, in *QueryInterchainAccountRequest, opts ...grpc.CallOption) (*QueryInterchainAccountResponse, error) // Params queries all parameters of the ICA controller submodule. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) } @@ -168,6 +281,15 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } +func (c *queryClient) InterchainAccount(ctx context.Context, in *QueryInterchainAccountRequest, opts ...grpc.CallOption) (*QueryInterchainAccountResponse, error) { + out := new(QueryInterchainAccountResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.interchain_accounts.controller.v1.Query/InterchainAccount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { out := new(QueryParamsResponse) err := c.cc.Invoke(ctx, "/ibc.applications.interchain_accounts.controller.v1.Query/Params", in, out, opts...) @@ -179,6 +301,8 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . // QueryServer is the server API for Query service. type QueryServer interface { + // InterchainAccount returns the interchain account address for a given owner address on a given connection + InterchainAccount(context.Context, *QueryInterchainAccountRequest) (*QueryInterchainAccountResponse, error) // Params queries all parameters of the ICA controller submodule. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) } @@ -187,6 +311,9 @@ type QueryServer interface { type UnimplementedQueryServer struct { } +func (*UnimplementedQueryServer) InterchainAccount(ctx context.Context, req *QueryInterchainAccountRequest) (*QueryInterchainAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InterchainAccount not implemented") +} func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } @@ -195,6 +322,24 @@ func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } +func _Query_InterchainAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryInterchainAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).InterchainAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.interchain_accounts.controller.v1.Query/InterchainAccount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).InterchainAccount(ctx, req.(*QueryInterchainAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryParamsRequest) if err := dec(in); err != nil { @@ -217,6 +362,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "ibc.applications.interchain_accounts.controller.v1.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "InterchainAccount", + Handler: _Query_InterchainAccount_Handler, + }, { MethodName: "Params", Handler: _Query_Params_Handler, @@ -226,6 +375,73 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Metadata: "ibc/applications/interchain_accounts/controller/v1/query.proto", } +func (m *QueryInterchainAccountRequest) 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 *QueryInterchainAccountRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryInterchainAccountRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ConnectionId) > 0 { + i -= len(m.ConnectionId) + copy(dAtA[i:], m.ConnectionId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConnectionId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryInterchainAccountResponse) 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 *QueryInterchainAccountResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryInterchainAccountResponse) 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 = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -295,6 +511,36 @@ func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *QueryInterchainAccountRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ConnectionId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryInterchainAccountResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func (m *QueryParamsRequest) Size() (n int) { if m == nil { return 0 @@ -323,6 +569,202 @@ func sovQuery(x uint64) (n int) { func sozQuery(x uint64) (n int) { return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *QueryInterchainAccountRequest) 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: QueryInterchainAccountRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryInterchainAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", 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.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", 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.ConnectionId = 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 (m *QueryInterchainAccountResponse) 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: QueryInterchainAccountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryInterchainAccountResponse: 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 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.Address = 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 (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/modules/apps/27-interchain-accounts/controller/types/query.pb.gw.go b/modules/apps/27-interchain-accounts/controller/types/query.pb.gw.go index a9ac1bc03bb..5a0301d480d 100644 --- a/modules/apps/27-interchain-accounts/controller/types/query.pb.gw.go +++ b/modules/apps/27-interchain-accounts/controller/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,83 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_InterchainAccount_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryInterchainAccountRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["owner"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner") + } + + protoReq.Owner, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner", err) + } + + val, ok = pathParams["connection_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "connection_id") + } + + protoReq.ConnectionId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "connection_id", err) + } + + msg, err := client.InterchainAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_InterchainAccount_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryInterchainAccountRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["owner"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner") + } + + protoReq.Owner, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner", err) + } + + val, ok = pathParams["connection_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "connection_id") + } + + protoReq.ConnectionId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "connection_id", err) + } + + msg, err := server.InterchainAccount(ctx, &protoReq) + return msg, metadata, err + +} func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryParamsRequest @@ -52,12 +130,37 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal // 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. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + mux.Handle("GET", pattern_Query_InterchainAccount_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_InterchainAccount_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_InterchainAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Params_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 { @@ -65,6 +168,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Params_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) @@ -116,6 +220,26 @@ func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // "QueryClient" to call the correct interceptors. func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + mux.Handle("GET", pattern_Query_InterchainAccount_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_InterchainAccount_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_InterchainAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -140,9 +264,13 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"ibc", "apps", "interchain_accounts", "controller", "v1", "params"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_InterchainAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5, 1, 0, 4, 1, 5, 6, 2, 7, 1, 0, 4, 1, 5, 8}, []string{"ibc", "apps", "interchain_accounts", "controller", "v1", "owners", "owner", "connections", "connection_id"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"ibc", "apps", "interchain_accounts", "controller", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( + forward_Query_InterchainAccount_0 = runtime.ForwardResponseMessage + forward_Query_Params_0 = runtime.ForwardResponseMessage ) diff --git a/modules/apps/27-interchain-accounts/controller/types/tx.pb.go b/modules/apps/27-interchain-accounts/controller/types/tx.pb.go new file mode 100644 index 00000000000..b15979a713e --- /dev/null +++ b/modules/apps/27-interchain-accounts/controller/types/tx.pb.go @@ -0,0 +1,1212 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/interchain_accounts/controller/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgRegisterInterchainAccount defines the payload for Msg/RegisterAccount +type MsgRegisterInterchainAccount struct { + Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"` + ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` +} + +func (m *MsgRegisterInterchainAccount) Reset() { *m = MsgRegisterInterchainAccount{} } +func (m *MsgRegisterInterchainAccount) String() string { return proto.CompactTextString(m) } +func (*MsgRegisterInterchainAccount) ProtoMessage() {} +func (*MsgRegisterInterchainAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_7def041328c84a30, []int{0} +} +func (m *MsgRegisterInterchainAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRegisterInterchainAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRegisterInterchainAccount.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 *MsgRegisterInterchainAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRegisterInterchainAccount.Merge(m, src) +} +func (m *MsgRegisterInterchainAccount) XXX_Size() int { + return m.Size() +} +func (m *MsgRegisterInterchainAccount) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRegisterInterchainAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRegisterInterchainAccount proto.InternalMessageInfo + +// MsgRegisterInterchainAccountResponse defines the response for Msg/RegisterAccount +type MsgRegisterInterchainAccountResponse struct { + ChannelId string `protobuf:"bytes,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"` + PortId string `protobuf:"bytes,2,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` +} + +func (m *MsgRegisterInterchainAccountResponse) Reset() { *m = MsgRegisterInterchainAccountResponse{} } +func (m *MsgRegisterInterchainAccountResponse) String() string { return proto.CompactTextString(m) } +func (*MsgRegisterInterchainAccountResponse) ProtoMessage() {} +func (*MsgRegisterInterchainAccountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7def041328c84a30, []int{1} +} +func (m *MsgRegisterInterchainAccountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRegisterInterchainAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRegisterInterchainAccountResponse.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 *MsgRegisterInterchainAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRegisterInterchainAccountResponse.Merge(m, src) +} +func (m *MsgRegisterInterchainAccountResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgRegisterInterchainAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRegisterInterchainAccountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRegisterInterchainAccountResponse proto.InternalMessageInfo + +func (m *MsgRegisterInterchainAccountResponse) GetChannelId() string { + if m != nil { + return m.ChannelId + } + return "" +} + +func (m *MsgRegisterInterchainAccountResponse) GetPortId() string { + if m != nil { + return m.PortId + } + return "" +} + +// MsgSendTx defines the payload for Msg/SendTx +type MsgSendTx struct { + Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"` + ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` + PacketData types.InterchainAccountPacketData `protobuf:"bytes,3,opt,name=packet_data,json=packetData,proto3" json:"packet_data" yaml:"packet_data"` + // Relative timeout timestamp provided will be added to the current block time during transaction execution. + // The timeout timestamp must be non-zero. + RelativeTimeout uint64 `protobuf:"varint,4,opt,name=relative_timeout,json=relativeTimeout,proto3" json:"relative_timeout,omitempty" yaml:"relative_timeout"` +} + +func (m *MsgSendTx) Reset() { *m = MsgSendTx{} } +func (m *MsgSendTx) String() string { return proto.CompactTextString(m) } +func (*MsgSendTx) ProtoMessage() {} +func (*MsgSendTx) Descriptor() ([]byte, []int) { + return fileDescriptor_7def041328c84a30, []int{2} +} +func (m *MsgSendTx) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendTx.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 *MsgSendTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendTx.Merge(m, src) +} +func (m *MsgSendTx) XXX_Size() int { + return m.Size() +} +func (m *MsgSendTx) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendTx.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendTx proto.InternalMessageInfo + +// MsgSendTxResponse defines the response for MsgSendTx +type MsgSendTxResponse struct { + Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` +} + +func (m *MsgSendTxResponse) Reset() { *m = MsgSendTxResponse{} } +func (m *MsgSendTxResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSendTxResponse) ProtoMessage() {} +func (*MsgSendTxResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7def041328c84a30, []int{3} +} +func (m *MsgSendTxResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendTxResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendTxResponse.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 *MsgSendTxResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendTxResponse.Merge(m, src) +} +func (m *MsgSendTxResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSendTxResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendTxResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendTxResponse proto.InternalMessageInfo + +func (m *MsgSendTxResponse) GetSequence() uint64 { + if m != nil { + return m.Sequence + } + return 0 +} + +func init() { + proto.RegisterType((*MsgRegisterInterchainAccount)(nil), "ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccount") + proto.RegisterType((*MsgRegisterInterchainAccountResponse)(nil), "ibc.applications.interchain_accounts.controller.v1.MsgRegisterInterchainAccountResponse") + proto.RegisterType((*MsgSendTx)(nil), "ibc.applications.interchain_accounts.controller.v1.MsgSendTx") + proto.RegisterType((*MsgSendTxResponse)(nil), "ibc.applications.interchain_accounts.controller.v1.MsgSendTxResponse") +} + +func init() { + proto.RegisterFile("ibc/applications/interchain_accounts/controller/v1/tx.proto", fileDescriptor_7def041328c84a30) +} + +var fileDescriptor_7def041328c84a30 = []byte{ + // 570 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0xbf, 0x6f, 0xd3, 0x40, + 0x14, 0xc7, 0xed, 0x34, 0xa4, 0xcd, 0x95, 0x5f, 0xb5, 0x82, 0x30, 0x06, 0xd9, 0x95, 0xc5, 0x50, + 0x09, 0xc5, 0xa7, 0x84, 0x4a, 0x95, 0x8a, 0x3a, 0x10, 0x15, 0xa4, 0x0c, 0x91, 0x22, 0xd3, 0x01, + 0xb1, 0x44, 0x97, 0xf3, 0xc9, 0x39, 0x70, 0xee, 0x8c, 0xef, 0x62, 0xda, 0x91, 0x0d, 0x16, 0xc4, + 0xc6, 0xda, 0xbf, 0x82, 0x7f, 0x81, 0x8e, 0x1d, 0x99, 0xac, 0x2a, 0x59, 0x98, 0xf3, 0x17, 0x20, + 0xdb, 0x89, 0x53, 0xa0, 0x54, 0xe5, 0x47, 0x37, 0xbf, 0x7b, 0xf7, 0x79, 0xef, 0x7b, 0xef, 0x3d, + 0x3f, 0xf0, 0x88, 0xf6, 0x31, 0x44, 0x61, 0x18, 0x50, 0x8c, 0x24, 0xe5, 0x4c, 0x40, 0xca, 0x24, + 0x89, 0xf0, 0x00, 0x51, 0xd6, 0x43, 0x18, 0xf3, 0x11, 0x93, 0x02, 0x62, 0xce, 0x64, 0xc4, 0x83, + 0x80, 0x44, 0x30, 0x6e, 0x40, 0xb9, 0xef, 0x84, 0x11, 0x97, 0x5c, 0x6b, 0xd2, 0x3e, 0x76, 0x4e, + 0xc3, 0xce, 0x19, 0xb0, 0xb3, 0x80, 0x9d, 0xb8, 0x61, 0xd4, 0x7c, 0xee, 0xf3, 0x0c, 0x87, 0xe9, + 0x57, 0x1e, 0xc9, 0xd8, 0xbc, 0x90, 0x8c, 0xb8, 0x01, 0x43, 0x84, 0x5f, 0x11, 0x99, 0x53, 0xf6, + 0x27, 0x15, 0xdc, 0xeb, 0x08, 0xdf, 0x25, 0x3e, 0x15, 0x92, 0x44, 0xed, 0x02, 0x79, 0x9c, 0x13, + 0x5a, 0x0d, 0x5c, 0xe1, 0x6f, 0x18, 0x89, 0x74, 0x75, 0x5d, 0xdd, 0xa8, 0xba, 0xb9, 0xa1, 0xed, + 0x80, 0x6b, 0x98, 0x33, 0x46, 0x70, 0x9a, 0xa9, 0x47, 0x3d, 0xbd, 0x94, 0x7a, 0x5b, 0xfa, 0x34, + 0xb1, 0x6a, 0x07, 0x68, 0x18, 0x6c, 0xdb, 0x3f, 0xb8, 0x6d, 0xf7, 0xea, 0xc2, 0x6e, 0x7b, 0x9a, + 0x0e, 0x96, 0x63, 0x12, 0x09, 0xca, 0x99, 0xbe, 0x94, 0x85, 0x9d, 0x9b, 0xdb, 0x2b, 0xef, 0x0e, + 0x2d, 0xe5, 0xdb, 0xa1, 0xa5, 0xd8, 0xef, 0x55, 0x70, 0xff, 0x3c, 0x65, 0x2e, 0x11, 0x21, 0x67, + 0x82, 0x68, 0x9b, 0x00, 0xe0, 0x01, 0x62, 0x8c, 0x04, 0xa9, 0x90, 0x4c, 0x66, 0xeb, 0xd6, 0x34, + 0xb1, 0xd6, 0x66, 0x42, 0x0a, 0x9f, 0xed, 0x56, 0x67, 0x46, 0xdb, 0xd3, 0x1e, 0x80, 0xe5, 0x90, + 0x47, 0x72, 0xa1, 0x5d, 0x9b, 0x26, 0xd6, 0xf5, 0x1c, 0x99, 0x39, 0x6c, 0xb7, 0x92, 0x7e, 0xb5, + 0x3d, 0xfb, 0x73, 0x09, 0x54, 0x3b, 0xc2, 0x7f, 0x46, 0x98, 0xb7, 0xb7, 0x7f, 0x39, 0x25, 0x79, + 0xab, 0x82, 0xd5, 0xbc, 0x33, 0x3d, 0x0f, 0x49, 0x94, 0xd5, 0x65, 0xb5, 0xb9, 0xeb, 0x5c, 0x68, + 0x3e, 0xe2, 0x86, 0xf3, 0x4b, 0x7d, 0xba, 0x59, 0xb0, 0x5d, 0x24, 0x51, 0xcb, 0x38, 0x4a, 0x2c, + 0x65, 0x9a, 0x58, 0xda, 0xec, 0x79, 0x8b, 0x34, 0xb6, 0x0b, 0xc2, 0xe2, 0x9e, 0xf6, 0x14, 0xdc, + 0x8c, 0x48, 0x80, 0x24, 0x8d, 0x49, 0x4f, 0xd2, 0x21, 0xe1, 0x23, 0xa9, 0x97, 0xd7, 0xd5, 0x8d, + 0x72, 0xeb, 0xee, 0x34, 0xb1, 0x6e, 0xe7, 0xf4, 0xcf, 0x37, 0x6c, 0xf7, 0xc6, 0xfc, 0x68, 0x2f, + 0x3f, 0x39, 0xd5, 0x44, 0x08, 0xd6, 0x8a, 0xba, 0x15, 0x0d, 0x33, 0xc0, 0x8a, 0x20, 0xaf, 0x47, + 0x84, 0x61, 0x92, 0x95, 0xb0, 0xec, 0x16, 0x76, 0xf3, 0xa4, 0x04, 0x96, 0x3a, 0xc2, 0xd7, 0xbe, + 0xa8, 0xe0, 0xce, 0xef, 0x87, 0xb2, 0xeb, 0xfc, 0xf9, 0x6f, 0xe3, 0x9c, 0x37, 0x4c, 0xc6, 0xf3, + 0xff, 0x1d, 0xb1, 0x78, 0xed, 0x07, 0x15, 0x54, 0x66, 0x83, 0xb3, 0xf3, 0x97, 0x49, 0x72, 0xdc, + 0x78, 0xf2, 0x4f, 0xf8, 0x5c, 0x50, 0xeb, 0xe5, 0xd1, 0xd8, 0x54, 0x8f, 0xc7, 0xa6, 0x7a, 0x32, + 0x36, 0xd5, 0x8f, 0x13, 0x53, 0x39, 0x9e, 0x98, 0xca, 0xd7, 0x89, 0xa9, 0xbc, 0xe8, 0xfa, 0x54, + 0x0e, 0x46, 0x7d, 0x07, 0xf3, 0x21, 0xc4, 0x5c, 0x0c, 0xb9, 0x80, 0xb4, 0x8f, 0xeb, 0x3e, 0x87, + 0xf1, 0x16, 0x1c, 0x72, 0x6f, 0x14, 0x10, 0x91, 0xae, 0x18, 0x01, 0x9b, 0x5b, 0xf5, 0x45, 0xea, + 0xfa, 0x59, 0x4b, 0x4e, 0x1e, 0x84, 0x44, 0xf4, 0x2b, 0xd9, 0x96, 0x79, 0xf8, 0x3d, 0x00, 0x00, + 0xff, 0xff, 0xf0, 0x81, 0x7c, 0xb2, 0x24, 0x05, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// 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 { + // RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount. + RegisterInterchainAccount(ctx context.Context, in *MsgRegisterInterchainAccount, opts ...grpc.CallOption) (*MsgRegisterInterchainAccountResponse, error) + // SendTx defines a rpc handler for MsgSendTx. + SendTx(ctx context.Context, in *MsgSendTx, opts ...grpc.CallOption) (*MsgSendTxResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) RegisterInterchainAccount(ctx context.Context, in *MsgRegisterInterchainAccount, opts ...grpc.CallOption) (*MsgRegisterInterchainAccountResponse, error) { + out := new(MsgRegisterInterchainAccountResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.interchain_accounts.controller.v1.Msg/RegisterInterchainAccount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) SendTx(ctx context.Context, in *MsgSendTx, opts ...grpc.CallOption) (*MsgSendTxResponse, error) { + out := new(MsgSendTxResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.interchain_accounts.controller.v1.Msg/SendTx", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount. + RegisterInterchainAccount(context.Context, *MsgRegisterInterchainAccount) (*MsgRegisterInterchainAccountResponse, error) + // SendTx defines a rpc handler for MsgSendTx. + SendTx(context.Context, *MsgSendTx) (*MsgSendTxResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) RegisterInterchainAccount(ctx context.Context, req *MsgRegisterInterchainAccount) (*MsgRegisterInterchainAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterInterchainAccount not implemented") +} +func (*UnimplementedMsgServer) SendTx(ctx context.Context, req *MsgSendTx) (*MsgSendTxResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendTx not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_RegisterInterchainAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRegisterInterchainAccount) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RegisterInterchainAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.interchain_accounts.controller.v1.Msg/RegisterInterchainAccount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RegisterInterchainAccount(ctx, req.(*MsgRegisterInterchainAccount)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_SendTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSendTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SendTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.interchain_accounts.controller.v1.Msg/SendTx", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SendTx(ctx, req.(*MsgSendTx)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.applications.interchain_accounts.controller.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "RegisterInterchainAccount", + Handler: _Msg_RegisterInterchainAccount_Handler, + }, + { + MethodName: "SendTx", + Handler: _Msg_SendTx_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/applications/interchain_accounts/controller/v1/tx.proto", +} + +func (m *MsgRegisterInterchainAccount) 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 *MsgRegisterInterchainAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRegisterInterchainAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintTx(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x1a + } + if len(m.ConnectionId) > 0 { + i -= len(m.ConnectionId) + copy(dAtA[i:], m.ConnectionId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ConnectionId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintTx(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgRegisterInterchainAccountResponse) 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 *MsgRegisterInterchainAccountResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRegisterInterchainAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0x12 + } + if len(m.ChannelId) > 0 { + i -= len(m.ChannelId) + copy(dAtA[i:], m.ChannelId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChannelId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSendTx) 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 *MsgSendTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.RelativeTimeout != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.RelativeTimeout)) + i-- + dAtA[i] = 0x20 + } + { + size, err := m.PacketData.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.ConnectionId) > 0 { + i -= len(m.ConnectionId) + copy(dAtA[i:], m.ConnectionId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ConnectionId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintTx(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSendTxResponse) 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 *MsgSendTxResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Sequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgRegisterInterchainAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ConnectionId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgRegisterInterchainAccountResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSendTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ConnectionId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.PacketData.Size() + n += 1 + l + sovTx(uint64(l)) + if m.RelativeTimeout != 0 { + n += 1 + sovTx(uint64(m.RelativeTimeout)) + } + return n +} + +func (m *MsgSendTxResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sequence != 0 { + n += 1 + sovTx(uint64(m.Sequence)) + } + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgRegisterInterchainAccount) 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: MsgRegisterInterchainAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRegisterInterchainAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", 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.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", 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.ConnectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", 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.Version = 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 *MsgRegisterInterchainAccountResponse) 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: MsgRegisterInterchainAccountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRegisterInterchainAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", 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.ChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PortId", 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.PortId = 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 *MsgSendTx) 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: MsgSendTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", 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.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", 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.ConnectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PacketData", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PacketData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RelativeTimeout", wireType) + } + m.RelativeTimeout = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RelativeTimeout |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + 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 *MsgSendTxResponse) 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: MsgSendTxResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendTxResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + m.Sequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + 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 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-interchain-accounts/doc.go b/modules/apps/27-interchain-accounts/doc.go new file mode 100644 index 00000000000..b31e3a63d3e --- /dev/null +++ b/modules/apps/27-interchain-accounts/doc.go @@ -0,0 +1,8 @@ +/* +Package ica implements the packet data structure, state machine handling logic, +and encoding details for the account management system over an IBC channel +between separate chains. +This implementation is based off the ICS 27 specification +(https://github.com/cosmos/ibc/tree/main/spec/app/ics-027-interchain-accounts) +*/ +package ica diff --git a/modules/apps/27-interchain-accounts/types/genesis.go b/modules/apps/27-interchain-accounts/genesis/types/genesis.go similarity index 88% rename from modules/apps/27-interchain-accounts/types/genesis.go rename to modules/apps/27-interchain-accounts/genesis/types/genesis.go index 67e8391ef66..f69ae13a00a 100644 --- a/modules/apps/27-interchain-accounts/types/genesis.go +++ b/modules/apps/27-interchain-accounts/genesis/types/genesis.go @@ -1,9 +1,10 @@ package types import ( - controllertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - hosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + hosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // DefaultGenesis creates and returns the interchain accounts GenesisState @@ -69,7 +70,7 @@ func (gs ControllerGenesisState) Validate() error { return err } - if err := ValidateAccountAddress(acc.AccountAddress); err != nil { + if err := icatypes.ValidateAccountAddress(acc.AccountAddress); err != nil { return err } } @@ -90,7 +91,7 @@ func (gs ControllerGenesisState) Validate() error { // DefaultHostGenesis creates and returns the default interchain accounts HostGenesisState func DefaultHostGenesis() HostGenesisState { return HostGenesisState{ - Port: PortID, + Port: icatypes.HostPortID, Params: hosttypes.DefaultParams(), } } @@ -122,7 +123,7 @@ func (gs HostGenesisState) Validate() error { return err } - if err := ValidateAccountAddress(acc.AccountAddress); err != nil { + if err := icatypes.ValidateAccountAddress(acc.AccountAddress); err != nil { return err } } diff --git a/modules/apps/27-interchain-accounts/types/genesis.pb.go b/modules/apps/27-interchain-accounts/genesis/types/genesis.pb.go similarity index 85% rename from modules/apps/27-interchain-accounts/types/genesis.pb.go rename to modules/apps/27-interchain-accounts/genesis/types/genesis.pb.go index 5dc6b9e4112..8e551ec1d62 100644 --- a/modules/apps/27-interchain-accounts/types/genesis.pb.go +++ b/modules/apps/27-interchain-accounts/genesis/types/genesis.pb.go @@ -1,14 +1,14 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: ibc/applications/interchain_accounts/v1/genesis.proto +// source: ibc/applications/interchain_accounts/genesis/v1/genesis.proto package types import ( fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - types1 "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + types1 "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" io "io" math "math" math_bits "math/bits" @@ -35,7 +35,7 @@ func (m *GenesisState) Reset() { *m = GenesisState{} } func (m *GenesisState) String() string { return proto.CompactTextString(m) } func (*GenesisState) ProtoMessage() {} func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_629b3ced0911516b, []int{0} + return fileDescriptor_d4aa48c8e29a1947, []int{0} } func (m *GenesisState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -90,7 +90,7 @@ func (m *ControllerGenesisState) Reset() { *m = ControllerGenesisState{} func (m *ControllerGenesisState) String() string { return proto.CompactTextString(m) } func (*ControllerGenesisState) ProtoMessage() {} func (*ControllerGenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_629b3ced0911516b, []int{1} + return fileDescriptor_d4aa48c8e29a1947, []int{1} } func (m *ControllerGenesisState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -159,7 +159,7 @@ func (m *HostGenesisState) Reset() { *m = HostGenesisState{} } func (m *HostGenesisState) String() string { return proto.CompactTextString(m) } func (*HostGenesisState) ProtoMessage() {} func (*HostGenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_629b3ced0911516b, []int{2} + return fileDescriptor_d4aa48c8e29a1947, []int{2} } func (m *HostGenesisState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -216,18 +216,20 @@ func (m *HostGenesisState) GetParams() types1.Params { return types1.Params{} } -// ActiveChannel contains a connection ID, port ID and associated active channel ID +// ActiveChannel contains a connection ID, port ID and associated active channel ID, as well as a boolean flag to +// indicate if the channel is middleware enabled type ActiveChannel struct { - ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` - PortId string `protobuf:"bytes,2,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` - ChannelId string `protobuf:"bytes,3,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"` + ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` + PortId string `protobuf:"bytes,2,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` + ChannelId string `protobuf:"bytes,3,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"` + IsMiddlewareEnabled bool `protobuf:"varint,4,opt,name=is_middleware_enabled,json=isMiddlewareEnabled,proto3" json:"is_middleware_enabled,omitempty" yaml:"is_middleware_enabled"` } func (m *ActiveChannel) Reset() { *m = ActiveChannel{} } func (m *ActiveChannel) String() string { return proto.CompactTextString(m) } func (*ActiveChannel) ProtoMessage() {} func (*ActiveChannel) Descriptor() ([]byte, []int) { - return fileDescriptor_629b3ced0911516b, []int{3} + return fileDescriptor_d4aa48c8e29a1947, []int{3} } func (m *ActiveChannel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -277,6 +279,13 @@ func (m *ActiveChannel) GetChannelId() string { return "" } +func (m *ActiveChannel) GetIsMiddlewareEnabled() bool { + if m != nil { + return m.IsMiddlewareEnabled + } + return false +} + // RegisteredInterchainAccount contains a connection ID, port ID and associated interchain account address type RegisteredInterchainAccount struct { ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` @@ -288,7 +297,7 @@ func (m *RegisteredInterchainAccount) Reset() { *m = RegisteredInterchai func (m *RegisteredInterchainAccount) String() string { return proto.CompactTextString(m) } func (*RegisteredInterchainAccount) ProtoMessage() {} func (*RegisteredInterchainAccount) Descriptor() ([]byte, []int) { - return fileDescriptor_629b3ced0911516b, []int{4} + return fileDescriptor_d4aa48c8e29a1947, []int{4} } func (m *RegisteredInterchainAccount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -339,60 +348,63 @@ func (m *RegisteredInterchainAccount) GetAccountAddress() string { } func init() { - proto.RegisterType((*GenesisState)(nil), "ibc.applications.interchain_accounts.v1.GenesisState") - proto.RegisterType((*ControllerGenesisState)(nil), "ibc.applications.interchain_accounts.v1.ControllerGenesisState") - proto.RegisterType((*HostGenesisState)(nil), "ibc.applications.interchain_accounts.v1.HostGenesisState") - proto.RegisterType((*ActiveChannel)(nil), "ibc.applications.interchain_accounts.v1.ActiveChannel") - proto.RegisterType((*RegisteredInterchainAccount)(nil), "ibc.applications.interchain_accounts.v1.RegisteredInterchainAccount") + proto.RegisterType((*GenesisState)(nil), "ibc.applications.interchain_accounts.genesis.v1.GenesisState") + proto.RegisterType((*ControllerGenesisState)(nil), "ibc.applications.interchain_accounts.genesis.v1.ControllerGenesisState") + proto.RegisterType((*HostGenesisState)(nil), "ibc.applications.interchain_accounts.genesis.v1.HostGenesisState") + proto.RegisterType((*ActiveChannel)(nil), "ibc.applications.interchain_accounts.genesis.v1.ActiveChannel") + proto.RegisterType((*RegisteredInterchainAccount)(nil), "ibc.applications.interchain_accounts.genesis.v1.RegisteredInterchainAccount") } func init() { - proto.RegisterFile("ibc/applications/interchain_accounts/v1/genesis.proto", fileDescriptor_629b3ced0911516b) -} - -var fileDescriptor_629b3ced0911516b = []byte{ - // 643 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x95, 0x3f, 0x6f, 0x13, 0x31, - 0x18, 0xc6, 0xe3, 0xa4, 0x14, 0xc5, 0xfd, 0x43, 0x31, 0xa5, 0x3a, 0x82, 0x74, 0x09, 0x5e, 0x1a, - 0x09, 0xf5, 0x4e, 0x2d, 0x85, 0x8a, 0x4a, 0x08, 0xf5, 0x02, 0x82, 0x6c, 0xc8, 0x2c, 0x88, 0xe5, - 0xe4, 0xf8, 0xac, 0xc4, 0x52, 0x72, 0x8e, 0xce, 0x6e, 0xa4, 0x4e, 0xec, 0x4c, 0x6c, 0x88, 0x15, - 0x89, 0x0f, 0xc0, 0x37, 0x60, 0xec, 0x84, 0x3a, 0x32, 0x45, 0xa8, 0xfd, 0x06, 0xf9, 0x04, 0xc8, - 0xbe, 0x53, 0x92, 0x1e, 0x69, 0x75, 0x13, 0x13, 0x53, 0xec, 0x7b, 0xfd, 0x3c, 0xef, 0xef, 0xf5, - 0xeb, 0xd8, 0xf0, 0xb1, 0xe8, 0x30, 0x9f, 0x0e, 0x87, 0x7d, 0xc1, 0xa8, 0x16, 0x32, 0x56, 0xbe, - 0x88, 0x35, 0x4f, 0x58, 0x8f, 0x8a, 0x38, 0xa4, 0x8c, 0xc9, 0xe3, 0x58, 0x2b, 0x7f, 0xb4, 0xeb, - 0x77, 0x79, 0xcc, 0x95, 0x50, 0xde, 0x30, 0x91, 0x5a, 0xa2, 0x6d, 0xd1, 0x61, 0xde, 0xbc, 0xcc, - 0x5b, 0x20, 0xf3, 0x46, 0xbb, 0xb5, 0xcd, 0xae, 0xec, 0x4a, 0xab, 0xf1, 0xcd, 0x28, 0x95, 0xd7, - 0x5a, 0x85, 0xb2, 0x32, 0x19, 0xeb, 0x44, 0xf6, 0xfb, 0x3c, 0x31, 0x00, 0xb3, 0x59, 0x66, 0x72, - 0x50, 0xc8, 0xa4, 0x27, 0x95, 0x36, 0x72, 0xf3, 0x9b, 0x0a, 0xf1, 0x8f, 0x32, 0x5c, 0x7d, 0x95, - 0x96, 0xf3, 0x56, 0x53, 0xcd, 0xd1, 0x57, 0x00, 0x9d, 0x99, 0x7d, 0x98, 0x95, 0x1a, 0x2a, 0x13, - 0x74, 0x40, 0x03, 0x34, 0x57, 0xf6, 0x9e, 0x7b, 0x05, 0x2b, 0xf6, 0x5a, 0x53, 0xa3, 0xf9, 0x1c, - 0xc1, 0xf6, 0xe9, 0xb8, 0x5e, 0x9a, 0x8c, 0xeb, 0xf5, 0x13, 0x3a, 0xe8, 0x1f, 0xe2, 0xab, 0xd2, - 0x61, 0xb2, 0xc5, 0x16, 0x1a, 0xa0, 0x8f, 0x00, 0x22, 0x53, 0x44, 0x0e, 0xaf, 0x6c, 0xf1, 0x9e, - 0x16, 0xc6, 0x7b, 0x2d, 0x95, 0xbe, 0x04, 0xf6, 0x20, 0x03, 0xbb, 0x97, 0x82, 0xfd, 0x9d, 0x02, - 0x93, 0x8d, 0x5e, 0x4e, 0x84, 0xbf, 0x55, 0xe0, 0xd6, 0xe2, 0x42, 0xd1, 0x07, 0x78, 0x8b, 0x32, - 0x2d, 0x46, 0x3c, 0x64, 0x3d, 0x1a, 0xc7, 0xbc, 0xaf, 0x1c, 0xd0, 0xa8, 0x34, 0x57, 0xf6, 0x9e, - 0x14, 0x66, 0x3c, 0xb2, 0xfa, 0x56, 0x2a, 0x0f, 0xdc, 0x0c, 0x70, 0x2b, 0x05, 0xcc, 0x99, 0x63, - 0xb2, 0x4e, 0xe7, 0x97, 0x2b, 0xf4, 0x05, 0xc0, 0x3b, 0x0b, 0x8c, 0x9d, 0xb2, 0xa5, 0x78, 0x51, - 0x98, 0x82, 0xf0, 0xae, 0x50, 0x9a, 0x27, 0x3c, 0x6a, 0x4f, 0x17, 0x1c, 0xa5, 0xf1, 0x00, 0x67, - 0x4c, 0xb5, 0x94, 0x69, 0x81, 0x03, 0x26, 0x48, 0xe4, 0x65, 0x0a, 0x6d, 0xc2, 0x1b, 0x43, 0x99, - 0x68, 0xe5, 0x54, 0x1a, 0x95, 0x66, 0x95, 0xa4, 0x13, 0xf4, 0x0e, 0x2e, 0x0f, 0x69, 0x42, 0x07, - 0xca, 0x59, 0xb2, 0xdd, 0x3c, 0x2c, 0xc6, 0x38, 0xf7, 0x8f, 0x18, 0xed, 0x7a, 0x6f, 0xac, 0x43, - 0xb0, 0x64, 0xc8, 0x48, 0xe6, 0x87, 0x3f, 0x57, 0xe0, 0x46, 0xbe, 0xe3, 0xff, 0x3b, 0x74, 0x5d, - 0x87, 0x10, 0x5c, 0x32, 0x4d, 0x71, 0x2a, 0x0d, 0xd0, 0xac, 0x12, 0x3b, 0x46, 0x24, 0xd7, 0x9f, - 0xfd, 0x62, 0x84, 0xf6, 0xca, 0xb9, 0xaa, 0x33, 0xdf, 0x01, 0x5c, 0xbb, 0xb4, 0x8b, 0xe8, 0x19, - 0x5c, 0x63, 0x32, 0x8e, 0x39, 0x33, 0x8e, 0xa1, 0x88, 0xec, 0xcd, 0x53, 0x0d, 0x9c, 0xc9, 0xb8, - 0xbe, 0x39, 0xbd, 0x34, 0x66, 0x61, 0x4c, 0x56, 0x67, 0xf3, 0x76, 0x84, 0x1e, 0xc2, 0x9b, 0x06, - 0xd6, 0x08, 0xcb, 0x56, 0x88, 0x26, 0xe3, 0xfa, 0x7a, 0x2a, 0xcc, 0x02, 0x98, 0x2c, 0x9b, 0x51, - 0x3b, 0x42, 0xfb, 0x10, 0x66, 0xed, 0x31, 0xeb, 0x6d, 0xad, 0xc1, 0xdd, 0xc9, 0xb8, 0x7e, 0x3b, - 0x4b, 0x34, 0x8d, 0x61, 0x52, 0xcd, 0x26, 0xed, 0x08, 0xff, 0x04, 0xf0, 0xfe, 0x35, 0x7b, 0xfe, - 0x4f, 0x2b, 0x68, 0x99, 0x43, 0x6c, 0xd3, 0x86, 0x34, 0x8a, 0x12, 0xae, 0x54, 0x56, 0x46, 0x6d, - 0xfe, 0x20, 0x5e, 0x5a, 0x60, 0x0f, 0xa2, 0xfd, 0x72, 0x94, 0x7e, 0x08, 0xc2, 0xd3, 0x73, 0x17, - 0x9c, 0x9d, 0xbb, 0xe0, 0xf7, 0xb9, 0x0b, 0x3e, 0x5d, 0xb8, 0xa5, 0xb3, 0x0b, 0xb7, 0xf4, 0xeb, - 0xc2, 0x2d, 0xbd, 0x7f, 0xd9, 0x15, 0xba, 0x77, 0xdc, 0xf1, 0x98, 0x1c, 0xf8, 0x4c, 0xaa, 0x81, - 0x54, 0xbe, 0xe8, 0xb0, 0x9d, 0xae, 0xf4, 0x47, 0xfb, 0xfe, 0x40, 0x46, 0xc7, 0x7d, 0xae, 0xcc, - 0xe3, 0xa3, 0xfc, 0xbd, 0x83, 0x9d, 0x59, 0xf3, 0x77, 0xa6, 0xef, 0x8e, 0x3e, 0x19, 0x72, 0xd5, - 0x59, 0xb6, 0x2f, 0xce, 0xa3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xd8, 0xa4, 0x04, 0x67, - 0x07, 0x00, 0x00, + proto.RegisterFile("ibc/applications/interchain_accounts/genesis/v1/genesis.proto", fileDescriptor_d4aa48c8e29a1947) +} + +var fileDescriptor_d4aa48c8e29a1947 = []byte{ + // 692 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x95, 0x4d, 0x6b, 0xdb, 0x3e, + 0x1c, 0xc7, 0xe3, 0xa4, 0xff, 0xfe, 0x17, 0xf5, 0x61, 0x9d, 0xfa, 0x80, 0x97, 0x0d, 0x3b, 0xf3, + 0x65, 0x81, 0x51, 0x9b, 0x76, 0x85, 0x42, 0xa1, 0x83, 0x38, 0x8c, 0x2e, 0xb0, 0xc2, 0xf0, 0x76, + 0x18, 0xbb, 0x18, 0x45, 0x16, 0x8e, 0xc0, 0xb1, 0x82, 0xa5, 0x66, 0xf4, 0x15, 0xf4, 0x3a, 0xf6, + 0x0e, 0x76, 0x1b, 0x7b, 0x01, 0x7b, 0x0d, 0x3d, 0x8d, 0x1e, 0x77, 0x0a, 0xa3, 0x7d, 0x07, 0x79, + 0x05, 0x43, 0xb2, 0x9a, 0xa4, 0x69, 0x3a, 0x92, 0xcb, 0x4e, 0x3b, 0x59, 0x0f, 0xbf, 0xef, 0xf7, + 0xf7, 0x91, 0x7e, 0xb2, 0x04, 0x0e, 0x69, 0x0b, 0x7b, 0xa8, 0xdb, 0x4d, 0x28, 0x46, 0x82, 0xb2, + 0x94, 0x7b, 0x34, 0x15, 0x24, 0xc3, 0x6d, 0x44, 0xd3, 0x10, 0x61, 0xcc, 0x4e, 0x52, 0xc1, 0xbd, + 0x98, 0xa4, 0x84, 0x53, 0xee, 0xf5, 0x76, 0xae, 0x9b, 0x6e, 0x37, 0x63, 0x82, 0x41, 0x8f, 0xb6, + 0xb0, 0x3b, 0x2e, 0x77, 0xa7, 0xc8, 0xdd, 0x6b, 0x4d, 0x6f, 0xa7, 0xb2, 0x11, 0xb3, 0x98, 0x29, + 0xad, 0x27, 0x5b, 0xb9, 0x4d, 0xa5, 0x31, 0x13, 0x05, 0x66, 0xa9, 0xc8, 0x58, 0x92, 0x90, 0x4c, + 0x82, 0x8c, 0x7a, 0xda, 0x64, 0x7f, 0x26, 0x93, 0x36, 0xe3, 0x42, 0xca, 0xe5, 0x37, 0x17, 0x3a, + 0x17, 0x45, 0xb0, 0x7c, 0x94, 0x23, 0xbe, 0x15, 0x48, 0x10, 0xf8, 0xcd, 0x00, 0xe6, 0xc8, 0x3e, + 0xd4, 0xf8, 0x21, 0x97, 0x93, 0xa6, 0x51, 0x35, 0x6a, 0x4b, 0xbb, 0x47, 0xee, 0x9c, 0x2b, 0x77, + 0x1b, 0x43, 0xc3, 0xf1, 0x5c, 0xfe, 0xd3, 0xf3, 0xbe, 0x5d, 0x18, 0xf4, 0x6d, 0xfb, 0x14, 0x75, + 0x92, 0x03, 0xe7, 0xae, 0xb4, 0x4e, 0xb0, 0x85, 0xa7, 0x1a, 0xc0, 0xcf, 0x06, 0x80, 0x72, 0x31, + 0x13, 0x98, 0x45, 0x85, 0x59, 0x9f, 0x1b, 0xf3, 0x15, 0xe3, 0xe2, 0x06, 0xe0, 0x13, 0x0d, 0xf8, + 0x30, 0x07, 0xbc, 0x9d, 0xca, 0x09, 0xd6, 0xda, 0x13, 0x22, 0xe7, 0x7b, 0x09, 0x6c, 0x4d, 0x5f, + 0x30, 0x3c, 0x33, 0xc0, 0x7d, 0x84, 0x05, 0xed, 0x91, 0x10, 0xb7, 0x51, 0x9a, 0x92, 0x84, 0x9b, + 0x46, 0xb5, 0x54, 0x5b, 0xda, 0x7d, 0x31, 0x37, 0x6c, 0x5d, 0xf9, 0x34, 0x72, 0x1b, 0xdf, 0xd2, + 0xa4, 0x5b, 0x39, 0xe9, 0x44, 0x12, 0x27, 0x58, 0x45, 0xe3, 0xe1, 0x1c, 0x7e, 0x31, 0xc0, 0xfa, + 0x94, 0x04, 0x66, 0x51, 0xd1, 0xbc, 0x9e, 0x9b, 0x26, 0x20, 0x31, 0xe5, 0x82, 0x64, 0x24, 0x6a, + 0x0e, 0x03, 0xeb, 0x79, 0x9c, 0xef, 0x68, 0xb6, 0x4a, 0xce, 0x36, 0xc5, 0xc9, 0x09, 0x20, 0x9d, + 0x94, 0x71, 0xb8, 0x01, 0xfe, 0xeb, 0xb2, 0x4c, 0x70, 0xb3, 0x54, 0x2d, 0xd5, 0xca, 0x41, 0xde, + 0x81, 0xef, 0xc1, 0x62, 0x17, 0x65, 0xa8, 0xc3, 0xcd, 0x05, 0x55, 0xe6, 0x83, 0xd9, 0x58, 0xc7, + 0x7e, 0x99, 0xde, 0x8e, 0xfb, 0x46, 0x39, 0xf8, 0x0b, 0x92, 0x2c, 0xd0, 0x7e, 0xce, 0xd7, 0x12, + 0x58, 0x9b, 0x3c, 0x02, 0xff, 0x4a, 0x36, 0x57, 0xc9, 0x20, 0x58, 0x90, 0x55, 0x32, 0x4b, 0x55, + 0xa3, 0x56, 0x0e, 0x54, 0x1b, 0x06, 0x13, 0x05, 0xdb, 0x9b, 0x8d, 0x54, 0x5d, 0x52, 0x77, 0x95, + 0xea, 0xac, 0x08, 0x56, 0x6e, 0xec, 0x26, 0x3c, 0x04, 0x2b, 0x98, 0xa5, 0x29, 0xc1, 0xd2, 0x31, + 0xa4, 0x91, 0xba, 0xab, 0xca, 0xbe, 0x39, 0xe8, 0xdb, 0x1b, 0xc3, 0xeb, 0x65, 0x34, 0xed, 0x04, + 0xcb, 0xa3, 0x7e, 0x33, 0x82, 0xcf, 0xc0, 0xff, 0x12, 0x56, 0x0a, 0x8b, 0x4a, 0x08, 0x07, 0x7d, + 0x7b, 0x35, 0x17, 0xea, 0x09, 0x27, 0x58, 0x94, 0xad, 0x66, 0x04, 0xf7, 0x00, 0xd0, 0x65, 0x92, + 0xf1, 0x6a, 0xad, 0xfe, 0xe6, 0xa0, 0x6f, 0x3f, 0xd0, 0x89, 0x86, 0x73, 0x4e, 0x50, 0xd6, 0x9d, + 0x66, 0x04, 0xdf, 0x81, 0x4d, 0xca, 0xc3, 0x0e, 0x8d, 0xa2, 0x84, 0x7c, 0x44, 0x19, 0x09, 0x49, + 0x8a, 0x5a, 0x09, 0x89, 0xd4, 0xb6, 0xdc, 0xf3, 0xab, 0x83, 0xbe, 0xfd, 0x58, 0x6f, 0xf7, 0xb4, + 0x30, 0x27, 0x58, 0xa7, 0xfc, 0x78, 0x38, 0xfc, 0x52, 0x8f, 0xfe, 0x30, 0xc0, 0xa3, 0x3f, 0x54, + 0xf2, 0xaf, 0xee, 0x4b, 0x43, 0xfe, 0x2a, 0x2a, 0x6d, 0x88, 0xa2, 0x28, 0x23, 0x9c, 0xeb, 0xcd, + 0xa9, 0x8c, 0x1f, 0xf3, 0x1b, 0x01, 0xea, 0x98, 0xab, 0x91, 0x7a, 0x3e, 0xe0, 0xc7, 0xe7, 0x97, + 0x96, 0x71, 0x71, 0x69, 0x19, 0xbf, 0x2e, 0x2d, 0xe3, 0xd3, 0x95, 0x55, 0xb8, 0xb8, 0xb2, 0x0a, + 0x3f, 0xaf, 0xac, 0xc2, 0x87, 0xe3, 0x98, 0x8a, 0xf6, 0x49, 0xcb, 0xc5, 0xac, 0xe3, 0x61, 0xc6, + 0x3b, 0x8c, 0xcb, 0x27, 0x78, 0x3b, 0x66, 0x5e, 0x6f, 0xdf, 0xeb, 0xb0, 0xe8, 0x24, 0x21, 0x5c, + 0x3e, 0x82, 0xdc, 0xdb, 0xdd, 0xdf, 0x1e, 0x1d, 0xa9, 0xed, 0x5b, 0x4f, 0xb9, 0x38, 0xed, 0x12, + 0xde, 0x5a, 0x54, 0x2f, 0xe0, 0xf3, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x33, 0x7f, 0xe2, 0xc0, + 0x07, 0x08, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -596,6 +608,16 @@ func (m *ActiveChannel) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.IsMiddlewareEnabled { + i-- + if m.IsMiddlewareEnabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } if len(m.ChannelId) > 0 { i -= len(m.ChannelId) copy(dAtA[i:], m.ChannelId) @@ -762,6 +784,9 @@ func (m *ActiveChannel) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } + if m.IsMiddlewareEnabled { + n += 2 + } return n } @@ -1399,6 +1424,26 @@ func (m *ActiveChannel) Unmarshal(dAtA []byte) error { } m.ChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsMiddlewareEnabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsMiddlewareEnabled = bool(v != 0) default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/modules/apps/27-interchain-accounts/types/genesis_test.go b/modules/apps/27-interchain-accounts/genesis/types/genesis_test.go similarity index 50% rename from modules/apps/27-interchain-accounts/types/genesis_test.go rename to modules/apps/27-interchain-accounts/genesis/types/genesis_test.go index be86e8595a4..d26ebff53a9 100644 --- a/modules/apps/27-interchain-accounts/types/genesis_test.go +++ b/modules/apps/27-interchain-accounts/genesis/types/genesis_test.go @@ -1,14 +1,29 @@ package types_test import ( - controllertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - hosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/stretchr/testify/suite" + + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + hosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +var ( + // TestOwnerAddress defines a reusable bech32 address for testing purposes + TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + + // TestPortID defines a reusable port identifier for testing purposes + TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) ) -func (suite *TypesTestSuite) TestValidateGenesisState() { - var genesisState types.GenesisState +type GenesisTypesTestSuite struct { + suite.Suite +} + +func (suite *GenesisTypesTestSuite) TestValidateGenesisState() { + var genesisState genesistypes.GenesisState testCases := []struct { name string @@ -23,21 +38,21 @@ func (suite *TypesTestSuite) TestValidateGenesisState() { { "failed to validate - empty value", func() { - genesisState = types.GenesisState{} + genesisState = genesistypes.GenesisState{} }, false, }, { "failed to validate - invalid controller genesis", func() { - genesisState = *types.NewGenesisState(types.ControllerGenesisState{Ports: []string{"invalid|port"}}, types.DefaultHostGenesis()) + genesisState = *genesistypes.NewGenesisState(genesistypes.ControllerGenesisState{Ports: []string{"invalid|port"}}, genesistypes.DefaultHostGenesis()) }, false, }, { "failed to validate - invalid host genesis", func() { - genesisState = *types.NewGenesisState(types.DefaultControllerGenesis(), types.HostGenesisState{}) + genesisState = *genesistypes.NewGenesisState(genesistypes.DefaultControllerGenesis(), genesistypes.HostGenesisState{}) }, false, }, @@ -45,7 +60,7 @@ func (suite *TypesTestSuite) TestValidateGenesisState() { for _, tc := range testCases { suite.Run(tc.name, func() { - genesisState = *types.DefaultGenesis() + genesisState = *genesistypes.DefaultGenesis() tc.malleate() // malleate mutates test data @@ -60,8 +75,8 @@ func (suite *TypesTestSuite) TestValidateGenesisState() { } } -func (suite *TypesTestSuite) TestValidateControllerGenesisState() { - var genesisState types.ControllerGenesisState +func (suite *GenesisTypesTestSuite) TestValidateControllerGenesisState() { + var genesisState genesistypes.ControllerGenesisState testCases := []struct { name string @@ -76,91 +91,91 @@ func (suite *TypesTestSuite) TestValidateControllerGenesisState() { { "failed to validate active channel - invalid port identifier", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: "invalid|port", ChannelId: ibctesting.FirstChannelID, }, } - genesisState = types.NewControllerGenesisState(activeChannels, []types.RegisteredInterchainAccount{}, []string{}, controllertypes.DefaultParams()) + genesisState = genesistypes.NewControllerGenesisState(activeChannels, []genesistypes.RegisteredInterchainAccount{}, []string{}, controllertypes.DefaultParams()) }, false, }, { "failed to validate active channel - invalid channel identifier", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: TestPortID, ChannelId: "invalid|channel", }, } - genesisState = types.NewControllerGenesisState(activeChannels, []types.RegisteredInterchainAccount{}, []string{}, controllertypes.DefaultParams()) + genesisState = genesistypes.NewControllerGenesisState(activeChannels, []genesistypes.RegisteredInterchainAccount{}, []string{}, controllertypes.DefaultParams()) }, false, }, { "failed to validate registered account - invalid port identifier", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: TestPortID, ChannelId: ibctesting.FirstChannelID, }, } - registeredAccounts := []types.RegisteredInterchainAccount{ + registeredAccounts := []genesistypes.RegisteredInterchainAccount{ { PortId: "invalid|port", AccountAddress: TestOwnerAddress, }, } - genesisState = types.NewControllerGenesisState(activeChannels, registeredAccounts, []string{}, controllertypes.DefaultParams()) + genesisState = genesistypes.NewControllerGenesisState(activeChannels, registeredAccounts, []string{}, controllertypes.DefaultParams()) }, false, }, { "failed to validate registered account - invalid owner address", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: TestPortID, ChannelId: ibctesting.FirstChannelID, }, } - registeredAccounts := []types.RegisteredInterchainAccount{ + registeredAccounts := []genesistypes.RegisteredInterchainAccount{ { PortId: TestPortID, AccountAddress: "", }, } - genesisState = types.NewControllerGenesisState(activeChannels, registeredAccounts, []string{}, controllertypes.DefaultParams()) + genesisState = genesistypes.NewControllerGenesisState(activeChannels, registeredAccounts, []string{}, controllertypes.DefaultParams()) }, false, }, { "failed to validate controller ports - invalid port identifier", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: TestPortID, ChannelId: ibctesting.FirstChannelID, }, } - registeredAccounts := []types.RegisteredInterchainAccount{ + registeredAccounts := []genesistypes.RegisteredInterchainAccount{ { PortId: TestPortID, AccountAddress: TestOwnerAddress, }, } - genesisState = types.NewControllerGenesisState(activeChannels, registeredAccounts, []string{"invalid|port"}, controllertypes.DefaultParams()) + genesisState = genesistypes.NewControllerGenesisState(activeChannels, registeredAccounts, []string{"invalid|port"}, controllertypes.DefaultParams()) }, false, }, @@ -168,7 +183,7 @@ func (suite *TypesTestSuite) TestValidateControllerGenesisState() { for _, tc := range testCases { suite.Run(tc.name, func() { - genesisState = types.DefaultControllerGenesis() + genesisState = genesistypes.DefaultControllerGenesis() tc.malleate() // malleate mutates test data @@ -183,8 +198,8 @@ func (suite *TypesTestSuite) TestValidateControllerGenesisState() { } } -func (suite *TypesTestSuite) TestValidateHostGenesisState() { - var genesisState types.HostGenesisState +func (suite *GenesisTypesTestSuite) TestValidateHostGenesisState() { + var genesisState genesistypes.HostGenesisState testCases := []struct { name string @@ -199,91 +214,91 @@ func (suite *TypesTestSuite) TestValidateHostGenesisState() { { "failed to validate active channel - invalid port identifier", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: "invalid|port", ChannelId: ibctesting.FirstChannelID, }, } - genesisState = types.NewHostGenesisState(activeChannels, []types.RegisteredInterchainAccount{}, types.PortID, hosttypes.DefaultParams()) + genesisState = genesistypes.NewHostGenesisState(activeChannels, []genesistypes.RegisteredInterchainAccount{}, icatypes.HostPortID, hosttypes.DefaultParams()) }, false, }, { "failed to validate active channel - invalid channel identifier", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: TestPortID, ChannelId: "invalid|channel", }, } - genesisState = types.NewHostGenesisState(activeChannels, []types.RegisteredInterchainAccount{}, types.PortID, hosttypes.DefaultParams()) + genesisState = genesistypes.NewHostGenesisState(activeChannels, []genesistypes.RegisteredInterchainAccount{}, icatypes.HostPortID, hosttypes.DefaultParams()) }, false, }, { "failed to validate registered account - invalid port identifier", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: TestPortID, ChannelId: ibctesting.FirstChannelID, }, } - registeredAccounts := []types.RegisteredInterchainAccount{ + registeredAccounts := []genesistypes.RegisteredInterchainAccount{ { PortId: "invalid|port", AccountAddress: TestOwnerAddress, }, } - genesisState = types.NewHostGenesisState(activeChannels, registeredAccounts, types.PortID, hosttypes.DefaultParams()) + genesisState = genesistypes.NewHostGenesisState(activeChannels, registeredAccounts, icatypes.HostPortID, hosttypes.DefaultParams()) }, false, }, { "failed to validate registered account - invalid owner address", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: TestPortID, ChannelId: ibctesting.FirstChannelID, }, } - registeredAccounts := []types.RegisteredInterchainAccount{ + registeredAccounts := []genesistypes.RegisteredInterchainAccount{ { PortId: TestPortID, AccountAddress: "", }, } - genesisState = types.NewHostGenesisState(activeChannels, registeredAccounts, types.PortID, hosttypes.DefaultParams()) + genesisState = genesistypes.NewHostGenesisState(activeChannels, registeredAccounts, icatypes.HostPortID, hosttypes.DefaultParams()) }, false, }, { "failed to validate controller ports - invalid port identifier", func() { - activeChannels := []types.ActiveChannel{ + activeChannels := []genesistypes.ActiveChannel{ { PortId: TestPortID, ChannelId: ibctesting.FirstChannelID, }, } - registeredAccounts := []types.RegisteredInterchainAccount{ + registeredAccounts := []genesistypes.RegisteredInterchainAccount{ { PortId: TestPortID, AccountAddress: TestOwnerAddress, }, } - genesisState = types.NewHostGenesisState(activeChannels, registeredAccounts, "invalid|port", hosttypes.DefaultParams()) + genesisState = genesistypes.NewHostGenesisState(activeChannels, registeredAccounts, "invalid|port", hosttypes.DefaultParams()) }, false, }, @@ -291,7 +306,7 @@ func (suite *TypesTestSuite) TestValidateHostGenesisState() { for _, tc := range testCases { suite.Run(tc.name, func() { - genesisState = types.DefaultHostGenesis() + genesisState = genesistypes.DefaultHostGenesis() tc.malleate() // malleate mutates test data diff --git a/modules/apps/27-interchain-accounts/host/client/cli/cli.go b/modules/apps/27-interchain-accounts/host/client/cli/cli.go index 2ae88a48b70..23d2dc2e83a 100644 --- a/modules/apps/27-interchain-accounts/host/client/cli/cli.go +++ b/modules/apps/27-interchain-accounts/host/client/cli/cli.go @@ -1,6 +1,7 @@ package cli import ( + "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" ) @@ -8,7 +9,7 @@ import ( func GetQueryCmd() *cobra.Command { queryCmd := &cobra.Command{ Use: "host", - Short: "interchain-accounts host subcommands", + Short: "IBC interchain accounts host query subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, } @@ -20,3 +21,20 @@ func GetQueryCmd() *cobra.Command { return queryCmd } + +// NewTxCmd creates and returns the tx command +func NewTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "host", + Short: "IBC interchain accounts host transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + generatePacketDataCmd(), + ) + + return cmd +} diff --git a/modules/apps/27-interchain-accounts/host/client/cli/query.go b/modules/apps/27-interchain-accounts/host/client/cli/query.go index a5a6637ce9a..95ff6a77fc8 100644 --- a/modules/apps/27-interchain-accounts/host/client/cli/query.go +++ b/modules/apps/27-interchain-accounts/host/client/cli/query.go @@ -12,10 +12,10 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // GetCmdParams returns the command handler for the host submodule parameter querying. @@ -61,7 +61,7 @@ func GetCmdPacketEvents() *cobra.Command { return err } - channelID, portID := args[0], icatypes.PortID + channelID, portID := args[0], icatypes.HostPortID if err := host.ChannelIdentifierValidator(channelID); err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/host/client/cli/tx.go b/modules/apps/27-interchain-accounts/host/client/cli/tx.go new file mode 100644 index 00000000000..8d74f1ce66c --- /dev/null +++ b/modules/apps/27-interchain-accounts/host/client/cli/tx.go @@ -0,0 +1,148 @@ +package cli + +import ( + "encoding/json" + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/cosmos/gogoproto/proto" + "github.com/spf13/cobra" + + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" +) + +const ( + memoFlag string = "memo" +) + +func generatePacketDataCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "generate-packet-data [message]", + Short: "Generates ICA packet data.", + Long: `generate-packet-data accepts a message string and serializes it +into packet data which is outputted to stdout. It can be used in conjunction with send-tx" +which submits pre-built packet data containing messages to be executed on the host chain. +`, + Example: fmt.Sprintf(`%s tx interchain-accounts host generate-packet-data '{ + "@type":"/cosmos.bank.v1beta1.MsgSend", + "from_address":"cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", + "to_address":"cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw", + "amount": [ + { + "denom": "stake", + "amount": "1000" + } + ] +}' --memo memo + + +%s tx interchain-accounts host generate-packet-data '[{ + "@type":"/cosmos.bank.v1beta1.MsgSend", + "from_address":"cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", + "to_address":"cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw", + "amount": [ + { + "denom": "stake", + "amount": "1000" + } + ] +}, +{ + "@type": "/cosmos.staking.v1beta1.MsgDelegate", + "delegator_address": "cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", + "validator_address": "cosmosvaloper1qnk2n4nlkpw9xfqntladh74w6ujtulwnmxnh3k", + "amount": { + "denom": "stake", + "amount": "1000" + } +}]'`, version.AppName, version.AppName), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) + + memo, err := cmd.Flags().GetString(memoFlag) + if err != nil { + return err + } + + packetDataBytes, err := generatePacketData(cdc, []byte(args[0]), memo) + if err != nil { + return err + } + + cmd.Println(string(packetDataBytes)) + + return nil + }, + } + + cmd.Flags().String(memoFlag, "", "an optional memo to be included in the interchain account packet data") + return cmd +} + +// generatePacketData takes in message bytes and a memo and serializes the message into an +// instance of InterchainAccountPacketData which is returned as bytes. +func generatePacketData(cdc *codec.ProtoCodec, msgBytes []byte, memo string) ([]byte, error) { + protoMessages, err := convertBytesIntoProtoMessages(cdc, msgBytes) + if err != nil { + return nil, err + } + + return generateIcaPacketDataFromProtoMessages(cdc, protoMessages, memo) +} + +// convertBytesIntoProtoMessages returns a list of proto messages from bytes. The bytes can be in the form of a single +// message, or a json array of messages. +func convertBytesIntoProtoMessages(cdc *codec.ProtoCodec, msgBytes []byte) ([]proto.Message, error) { + var rawMessages []json.RawMessage + if err := json.Unmarshal(msgBytes, &rawMessages); err != nil { + // if we fail to unmarshal a list of messages, we assume we are just dealing with a single message. + // in this case we return a list of a single item. + var msg sdk.Msg + if err := cdc.UnmarshalInterfaceJSON(msgBytes, &msg); err != nil { + return nil, err + } + + return []proto.Message{msg}, nil + } + + sdkMessages := make([]proto.Message, len(rawMessages)) + for i, anyJSON := range rawMessages { + var msg sdk.Msg + if err := cdc.UnmarshalInterfaceJSON(anyJSON, &msg); err != nil { + return nil, err + } + + sdkMessages[i] = msg + } + + return sdkMessages, nil +} + +// generateIcaPacketDataFromProtoMessages generates ica packet data as bytes from a given set of proto encoded sdk messages and a memo. +func generateIcaPacketDataFromProtoMessages(cdc *codec.ProtoCodec, sdkMessages []proto.Message, memo string) ([]byte, error) { + icaPacketDataBytes, err := icatypes.SerializeCosmosTx(cdc, sdkMessages) + if err != nil { + return nil, err + } + + icaPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: icaPacketDataBytes, + Memo: memo, + } + + if err := icaPacketData.ValidateBasic(); err != nil { + return nil, err + } + + return cdc.MarshalJSON(&icaPacketData) +} diff --git a/modules/apps/27-interchain-accounts/host/client/cli/tx_test.go b/modules/apps/27-interchain-accounts/host/client/cli/tx_test.go new file mode 100644 index 00000000000..b8a617e224e --- /dev/null +++ b/modules/apps/27-interchain-accounts/host/client/cli/tx_test.go @@ -0,0 +1,155 @@ +package cli + +import ( + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" + + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" +) + +const msgDelegateMessage = `{ + "@type": "/cosmos.staking.v1beta1.MsgDelegate", + "delegator_address": "cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", + "validator_address": "cosmosvaloper1qnk2n4nlkpw9xfqntladh74w6ujtulwnmxnh3k", + "amount": { + "denom": "stake", + "amount": "1000" + } +}` + +const bankSendMessage = `{ + "@type":"/cosmos.bank.v1beta1.MsgSend", + "from_address":"cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", + "to_address":"cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw", + "amount": [ + { + "denom": "stake", + "amount": "1000" + } + ] +}` + +var multiMsg = fmt.Sprintf("[ %s, %s ]", msgDelegateMessage, bankSendMessage) + +func TestGeneratePacketData(t *testing.T) { + tests := []struct { + name string + memo string + expectedPass bool + message string + registerInterfaceFn func(registry codectypes.InterfaceRegistry) + assertionFn func(t *testing.T, msgs []sdk.Msg) + }{ + { + name: "packet data generation succeeds (MsgDelegate & MsgSend)", + memo: "", + expectedPass: true, + message: multiMsg, + registerInterfaceFn: func(registry codectypes.InterfaceRegistry) { + stakingtypes.RegisterInterfaces(registry) + banktypes.RegisterInterfaces(registry) + }, + assertionFn: func(t *testing.T, msgs []sdk.Msg) { + assertMsgDelegate(t, msgs[0]) + assertMsgBankSend(t, msgs[1]) + }, + }, + { + name: "packet data generation succeeds (MsgDelegate)", + memo: "non-empty-memo", + expectedPass: true, + message: msgDelegateMessage, + registerInterfaceFn: stakingtypes.RegisterInterfaces, + assertionFn: func(t *testing.T, msgs []sdk.Msg) { + assertMsgDelegate(t, msgs[0]) + }, + }, + { + name: "packet data generation succeeds (MsgSend)", + memo: "non-empty-memo", + expectedPass: true, + message: bankSendMessage, + registerInterfaceFn: banktypes.RegisterInterfaces, + assertionFn: func(t *testing.T, msgs []sdk.Msg) { + assertMsgBankSend(t, msgs[0]) + }, + }, + { + name: "empty memo is valid", + memo: "", + expectedPass: true, + message: msgDelegateMessage, + registerInterfaceFn: stakingtypes.RegisterInterfaces, + assertionFn: nil, + }, + { + name: "invalid message string", + expectedPass: false, + message: "", + }, + } + + for _, tc := range tests { + tc := tc + ir := codectypes.NewInterfaceRegistry() + if tc.registerInterfaceFn != nil { + tc.registerInterfaceFn(ir) + } + + cdc := codec.NewProtoCodec(ir) + + t.Run(tc.name, func(t *testing.T) { + bz, err := generatePacketData(cdc, []byte(tc.message), tc.memo) + + if tc.expectedPass { + require.NoError(t, err) + require.NotNil(t, bz) + + packetData := icatypes.InterchainAccountPacketData{} + err = cdc.UnmarshalJSON(bz, &packetData) + require.NoError(t, err) + + require.Equal(t, icatypes.EXECUTE_TX, packetData.Type) + require.Equal(t, tc.memo, packetData.Memo) + + data := packetData.Data + messages, err := icatypes.DeserializeCosmosTx(cdc, data) + + require.NoError(t, err) + require.NotNil(t, messages) + + if tc.assertionFn != nil { + tc.assertionFn(t, messages) + } + } else { + require.Error(t, err) + require.Nil(t, bz) + } + }) + } +} + +func assertMsgBankSend(t *testing.T, msg sdk.Msg) { + bankSendMsg, ok := msg.(*banktypes.MsgSend) + require.True(t, ok) + require.Equal(t, "cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", bankSendMsg.FromAddress) + require.Equal(t, "cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw", bankSendMsg.ToAddress) + require.Equal(t, "stake", bankSendMsg.Amount.GetDenomByIndex(0)) + require.Equal(t, uint64(1000), bankSendMsg.Amount[0].Amount.Uint64()) +} + +func assertMsgDelegate(t *testing.T, msg sdk.Msg) { + msgDelegate, ok := msg.(*stakingtypes.MsgDelegate) + require.True(t, ok) + require.Equal(t, "cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", msgDelegate.DelegatorAddress) + require.Equal(t, "cosmosvaloper1qnk2n4nlkpw9xfqntladh74w6ujtulwnmxnh3k", msgDelegate.ValidatorAddress) + require.Equal(t, "stake", msgDelegate.Amount.Denom) + require.Equal(t, uint64(1000), msgDelegate.Amount.Amount.Uint64()) +} diff --git a/modules/apps/27-interchain-accounts/host/ibc_module.go b/modules/apps/27-interchain-accounts/host/ibc_module.go index 7cf0deca969..1620ce87bc5 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module.go @@ -1,15 +1,18 @@ package host import ( + "fmt" + + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/keeper" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // IBCModule implements the ICS26 interface for interchain accounts host chains @@ -35,7 +38,7 @@ func (im IBCModule) OnChanOpenInit( counterparty channeltypes.Counterparty, version string, ) (string, error) { - return "", sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") + return "", errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") } // OnChanOpenTry implements the IBCModule interface @@ -64,7 +67,7 @@ func (im IBCModule) OnChanOpenAck( counterpartyChannelID string, counterpartyVersion string, ) error { - return sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") + return errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain") } // OnChanOpenAck implements the IBCModule interface @@ -87,7 +90,7 @@ func (im IBCModule) OnChanCloseInit( channelID string, ) error { // Disallow user-initiated channel closing for interchain account channels - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") + return errorsmod.Wrap(ibcerrors.ErrInvalidRequest, "user cannot close channel") } // OnChanCloseConfirm implements the IBCModule interface @@ -105,7 +108,9 @@ func (im IBCModule) OnRecvPacket( packet channeltypes.Packet, _ sdk.AccAddress, ) ibcexported.Acknowledgement { + logger := im.keeper.Logger(ctx) if !im.keeper.IsHostEnabled(ctx) { + logger.Info("host submodule is disabled") return channeltypes.NewErrorAcknowledgement(types.ErrHostSubModuleDisabled) } @@ -113,6 +118,9 @@ func (im IBCModule) OnRecvPacket( ack := channeltypes.NewResultAcknowledgement(txResponse) if err != nil { ack = channeltypes.NewErrorAcknowledgement(err) + logger.Error(fmt.Sprintf("%s sequence %d", err.Error(), packet.Sequence)) + } else { + logger.Info("successfully handled packet sequence: %d", packet.Sequence) } // Emit an event indicating a successful or failed acknowledgement. @@ -129,7 +137,7 @@ func (im IBCModule) OnAcknowledgementPacket( acknowledgement []byte, relayer sdk.AccAddress, ) error { - return sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "cannot receive acknowledgement on a host channel end, a host chain does not send a packet over the channel") + return errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "cannot receive acknowledgement on a host channel end, a host chain does not send a packet over the channel") } // OnTimeoutPacket implements the IBCModule interface @@ -138,5 +146,5 @@ func (im IBCModule) OnTimeoutPacket( packet channeltypes.Packet, relayer sdk.AccAddress, ) error { - return sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "cannot cause a packet timeout on a host channel end, a host chain does not send a packet over the channel") + return errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "cannot cause a packet timeout on a host channel end, a host chain does not send a packet over the channel") } diff --git a/modules/apps/27-interchain-accounts/host/ibc_module_test.go b/modules/apps/27-interchain-accounts/host/ibc_module_test.go index b3e19a00ad2..ff3718ad9be 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module_test.go @@ -4,36 +4,31 @@ import ( "fmt" "testing" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/gogo/protobuf/proto" + "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/suite" - "github.com/tendermint/tendermint/crypto" - - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) var ( - // TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module() - // https://github.com/cosmos/cosmos-sdk/issues/10225 - // - // TestAccAddress defines a resuable bech32 address for testing purposes - TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), ibctesting.FirstConnectionID, TestPortID) - // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" - // TestPortID defines a resuable port identifier for testing purposes + // TestPortID defines a reusable port identifier for testing purposes TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) - // TestVersion defines a resuable interchainaccounts version string for testing purposes + // TestVersion defines a reusable interchainaccounts version string for testing purposes TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ Version: icatypes.Version, ControllerConnectionId: ibctesting.FirstConnectionID, @@ -65,8 +60,8 @@ func (suite *InterchainAccountsTestSuite) SetupTest() { func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) - path.EndpointA.ChannelConfig.PortID = icatypes.PortID - path.EndpointB.ChannelConfig.PortID = icatypes.PortID + path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED path.EndpointA.ChannelConfig.Version = TestVersion @@ -83,7 +78,7 @@ func RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) erro channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) - if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, TestVersion); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, endpoint.ChannelConfig.Version); err != nil { return err } @@ -147,6 +142,17 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenTry() { { "success", func() {}, true, }, + { + "account address generation is block dependent", func() { + icaHostAccount := icatypes.GenerateAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + err := suite.chainB.GetSimApp().BankKeeper.SendCoins(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), icaHostAccount, sdk.Coins{sdk.NewCoin("stake", sdk.NewInt(1))}) + suite.Require().NoError(err) + suite.Require().True(suite.chainB.GetSimApp().AccountKeeper.HasAccount(suite.chainB.GetContext(), icaHostAccount)) + + // ensure account registration is simulated in a separate block + suite.chainB.NextBlock() + }, true, + }, { "host submodule disabled", func() { suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), types.NewParams(false, []string{})) @@ -213,6 +219,10 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenTry() { if tc.expPass { suite.Require().NoError(err) + + addr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, counterparty.PortId) + suite.Require().True(exists) + suite.Require().NotNil(addr) } else { suite.Require().Error(err) suite.Require().Equal("", version) @@ -241,7 +251,8 @@ func (suite *InterchainAccountsTestSuite) TestChanOpenAck() { // commit state changes so proof can be created suite.chainA.NextBlock() - path.EndpointB.UpdateClient() + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) // query proof from ChainA channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) @@ -436,7 +447,7 @@ func (suite *InterchainAccountsTestSuite) TestOnRecvPacket() { ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount, } - data, err := icatypes.SerializeCosmosTx(suite.chainA.Codec, []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.Codec, []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -446,16 +457,11 @@ func (suite *InterchainAccountsTestSuite) TestOnRecvPacket() { packetData = icaPacketData.GetBytes() // build expected ack - msgResponseBz, err := proto.Marshal(&banktypes.MsgSendResponse{}) + protoAny, err := codectypes.NewAnyWithValue(&banktypes.MsgSendResponse{}) suite.Require().NoError(err) - msgData := &sdk.MsgData{ - MsgType: sdk.MsgTypeURL(msg), - Data: msgResponseBz, - } - expectedTxResponse, err := proto.Marshal(&sdk.TxMsgData{ - Data: []*sdk.MsgData{msgData}, + MsgResponses: []*codectypes.Any{protoAny}, }) suite.Require().NoError(err) @@ -531,7 +537,7 @@ func (suite *InterchainAccountsTestSuite) TestOnAcknowledgementPacket() { 0, ) - err = cbs.OnAcknowledgementPacket(suite.chainB.GetContext(), packet, []byte("ackBytes"), TestAccAddress) + err = cbs.OnAcknowledgementPacket(suite.chainB.GetContext(), packet, []byte("ackBytes"), nil) if tc.expPass { suite.Require().NoError(err) @@ -584,7 +590,7 @@ func (suite *InterchainAccountsTestSuite) TestOnTimeoutPacket() { 0, ) - err = cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, TestAccAddress) + err = cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, nil) if tc.expPass { suite.Require().NoError(err) @@ -610,28 +616,47 @@ func (suite *InterchainAccountsTestSuite) fundICAWallet(ctx sdk.Context, portID suite.Require().NoError(err) } -// TestControlAccountAfterChannelClose tests that a controller chain can control a registered interchain account after the currently active channel for that interchain account has been closed -// by opening a new channel on the associated portID +// TestControlAccountAfterChannelClose tests that a controller chain can control a registered interchain account after the currently active channel for that interchain account has been closed. +// A new channel will be opened for the controller portID. The interchain account address should remain unchanged. func (suite *InterchainAccountsTestSuite) TestControlAccountAfterChannelClose() { - // create channel + init interchain account on a particular port path := NewICAPath(suite.chainA, suite.chainB) + + // use a fee enabled version to cover unwrapping channel version code paths + feeMetadata := feetypes.Metadata{ + FeeVersion: feetypes.Version, + AppVersion: TestVersion, + } + + feeICAVersion := string(feetypes.ModuleCdc.MustMarshalJSON(&feeMetadata)) + + path.EndpointA.ChannelConfig.Version = feeICAVersion + path.EndpointB.ChannelConfig.Version = feeICAVersion + suite.coordinator.SetupConnections(path) + err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) + // two sends will be performed, one after initial creation of the account and one after channel closure and reopening + var ( + startingBal = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000))) + tokenAmt = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(5000))) + expBalAfterFirstSend = startingBal.Sub(tokenAmt...) + expBalAfterSecondSend = expBalAfterFirstSend.Sub(tokenAmt...) + ) + // check that the account is working as expected - suite.fundICAWallet(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10000)))) - interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.fundICAWallet(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID, startingBal) + interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) suite.Require().True(found) - tokenAmt := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(5000))) msg := &banktypes.MsgSend{ FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: tokenAmt, } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -642,12 +667,11 @@ func (suite *InterchainAccountsTestSuite) TestControlAccountAfterChannelClose() params := types.NewParams(true, []string{sdk.MsgTypeURL(msg)}) suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), params) - chanCap, ok := suite.chainA.GetSimApp().ScopedICAMockKeeper.GetCapability(path.EndpointA.Chain.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) - suite.Require().True(ok) - - _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), chanCap, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, icaPacketData, ^uint64(0)) + //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) + _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, icaPacketData, ^uint64(0)) + suite.Require().NoError(err) + err = path.EndpointB.UpdateClient() suite.Require().NoError(err) - path.EndpointB.UpdateClient() // relay the packet packetRelay := channeltypes.NewPacket(icaPacketData.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.ZeroHeight(), ^uint64(0)) @@ -658,13 +682,12 @@ func (suite *InterchainAccountsTestSuite) TestControlAccountAfterChannelClose() icaAddr, err := sdk.AccAddressFromBech32(interchainAccountAddr) suite.Require().NoError(err) - hasBalance := suite.chainB.GetSimApp().BankKeeper.HasBalance(suite.chainB.GetContext(), icaAddr, sdk.Coin{Denom: sdk.DefaultBondDenom, Amount: sdk.NewInt(5000)}) - suite.Require().True(hasBalance) + suite.assertBalance(icaAddr, expBalAfterFirstSend) // close the channel - err = path.EndpointA.SetChannelClosed() + err = path.EndpointA.SetChannelState(channeltypes.CLOSED) suite.Require().NoError(err) - err = path.EndpointB.SetChannelClosed() + err = path.EndpointB.SetChannelState(channeltypes.CLOSED) suite.Require().NoError(err) // open a new channel on the same port @@ -672,20 +695,23 @@ func (suite *InterchainAccountsTestSuite) TestControlAccountAfterChannelClose() path.EndpointB.ChannelID = "" suite.coordinator.CreateChannels(path) - // try to control the interchain account again - chanCap, ok = suite.chainA.GetSimApp().ScopedICAMockKeeper.GetCapability(path.EndpointA.Chain.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) - suite.Require().True(ok) - - _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), chanCap, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, icaPacketData, ^uint64(0)) + //nolint: staticcheck // SA1019: ibctesting.FirstConnectionID is deprecated: use path.EndpointA.ConnectionID instead. (staticcheck) + _, err = suite.chainA.GetSimApp().ICAControllerKeeper.SendTx(suite.chainA.GetContext(), nil, ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, icaPacketData, ^uint64(0)) + suite.Require().NoError(err) + err = path.EndpointB.UpdateClient() suite.Require().NoError(err) - path.EndpointB.UpdateClient() // relay the packet packetRelay = channeltypes.NewPacket(icaPacketData.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.ZeroHeight(), ^uint64(0)) err = path.RelayPacket(packetRelay) suite.Require().NoError(err) // relay committed - // check that the ica balance is updated - hasBalance = suite.chainB.GetSimApp().BankKeeper.HasBalance(suite.chainB.GetContext(), icaAddr, sdk.Coin{Denom: sdk.DefaultBondDenom, Amount: sdk.NewInt(0)}) - suite.Require().True(hasBalance) + suite.assertBalance(icaAddr, expBalAfterSecondSend) +} + +// assertBalance asserts that the provided address has exactly the expected balance. +// CONTRACT: the expected balance must only contain one coin denom. +func (suite *InterchainAccountsTestSuite) assertBalance(addr sdk.AccAddress, expBalance sdk.Coins) { + balance := suite.chainB.GetSimApp().BankKeeper.GetBalance(suite.chainB.GetContext(), addr, sdk.DefaultBondDenom) + suite.Require().Equal(expBalance[0], balance) } diff --git a/modules/apps/27-interchain-accounts/host/keeper/account.go b/modules/apps/27-interchain-accounts/host/keeper/account.go index a4c8b511dda..3b02d3c7cae 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/account.go +++ b/modules/apps/27-interchain-accounts/host/keeper/account.go @@ -1,18 +1,21 @@ package keeper import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ) -// RegisterInterchainAccount attempts to create a new account using the provided address and -// stores it in state keyed by the provided connection and port identifiers -// If an account for the provided address already exists this function returns early (no-op) -func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, connectionID, controllerPortID string, accAddress sdk.AccAddress) { +// createInterchainAccount creates a new interchain account. An address is generated using the host connectionID, the controller portID, +// and block dependent information. An error is returned if an account already exists for the generated account. +// An interchain account type is set in the account keeper and the interchain account address mapping is updated. +func (k Keeper) createInterchainAccount(ctx sdk.Context, connectionID, controllerPortID string) (sdk.AccAddress, error) { + accAddress := icatypes.GenerateAddress(ctx, connectionID, controllerPortID) + if acc := k.accountKeeper.GetAccount(ctx, accAddress); acc != nil { - return + return nil, errorsmod.Wrapf(icatypes.ErrAccountAlreadyExist, "existing account for newly generated interchain account address %s", accAddress) } interchainAccount := icatypes.NewInterchainAccount( @@ -24,4 +27,6 @@ func (k Keeper) RegisterInterchainAccount(ctx sdk.Context, connectionID, control k.accountKeeper.SetAccount(ctx, interchainAccount) k.SetInterchainAccountAddress(ctx, connectionID, controllerPortID, interchainAccount.Address) + + return accAddress, nil } diff --git a/modules/apps/27-interchain-accounts/host/keeper/account_test.go b/modules/apps/27-interchain-accounts/host/keeper/account_test.go deleted file mode 100644 index 038ed003748..00000000000 --- a/modules/apps/27-interchain-accounts/host/keeper/account_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package keeper_test - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { - suite.SetupTest() - - path := NewICAPath(suite.chainA, suite.chainB) - suite.coordinator.SetupConnections(path) - - // RegisterInterchainAccount - err := SetupICAPath(path, TestOwnerAddress) - suite.Require().NoError(err) - - portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - suite.Require().NoError(err) - - // Get the address of the interchain account stored in state during handshake step - storedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, portID) - suite.Require().True(found) - - icaAddr, err := sdk.AccAddressFromBech32(storedAddr) - suite.Require().NoError(err) - - // Check if account is created - interchainAccount := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), icaAddr) - suite.Require().Equal(interchainAccount.GetAddress().String(), storedAddr) -} diff --git a/modules/apps/27-interchain-accounts/host/keeper/events.go b/modules/apps/27-interchain-accounts/host/keeper/events.go index ead5d783864..6c320ace6c0 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/events.go +++ b/modules/apps/27-interchain-accounts/host/keeper/events.go @@ -5,8 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // EmitAcknowledgementEvent emits an event signalling a successful or failed acknowledgement and including the error diff --git a/modules/apps/27-interchain-accounts/host/keeper/genesis.go b/modules/apps/27-interchain-accounts/host/keeper/genesis.go index c3dff759f4d..6575bac1713 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/genesis.go +++ b/modules/apps/27-interchain-accounts/host/keeper/genesis.go @@ -5,12 +5,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // InitGenesis initializes the interchain accounts host application state from a provided genesis state -func InitGenesis(ctx sdk.Context, keeper Keeper, state icatypes.HostGenesisState) { +func InitGenesis(ctx sdk.Context, keeper Keeper, state genesistypes.HostGenesisState) { if !keeper.IsBound(ctx, state.Port) { cap := keeper.BindPort(ctx, state.Port) if err := keeper.ClaimCapability(ctx, cap, host.PortPath(state.Port)); err != nil { @@ -30,11 +31,11 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, state icatypes.HostGenesisState } // ExportGenesis returns the interchain accounts host exported genesis -func ExportGenesis(ctx sdk.Context, keeper Keeper) icatypes.HostGenesisState { - return icatypes.NewHostGenesisState( +func ExportGenesis(ctx sdk.Context, keeper Keeper) genesistypes.HostGenesisState { + return genesistypes.NewHostGenesisState( keeper.GetAllActiveChannels(ctx), keeper.GetAllInterchainAccounts(ctx), - icatypes.PortID, + icatypes.HostPortID, keeper.GetParams(ctx), ) } diff --git a/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go b/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go index be6ae690385..7851b730527 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/genesis_test.go @@ -1,31 +1,34 @@ package keeper_test import ( - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/keeper" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestInitGenesis() { suite.SetupTest() - genesisState := icatypes.HostGenesisState{ - ActiveChannels: []icatypes.ActiveChannel{ + interchainAccAddr := icatypes.GenerateAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, TestPortID) + + genesisState := genesistypes.HostGenesisState{ + ActiveChannels: []genesistypes.ActiveChannel{ { ConnectionId: ibctesting.FirstConnectionID, PortId: TestPortID, ChannelId: ibctesting.FirstChannelID, }, }, - InterchainAccounts: []icatypes.RegisteredInterchainAccount{ + InterchainAccounts: []genesistypes.RegisteredInterchainAccount{ { ConnectionId: ibctesting.FirstConnectionID, PortId: TestPortID, - AccountAddress: TestAccAddress.String(), + AccountAddress: interchainAccAddr.String(), }, }, - Port: icatypes.PortID, + Port: icatypes.HostPortID, } keeper.InitGenesis(suite.chainA.GetContext(), suite.chainA.GetSimApp().ICAHostKeeper, genesisState) @@ -36,7 +39,7 @@ func (suite *KeeperTestSuite) TestInitGenesis() { accountAdrr, found := suite.chainA.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, TestPortID) suite.Require().True(found) - suite.Require().Equal(TestAccAddress.String(), accountAdrr) + suite.Require().Equal(interchainAccAddr.String(), accountAdrr) expParams := types.NewParams(false, nil) params := suite.chainA.GetSimApp().ICAHostKeeper.GetParams(suite.chainA.GetContext()) @@ -52,15 +55,18 @@ func (suite *KeeperTestSuite) TestExportGenesis() { err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) + genesisState := keeper.ExportGenesis(suite.chainB.GetContext(), suite.chainB.GetSimApp().ICAHostKeeper) suite.Require().Equal(path.EndpointB.ChannelID, genesisState.ActiveChannels[0].ChannelId) suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.ActiveChannels[0].PortId) - suite.Require().Equal(TestAccAddress.String(), genesisState.InterchainAccounts[0].AccountAddress) + suite.Require().Equal(interchainAccAddr, genesisState.InterchainAccounts[0].AccountAddress) suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, genesisState.InterchainAccounts[0].PortId) - suite.Require().Equal(icatypes.PortID, genesisState.GetPort()) + suite.Require().Equal(icatypes.HostPortID, genesisState.GetPort()) expParams := types.DefaultParams() suite.Require().Equal(expParams, genesisState.GetParams()) diff --git a/modules/apps/27-interchain-accounts/host/keeper/grpc_query.go b/modules/apps/27-interchain-accounts/host/keeper/grpc_query.go index 65afdece331..8677c6b5754 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/grpc_query.go +++ b/modules/apps/27-interchain-accounts/host/keeper/grpc_query.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ) var _ types.QueryServer = Keeper{} diff --git a/modules/apps/27-interchain-accounts/host/keeper/grpc_query_test.go b/modules/apps/27-interchain-accounts/host/keeper/grpc_query_test.go index 44aae4b4e1f..c8698194a1e 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/grpc_query_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/grpc_query_test.go @@ -3,7 +3,7 @@ package keeper_test import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ) func (suite *KeeperTestSuite) TestQueryParams() { diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake.go b/modules/apps/27-interchain-accounts/host/keeper/handshake.go index 15a18fcea77..8f3f4a0ccff 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake.go @@ -2,15 +2,14 @@ package keeper import ( "fmt" - "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // OnChanOpenTry performs basic validation of the ICA channel @@ -28,20 +27,16 @@ func (k Keeper) OnChanOpenTry( counterpartyVersion string, ) (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) } - if portID != icatypes.PortID { - return "", sdkerrors.Wrapf(icatypes.ErrInvalidHostPort, "expected %s, got %s", icatypes.PortID, portID) - } - - if !strings.HasPrefix(counterparty.PortId, icatypes.PortPrefix) { - return "", sdkerrors.Wrapf(icatypes.ErrInvalidControllerPort, "expected %s{owner-account-address}, got %s", icatypes.PortPrefix, counterparty.PortId) + if portID != icatypes.HostPortID { + return "", errorsmod.Wrapf(icatypes.ErrInvalidHostPort, "expected %s, got %s", icatypes.HostPortID, portID) } var metadata icatypes.Metadata if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &metadata); err != nil { - return "", sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") + return "", errorsmod.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") } if err := icatypes.ValidateHostMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { @@ -56,24 +51,46 @@ func (k Keeper) OnChanOpenTry( } if channel.State == channeltypes.OPEN { - return "", sdkerrors.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s is already OPEN", activeChannelID, portID) + return "", errorsmod.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s is already OPEN", activeChannelID, portID) + } + + appVersion, found := k.GetAppVersion(ctx, portID, activeChannelID) + if !found { + panic(fmt.Sprintf("active channel mapping set for %s, but channel does not exist in channel store", activeChannelID)) } - if !icatypes.IsPreviousMetadataEqual(channel.Version, metadata) { - return "", sdkerrors.Wrap(icatypes.ErrInvalidVersion, "previous active channel metadata does not match provided version") + if !icatypes.IsPreviousMetadataEqual(appVersion, metadata) { + return "", errorsmod.Wrap(icatypes.ErrInvalidVersion, "previous active channel metadata does not match provided version") } } // On the host chain the capability may only be claimed during the OnChanOpenTry // The capability being claimed in OpenInit is for a controller chain (the port is different) if err := k.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return "", sdkerrors.Wrapf(err, "failed to claim capability for channel %s on port %s", channelID, portID) + return "", errorsmod.Wrapf(err, "failed to claim capability for channel %s on port %s", channelID, portID) } - accAddress := icatypes.GenerateAddress(k.accountKeeper.GetModuleAddress(icatypes.ModuleName), metadata.HostConnectionId, counterparty.PortId) + var ( + accAddress sdk.AccAddress + err error + ) - // Register interchain account if it does not already exist - k.RegisterInterchainAccount(ctx, metadata.HostConnectionId, counterparty.PortId, accAddress) + interchainAccAddr, found := k.GetInterchainAccountAddress(ctx, metadata.HostConnectionId, counterparty.PortId) + if found { + // reopening an interchain account + k.Logger(ctx).Info("reopening existing interchain account", "address", interchainAccAddr) + accAddress = sdk.MustAccAddressFromBech32(interchainAccAddr) + if _, ok := k.accountKeeper.GetAccount(ctx, accAddress).(*icatypes.InterchainAccount); !ok { + return "", errorsmod.Wrapf(icatypes.ErrInvalidAccountReopening, "existing account address %s, does not have interchain account type", accAddress) + } + + } else { + accAddress, err = k.createInterchainAccount(ctx, metadata.HostConnectionId, counterparty.PortId) + if err != nil { + return "", err + } + k.Logger(ctx).Info("successfully created new interchain account", "host-connection-id", metadata.HostConnectionId, "port-id", counterparty.PortId, "address", accAddress) + } metadata.Address = accAddress.String() versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) @@ -92,7 +109,7 @@ func (k Keeper) OnChanOpenConfirm( ) error { channel, found := k.channelKeeper.GetChannel(ctx, portID, channelID) if !found { - return sdkerrors.Wrapf(channeltypes.ErrChannelNotFound, "failed to retrieve channel %s on port %s", channelID, portID) + return errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "failed to retrieve channel %s on port %s", channelID, portID) } // It is assumed the controller chain will not allow multiple active channels to be created for the same connectionID/portID diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go index 9784c0ba412..fdba6518538 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -1,14 +1,43 @@ package keeper_test 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" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + hosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) +// open and close channel is a helper function for TestOnChanOpenTry for reopening accounts +func (suite *KeeperTestSuite) openAndCloseChannel(path *ibctesting.Path) { + err := path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanOpenAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanOpenConfirm() + suite.Require().NoError(err) + + err = path.EndpointA.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) + + err = path.EndpointB.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) + + path.EndpointA.ChannelID = "" + err = RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) + + // bump channel sequence as these test mock core IBC behaviour on ChanOpenTry + channelSequence := path.EndpointB.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(path.EndpointB.Chain.GetContext()) + path.EndpointB.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) +} + func (suite *KeeperTestSuite) TestOnChanOpenTry() { var ( channel *channeltypes.Channel @@ -24,22 +53,89 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { }{ { "success", - func() { - path.EndpointB.SetChannel(*channel) - }, + func() {}, true, }, { "success - reopening closed active channel", func() { - // create a new channel and set it in state - ch := channeltypes.NewChannel(channeltypes.CLOSED, channeltypes.ORDERED, channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointA.ConnectionID}, TestVersion) - suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, ch) + // create interchain account + // undo setup + path.EndpointB.ChannelID = "" + err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) + suite.Require().NoError(err) - // set the active channelID in state - suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.openAndCloseChannel(path) }, true, }, + { + "success - reopening account with new address", + func() { + // create interchain account + // undo setup + path.EndpointB.ChannelID = "" + err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) + suite.Require().NoError(err) + + suite.openAndCloseChannel(path) + + // delete interchain account address + store := suite.chainB.GetContext().KVStore(suite.chainB.GetSimApp().GetKey(hosttypes.SubModuleName)) + store.Delete(icatypes.KeyOwnerAccount(path.EndpointA.ChannelConfig.PortID, path.EndpointB.ConnectionID)) + + // assert interchain account address mapping was deleted + _, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().False(found) + }, true, + }, + { + "reopening account fails - no existing account", + func() { + // create interchain account + // undo setup + path.EndpointB.ChannelID = "" + err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) + suite.Require().NoError(err) + + suite.openAndCloseChannel(path) + + // delete existing account + addr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + acc := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), sdk.MustAccAddressFromBech32(addr)) + suite.chainB.GetSimApp().AccountKeeper.RemoveAccount(suite.chainB.GetContext(), acc) + }, false, + }, + { + "reopening account fails - existing account is not interchain account type", + func() { + // create interchain account + // undo setup + path.EndpointB.ChannelID = "" + err := suite.chainB.App.GetScopedIBCKeeper().ReleaseCapability(suite.chainB.GetContext(), chanCap) + suite.Require().NoError(err) + + suite.openAndCloseChannel(path) + + addr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + accAddress := sdk.MustAccAddressFromBech32(addr) + baseAcc := authtypes.NewBaseAccountWithAddress(accAddress) + suite.chainB.GetSimApp().AccountKeeper.SetAccount(suite.chainB.GetContext(), baseAcc) + }, false, + }, + { + "account already exists", + func() { + interchainAccAddr := icatypes.GenerateAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + err := suite.chainB.GetSimApp().BankKeeper.SendCoins(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), interchainAccAddr, sdk.Coins{sdk.NewCoin("stake", sdk.NewInt(1))}) + suite.Require().NoError(err) + suite.Require().True(suite.chainB.GetSimApp().AccountKeeper.HasAccount(suite.chainB.GetContext(), interchainAccAddr)) + }, + false, + }, { "invalid metadata - previous metadata is different", func() { @@ -48,15 +144,17 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, ch) // set the active channelID in state - suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointB.ChannelID) - // modify metadata + // attempt to downgrade version by reinitializing channel with version 1, but setting channel to version 2 metadata.Version = "ics27-2" versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) - path.EndpointA.ChannelConfig.Version = string(versionBytes) + channel.Version = string(versionBytes) + + path.EndpointB.SetChannel(*channel) }, false, }, { @@ -69,14 +167,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { { "invalid port ID", func() { - path.EndpointB.ChannelConfig.PortID = "invalid-port-id" - }, - false, - }, - { - "invalid counterparty port ID", - func() { - channel.Counterparty.PortId = "invalid-port-id" + path.EndpointB.ChannelConfig.PortID = "invalid-port-id" //nolint:goconst }, false, }, @@ -218,6 +309,16 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { if tc.expPass { suite.Require().NoError(err) + + storedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + interchainAccAddr, err := sdk.AccAddressFromBech32(storedAddr) + suite.Require().NoError(err) + + // Check if account is created + interchainAccount := suite.chainB.GetSimApp().AccountKeeper.GetAccount(suite.chainB.GetContext(), interchainAccAddr) + suite.Require().Equal(interchainAccount.GetAddress().String(), storedAddr) } else { suite.Require().Error(err) suite.Require().Equal("", version) diff --git a/modules/apps/27-interchain-accounts/host/keeper/keeper.go b/modules/apps/27-interchain-accounts/host/keeper/keeper.go index 7125bb52f20..fe8d3310adf 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/keeper.go +++ b/modules/apps/27-interchain-accounts/host/keeper/keeper.go @@ -4,40 +4,43 @@ import ( "fmt" "strings" - baseapp "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/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" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // Keeper defines the IBC interchain accounts host keeper type Keeper struct { - storeKey sdk.StoreKey + storeKey storetypes.StoreKey cdc codec.BinaryCodec paramSpace paramtypes.Subspace + ics4Wrapper porttypes.ICS4Wrapper channelKeeper icatypes.ChannelKeeper portKeeper icatypes.PortKeeper accountKeeper icatypes.AccountKeeper - scopedKeeper capabilitykeeper.ScopedKeeper + scopedKeeper exported.ScopedKeeper - msgRouter *baseapp.MsgServiceRouter + msgRouter icatypes.MessageRouter } // NewKeeper creates a new interchain accounts host Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Subspace, - channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, - accountKeeper icatypes.AccountKeeper, scopedKeeper capabilitykeeper.ScopedKeeper, msgRouter *baseapp.MsgServiceRouter, + cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, + ics4Wrapper porttypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, + accountKeeper icatypes.AccountKeeper, scopedKeeper exported.ScopedKeeper, msgRouter icatypes.MessageRouter, ) Keeper { // ensure ibc interchain accounts module account is set if addr := accountKeeper.GetModuleAddress(icatypes.ModuleName); addr == nil { @@ -53,6 +56,7 @@ func NewKeeper( storeKey: key, cdc: cdc, paramSpace: paramSpace, + ics4Wrapper: ics4Wrapper, channelKeeper: channelKeeper, portKeeper: portKeeper, accountKeeper: accountKeeper, @@ -63,7 +67,7 @@ func NewKeeper( // Logger returns the application logger, scoped to the associated module func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", fmt.Sprintf("x/%s-%s", host.ModuleName, icatypes.ModuleName)) + return ctx.Logger().With("module", fmt.Sprintf("x/%s-%s", exported.ModuleName, icatypes.ModuleName)) } // BindPort stores the provided portID and binds to it, returning the associated capability @@ -90,6 +94,11 @@ func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability return k.scopedKeeper.ClaimCapability(ctx, cap, name) } +// GetAppVersion calls the ICS4Wrapper GetAppVersion function. +func (k Keeper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { + return k.ics4Wrapper.GetAppVersion(ctx, portID, channelID) +} + // GetActiveChannelID retrieves the active channelID from the store keyed by the provided connectionID and portID func (k Keeper) GetActiveChannelID(ctx sdk.Context, connectionID, portID string) (string, bool) { store := ctx.KVStore(k.storeKey) @@ -119,16 +128,16 @@ func (k Keeper) GetOpenActiveChannel(ctx sdk.Context, connectionID, portID strin } // GetAllActiveChannels returns a list of all active interchain accounts host channels and their associated connection and port identifiers -func (k Keeper) GetAllActiveChannels(ctx sdk.Context) []icatypes.ActiveChannel { +func (k Keeper) GetAllActiveChannels(ctx sdk.Context) []genesistypes.ActiveChannel { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(icatypes.ActiveChannelKeyPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) - var activeChannels []icatypes.ActiveChannel + var activeChannels []genesistypes.ActiveChannel for ; iterator.Valid(); iterator.Next() { keySplit := strings.Split(string(iterator.Key()), "/") - ch := icatypes.ActiveChannel{ + ch := genesistypes.ActiveChannel{ ConnectionId: keySplit[2], PortId: keySplit[1], ChannelId: string(iterator.Value()), @@ -165,15 +174,15 @@ func (k Keeper) GetInterchainAccountAddress(ctx sdk.Context, connectionID, portI } // GetAllInterchainAccounts returns a list of all registered interchain account addresses and their associated connection and controller port identifiers -func (k Keeper) GetAllInterchainAccounts(ctx sdk.Context) []icatypes.RegisteredInterchainAccount { +func (k Keeper) GetAllInterchainAccounts(ctx sdk.Context) []genesistypes.RegisteredInterchainAccount { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(icatypes.OwnerKeyPrefix)) - var interchainAccounts []icatypes.RegisteredInterchainAccount + var interchainAccounts []genesistypes.RegisteredInterchainAccount for ; iterator.Valid(); iterator.Next() { keySplit := strings.Split(string(iterator.Key()), "/") - acc := icatypes.RegisteredInterchainAccount{ + acc := genesistypes.RegisteredInterchainAccount{ ConnectionId: keySplit[2], PortId: keySplit[1], AccountAddress: string(iterator.Value()), diff --git a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go index 7953f0f5663..c250e046d67 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go @@ -3,29 +3,22 @@ package keeper_test import ( "testing" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" - "github.com/tendermint/tendermint/crypto" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) var ( - // TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module() - // https://github.com/cosmos/cosmos-sdk/issues/10225 - // - // TestAccAddress defines a resuable bech32 address for testing purposes - TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), ibctesting.FirstConnectionID, TestPortID) - // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" - // TestPortID defines a resuable port identifier for testing purposes + // TestPortID defines a reusable port identifier for testing purposes TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) - // TestVersion defines a resuable interchainaccounts version string for testing purposes + // TestVersion defines a reusable interchainaccounts version string for testing purposes TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ Version: icatypes.Version, ControllerConnectionId: ibctesting.FirstConnectionID, @@ -55,8 +48,8 @@ func (suite *KeeperTestSuite) SetupTest() { func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path := ibctesting.NewPath(chainA, chainB) - path.EndpointA.ChannelConfig.PortID = icatypes.PortID - path.EndpointB.ChannelConfig.PortID = icatypes.PortID + path.EndpointA.ChannelConfig.PortID = icatypes.HostPortID + path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED path.EndpointA.ChannelConfig.Version = TestVersion @@ -136,11 +129,10 @@ func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() { suite.Require().NoError(err) counterpartyPortID := path.EndpointA.ChannelConfig.PortID - expectedAddr := icatypes.GenerateAddress(suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(icatypes.ModuleName), ibctesting.FirstConnectionID, counterpartyPortID) retrievedAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, counterpartyPortID) suite.Require().True(found) - suite.Require().Equal(expectedAddr.String(), retrievedAddr) + suite.Require().NotEmpty(retrievedAddr) retrievedAddr, found = suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, "invalid port") suite.Require().False(found) @@ -149,8 +141,8 @@ func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() { func (suite *KeeperTestSuite) TestGetAllActiveChannels() { var ( - expectedChannelID string = "test-channel" - expectedPortID string = "test-port" + expectedChannelID = "test-channel" + expectedPortID = "test-port" ) suite.SetupTest() @@ -163,7 +155,7 @@ func (suite *KeeperTestSuite) TestGetAllActiveChannels() { suite.chainB.GetSimApp().ICAHostKeeper.SetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedChannelID) - expectedChannels := []icatypes.ActiveChannel{ + expectedChannels := []genesistypes.ActiveChannel{ { ConnectionId: ibctesting.FirstConnectionID, PortId: path.EndpointA.ChannelConfig.PortID, @@ -183,8 +175,8 @@ func (suite *KeeperTestSuite) TestGetAllActiveChannels() { func (suite *KeeperTestSuite) TestGetAllInterchainAccounts() { var ( - expectedAccAddr string = "test-acc-addr" - expectedPortID string = "test-port" + expectedAccAddr = "test-acc-addr" + expectedPortID = "test-port" ) suite.SetupTest() @@ -195,13 +187,16 @@ func (suite *KeeperTestSuite) TestGetAllInterchainAccounts() { err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) + interchainAccAddr, exists := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(exists) + suite.chainB.GetSimApp().ICAHostKeeper.SetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr) - expectedAccounts := []icatypes.RegisteredInterchainAccount{ + expectedAccounts := []genesistypes.RegisteredInterchainAccount{ { ConnectionId: ibctesting.FirstConnectionID, PortId: TestPortID, - AccountAddress: TestAccAddress.String(), + AccountAddress: interchainAccAddr, }, { ConnectionId: ibctesting.FirstConnectionID, @@ -230,8 +225,8 @@ func (suite *KeeperTestSuite) TestIsActiveChannel() { func (suite *KeeperTestSuite) TestSetInterchainAccountAddress() { var ( - expectedAccAddr string = "test-acc-addr" - expectedPortID string = "test-port" + expectedAccAddr = "test-acc-addr" + expectedPortID = "test-port" ) suite.chainB.GetSimApp().ICAHostKeeper.SetInterchainAccountAddress(suite.chainB.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr) diff --git a/modules/apps/27-interchain-accounts/host/keeper/params.go b/modules/apps/27-interchain-accounts/host/keeper/params.go index e56e72342c8..6c95d737541 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/params.go +++ b/modules/apps/27-interchain-accounts/host/keeper/params.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ) // IsHostEnabled retrieves the host enabled boolean from the paramstore. diff --git a/modules/apps/27-interchain-accounts/host/keeper/params_test.go b/modules/apps/27-interchain-accounts/host/keeper/params_test.go index c769ade3fdb..a8d056ce007 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/params_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/params_test.go @@ -1,6 +1,6 @@ package keeper_test -import "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" +import "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" func (suite *KeeperTestSuite) TestParams() { expParams := types.DefaultParams() diff --git a/modules/apps/27-interchain-accounts/host/keeper/relay.go b/modules/apps/27-interchain-accounts/host/keeper/relay.go index e658c5bd3f5..4e620291a6b 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/relay.go +++ b/modules/apps/27-interchain-accounts/host/keeper/relay.go @@ -1,13 +1,15 @@ package keeper import ( + errorsmod "cosmossdk.io/errors" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/gogo/protobuf/proto" + "github.com/cosmos/gogoproto/proto" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // OnRecvPacket handles a given interchain accounts packet on a destination host chain. @@ -17,21 +19,20 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet) ([]byt if err := icatypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { // UnmarshalJSON errors are indeterminate and therefore are not wrapped and included in failed acks - return nil, sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account packet data") + return nil, errorsmod.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account packet data") } switch data.Type { case icatypes.EXECUTE_TX: msgs, err := icatypes.DeserializeCosmosTx(k.cdc, data.Data) if err != nil { - return nil, err + return nil, errorsmod.Wrapf(err, "failed to deserialize interchain account transaction") } txResponse, err := k.executeTx(ctx, packet.SourcePort, packet.DestinationPort, packet.DestinationChannel, msgs) if err != nil { - return nil, err + return nil, errorsmod.Wrapf(err, "failed to execute interchain account transaction") } - return txResponse, nil default: return nil, icatypes.ErrUnknownDataType @@ -53,7 +54,7 @@ func (k Keeper) executeTx(ctx sdk.Context, sourcePort, destPort, destChannel str } txMsgData := &sdk.TxMsgData{ - Data: make([]*sdk.MsgData, len(msgs)), + MsgResponses: make([]*codectypes.Any, len(msgs)), } // CacheContext returns a new context with the multi-store branched into a cached storage object @@ -64,25 +65,19 @@ func (k Keeper) executeTx(ctx sdk.Context, sourcePort, destPort, destChannel str return nil, err } - msgResponse, err := k.executeMsg(cacheCtx, msg) + protoAny, err := k.executeMsg(cacheCtx, msg) if err != nil { return nil, err } - txMsgData.Data[i] = &sdk.MsgData{ - MsgType: sdk.MsgTypeURL(msg), - Data: msgResponse, - } - + txMsgData.MsgResponses[i] = protoAny } - // NOTE: The context returned by CacheContext() creates a new EventManager, so events must be correctly propagated back to the current context - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) writeCache() txResponse, err := proto.Marshal(txMsgData) if err != nil { - return nil, sdkerrors.Wrap(err, "failed to marshal tx data") + return nil, errorsmod.Wrap(err, "failed to marshal tx data") } return txResponse, nil @@ -93,18 +88,18 @@ func (k Keeper) executeTx(ctx sdk.Context, sourcePort, destPort, destChannel str func (k Keeper) authenticateTx(ctx sdk.Context, msgs []sdk.Msg, connectionID, portID string) error { interchainAccountAddr, found := k.GetInterchainAccountAddress(ctx, connectionID, portID) if !found { - return sdkerrors.Wrapf(icatypes.ErrInterchainAccountNotFound, "failed to retrieve interchain account on port %s", portID) + return errorsmod.Wrapf(icatypes.ErrInterchainAccountNotFound, "failed to retrieve interchain account on port %s", portID) } allowMsgs := k.GetAllowMessages(ctx) for _, msg := range msgs { if !types.ContainsMsgType(allowMsgs, msg) { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "message type not allowed: %s", sdk.MsgTypeURL(msg)) + return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "message type not allowed: %s", sdk.MsgTypeURL(msg)) } for _, signer := range msg.GetSigners() { if interchainAccountAddr != signer.String() { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "unexpected signer address: expected %s, got %s", interchainAccountAddr, signer.String()) + return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "unexpected signer address: expected %s, got %s", interchainAccountAddr, signer.String()) } } } @@ -114,7 +109,7 @@ func (k Keeper) authenticateTx(ctx sdk.Context, msgs []sdk.Msg, connectionID, po // Attempts to get the message handler from the router and if found will then execute the message. // If the message execution is successful, the proto marshaled message response will be returned. -func (k Keeper) executeMsg(ctx sdk.Context, msg sdk.Msg) ([]byte, error) { +func (k Keeper) executeMsg(ctx sdk.Context, msg sdk.Msg) (*codectypes.Any, error) { handler := k.msgRouter.Handler(msg) if handler == nil { return nil, icatypes.ErrInvalidRoute @@ -128,5 +123,11 @@ func (k Keeper) executeMsg(ctx sdk.Context, msg sdk.Msg) ([]byte, error) { // NOTE: The sdk msg handler creates a new EventManager, so events must be correctly propagated back to the current context ctx.EventManager().EmitEvents(res.GetEvents()) - return res.Data, nil + // Each individual sdk.Result has exactly one Msg response. We aggregate here. + msgResponse := res.MsgResponses[0] + if msgResponse == nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrLogic, "got nil Msg response for msg %s", sdk.MsgTypeURL(msg)) + } + + return msgResponse, nil } diff --git a/modules/apps/27-interchain-accounts/host/keeper/relay_test.go b/modules/apps/27-interchain-accounts/host/keeper/relay_test.go index c7ebd9428f5..6e07e58715f 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/relay_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/relay_test.go @@ -1,21 +1,21 @@ package keeper_test import ( - "time" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/gogoproto/proto" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestOnRecvPacket() { @@ -41,7 +41,10 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Description: "tokens for all!", } - proposal, err := govtypes.NewProposal(testProposal, govtypes.DefaultStartingProposalID, time.Now(), time.Now().Add(time.Hour)) + proposalMsg, err := govv1.NewLegacyContent(testProposal, interchainAccountAddr) + suite.Require().NoError(err) + + proposal, err := govv1.NewProposal([]sdk.Msg{proposalMsg}, govtypes.DefaultStartingProposalID, suite.chainA.GetContext().BlockTime(), suite.chainA.GetContext().BlockTime(), "test proposal", "title", "Description", sdk.AccAddress(interchainAccountAddr)) suite.Require().NoError(err) suite.chainB.GetSimApp().GovKeeper.SetProposal(suite.chainB.GetContext(), proposal) @@ -53,7 +56,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Option: govtypes.OptionYes, } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -80,7 +83,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -108,7 +111,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(5000)), } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -142,7 +145,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(5000)), } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msgDelegate, msgUndelegate}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msgDelegate, msgUndelegate}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -168,16 +171,16 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Description: "tokens for all!", } - any, err := codectypes.NewAnyWithValue(testProposal) + protoAny, err := codectypes.NewAnyWithValue(testProposal) suite.Require().NoError(err) msg := &govtypes.MsgSubmitProposal{ - Content: any, + Content: protoAny, InitialDeposit: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(5000))), Proposer: interchainAccountAddr, } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -204,7 +207,10 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Description: "tokens for all!", } - proposal, err := govtypes.NewProposal(testProposal, govtypes.DefaultStartingProposalID, time.Now(), time.Now().Add(time.Hour)) + proposalMsg, err := govv1.NewLegacyContent(testProposal, interchainAccountAddr) + suite.Require().NoError(err) + + proposal, err := govv1.NewProposal([]sdk.Msg{proposalMsg}, govtypes.DefaultStartingProposalID, suite.chainA.GetContext().BlockTime(), suite.chainA.GetContext().BlockTime(), "test proposal", "title", "description", sdk.AccAddress(interchainAccountAddr)) suite.Require().NoError(err) suite.chainB.GetSimApp().GovKeeper.SetProposal(suite.chainB.GetContext(), proposal) @@ -216,7 +222,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Option: govtypes.OptionYes, } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -242,7 +248,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Depositor: interchainAccountAddr, } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -268,7 +274,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { WithdrawAddress: suite.chainB.SenderAccount.GetAddress().String(), } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -303,11 +309,11 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Token: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), Sender: interchainAccountAddr, Receiver: suite.chainA.SenderAccount.GetAddress().String(), - TimeoutHeight: clienttypes.NewHeight(0, 100), + TimeoutHeight: clienttypes.NewHeight(1, 100), TimeoutTimestamp: uint64(0), } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -322,6 +328,26 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { }, true, }, + { + "unregistered sdk.Msg", + func() { + msg := &banktypes.MsgSendResponse{} + + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) + suite.Require().NoError(err) + + icaPacketData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: data, + } + + packetData = icaPacketData.GetBytes() + + params := types.NewParams(true, []string{"/" + proto.MessageName(msg)}) + suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), params) + }, + false, + }, { "cannot unmarshal interchain account packet data", func() { @@ -346,7 +372,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { { "invalid packet type - UNSPECIFIED", func() { - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{&banktypes.MsgSend{}}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{&banktypes.MsgSend{}}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -363,7 +389,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { func() { path.EndpointA.ChannelConfig.PortID = "invalid-port-id" - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{&banktypes.MsgSend{}}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{&banktypes.MsgSend{}}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -384,7 +410,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -405,7 +431,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msg}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msg}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -459,7 +485,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, - clienttypes.NewHeight(0, 100), + clienttypes.NewHeight(1, 100), 0, ) diff --git a/modules/apps/27-interchain-accounts/host/types/errors.go b/modules/apps/27-interchain-accounts/host/types/errors.go index b16b4093e5e..adba00f6596 100644 --- a/modules/apps/27-interchain-accounts/host/types/errors.go +++ b/modules/apps/27-interchain-accounts/host/types/errors.go @@ -1,10 +1,10 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // ICA Host sentinel errors var ( - ErrHostSubModuleDisabled = sdkerrors.Register(SubModuleName, 2, "host submodule is disabled") + ErrHostSubModuleDisabled = errorsmod.Register(SubModuleName, 2, "host submodule is disabled") ) diff --git a/modules/apps/27-interchain-accounts/host/types/host.pb.go b/modules/apps/27-interchain-accounts/host/types/host.pb.go index db7356b7e9a..4b2cc0c6218 100644 --- a/modules/apps/27-interchain-accounts/host/types/host.pb.go +++ b/modules/apps/27-interchain-accounts/host/types/host.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -104,9 +104,9 @@ var fileDescriptor_48e202774f13d08e = []byte{ 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xf2, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0xcf, 0x4c, 0x4a, 0xd6, 0x4d, - 0xcf, 0xd7, 0x2f, 0x33, 0xd1, 0xcf, 0xcd, 0x4f, 0x29, 0xcd, 0x49, 0x2d, 0x06, 0x85, 0x5f, 0xb1, + 0xcf, 0xd7, 0x2f, 0x33, 0xd7, 0xcf, 0xcd, 0x4f, 0x29, 0xcd, 0x49, 0x2d, 0x06, 0x85, 0x5f, 0xb1, 0xbe, 0x91, 0xb9, 0x2e, 0x22, 0x04, 0x74, 0x51, 0x83, 0xae, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, - 0x0d, 0xec, 0x6b, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd5, 0xb2, 0xee, 0x31, 0x74, 0x01, + 0x0d, 0xec, 0x6b, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xac, 0x86, 0x51, 0x17, 0x74, 0x01, 0x00, 0x00, } diff --git a/modules/apps/27-interchain-accounts/host/types/keys.go b/modules/apps/27-interchain-accounts/host/types/keys.go index 7f1a04facb5..7e0ca350d0e 100644 --- a/modules/apps/27-interchain-accounts/host/types/keys.go +++ b/modules/apps/27-interchain-accounts/host/types/keys.go @@ -10,12 +10,15 @@ const ( // StoreKey is the store key string for the interchain accounts host module StoreKey = SubModuleName + + // AllowAllHostMsgs holds the string key that allows all message types on interchain accounts host module + AllowAllHostMsgs = "*" ) // ContainsMsgType returns true if the sdk.Msg TypeURL is present in allowMsgs, otherwise false func ContainsMsgType(allowMsgs []string, msg sdk.Msg) bool { // check that wildcard * option for allowing all message types is the only string in the array, if so, return true - if len(allowMsgs) == 1 && allowMsgs[0] == "*" { + if len(allowMsgs) == 1 && allowMsgs[0] == AllowAllHostMsgs { return true } diff --git a/modules/apps/27-interchain-accounts/host/types/params.go b/modules/apps/27-interchain-accounts/host/types/params.go index 480de05c286..af28c413c9e 100644 --- a/modules/apps/27-interchain-accounts/host/types/params.go +++ b/modules/apps/27-interchain-accounts/host/types/params.go @@ -34,12 +34,12 @@ func NewParams(enableHost bool, allowMsgs []string) Params { // DefaultParams is the default parameter configuration for the host submodule func DefaultParams() Params { - return NewParams(DefaultHostEnabled, nil) + return NewParams(DefaultHostEnabled, []string{AllowAllHostMsgs}) } // Validate validates all host submodule parameters func (p Params) Validate() error { - if err := validateEnabled(p.HostEnabled); err != nil { + if err := validateEnabledType(p.HostEnabled); err != nil { return err } @@ -53,12 +53,12 @@ func (p Params) Validate() error { // ParamSetPairs implements params.ParamSet func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(KeyHostEnabled, p.HostEnabled, validateEnabled), + paramtypes.NewParamSetPair(KeyHostEnabled, p.HostEnabled, validateEnabledType), paramtypes.NewParamSetPair(KeyAllowMessages, p.AllowMessages, validateAllowlist), } } -func validateEnabled(i interface{}) error { +func validateEnabledType(i interface{}) error { _, ok := i.(bool) if !ok { return fmt.Errorf("invalid parameter type: %T", i) diff --git a/modules/apps/27-interchain-accounts/host/types/params_test.go b/modules/apps/27-interchain-accounts/host/types/params_test.go index 39ed24251f7..e83b82e7447 100644 --- a/modules/apps/27-interchain-accounts/host/types/params_test.go +++ b/modules/apps/27-interchain-accounts/host/types/params_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" ) func TestValidateParams(t *testing.T) { diff --git a/modules/apps/27-interchain-accounts/host/types/query.pb.go b/modules/apps/27-interchain-accounts/host/types/query.pb.go index 313d0f10b6f..e1019e8c1f6 100644 --- a/modules/apps/27-interchain-accounts/host/types/query.pb.go +++ b/modules/apps/27-interchain-accounts/host/types/query.pb.go @@ -6,8 +6,8 @@ package types import ( context "context" fmt "fmt" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -139,9 +139,9 @@ var fileDescriptor_e6b7e23fc90c353a = []byte{ 0xc5, 0xc8, 0x80, 0x37, 0x67, 0xfd, 0xfb, 0x9c, 0x75, 0x9f, 0xf3, 0xd9, 0x73, 0x41, 0xd1, 0xba, 0xa0, 0xe8, 0xbd, 0xa0, 0xe8, 0xa1, 0xa4, 0x9d, 0x75, 0x49, 0x3b, 0x6f, 0x25, 0xed, 0xdc, 0x5e, 0xc4, 0xda, 0xcf, 0xb3, 0x88, 0x49, 0x48, 0xb8, 0x04, 0x97, 0x80, 0xab, 0xc4, 0xc3, 0x18, 0x78, - 0x3e, 0xe1, 0x09, 0xcc, 0xb2, 0x85, 0x72, 0x75, 0xcc, 0x78, 0x3a, 0xfc, 0x4a, 0x1a, 0x6e, 0x26, - 0xf9, 0x95, 0x55, 0x2e, 0xea, 0x86, 0x7f, 0x3b, 0xfe, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x58, 0x8e, - 0x7b, 0xe6, 0x78, 0x02, 0x00, 0x00, + 0x3e, 0xe5, 0x09, 0xcc, 0xb2, 0x85, 0x72, 0x75, 0xcc, 0x78, 0x3a, 0xfc, 0x4a, 0x1a, 0x6e, 0x26, + 0xf9, 0x95, 0x55, 0x2e, 0xea, 0x86, 0x7f, 0x3b, 0xfe, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x21, 0xba, + 0xc4, 0xc0, 0x78, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/apps/27-interchain-accounts/host/types/query.pb.gw.go b/modules/apps/27-interchain-accounts/host/types/query.pb.gw.go index fbf8503339f..abfb56ce79f 100644 --- a/modules/apps/27-interchain-accounts/host/types/query.pb.gw.go +++ b/modules/apps/27-interchain-accounts/host/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryParamsRequest @@ -52,12 +54,14 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal // 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. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_Params_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 { @@ -65,6 +69,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Params_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) @@ -140,7 +145,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"ibc", "apps", "interchain_accounts", "host", "v1", "params"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"ibc", "apps", "interchain_accounts", "host", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/modules/apps/27-interchain-accounts/module.go b/modules/apps/27-interchain-accounts/module.go index cfcf9804a66..e845df02e35 100644 --- a/modules/apps/27-interchain-accounts/module.go +++ b/modules/apps/27-interchain-accounts/module.go @@ -10,25 +10,28 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - "github.com/gorilla/mux" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/client/cli" - controllerkeeper "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/keeper" - controllertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host" - hostkeeper "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/keeper" - hosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/client/cli" + controllerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host" + hostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" + hosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/simulation" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModuleSimulation = AppModule{} _ porttypes.IBCModule = host.IBCModule{} ) @@ -46,18 +49,19 @@ func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} // RegisterInterfaces registers module concrete types into protobuf Any func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + controllertypes.RegisterInterfaces(registry) types.RegisterInterfaces(registry) } // DefaultGenesis returns default genesis state as raw bytes for the IBC // interchain accounts module func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(types.DefaultGenesis()) + return cdc.MustMarshalJSON(genesistypes.DefaultGenesis()) } // ValidateGenesis performs genesis state validation for the IBC interchain acounts module func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - var gs types.GenesisState + var gs genesistypes.GenesisState if err := cdc.UnmarshalJSON(bz, &gs); err != nil { return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) } @@ -65,19 +69,22 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod return gs.Validate() } -// RegisterRESTRoutes implements AppModuleBasic interface -func (AppModuleBasic) RegisterRESTRoutes(ctx client.Context, rtr *mux.Router) { -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the interchain accounts module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - controllertypes.RegisterQueryHandlerClient(context.Background(), mux, controllertypes.NewQueryClient(clientCtx)) - hosttypes.RegisterQueryHandlerClient(context.Background(), mux, hosttypes.NewQueryClient(clientCtx)) + err := controllertypes.RegisterQueryHandlerClient(context.Background(), mux, controllertypes.NewQueryClient(clientCtx)) + if err != nil { + panic(err) + } + + err = hosttypes.RegisterQueryHandlerClient(context.Background(), mux, hosttypes.NewQueryClient(clientCtx)) + if err != nil { + panic(err) + } } // GetTxCmd implements AppModuleBasic interface func (AppModuleBasic) GetTxCmd() *cobra.Command { - return nil + return cli.NewTxCmd() } // GetQueryCmd implements AppModuleBasic interface @@ -110,8 +117,8 @@ func (am AppModule) InitModule(ctx sdk.Context, controllerParams controllertypes if am.hostKeeper != nil { am.hostKeeper.SetParams(ctx, hostParams) - cap := am.hostKeeper.BindPort(ctx, types.PortID) - if err := am.hostKeeper.ClaimCapability(ctx, cap, ibchost.PortPath(types.PortID)); err != nil { + cap := am.hostKeeper.BindPort(ctx, types.HostPortID) + if err := am.hostKeeper.ClaimCapability(ctx, cap, ibchost.PortPath(types.HostPortID)); err != nil { panic(fmt.Sprintf("could not claim port capability: %v", err)) } } @@ -121,36 +128,27 @@ func (am AppModule) InitModule(ctx sdk.Context, controllerParams controllertypes func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { } -// Route implements the AppModule interface -func (AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, nil) -} - -// NewHandler implements the AppModule interface -func (AppModule) NewHandler() sdk.Handler { - return nil -} - -// QuerierRoute implements the AppModule interface -func (AppModule) QuerierRoute() string { - return types.QuerierRoute -} - -// LegacyQuerierHandler implements the AppModule interface -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { - return nil -} - // RegisterServices registers module services func (am AppModule) RegisterServices(cfg module.Configurator) { - controllertypes.RegisterQueryServer(cfg.QueryServer(), am.controllerKeeper) - hosttypes.RegisterQueryServer(cfg.QueryServer(), am.hostKeeper) + if am.controllerKeeper != nil { + controllertypes.RegisterMsgServer(cfg.MsgServer(), controllerkeeper.NewMsgServerImpl(am.controllerKeeper)) + controllertypes.RegisterQueryServer(cfg.QueryServer(), am.controllerKeeper) + } + + if am.hostKeeper != nil { + hosttypes.RegisterQueryServer(cfg.QueryServer(), am.hostKeeper) + } + + m := controllerkeeper.NewMigrator(am.controllerKeeper) + if err := cfg.RegisterMigration(types.ModuleName, 1, m.AssertChannelCapabilityMigrations); err != nil { + panic(fmt.Sprintf("failed to migrate interchainaccounts app from version 1 to 2: %v", err)) + } } // InitGenesis performs genesis initialization for the interchain accounts module. // It returns no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState types.GenesisState + var genesisState genesistypes.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) if am.controllerKeeper != nil { @@ -167,8 +165,8 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json. // ExportGenesis returns the exported genesis state as raw bytes for the interchain accounts module func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { var ( - controllerGenesisState = types.DefaultControllerGenesis() - hostGenesisState = types.DefaultHostGenesis() + controllerGenesisState = genesistypes.DefaultControllerGenesis() + hostGenesisState = genesistypes.DefaultHostGenesis() ) if am.controllerKeeper != nil { @@ -179,13 +177,13 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw hostGenesisState = hostkeeper.ExportGenesis(ctx, *am.hostKeeper) } - gs := types.NewGenesisState(controllerGenesisState, hostGenesisState) + gs := genesistypes.NewGenesisState(controllerGenesisState, hostGenesisState) return cdc.MustMarshalJSON(gs) } // 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) { @@ -195,3 +193,20 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } + +// AppModuleSimulation functions + +// GenerateGenesisState creates a randomized GenState of the ics27 module. +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState) +} + +// WeightedOperations is unimplemented. +func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return nil +} + +// RegisterStoreDecoder registers a decoder for interchain accounts module's types +func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { + sdr[types.StoreKey] = simulation.NewDecodeStore() +} diff --git a/modules/apps/27-interchain-accounts/module_test.go b/modules/apps/27-interchain-accounts/module_test.go index be51b9d71c7..a1215a60ddb 100644 --- a/modules/apps/27-interchain-accounts/module_test.go +++ b/modules/apps/27-interchain-accounts/module_test.go @@ -3,17 +3,18 @@ package ica_test import ( "testing" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/stretchr/testify/suite" "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" - ica "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts" - controllertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - hosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - "github.com/cosmos/ibc-go/v4/testing/simapp" + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + hosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) type InterchainAccountsTestSuite struct { @@ -32,7 +33,7 @@ func (suite *InterchainAccountsTestSuite) SetupTest() { func (suite *InterchainAccountsTestSuite) TestInitModule() { // setup and basic testing - app := simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, simapp.MakeTestEncodingConfig(), simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, simapp.MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}) appModule, ok := app.GetModuleManager().Modules[types.ModuleName].(ica.AppModule) suite.Require().True(ok) @@ -59,7 +60,7 @@ func (suite *InterchainAccountsTestSuite) TestInitModule() { expAllowMessages := []string{"sdk.Msg"} hostParams.HostEnabled = true hostParams.AllowMessages = expAllowMessages - suite.Require().False(app.IBCKeeper.PortKeeper.IsBound(ctx, types.PortID)) + suite.Require().False(app.IBCKeeper.PortKeeper.IsBound(ctx, types.HostPortID)) testCases := []struct { name string @@ -98,7 +99,7 @@ func (suite *InterchainAccountsTestSuite) TestInitModule() { suite.SetupTest() // reset // reset app state - app = simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, simapp.MakeTestEncodingConfig(), simapp.EmptyAppOptions{}) + app = simapp.NewSimApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, simapp.MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}) header := tmproto.Header{ ChainID: "testchain", Height: 1, @@ -123,7 +124,7 @@ func (suite *InterchainAccountsTestSuite) TestInitModule() { suite.Require().True(hostParams.HostEnabled) suite.Require().Equal(expAllowMessages, hostParams.AllowMessages) - suite.Require().True(app.IBCKeeper.PortKeeper.IsBound(ctx, types.PortID)) + suite.Require().True(app.IBCKeeper.PortKeeper.IsBound(ctx, types.HostPortID)) } }) } diff --git a/modules/apps/27-interchain-accounts/simulation/decoder.go b/modules/apps/27-interchain-accounts/simulation/decoder.go new file mode 100644 index 00000000000..b0ceaaf1de3 --- /dev/null +++ b/modules/apps/27-interchain-accounts/simulation/decoder.go @@ -0,0 +1,30 @@ +package simulation + +import ( + "bytes" + "fmt" + + "github.com/cosmos/cosmos-sdk/types/kv" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" +) + +// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's +// Value to the corresponding DenomTrace type. +func NewDecodeStore() func(kvA, kvB kv.Pair) string { + return func(kvA, kvB kv.Pair) string { + switch { + case bytes.Equal(kvA.Key[:len(types.PortKeyPrefix)], []byte(types.PortKeyPrefix)): + return fmt.Sprintf("Port A: %s\nPort B: %s", string(kvA.Value), string(kvB.Value)) + case bytes.Equal(kvA.Key[:len(types.OwnerKeyPrefix)], []byte(types.OwnerKeyPrefix)): + return fmt.Sprintf("Owner A: %s\nOwner B: %s", string(kvA.Value), string(kvB.Value)) + case bytes.Equal(kvA.Key[:len(types.ActiveChannelKeyPrefix)], []byte(types.ActiveChannelKeyPrefix)): + return fmt.Sprintf("ActiveChannel A: %s\nActiveChannel B: %s", string(kvA.Value), string(kvB.Value)) + case bytes.Equal(kvA.Key[:len(types.IsMiddlewareEnabledPrefix)], []byte(types.IsMiddlewareEnabledPrefix)): + return fmt.Sprintf("IsMiddlewareEnabled A: %s\nIsMiddlewareEnabled B: %s", string(kvA.Value), string(kvB.Value)) + + default: + panic(fmt.Sprintf("invalid %s key prefix %s", types.ModuleName, kvA.Key)) + } + } +} diff --git a/modules/apps/27-interchain-accounts/simulation/decoder_test.go b/modules/apps/27-interchain-accounts/simulation/decoder_test.go new file mode 100644 index 00000000000..81e899b620e --- /dev/null +++ b/modules/apps/27-interchain-accounts/simulation/decoder_test.go @@ -0,0 +1,64 @@ +package simulation_test + +import ( + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/types/kv" + "github.com/stretchr/testify/require" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/simulation" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func TestDecodeStore(t *testing.T) { + var ( + owner = "owner" + channelID = ibctesting.FirstChannelID + ) + + dec := simulation.NewDecodeStore() + + kvPairs := kv.Pairs{ + Pairs: []kv.Pair{ + { + Key: []byte(types.PortKeyPrefix), + Value: []byte(types.HostPortID), + }, + { + Key: []byte(types.OwnerKeyPrefix), + Value: []byte("owner"), + }, + { + Key: []byte(types.ActiveChannelKeyPrefix), + Value: []byte("channel-0"), + }, + { + Key: []byte(types.IsMiddlewareEnabledPrefix), + Value: []byte("false"), + }, + }, + } + tests := []struct { + name string + expectedLog string + }{ + {"PortID", fmt.Sprintf("Port A: %s\nPort B: %s", types.HostPortID, types.HostPortID)}, + {"Owner", fmt.Sprintf("Owner A: %s\nOwner B: %s", owner, owner)}, + {"ActiveChannel", fmt.Sprintf("ActiveChannel A: %s\nActiveChannel B: %s", channelID, channelID)}, + {"IsMiddlewareEnabled", fmt.Sprintf("IsMiddlewareEnabled A: %s\nIsMiddlewareEnabled B: %s", "false", "false")}, + {"other", ""}, + } + + for i, tt := range tests { + i, tt := i, tt + t.Run(tt.name, func(t *testing.T) { + if i == len(tests)-1 { + require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name) + } else { + require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name) + } + }) + } +} diff --git a/modules/apps/27-interchain-accounts/simulation/genesis.go b/modules/apps/27-interchain-accounts/simulation/genesis.go new file mode 100644 index 00000000000..c90ecaf7003 --- /dev/null +++ b/modules/apps/27-interchain-accounts/simulation/genesis.go @@ -0,0 +1,70 @@ +package simulation + +import ( + "encoding/json" + "fmt" + "math/rand" + + "github.com/cosmos/cosmos-sdk/types/module" + + controllertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + hosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" +) + +// RandomEnabled randomized controller or host enabled param with 75% prob of being true. +func RandomEnabled(r *rand.Rand) bool { + return r.Int63n(101) <= 75 +} + +// RandomizedGenState generates a random GenesisState for ics27. +// Only the params are non nil +func RandomizedGenState(simState *module.SimulationState) { + var controllerEnabled bool + simState.AppParams.GetOrGenerate( + simState.Cdc, string(controllertypes.KeyControllerEnabled), &controllerEnabled, simState.Rand, + func(r *rand.Rand) { controllerEnabled = RandomEnabled(r) }, + ) + + controllerParams := controllertypes.Params{ + ControllerEnabled: controllerEnabled, + } + + controllerGenesisState := genesistypes.ControllerGenesisState{ + ActiveChannels: nil, + InterchainAccounts: nil, + Ports: []string{}, + Params: controllerParams, + } + + var hostEnabled bool + simState.AppParams.GetOrGenerate( + simState.Cdc, string(hosttypes.KeyHostEnabled), &hostEnabled, simState.Rand, + func(r *rand.Rand) { hostEnabled = RandomEnabled(r) }, + ) + + hostParams := hosttypes.Params{ + HostEnabled: hostEnabled, + AllowMessages: []string{"*"}, // allow all messages + } + + hostGenesisState := genesistypes.HostGenesisState{ + ActiveChannels: nil, + InterchainAccounts: nil, + Port: types.HostPortID, + Params: hostParams, + } + + icaGenesis := genesistypes.GenesisState{ + ControllerGenesisState: controllerGenesisState, + HostGenesisState: hostGenesisState, + } + + bz, err := json.MarshalIndent(&icaGenesis, "", " ") + if err != nil { + panic(err) + } + fmt.Printf("Selected randomly generated %s parameters:\n%s\n", types.ModuleName, bz) + simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(&icaGenesis) +} diff --git a/modules/apps/27-interchain-accounts/simulation/genesis_test.go b/modules/apps/27-interchain-accounts/simulation/genesis_test.go new file mode 100644 index 00000000000..28b927643b9 --- /dev/null +++ b/modules/apps/27-interchain-accounts/simulation/genesis_test.go @@ -0,0 +1,56 @@ +package simulation_test + +import ( + "encoding/json" + "math/rand" + "testing" + + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/stretchr/testify/require" + + genesistypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/simulation" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" +) + +// TestRandomizedGenState tests the normal scenario of applying RandomizedGenState. +// Abonormal scenarios are not tested here. +func TestRandomizedGenState(t *testing.T) { + interfaceRegistry := codectypes.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(interfaceRegistry) + cdc := codec.NewProtoCodec(interfaceRegistry) + + s := rand.NewSource(1) // 1 is the seed + r := rand.New(s) + + simState := module.SimulationState{ + AppParams: make(simtypes.AppParams), + Cdc: cdc, + Rand: r, + NumBonded: 3, + Accounts: simtypes.RandomAccounts(r, 3), + InitialStake: math.NewInt(1000), + GenState: make(map[string]json.RawMessage), + } + + simulation.RandomizedGenState(&simState) + + var icaGenesis genesistypes.GenesisState + simState.Cdc.MustUnmarshalJSON(simState.GenState[types.ModuleName], &icaGenesis) + + require.True(t, icaGenesis.ControllerGenesisState.Params.ControllerEnabled) + require.Empty(t, icaGenesis.ControllerGenesisState.ActiveChannels) + require.Empty(t, icaGenesis.ControllerGenesisState.InterchainAccounts) + require.Empty(t, icaGenesis.ControllerGenesisState.Ports) + + require.True(t, icaGenesis.HostGenesisState.Params.HostEnabled) + require.Equal(t, []string{"*"}, icaGenesis.HostGenesisState.Params.AllowMessages) + require.Equal(t, types.HostPortID, icaGenesis.HostGenesisState.Port) + require.Empty(t, icaGenesis.ControllerGenesisState.ActiveChannels) + require.Empty(t, icaGenesis.ControllerGenesisState.InterchainAccounts) +} diff --git a/modules/apps/27-interchain-accounts/types/account.go b/modules/apps/27-interchain-accounts/types/account.go index 38d7c4c5fe5..472b509818c 100644 --- a/modules/apps/27-interchain-accounts/types/account.go +++ b/modules/apps/27-interchain-accounts/types/account.go @@ -5,10 +5,10 @@ import ( "regexp" "strings" + errorsmod "cosmossdk.io/errors" crypto "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkaddress "github.com/cosmos/cosmos-sdk/types/address" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" yaml "gopkg.in/yaml.v2" ) @@ -39,17 +39,24 @@ type interchainAccountPretty struct { AccountOwner string `json:"account_owner" yaml:"account_owner"` } -// GenerateAddress returns an sdk.AccAddress derived using the provided module account address and connection and port identifiers. -// The sdk.AccAddress returned is a sub-address of the module account, using the host chain connection ID and controller chain's port ID as the derivation key -func GenerateAddress(moduleAccAddr sdk.AccAddress, connectionID, portID string) sdk.AccAddress { - return sdk.AccAddress(sdkaddress.Derive(moduleAccAddr, []byte(connectionID+portID))) +// GenerateAddress returns an sdk.AccAddress derived using a host module account address, host connection ID, the controller portID, +// the current block app hash, and the current block data hash. The sdk.AccAddress returned is a sub-address of the host module account. +func GenerateAddress(ctx sdk.Context, connectionID, portID string) sdk.AccAddress { + hostModuleAcc := sdkaddress.Module(ModuleName, []byte(hostAccountsKey)) + header := ctx.BlockHeader() + + buf := []byte(connectionID + portID) + buf = append(buf, header.AppHash...) + buf = append(buf, header.DataHash...) + + return sdkaddress.Derive(hostModuleAcc, buf) } // ValidateAccountAddress performs basic validation of interchain account addresses, enforcing constraints // on address length and character set func ValidateAccountAddress(addr string) error { if !isValidAddr(addr) || len(addr) > DefaultMaxAddrLength { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( ErrInvalidAccountAddress, "address must contain strictly alphanumeric characters, not exceeding %d characters in length", DefaultMaxAddrLength, @@ -69,18 +76,18 @@ func NewInterchainAccount(ba *authtypes.BaseAccount, accountOwner string) *Inter // SetPubKey implements the authtypes.AccountI interface func (ia InterchainAccount) SetPubKey(pubKey crypto.PubKey) error { - return sdkerrors.Wrap(ErrUnsupported, "cannot set public key for interchain account") + return errorsmod.Wrap(ErrUnsupported, "cannot set public key for interchain account") } // SetSequence implements the authtypes.AccountI interface func (ia InterchainAccount) SetSequence(seq uint64) error { - return sdkerrors.Wrap(ErrUnsupported, "cannot set sequence number for interchain account") + return errorsmod.Wrap(ErrUnsupported, "cannot set sequence number for interchain account") } // Validate implements basic validation of the InterchainAccount func (ia InterchainAccount) Validate() error { if strings.TrimSpace(ia.AccountOwner) == "" { - return sdkerrors.Wrap(ErrInvalidAccountAddress, "AccountOwner cannot be empty") + return errorsmod.Wrap(ErrInvalidAccountAddress, "AccountOwner cannot be empty") } return ia.BaseAccount.Validate() diff --git a/modules/apps/27-interchain-accounts/types/account.pb.go b/modules/apps/27-interchain-accounts/types/account.pb.go index 4978a25f4a7..67273dfd591 100644 --- a/modules/apps/27-interchain-accounts/types/account.pb.go +++ b/modules/apps/27-interchain-accounts/types/account.pb.go @@ -5,10 +5,10 @@ package types import ( fmt "fmt" + _ "github.com/cosmos/cosmos-proto" types "github.com/cosmos/cosmos-sdk/x/auth/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - _ "github.com/regen-network/cosmos-proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -72,7 +72,7 @@ func init() { } var fileDescriptor_5561bd92625bf7da = []byte{ - // 341 bytes of a gzipped FileDescriptorProto + // 344 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0xcd, 0x4c, 0x4a, 0xd6, 0x4f, 0x2c, 0x28, 0xc8, 0xc9, 0x4c, 0x4e, 0x2c, 0xc9, 0xcc, 0xcf, 0x2b, 0xd6, 0xcf, 0xcc, 0x2b, 0x49, 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0x8b, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0x29, @@ -80,21 +80,21 @@ var fileDescriptor_5561bd92625bf7da = []byte{ 0x92, 0xf5, 0x90, 0xb5, 0xe9, 0x61, 0xd1, 0xa6, 0x57, 0x66, 0x28, 0x25, 0x99, 0x9c, 0x5f, 0x9c, 0x9b, 0x5f, 0x1c, 0x0f, 0xd6, 0xa6, 0x0f, 0xe1, 0x40, 0xcc, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x87, 0x88, 0x83, 0x58, 0x50, 0x51, 0x39, 0x88, 0x1a, 0xfd, 0xc4, 0xd2, 0x92, 0x0c, 0xfd, 0x32, - 0xc3, 0xa4, 0xd4, 0x92, 0x44, 0x43, 0x30, 0x07, 0x22, 0xaf, 0x74, 0x85, 0x91, 0x4b, 0xd0, 0x13, + 0xc3, 0xa4, 0xd4, 0x92, 0x44, 0x43, 0x30, 0x07, 0x22, 0xaf, 0xf4, 0x87, 0x91, 0x4b, 0xd0, 0x13, 0x6e, 0x97, 0x23, 0xc4, 0x2a, 0xa1, 0x04, 0x2e, 0x9e, 0xa4, 0xc4, 0xe2, 0x54, 0x98, 0xd5, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x0a, 0x7a, 0x50, 0x0b, 0xc1, 0xfa, 0xa1, 0x86, 0xe9, 0x39, 0x25, 0x16, 0xa7, 0x42, 0xf5, 0x39, 0x49, 0x5f, 0xb8, 0x27, 0xcf, 0xf8, 0xe9, 0x9e, 0xbc, 0x70, 0x65, 0x62, 0x6e, 0x8e, 0x95, 0x12, 0xb2, 0x19, 0x4a, 0x41, 0xdc, 0x49, 0x08, 0x95, 0x42, 0xb6, 0x5c, 0xbc, 0x50, 0x89, 0xf8, 0xfc, 0xf2, 0xbc, 0xd4, 0x22, 0x09, 0x26, 0x05, 0x46, 0x0d, 0x4e, 0x27, 0x89, 0x4f, 0xf7, 0xe4, 0x45, 0x20, 0x9a, 0x51, 0xa4, 0x95, 0x82, 0x78, 0xa0, 0x7c, 0x7f, - 0x10, 0xd7, 0x4a, 0xae, 0x63, 0x81, 0x3c, 0xc3, 0x8c, 0x05, 0xf2, 0x0c, 0x97, 0xb6, 0xe8, 0x0a, - 0x61, 0xb8, 0xdf, 0xd3, 0x29, 0xfe, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, - 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, - 0x5c, 0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xa1, 0xe1, 0xa7, 0x9f, 0x99, - 0x94, 0xac, 0x9b, 0x9e, 0xaf, 0x5f, 0x66, 0xa2, 0x9f, 0x9b, 0x9f, 0x52, 0x9a, 0x93, 0x5a, 0x0c, - 0x8a, 0xc1, 0x62, 0x7d, 0x23, 0x73, 0x5d, 0x44, 0x2c, 0xe8, 0xc2, 0x23, 0xaf, 0xa4, 0xb2, 0x20, - 0xb5, 0x38, 0x89, 0x0d, 0x1c, 0x7c, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4e, 0xd7, 0x23, - 0x15, 0xf1, 0x01, 0x00, 0x00, + 0x10, 0xd7, 0xca, 0xad, 0x63, 0x81, 0x3c, 0xc3, 0x8c, 0x05, 0xf2, 0x0c, 0xa7, 0xb6, 0xe8, 0x5a, + 0x11, 0x19, 0x78, 0x7a, 0x18, 0xfe, 0xf4, 0x74, 0x8a, 0x3f, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, + 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, + 0x63, 0x39, 0x86, 0x28, 0xd7, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x68, + 0x38, 0xeb, 0x67, 0x26, 0x25, 0xeb, 0xa6, 0xe7, 0xeb, 0x97, 0x99, 0xeb, 0xe7, 0xe6, 0xa7, 0x94, + 0xe6, 0xa4, 0x16, 0x83, 0x62, 0xba, 0x58, 0xdf, 0xc8, 0x5c, 0x17, 0x61, 0xa1, 0x2e, 0x3c, 0x92, + 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0xc1, 0x6c, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, + 0xae, 0x11, 0x4f, 0x20, 0x19, 0x02, 0x00, 0x00, } func (m *InterchainAccount) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/27-interchain-accounts/types/account_test.go b/modules/apps/27-interchain-accounts/types/account_test.go index 19684cb8c80..8acef7e33a9 100644 --- a/modules/apps/27-interchain-accounts/types/account_test.go +++ b/modules/apps/27-interchain-accounts/types/account_test.go @@ -10,15 +10,15 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/stretchr/testify/suite" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) var ( // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" - // TestPortID defines a resuable port identifier for testing purposes + // TestPortID defines a reusable port identifier for testing purposes TestPortID, _ = types.NewControllerPortID(TestOwnerAddress) ) @@ -43,7 +43,7 @@ func TestTypesTestSuite(t *testing.T) { } func (suite *TypesTestSuite) TestGenerateAddress() { - addr := types.GenerateAddress([]byte{}, "test-connection-id", "test-port-id") + addr := types.GenerateAddress(suite.chainA.GetContext(), "test-connection-id", "test-port-id") accAddr, err := sdk.AccAddressFromBech32(addr.String()) suite.Require().NoError(err, "TestGenerateAddress failed") diff --git a/modules/apps/27-interchain-accounts/types/codec.go b/modules/apps/27-interchain-accounts/types/codec.go index 033c264f9e7..b0ba7b8902b 100644 --- a/modules/apps/27-interchain-accounts/types/codec.go +++ b/modules/apps/27-interchain-accounts/types/codec.go @@ -1,11 +1,12 @@ package types import ( + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/gogoproto/proto" ) // ModuleCdc references the global interchain accounts module codec. Note, the codec @@ -15,8 +16,8 @@ import ( // defined at the application level. var ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) -// RegisterInterfaces registers the concrete InterchainAccount implementation against the associated -// x/auth AccountI and GenesisAccount interfaces +// RegisterInterfaces registers the interchain accounts controller types and the concrete InterchainAccount implementation +// against the associated x/auth AccountI and GenesisAccount interfaces. func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterImplementations((*authtypes.AccountI)(nil), &InterchainAccount{}) registry.RegisterImplementations((*authtypes.GenesisAccount)(nil), &InterchainAccount{}) @@ -25,10 +26,10 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { // SerializeCosmosTx serializes a slice of sdk.Msg's using the CosmosTx type. The sdk.Msg's are // packed into Any's and inserted into the Messages field of a CosmosTx. The proto marshaled CosmosTx // bytes are returned. Only the ProtoCodec is supported for serializing messages. -func SerializeCosmosTx(cdc codec.BinaryCodec, msgs []sdk.Msg) (bz []byte, err error) { +func SerializeCosmosTx(cdc codec.BinaryCodec, msgs []proto.Message) (bz []byte, err error) { // only ProtoCodec is supported if _, ok := cdc.(*codec.ProtoCodec); !ok { - return nil, sdkerrors.Wrap(ErrInvalidCodec, "only ProtoCodec is supported for receiving messages on the host chain") + return nil, errorsmod.Wrap(ErrInvalidCodec, "only ProtoCodec is supported for receiving messages on the host chain") } msgAnys := make([]*codectypes.Any, len(msgs)) @@ -58,7 +59,7 @@ func SerializeCosmosTx(cdc codec.BinaryCodec, msgs []sdk.Msg) (bz []byte, err er func DeserializeCosmosTx(cdc codec.BinaryCodec, data []byte) ([]sdk.Msg, error) { // only ProtoCodec is supported if _, ok := cdc.(*codec.ProtoCodec); !ok { - return nil, sdkerrors.Wrap(ErrInvalidCodec, "only ProtoCodec is supported for receiving messages on the host chain") + return nil, errorsmod.Wrap(ErrInvalidCodec, "only ProtoCodec is supported for receiving messages on the host chain") } var cosmosTx CosmosTx @@ -68,10 +69,10 @@ func DeserializeCosmosTx(cdc codec.BinaryCodec, data []byte) ([]sdk.Msg, error) msgs := make([]sdk.Msg, len(cosmosTx.Messages)) - for i, any := range cosmosTx.Messages { + for i, protoAny := range cosmosTx.Messages { var msg sdk.Msg - err := cdc.UnpackAny(any, &msg) + err := cdc.UnpackAny(protoAny, &msg) if err != nil { return nil, err } diff --git a/modules/apps/27-interchain-accounts/types/codec_test.go b/modules/apps/27-interchain-accounts/types/codec_test.go index 51fe1128fba..1df2dd4d66a 100644 --- a/modules/apps/27-interchain-accounts/types/codec_test.go +++ b/modules/apps/27-interchain-accounts/types/codec_test.go @@ -4,19 +4,13 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + "github.com/cosmos/gogoproto/proto" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) -// caseRawBytes defines a helper struct, used for testing codec operations -type caseRawBytes struct { - name string - bz []byte - expPass bool -} - // mockSdkMsg defines a mock struct, used for testing codec error scenarios type mockSdkMsg struct{} @@ -46,12 +40,12 @@ func (mockSdkMsg) GetSigners() []sdk.AccAddress { func (suite *TypesTestSuite) TestSerializeAndDeserializeCosmosTx() { testCases := []struct { name string - msgs []sdk.Msg + msgs []proto.Message expPass bool }{ { "single msg", - []sdk.Msg{ + []proto.Message{ &banktypes.MsgSend{ FromAddress: TestOwnerAddress, ToAddress: TestOwnerAddress, @@ -62,7 +56,7 @@ func (suite *TypesTestSuite) TestSerializeAndDeserializeCosmosTx() { }, { "multiple msgs, same types", - []sdk.Msg{ + []proto.Message{ &banktypes.MsgSend{ FromAddress: TestOwnerAddress, ToAddress: TestOwnerAddress, @@ -78,7 +72,7 @@ func (suite *TypesTestSuite) TestSerializeAndDeserializeCosmosTx() { }, { "multiple msgs, different types", - []sdk.Msg{ + []proto.Message{ &banktypes.MsgSend{ FromAddress: TestOwnerAddress, ToAddress: TestOwnerAddress, @@ -93,14 +87,14 @@ func (suite *TypesTestSuite) TestSerializeAndDeserializeCosmosTx() { }, { "unregistered msg type", - []sdk.Msg{ + []proto.Message{ &mockSdkMsg{}, }, false, }, { "multiple unregistered msg types", - []sdk.Msg{ + []proto.Message{ &mockSdkMsg{}, &mockSdkMsg{}, &mockSdkMsg{}, @@ -109,25 +103,35 @@ func (suite *TypesTestSuite) TestSerializeAndDeserializeCosmosTx() { }, } - testCasesAny := []caseRawBytes{} - for _, tc := range testCases { - bz, err := types.SerializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, tc.msgs) - suite.Require().NoError(err, tc.name) - - testCasesAny = append(testCasesAny, caseRawBytes{tc.name, bz, tc.expPass}) - } + tc := tc - for i, tc := range testCasesAny { - msgs, err := types.DeserializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, tc.bz) - if tc.expPass { + suite.Run(tc.name, func() { + bz, err := types.SerializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, tc.msgs) suite.Require().NoError(err, tc.name) - suite.Require().Equal(testCases[i].msgs, msgs, tc.name) - } else { - suite.Require().Error(err, tc.name) - } + + msgs, err := types.DeserializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, bz) + if tc.expPass { + suite.Require().NoError(err, tc.name) + } else { + suite.Require().Error(err, tc.name) + } + + for i, msg := range msgs { + suite.Require().Equal(tc.msgs[i], msg) + } + }) } + // test serializing non sdk.Msg type + bz, err := types.SerializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, []proto.Message{&banktypes.MsgSendResponse{}}) + suite.Require().NoError(err) + suite.Require().NotEmpty(bz) + + // test deserializing unknown bytes + _, err = types.DeserializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, bz) + suite.Require().Error(err) // unregistered type + // test deserializing unknown bytes msgs, err := types.DeserializeCosmosTx(simapp.MakeTestEncodingConfig().Marshaler, []byte("invalid")) suite.Require().Error(err) @@ -141,7 +145,7 @@ func (suite *TypesTestSuite) TestDeserializeAndSerializeCosmosTxWithAmino() { cdc := codec.NewLegacyAmino() marshaler := codec.NewAminoCodec(cdc) - msgs, err := types.SerializeCosmosTx(marshaler, []sdk.Msg{&banktypes.MsgSend{}}) + msgs, err := types.SerializeCosmosTx(marshaler, []proto.Message{&banktypes.MsgSend{}}) suite.Require().Error(err) suite.Require().Empty(msgs) diff --git a/modules/apps/27-interchain-accounts/types/errors.go b/modules/apps/27-interchain-accounts/types/errors.go index 7bb391dbe93..06989327dfb 100644 --- a/modules/apps/27-interchain-accounts/types/errors.go +++ b/modules/apps/27-interchain-accounts/types/errors.go @@ -1,25 +1,26 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) var ( - ErrUnknownDataType = sdkerrors.Register(ModuleName, 2, "unknown data type") - ErrAccountAlreadyExist = sdkerrors.Register(ModuleName, 3, "account already exist") - ErrPortAlreadyBound = sdkerrors.Register(ModuleName, 4, "port is already bound") - ErrInvalidChannelFlow = sdkerrors.Register(ModuleName, 5, "invalid message sent to channel end") - ErrInvalidOutgoingData = sdkerrors.Register(ModuleName, 6, "invalid outgoing data") - ErrInvalidRoute = sdkerrors.Register(ModuleName, 7, "invalid route") - ErrInterchainAccountNotFound = sdkerrors.Register(ModuleName, 8, "interchain account not found") - ErrInterchainAccountAlreadySet = sdkerrors.Register(ModuleName, 9, "interchain account is already set") - ErrActiveChannelAlreadySet = sdkerrors.Register(ModuleName, 10, "active channel already set for this owner") - ErrActiveChannelNotFound = sdkerrors.Register(ModuleName, 11, "no active channel for this owner") - ErrInvalidVersion = sdkerrors.Register(ModuleName, 12, "invalid interchain accounts version") - ErrInvalidAccountAddress = sdkerrors.Register(ModuleName, 13, "invalid account address") - ErrUnsupported = sdkerrors.Register(ModuleName, 14, "interchain account does not support this action") - ErrInvalidControllerPort = sdkerrors.Register(ModuleName, 15, "invalid controller port") - ErrInvalidHostPort = sdkerrors.Register(ModuleName, 16, "invalid host port") - ErrInvalidTimeoutTimestamp = sdkerrors.Register(ModuleName, 17, "timeout timestamp must be in the future") - ErrInvalidCodec = sdkerrors.Register(ModuleName, 18, "codec is not supported") + ErrUnknownDataType = errorsmod.Register(ModuleName, 2, "unknown data type") + ErrAccountAlreadyExist = errorsmod.Register(ModuleName, 3, "account already exist") + ErrPortAlreadyBound = errorsmod.Register(ModuleName, 4, "port is already bound") + ErrInvalidChannelFlow = errorsmod.Register(ModuleName, 5, "invalid message sent to channel end") + ErrInvalidOutgoingData = errorsmod.Register(ModuleName, 6, "invalid outgoing data") + ErrInvalidRoute = errorsmod.Register(ModuleName, 7, "invalid route") + ErrInterchainAccountNotFound = errorsmod.Register(ModuleName, 8, "interchain account not found") + ErrInterchainAccountAlreadySet = errorsmod.Register(ModuleName, 9, "interchain account is already set") + ErrActiveChannelAlreadySet = errorsmod.Register(ModuleName, 10, "active channel already set for this owner") + ErrActiveChannelNotFound = errorsmod.Register(ModuleName, 11, "no active channel for this owner") + ErrInvalidVersion = errorsmod.Register(ModuleName, 12, "invalid interchain accounts version") + ErrInvalidAccountAddress = errorsmod.Register(ModuleName, 13, "invalid account address") + ErrUnsupported = errorsmod.Register(ModuleName, 14, "interchain account does not support this action") + ErrInvalidControllerPort = errorsmod.Register(ModuleName, 15, "invalid controller port") + ErrInvalidHostPort = errorsmod.Register(ModuleName, 16, "invalid host port") + ErrInvalidTimeoutTimestamp = errorsmod.Register(ModuleName, 17, "timeout timestamp must be in the future") + ErrInvalidCodec = errorsmod.Register(ModuleName, 18, "codec is not supported") + ErrInvalidAccountReopening = errorsmod.Register(ModuleName, 19, "invalid account reopening") ) diff --git a/modules/apps/27-interchain-accounts/types/expected_keepers.go b/modules/apps/27-interchain-accounts/types/expected_keepers.go index e4873c561fd..fdb9374da00 100644 --- a/modules/apps/27-interchain-accounts/types/expected_keepers.go +++ b/modules/apps/27-interchain-accounts/types/expected_keepers.go @@ -5,8 +5,8 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // AccountKeeper defines the expected account keeper @@ -18,17 +18,12 @@ type AccountKeeper interface { GetModuleAddress(name string) sdk.AccAddress } -// ICS4Wrapper defines the expected ICS4Wrapper for middleware -type ICS4Wrapper interface { - SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error - GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) -} - // ChannelKeeper defines the expected IBC channel keeper type ChannelKeeper interface { GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) GetConnection(ctx sdk.Context, connectionID string) (ibcexported.ConnectionI, error) + GetAllChannelsWithPortPrefix(ctx sdk.Context, portPrefix string) []channeltypes.IdentifiedChannel } // PortKeeper defines the expected IBC port keeper diff --git a/modules/apps/27-interchain-accounts/types/keys.go b/modules/apps/27-interchain-accounts/types/keys.go index 2bf05ffda3f..2a062130ce2 100644 --- a/modules/apps/27-interchain-accounts/types/keys.go +++ b/modules/apps/27-interchain-accounts/types/keys.go @@ -8,11 +8,11 @@ const ( // ModuleName defines the interchain accounts module name ModuleName = "interchainaccounts" - // PortID is the default port id that the interchain accounts host submodule binds to - PortID = "icahost" + // HostPortID is the default port id that the interchain accounts host submodule binds to + HostPortID = "icahost" - // PortPrefix is the default port prefix that the interchain accounts controller submodule binds to - PortPrefix = "icacontroller-" + // ControllerPortPrefix is the default port prefix that the interchain accounts controller submodule binds to + ControllerPortPrefix = "icacontroller-" // Version defines the current version for interchain accounts Version = "ics27-1" @@ -25,6 +25,9 @@ const ( // QuerierRoute is the querier route for interchain accounts QuerierRoute = ModuleName + + // hostAccountKey is the key used when generating a module address for the host submodule + hostAccountsKey = "icahost-accounts" ) var ( @@ -36,6 +39,15 @@ var ( // PortKeyPrefix defines the key prefix used to store ports PortKeyPrefix = "port" + + // IsMiddlewareEnabledPrefix defines the key prefix used to store a flag for legacy API callback routing via ibc middleware + IsMiddlewareEnabledPrefix = "isMiddlewareEnabled" + + // MiddlewareEnabled is the value used to signal that controller middleware is enabled + MiddlewareEnabled = []byte{0x01} + + // MiddlewareDisabled is the value used to signal that controller midleware is disabled + MiddlewareDisabled = []byte{0x02} ) // KeyActiveChannel creates and returns a new key used for active channels store operations @@ -52,3 +64,8 @@ func KeyOwnerAccount(portID, connectionID string) []byte { func KeyPort(portID string) []byte { return []byte(fmt.Sprintf("%s/%s", PortKeyPrefix, portID)) } + +// KeyIsMiddlewareEnabled creates and returns a new key used for signaling legacy API callback routing via ibc middleware +func KeyIsMiddlewareEnabled(portID, connectionID string) []byte { + return []byte(fmt.Sprintf("%s/%s/%s", IsMiddlewareEnabledPrefix, portID, connectionID)) +} diff --git a/modules/apps/27-interchain-accounts/types/keys_test.go b/modules/apps/27-interchain-accounts/types/keys_test.go index 58b5b9c71b3..d9255850dea 100644 --- a/modules/apps/27-interchain-accounts/types/keys_test.go +++ b/modules/apps/27-interchain-accounts/types/keys_test.go @@ -1,7 +1,10 @@ package types_test import ( - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" + fmt "fmt" + + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *TypesTestSuite) TestKeyActiveChannel() { @@ -13,3 +16,8 @@ func (suite *TypesTestSuite) TestKeyOwnerAccount() { key := types.KeyOwnerAccount("port-id", "connection-id") suite.Require().Equal("owner/port-id/connection-id", string(key)) } + +func (suite *TypesTestSuite) TestKeyIsMiddlewareEnabled() { + key := types.KeyIsMiddlewareEnabled(ibctesting.MockPort, ibctesting.FirstChannelID) + suite.Require().Equal(fmt.Sprintf("%s/%s/%s", types.IsMiddlewareEnabledPrefix, ibctesting.MockPort, ibctesting.FirstChannelID), string(key)) +} diff --git a/modules/apps/27-interchain-accounts/types/metadata.go b/modules/apps/27-interchain-accounts/types/metadata.go index 148e5221f28..ee986a006f9 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.go +++ b/modules/apps/27-interchain-accounts/types/metadata.go @@ -1,10 +1,10 @@ package types import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) const ( @@ -67,11 +67,11 @@ func IsPreviousMetadataEqual(previousVersion string, metadata Metadata) bool { // ValidateControllerMetadata performs validation of the provided ICS27 controller metadata parameters func ValidateControllerMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connectionHops []string, metadata Metadata) error { if !isSupportedEncoding(metadata.Encoding) { - return sdkerrors.Wrapf(ErrInvalidCodec, "unsupported encoding format %s", metadata.Encoding) + return errorsmod.Wrapf(ErrInvalidCodec, "unsupported encoding format %s", metadata.Encoding) } if !isSupportedTxType(metadata.TxType) { - return sdkerrors.Wrapf(ErrUnknownDataType, "unsupported transaction type %s", metadata.TxType) + return errorsmod.Wrapf(ErrUnknownDataType, "unsupported transaction type %s", metadata.TxType) } connection, err := channelKeeper.GetConnection(ctx, connectionHops[0]) @@ -90,7 +90,7 @@ func ValidateControllerMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, co } if metadata.Version != Version { - return sdkerrors.Wrapf(ErrInvalidVersion, "expected %s, got %s", Version, metadata.Version) + return errorsmod.Wrapf(ErrInvalidVersion, "expected %s, got %s", Version, metadata.Version) } return nil @@ -99,11 +99,11 @@ func ValidateControllerMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, co // ValidateHostMetadata performs validation of the provided ICS27 host metadata parameters func ValidateHostMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connectionHops []string, metadata Metadata) error { if !isSupportedEncoding(metadata.Encoding) { - return sdkerrors.Wrapf(ErrInvalidCodec, "unsupported encoding format %s", metadata.Encoding) + return errorsmod.Wrapf(ErrInvalidCodec, "unsupported encoding format %s", metadata.Encoding) } if !isSupportedTxType(metadata.TxType) { - return sdkerrors.Wrapf(ErrUnknownDataType, "unsupported transaction type %s", metadata.TxType) + return errorsmod.Wrapf(ErrUnknownDataType, "unsupported transaction type %s", metadata.TxType) } connection, err := channelKeeper.GetConnection(ctx, connectionHops[0]) @@ -122,7 +122,7 @@ func ValidateHostMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connecti } if metadata.Version != Version { - return sdkerrors.Wrapf(ErrInvalidVersion, "expected %s, got %s", Version, metadata.Version) + return errorsmod.Wrapf(ErrInvalidVersion, "expected %s, got %s", Version, metadata.Version) } return nil @@ -163,11 +163,11 @@ func getSupportedTxTypes() []string { // validateConnectionParams compares the given the controller and host connection IDs to those set in the provided ICS27 Metadata func validateConnectionParams(metadata Metadata, controllerConnectionID, hostConnectionID string) error { if metadata.ControllerConnectionId != controllerConnectionID { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", controllerConnectionID, metadata.ControllerConnectionId) + return errorsmod.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", controllerConnectionID, metadata.ControllerConnectionId) } if metadata.HostConnectionId != hostConnectionID { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", hostConnectionID, metadata.HostConnectionId) + return errorsmod.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", hostConnectionID, metadata.HostConnectionId) } return nil diff --git a/modules/apps/27-interchain-accounts/types/metadata.pb.go b/modules/apps/27-interchain-accounts/types/metadata.pb.go index f1924453d83..38294e2732f 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.pb.go +++ b/modules/apps/27-interchain-accounts/types/metadata.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -128,26 +128,26 @@ var fileDescriptor_c29c32e397d1f21e = []byte{ // 349 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xcf, 0x4a, 0xeb, 0x40, 0x18, 0xc5, 0x9b, 0xde, 0x6b, 0x5b, 0x67, 0x25, 0x83, 0xe8, 0x58, 0x30, 0x95, 0xb8, 0xd0, 0x4d, - 0x33, 0x54, 0x45, 0xc1, 0x65, 0xc5, 0x85, 0x88, 0x9b, 0xe2, 0x4a, 0x90, 0x30, 0x99, 0x19, 0xd2, - 0x81, 0x64, 0xbe, 0x90, 0x99, 0x86, 0xf6, 0x2d, 0x7c, 0x03, 0x5f, 0xc7, 0x65, 0x97, 0xae, 0x8a, - 0xb4, 0x6f, 0xd0, 0x27, 0x90, 0xa4, 0xb5, 0xf5, 0xef, 0x2e, 0x27, 0xe7, 0x9c, 0xdf, 0xc7, 0x70, - 0xd0, 0xb9, 0x0a, 0x39, 0x65, 0x69, 0x1a, 0x2b, 0xce, 0xac, 0x02, 0x6d, 0xa8, 0xd2, 0x56, 0x66, - 0xbc, 0xcf, 0x94, 0x0e, 0x18, 0xe7, 0x30, 0xd0, 0xd6, 0xd0, 0xbc, 0x43, 0x13, 0x69, 0x99, 0x60, - 0x96, 0xf9, 0x69, 0x06, 0x16, 0xf0, 0x91, 0x0a, 0xb9, 0xff, 0xb9, 0xe7, 0xff, 0xd2, 0xf3, 0xf3, - 0x4e, 0x73, 0x3b, 0x82, 0x08, 0xca, 0x0e, 0x2d, 0xbe, 0x16, 0x75, 0xef, 0xb9, 0x8a, 0x1a, 0x77, - 0x4b, 0x22, 0x26, 0xa8, 0x9e, 0xcb, 0xcc, 0x28, 0xd0, 0xc4, 0x39, 0x70, 0x8e, 0x37, 0x7b, 0x1f, - 0x12, 0x3f, 0x22, 0xc2, 0x41, 0xdb, 0x0c, 0xe2, 0x58, 0x66, 0x01, 0x07, 0xad, 0x25, 0x2f, 0xae, - 0x05, 0x4a, 0x90, 0x6a, 0x11, 0xed, 0x1e, 0xce, 0x27, 0xad, 0xd6, 0x88, 0x25, 0xf1, 0xa5, 0xf7, - 0x57, 0xd2, 0xeb, 0xed, 0xac, 0xad, 0xab, 0x95, 0x73, 0x23, 0xf0, 0x2d, 0xc2, 0x7d, 0x30, 0xf6, - 0x1b, 0xf8, 0x5f, 0x09, 0xde, 0x9f, 0x4f, 0x5a, 0x7b, 0x0b, 0xf0, 0xcf, 0x8c, 0xd7, 0xdb, 0x2a, - 0x7e, 0x7e, 0x81, 0x11, 0x54, 0x67, 0x42, 0x64, 0xd2, 0x18, 0xf2, 0x7f, 0xf1, 0x8a, 0xa5, 0xc4, - 0x4d, 0xd4, 0x90, 0x9a, 0x83, 0x50, 0x3a, 0x22, 0x1b, 0xa5, 0xb5, 0xd2, 0x78, 0x17, 0xd5, 0xed, - 0x30, 0xb0, 0xa3, 0x54, 0x92, 0x5a, 0x69, 0xd5, 0xec, 0xf0, 0x7e, 0x94, 0xca, 0x6e, 0xf0, 0x32, - 0x75, 0x9d, 0xf1, 0xd4, 0x75, 0xde, 0xa6, 0xae, 0xf3, 0x34, 0x73, 0x2b, 0xe3, 0x99, 0x5b, 0x79, - 0x9d, 0xb9, 0x95, 0x87, 0xeb, 0x48, 0xd9, 0xfe, 0x20, 0xf4, 0x39, 0x24, 0x94, 0x83, 0x49, 0xc0, - 0x50, 0x15, 0xf2, 0x76, 0x04, 0x34, 0x3f, 0xa3, 0x09, 0x88, 0x41, 0x2c, 0x4d, 0x31, 0xa9, 0xa1, - 0x27, 0x17, 0xed, 0xf5, 0x2a, 0xed, 0xd5, 0x9a, 0xc5, 0x35, 0x13, 0xd6, 0xca, 0x25, 0x4e, 0xdf, - 0x03, 0x00, 0x00, 0xff, 0xff, 0x54, 0xa4, 0x03, 0x92, 0x02, 0x02, 0x00, 0x00, + 0x33, 0x54, 0xc1, 0x82, 0xcb, 0x8a, 0x0b, 0x11, 0x37, 0xc5, 0x95, 0x20, 0x61, 0x32, 0x33, 0xa4, + 0x03, 0xc9, 0x7c, 0x21, 0x33, 0x0d, 0xed, 0x5b, 0xf8, 0x06, 0xbe, 0x8e, 0xcb, 0x2e, 0x5d, 0x15, + 0x69, 0xdf, 0xa0, 0x4f, 0x20, 0x49, 0x6b, 0xeb, 0xdf, 0x5d, 0x4e, 0xce, 0x39, 0xbf, 0x8f, 0xe1, + 0xa0, 0x0b, 0x15, 0x72, 0xca, 0xd2, 0x34, 0x56, 0x9c, 0x59, 0x05, 0xda, 0x50, 0xa5, 0xad, 0xcc, + 0xf8, 0x80, 0x29, 0x1d, 0x30, 0xce, 0x61, 0xa8, 0xad, 0xa1, 0x79, 0x87, 0x26, 0xd2, 0x32, 0xc1, + 0x2c, 0xf3, 0xd3, 0x0c, 0x2c, 0xe0, 0x13, 0x15, 0x72, 0xff, 0x73, 0xcf, 0xff, 0xa5, 0xe7, 0xe7, + 0x9d, 0xe6, 0x6e, 0x04, 0x11, 0x94, 0x1d, 0x5a, 0x7c, 0x2d, 0xeb, 0xde, 0x73, 0x15, 0x35, 0xee, + 0x56, 0x44, 0x4c, 0x50, 0x3d, 0x97, 0x99, 0x51, 0xa0, 0x89, 0x73, 0xe4, 0x9c, 0x6e, 0xf7, 0x3f, + 0x24, 0x7e, 0x44, 0x84, 0x83, 0xb6, 0x19, 0xc4, 0xb1, 0xcc, 0x02, 0x0e, 0x5a, 0x4b, 0x5e, 0x5c, + 0x0b, 0x94, 0x20, 0xd5, 0x22, 0xda, 0x3b, 0x5e, 0x4c, 0x5b, 0xad, 0x31, 0x4b, 0xe2, 0x4b, 0xef, + 0xaf, 0xa4, 0xd7, 0xdf, 0xdb, 0x58, 0x57, 0x6b, 0xe7, 0x46, 0xe0, 0x5b, 0x84, 0x07, 0x60, 0xec, + 0x37, 0xf0, 0xbf, 0x12, 0x7c, 0xb8, 0x98, 0xb6, 0x0e, 0x96, 0xe0, 0x9f, 0x19, 0xaf, 0xbf, 0x53, + 0xfc, 0xfc, 0x02, 0x23, 0xa8, 0xce, 0x84, 0xc8, 0xa4, 0x31, 0xe4, 0xff, 0xf2, 0x15, 0x2b, 0x89, + 0x9b, 0xa8, 0x21, 0x35, 0x07, 0xa1, 0x74, 0x44, 0xb6, 0x4a, 0x6b, 0xad, 0xf1, 0x3e, 0xaa, 0xdb, + 0x51, 0x60, 0xc7, 0xa9, 0x24, 0xb5, 0xd2, 0xaa, 0xd9, 0xd1, 0xfd, 0x38, 0x95, 0xbd, 0xe0, 0x65, + 0xe6, 0x3a, 0x93, 0x99, 0xeb, 0xbc, 0xcd, 0x5c, 0xe7, 0x69, 0xee, 0x56, 0x26, 0x73, 0xb7, 0xf2, + 0x3a, 0x77, 0x2b, 0x0f, 0xd7, 0x91, 0xb2, 0x83, 0x61, 0xe8, 0x73, 0x48, 0x28, 0x07, 0x93, 0x80, + 0xa1, 0x2a, 0xe4, 0xed, 0x08, 0x68, 0xde, 0xa5, 0x09, 0x88, 0x61, 0x2c, 0x4d, 0x31, 0xa9, 0xa1, + 0x67, 0xdd, 0xf6, 0x66, 0x95, 0xf6, 0x7a, 0xcd, 0xe2, 0x9a, 0x09, 0x6b, 0xe5, 0x12, 0xe7, 0xef, + 0x01, 0x00, 0x00, 0xff, 0xff, 0xa0, 0xb6, 0x31, 0x17, 0x02, 0x02, 0x00, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/27-interchain-accounts/types/metadata_test.go b/modules/apps/27-interchain-accounts/types/metadata_test.go index 30b1e98f66a..c0274368e07 100644 --- a/modules/apps/27-interchain-accounts/types/metadata_test.go +++ b/modules/apps/27-interchain-accounts/types/metadata_test.go @@ -1,8 +1,8 @@ package types_test import ( - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) // use TestVersion as metadata being compared against diff --git a/modules/apps/27-interchain-accounts/types/packet.go b/modules/apps/27-interchain-accounts/types/packet.go index e7669a77fc9..f7d1c6648be 100644 --- a/modules/apps/27-interchain-accounts/types/packet.go +++ b/modules/apps/27-interchain-accounts/types/packet.go @@ -1,27 +1,42 @@ package types import ( + "time" + + errorsmod "cosmossdk.io/errors" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) // MaxMemoCharLength defines the maximum length for the InterchainAccountPacketData memo field const MaxMemoCharLength = 256 +var ( + // DefaultRelativePacketTimeoutHeight is the default packet timeout height (in blocks) relative + // to the current block height of the counterparty chain provided by the client state. The + // timeout is disabled when set to 0. + DefaultRelativePacketTimeoutHeight = "0-1000" + + // DefaultRelativePacketTimeoutTimestamp is the default packet timeout timestamp (in nanoseconds) + // relative to the current block timestamp of the counterparty chain provided by the client + // state. The timeout is disabled when set to 0. The default is currently set to a 10 minute + // timeout. + DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds()) +) + // ValidateBasic performs basic validation of the interchain account packet data. // The memo may be empty. func (iapd InterchainAccountPacketData) ValidateBasic() error { if iapd.Type == UNSPECIFIED { - return sdkerrors.Wrap(ErrInvalidOutgoingData, "packet data type cannot be unspecified") + return errorsmod.Wrap(ErrInvalidOutgoingData, "packet data type cannot be unspecified") } - if iapd.Data == nil { - return sdkerrors.Wrap(ErrInvalidOutgoingData, "packet data cannot be empty") + if len(iapd.Data) == 0 { + return errorsmod.Wrap(ErrInvalidOutgoingData, "packet data cannot be empty") } if len(iapd.Memo) > MaxMemoCharLength { - return sdkerrors.Wrapf(ErrInvalidOutgoingData, "packet data memo cannot be greater than %d characters", MaxMemoCharLength) + return errorsmod.Wrapf(ErrInvalidOutgoingData, "packet data memo cannot be greater than %d characters", MaxMemoCharLength) } return nil @@ -39,8 +54,8 @@ func (ct CosmosTx) GetBytes() []byte { // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (ct CosmosTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - for _, any := range ct.Messages { - err := unpacker.UnpackAny(any, new(sdk.Msg)) + for _, protoAny := range ct.Messages { + err := unpacker.UnpackAny(protoAny, new(sdk.Msg)) if err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/types/packet.pb.go b/modules/apps/27-interchain-accounts/types/packet.pb.go index faf353695d5..5a63e07f1eb 100644 --- a/modules/apps/27-interchain-accounts/types/packet.pb.go +++ b/modules/apps/27-interchain-accounts/types/packet.pb.go @@ -6,8 +6,8 @@ package types import ( fmt "fmt" types "github.com/cosmos/cosmos-sdk/codec/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -173,29 +173,29 @@ var fileDescriptor_89a080d7401cd393 = []byte{ // 393 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x51, 0x41, 0x8b, 0xd3, 0x40, 0x18, 0xcd, 0xb8, 0x41, 0xd6, 0x59, 0xd9, 0x2d, 0x61, 0x0f, 0x31, 0x42, 0x08, 0x2b, 0x62, 0x10, - 0x32, 0xe3, 0xd6, 0x82, 0x17, 0x2f, 0xb5, 0x8d, 0xd0, 0x8b, 0x94, 0x98, 0x42, 0xf5, 0x12, 0x26, + 0x32, 0xe3, 0x56, 0xa1, 0x17, 0x2f, 0xb5, 0x8d, 0xd0, 0x8b, 0x94, 0x98, 0x42, 0xf5, 0x12, 0x26, 0xd3, 0x31, 0x1d, 0x6c, 0x32, 0xa1, 0x33, 0x29, 0xe6, 0x1f, 0x94, 0x9e, 0xfc, 0x03, 0x3d, 0xf9, 0x67, 0x3c, 0xf6, 0xe8, 0x51, 0xda, 0x3f, 0x22, 0x99, 0x60, 0xdb, 0x83, 0x07, 0x6f, 0x8f, 0xc7, - 0xf7, 0xde, 0xf7, 0xbd, 0xef, 0xc1, 0x1e, 0x4f, 0x29, 0x26, 0x65, 0xb9, 0xe0, 0x94, 0x28, 0x2e, - 0x0a, 0x89, 0x79, 0xa1, 0xd8, 0x92, 0xce, 0x09, 0x2f, 0x12, 0x42, 0xa9, 0xa8, 0x0a, 0x25, 0xf1, - 0xea, 0x1e, 0x97, 0x84, 0x7e, 0x65, 0x0a, 0x95, 0x4b, 0xa1, 0x84, 0xf5, 0x82, 0xa7, 0x14, 0x9d, - 0xab, 0xd0, 0x3f, 0x54, 0x68, 0x75, 0xef, 0x3c, 0xc9, 0x84, 0xc8, 0x16, 0x0c, 0x6b, 0x59, 0x5a, - 0x7d, 0xc1, 0xa4, 0xa8, 0x5b, 0x0f, 0xe7, 0x36, 0x13, 0x99, 0xd0, 0x10, 0x37, 0xa8, 0x65, 0xef, - 0xd6, 0x00, 0x3e, 0x1d, 0x1d, 0xbd, 0xfa, 0xad, 0xd5, 0x58, 0xef, 0x1e, 0x12, 0x45, 0xac, 0x3e, - 0x34, 0x55, 0x5d, 0x32, 0x1b, 0x78, 0xc0, 0xbf, 0xee, 0x06, 0xe8, 0x3f, 0x0f, 0x41, 0x71, 0x5d, - 0xb2, 0x48, 0x4b, 0x2d, 0x0b, 0x9a, 0x33, 0xa2, 0x88, 0xfd, 0xc0, 0x03, 0xfe, 0xe3, 0x48, 0xe3, - 0x86, 0xcb, 0x59, 0x2e, 0xec, 0x0b, 0x0f, 0xf8, 0x8f, 0x22, 0x8d, 0xef, 0xde, 0xc2, 0xcb, 0x81, - 0x90, 0xb9, 0x90, 0xf1, 0x37, 0xeb, 0x15, 0xbc, 0xcc, 0x99, 0x94, 0x24, 0x63, 0xd2, 0x06, 0xde, - 0x85, 0x7f, 0xd5, 0xbd, 0x45, 0x6d, 0x34, 0xf4, 0x37, 0x1a, 0xea, 0x17, 0x75, 0x74, 0x9c, 0x7a, - 0x39, 0x85, 0x66, 0xb3, 0xd3, 0x7a, 0x0e, 0x3b, 0xf1, 0xa7, 0x71, 0x98, 0x4c, 0x3e, 0x7c, 0x1c, - 0x87, 0x83, 0xd1, 0xfb, 0x51, 0x38, 0xec, 0x18, 0xce, 0xcd, 0x66, 0xeb, 0x5d, 0x9d, 0x51, 0xd6, - 0x33, 0x78, 0xa3, 0xc7, 0xc2, 0x69, 0x38, 0x98, 0xc4, 0x61, 0x12, 0x4f, 0x3b, 0xc0, 0xb9, 0xde, - 0x6c, 0x3d, 0x78, 0x62, 0x1c, 0x73, 0xfd, 0xc3, 0x35, 0xde, 0x25, 0x3f, 0xf7, 0x2e, 0xd8, 0xed, - 0x5d, 0xf0, 0x7b, 0xef, 0x82, 0xef, 0x07, 0xd7, 0xd8, 0x1d, 0x5c, 0xe3, 0xd7, 0xc1, 0x35, 0x3e, - 0x87, 0x19, 0x57, 0xf3, 0x2a, 0x45, 0x54, 0xe4, 0x98, 0xea, 0xd3, 0x31, 0x4f, 0x69, 0x90, 0x09, - 0xbc, 0xea, 0xe1, 0x5c, 0xcc, 0xaa, 0x05, 0x93, 0x4d, 0xd9, 0x12, 0x77, 0xdf, 0x04, 0xa7, 0x47, + 0xf7, 0xde, 0xf7, 0xbd, 0xef, 0xc1, 0x37, 0x3c, 0xa5, 0x98, 0x94, 0xe5, 0x82, 0x53, 0xa2, 0xb8, + 0x28, 0x24, 0xe6, 0x85, 0x62, 0x4b, 0x3a, 0x27, 0xbc, 0x48, 0x08, 0xa5, 0xa2, 0x2a, 0x94, 0xc4, + 0xab, 0x7b, 0x5c, 0x12, 0xfa, 0x95, 0x29, 0x54, 0x2e, 0x85, 0x12, 0xd6, 0x0b, 0x9e, 0x52, 0x74, + 0xae, 0x42, 0xff, 0x50, 0xa1, 0xd5, 0xbd, 0xf3, 0x24, 0x13, 0x22, 0x5b, 0x30, 0xac, 0x65, 0x69, + 0xf5, 0x05, 0x93, 0xa2, 0x6e, 0x3d, 0x9c, 0xdb, 0x4c, 0x64, 0x42, 0x43, 0xdc, 0xa0, 0x96, 0xbd, + 0x5b, 0x03, 0xf8, 0x74, 0x74, 0xf4, 0xea, 0xb7, 0x56, 0x63, 0xbd, 0x7b, 0x48, 0x14, 0xb1, 0xfa, + 0xd0, 0x54, 0x75, 0xc9, 0x6c, 0xe0, 0x01, 0xff, 0xba, 0x1b, 0xa0, 0xff, 0x3c, 0x04, 0xc5, 0x75, + 0xc9, 0x22, 0x2d, 0xb5, 0x2c, 0x68, 0xce, 0x88, 0x22, 0xf6, 0x03, 0x0f, 0xf8, 0x8f, 0x23, 0x8d, + 0x1b, 0x2e, 0x67, 0xb9, 0xb0, 0x2f, 0x3c, 0xe0, 0x3f, 0x8a, 0x34, 0xbe, 0x7b, 0x0b, 0x2f, 0x07, + 0x42, 0xe6, 0x42, 0xc6, 0xdf, 0xac, 0x57, 0xf0, 0x32, 0x67, 0x52, 0x92, 0x8c, 0x49, 0x1b, 0x78, + 0x17, 0xfe, 0x55, 0xf7, 0x16, 0xb5, 0xd1, 0xd0, 0xdf, 0x68, 0xa8, 0x5f, 0xd4, 0xd1, 0x71, 0xea, + 0xe5, 0x14, 0x9a, 0xcd, 0x4e, 0xeb, 0x39, 0xec, 0xc4, 0x9f, 0xc6, 0x61, 0x32, 0xf9, 0xf0, 0x71, + 0x1c, 0x0e, 0x46, 0xef, 0x47, 0xe1, 0xb0, 0x63, 0x38, 0x37, 0x9b, 0xad, 0x77, 0x75, 0x46, 0x59, + 0xcf, 0xe0, 0x8d, 0x1e, 0x0b, 0xa7, 0xe1, 0x60, 0x12, 0x87, 0x49, 0x3c, 0xed, 0x00, 0xe7, 0x7a, + 0xb3, 0xf5, 0xe0, 0x89, 0x71, 0xcc, 0xf5, 0x0f, 0xd7, 0x78, 0x97, 0xfc, 0xdc, 0xbb, 0x60, 0xb7, + 0x77, 0xc1, 0xef, 0xbd, 0x0b, 0xbe, 0x1f, 0x5c, 0x63, 0x77, 0x70, 0x8d, 0x5f, 0x07, 0xd7, 0xf8, + 0x1c, 0x66, 0x5c, 0xcd, 0xab, 0x14, 0x51, 0x91, 0x63, 0xaa, 0x4f, 0xc7, 0x3c, 0xa5, 0x41, 0x26, + 0xf0, 0xaa, 0x87, 0x73, 0x31, 0xab, 0x16, 0x4c, 0x36, 0x65, 0x4b, 0xdc, 0xed, 0x05, 0xa7, 0x47, 0x05, 0xc7, 0x9e, 0x9b, 0xff, 0xc8, 0xf4, 0xa1, 0x8e, 0xf4, 0xfa, 0x4f, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xe7, 0xf5, 0x15, 0xdd, 0x1c, 0x02, 0x00, 0x00, + 0xff, 0x13, 0xe7, 0x27, 0x58, 0x1c, 0x02, 0x00, 0x00, } func (m *InterchainAccountPacketData) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/27-interchain-accounts/types/packet_test.go b/modules/apps/27-interchain-accounts/types/packet_test.go index bfbfa9d3802..329e5a837f4 100644 --- a/modules/apps/27-interchain-accounts/types/packet_test.go +++ b/modules/apps/27-interchain-accounts/types/packet_test.go @@ -1,7 +1,7 @@ package types_test import ( - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" ) var largeMemo = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum" @@ -40,6 +40,15 @@ func (suite *TypesTestSuite) TestValidateBasic() { }, { "empty data", + types.InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: []byte{}, + Memo: "memo", + }, + false, + }, + { + "nil data", types.InterchainAccountPacketData{ Type: types.EXECUTE_TX, Data: nil, diff --git a/modules/apps/27-interchain-accounts/types/port.go b/modules/apps/27-interchain-accounts/types/port.go index 54949b8a1c4..ee814279cf8 100644 --- a/modules/apps/27-interchain-accounts/types/port.go +++ b/modules/apps/27-interchain-accounts/types/port.go @@ -4,14 +4,14 @@ import ( "fmt" "strings" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // NewControllerPortID creates and returns a new prefixed controller port identifier using the provided owner string func NewControllerPortID(owner string) (string, error) { if strings.TrimSpace(owner) == "" { - return "", sdkerrors.Wrap(ErrInvalidAccountAddress, "owner address cannot be empty") + return "", errorsmod.Wrap(ErrInvalidAccountAddress, "owner address cannot be empty") } - return fmt.Sprint(PortPrefix, owner), nil + return fmt.Sprint(ControllerPortPrefix, owner), nil } diff --git a/modules/apps/27-interchain-accounts/types/port_test.go b/modules/apps/27-interchain-accounts/types/port_test.go index a5dc2532b60..0a64d517db9 100644 --- a/modules/apps/27-interchain-accounts/types/port_test.go +++ b/modules/apps/27-interchain-accounts/types/port_test.go @@ -3,8 +3,8 @@ package types_test import ( "fmt" - "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *TypesTestSuite) TestNewControllerPortID() { @@ -22,7 +22,7 @@ func (suite *TypesTestSuite) TestNewControllerPortID() { { "success", func() {}, - fmt.Sprint(types.PortPrefix, TestOwnerAddress), + fmt.Sprint(types.ControllerPortPrefix, TestOwnerAddress), true, }, { diff --git a/modules/apps/27-interchain-accounts/types/router.go b/modules/apps/27-interchain-accounts/types/router.go new file mode 100644 index 00000000000..007091b9d0d --- /dev/null +++ b/modules/apps/27-interchain-accounts/types/router.go @@ -0,0 +1,12 @@ +package types + +import ( + baseapp "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// MessageRouter ADR 031 request type routing +// https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-031-msg-service.md +type MessageRouter interface { + Handler(msg sdk.Msg) baseapp.MsgServiceHandler +} diff --git a/modules/apps/29-fee/client/cli/cli.go b/modules/apps/29-fee/client/cli/cli.go index 332493deec8..0fdeb0f398e 100644 --- a/modules/apps/29-fee/client/cli/cli.go +++ b/modules/apps/29-fee/client/cli/cli.go @@ -1,8 +1,9 @@ package cli import ( - "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" ) // GetQueryCmd returns the query commands for 29-fee diff --git a/modules/apps/29-fee/client/cli/query.go b/modules/apps/29-fee/client/cli/query.go index 815eec4d35b..5c57386668d 100644 --- a/modules/apps/29-fee/client/cli/query.go +++ b/modules/apps/29-fee/client/cli/query.go @@ -10,8 +10,8 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // GetCmdIncentivizedPacket returns the unrelayed incentivized packet for a given packetID @@ -34,7 +34,7 @@ func GetCmdIncentivizedPacket() *cobra.Command { return err } - packetID := channeltypes.NewPacketId(portID, channelID, seq) + packetID := channeltypes.NewPacketID(portID, channelID, seq) if err := packetID.Validate(); err != nil { return err @@ -122,7 +122,7 @@ func GetCmdTotalRecvFees() *cobra.Command { return err } - packetID := channeltypes.NewPacketId(portID, channelID, seq) + packetID := channeltypes.NewPacketID(portID, channelID, seq) if err := packetID.Validate(); err != nil { return err @@ -168,7 +168,7 @@ func GetCmdTotalAckFees() *cobra.Command { return err } - packetID := channeltypes.NewPacketId(portID, channelID, seq) + packetID := channeltypes.NewPacketID(portID, channelID, seq) if err := packetID.Validate(); err != nil { return err @@ -214,7 +214,7 @@ func GetCmdTotalTimeoutFees() *cobra.Command { return err } - packetID := channeltypes.NewPacketId(portID, channelID, seq) + packetID := channeltypes.NewPacketID(portID, channelID, seq) if err := packetID.Validate(); err != nil { return err diff --git a/modules/apps/29-fee/client/cli/tx.go b/modules/apps/29-fee/client/cli/tx.go index c31779c22f6..40d0f5e5c1c 100644 --- a/modules/apps/29-fee/client/cli/tx.go +++ b/modules/apps/29-fee/client/cli/tx.go @@ -12,8 +12,8 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) const ( @@ -95,7 +95,7 @@ func NewPayPacketFeeAsyncTxCmd() *cobra.Command { return err } - packetID := channeltypes.NewPacketId(args[0], args[1], seq) + packetID := channeltypes.NewPacketID(args[0], args[1], seq) recvFeeStr, err := cmd.Flags().GetString(flagRecvFee) if err != nil { diff --git a/modules/apps/29-fee/doc.go b/modules/apps/29-fee/doc.go new file mode 100644 index 00000000000..236b88b522c --- /dev/null +++ b/modules/apps/29-fee/doc.go @@ -0,0 +1,9 @@ +/* +Package fee implements the packet data structure, state machine handling logic, +and encoding details for handling fee payments on top of any ICS application protocol. +This implementation is based off the ICS 29 specification +(https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment) and follows +the middleware pattern specified in the ICS 30 specification +(https://github.com/cosmos/ibc/tree/main/spec/app/ics-030-middleware). +*/ +package fee diff --git a/modules/apps/29-fee/fee_test.go b/modules/apps/29-fee/fee_test.go index 33ac52a60b0..0505a186132 100644 --- a/modules/apps/29-fee/fee_test.go +++ b/modules/apps/29-fee/fee_test.go @@ -5,11 +5,11 @@ import ( "github.com/stretchr/testify/suite" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) type FeeTestSuite struct { diff --git a/modules/apps/29-fee/ibc_middleware.go b/modules/apps/29-fee/ibc_middleware.go index 2cbce3d2f9d..9ac7eec370c 100644 --- a/modules/apps/29-fee/ibc_middleware.go +++ b/modules/apps/29-fee/ibc_middleware.go @@ -3,15 +3,16 @@ package fee import ( "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/keeper" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var _ porttypes.Middleware = &IBCMiddleware{} @@ -61,7 +62,7 @@ func (im IBCMiddleware) OnChanOpenInit( } if versionMetadata.FeeVersion != types.Version { - return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion) + return "", errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion) } appVersion, err := im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, versionMetadata.AppVersion) @@ -103,7 +104,7 @@ func (im IBCMiddleware) OnChanOpenTry( } if versionMetadata.FeeVersion != types.Version { - return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion) + return "", errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion) } im.keeper.SetFeeEnabled(ctx, portID, channelID) @@ -136,11 +137,11 @@ func (im IBCMiddleware) OnChanOpenAck( if im.keeper.IsFeeEnabled(ctx, portID, channelID) { var versionMetadata types.Metadata if err := types.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &versionMetadata); err != nil { - return sdkerrors.Wrapf(err, "failed to unmarshal ICS29 counterparty version metadata: %s", counterpartyVersion) + return errorsmod.Wrapf(err, "failed to unmarshal ICS29 counterparty version metadata: %s", counterpartyVersion) } if versionMetadata.FeeVersion != types.Version { - return sdkerrors.Wrapf(types.ErrInvalidVersion, "expected counterparty fee version: %s, got: %s", types.Version, versionMetadata.FeeVersion) + return errorsmod.Wrapf(types.ErrInvalidVersion, "expected counterparty fee version: %s, got: %s", types.Version, versionMetadata.FeeVersion) } // call underlying app's OnChanOpenAck callback with the counterparty app version. @@ -226,7 +227,7 @@ func (im IBCMiddleware) OnRecvPacket( // in case of async aknowledgement (ack == nil) store the relayer address for use later during async WriteAcknowledgement if ack == nil { - im.keeper.SetRelayerAddressForAsyncAck(ctx, channeltypes.NewPacketId(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), relayer.String()) + im.keeper.SetRelayerAddressForAsyncAck(ctx, channeltypes.NewPacketID(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()), relayer.String()) return nil } @@ -248,9 +249,9 @@ func (im IBCMiddleware) OnAcknowledgementPacket( return im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) } - var ack = &types.IncentivizedAcknowledgement{} - if err := types.ModuleCdc.UnmarshalJSON(acknowledgement, ack); err != nil { - return sdkerrors.Wrapf(err, "cannot unmarshal ICS-29 incentivized packet acknowledgement: %v", ack) + var ack types.IncentivizedAcknowledgement + if err := types.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { + return errorsmod.Wrapf(err, "cannot unmarshal ICS-29 incentivized packet acknowledgement: %v", ack) } if im.keeper.IsLocked(ctx) { @@ -265,7 +266,7 @@ func (im IBCMiddleware) OnAcknowledgementPacket( return im.app.OnAcknowledgementPacket(ctx, packet, ack.AppAcknowledgement, relayer) } - packetID := channeltypes.NewPacketId(packet.SourcePort, packet.SourceChannel, packet.Sequence) + packetID := channeltypes.NewPacketID(packet.SourcePort, packet.SourceChannel, packet.Sequence) feesInEscrow, found := im.keeper.GetFeesInEscrow(ctx, packetID) if !found { // call underlying callback @@ -282,7 +283,7 @@ func (im IBCMiddleware) OnAcknowledgementPacket( payeeAddr, err := sdk.AccAddressFromBech32(payee) if err != nil { - return sdkerrors.Wrapf(err, "failed to create sdk.Address from payee: %s", payee) + return errorsmod.Wrapf(err, "failed to create sdk.Address from payee: %s", payee) } im.keeper.DistributePacketFeesOnAcknowledgement(ctx, ack.ForwardRelayerAddress, payeeAddr, feesInEscrow.PacketFees, packetID) @@ -307,7 +308,7 @@ func (im IBCMiddleware) OnTimeoutPacket( return im.app.OnTimeoutPacket(ctx, packet, relayer) } - packetID := channeltypes.NewPacketId(packet.SourcePort, packet.SourceChannel, packet.Sequence) + packetID := channeltypes.NewPacketID(packet.SourcePort, packet.SourceChannel, packet.Sequence) feesInEscrow, found := im.keeper.GetFeesInEscrow(ctx, packetID) if !found { // call underlying callback @@ -324,7 +325,7 @@ func (im IBCMiddleware) OnTimeoutPacket( payeeAddr, err := sdk.AccAddressFromBech32(payee) if err != nil { - return sdkerrors.Wrapf(err, "failed to create sdk.Address from payee: %s", payee) + return errorsmod.Wrapf(err, "failed to create sdk.Address from payee: %s", payee) } im.keeper.DistributePacketFeesOnTimeout(ctx, payeeAddr, feesInEscrow.PacketFees, packetID) @@ -337,9 +338,13 @@ func (im IBCMiddleware) OnTimeoutPacket( func (im IBCMiddleware) SendPacket( ctx sdk.Context, chanCap *capabilitytypes.Capability, - packet exported.PacketI, -) error { - return im.keeper.SendPacket(ctx, chanCap, packet) + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, +) (uint64, error) { + return im.keeper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) } // WriteAcknowledgement implements the ICS4 Wrapper interface diff --git a/modules/apps/29-fee/ibc_middleware_test.go b/modules/apps/29-fee/ibc_middleware_test.go index ea7cdcae8b6..0f1c1176210 100644 --- a/modules/apps/29-fee/ibc_middleware_test.go +++ b/modules/apps/29-fee/ibc_middleware_test.go @@ -6,14 +6,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - fee "github.com/cosmos/ibc-go/v4/modules/apps/29-fee" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" + fee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/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/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) var ( @@ -172,7 +172,8 @@ func (suite *FeeTestSuite) TestOnChanOpenTry() { // reset suite suite.SetupTest() suite.coordinator.SetupConnections(suite.path) - suite.path.EndpointB.ChanOpenInit() + err := suite.path.EndpointB.ChanOpenInit() + suite.Require().NoError(err) // setup mock callback suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanOpenTry = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string, @@ -188,7 +189,6 @@ func (suite *FeeTestSuite) TestOnChanOpenTry() { var ( chanCap *capabilitytypes.Capability ok bool - err error ) chanCap, err = suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID)) @@ -286,8 +286,10 @@ func (suite *FeeTestSuite) TestOnChanOpenAck() { // malleate test case tc.malleate(suite) - suite.path.EndpointA.ChanOpenInit() - suite.path.EndpointB.ChanOpenTry() + err := suite.path.EndpointA.ChanOpenInit() + suite.Require().NoError(err) + err = suite.path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.MockFeePort) suite.Require().NoError(err) @@ -331,7 +333,7 @@ func (suite *FeeTestSuite) TestOnChanCloseInit() { { "RefundFeesOnChannelClosure continues - invalid refund address", func() { // store the fee in state & update escrow account balance - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, "invalid refund address", nil)}) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), packetID, packetFees) @@ -360,7 +362,7 @@ func (suite *FeeTestSuite) TestOnChanCloseInit() { suite.SetupTest() suite.coordinator.Setup(suite.path) // setup channel - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) fee = types.Fee{ RecvFee: defaultRecvFee, AckFee: defaultAckFee, @@ -420,7 +422,7 @@ func (suite *FeeTestSuite) TestOnChanCloseConfirm() { { "RefundChannelFeesOnClosure continues - refund address is invalid", func() { // store the fee in state & update escrow account balance - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, "invalid refund address", nil)}) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), packetID, packetFees) @@ -450,7 +452,7 @@ func (suite *FeeTestSuite) TestOnChanCloseConfirm() { suite.SetupTest() suite.coordinator.Setup(suite.path) // setup channel - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) fee = types.Fee{ RecvFee: defaultRecvFee, AckFee: defaultAckFee, @@ -573,7 +575,7 @@ func (suite *FeeTestSuite) TestOnRecvPacket() { case tc.forwardRelayer && result == nil: suite.Require().Equal(nil, result) - packetID := channeltypes.NewPacketId(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) + packetID := channeltypes.NewPacketID(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) // retrieve the forward relayer that was stored in `onRecvPacket` relayer, _ := suite.chainB.GetSimApp().IBCFeeKeeper.GetRelayerAddressForAsyncAck(suite.chainB.GetContext(), packetID) @@ -787,7 +789,7 @@ func (suite *FeeTestSuite) TestOnAcknowledgementPacket() { refundAddr = suite.chainA.SenderAccounts[1].SenderAccount.GetAddress() packet := suite.CreateMockPacket() - packetID = channeltypes.NewPacketId(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + packetID = channeltypes.NewPacketID(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) packetFee = types.NewPacketFee(types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee), refundAddr.String(), nil) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), packetID, types.NewPacketFees([]types.PacketFee{packetFee})) @@ -973,7 +975,7 @@ func (suite *FeeTestSuite) TestOnTimeoutPacket() { refundAddr = suite.chainA.SenderAccounts[1].SenderAccount.GetAddress() packet := suite.CreateMockPacket() - packetID = channeltypes.NewPacketId(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + packetID = channeltypes.NewPacketID(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) packetFee = types.NewPacketFee(types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee), refundAddr.String(), nil) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), packetID, types.NewPacketFees([]types.PacketFee{packetFee})) diff --git a/modules/apps/29-fee/ica_test.go b/modules/apps/29-fee/ica_test.go index bc10f4941dd..b8034b78914 100644 --- a/modules/apps/29-fee/ica_test.go +++ b/modules/apps/29-fee/ica_test.go @@ -4,23 +4,24 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/gogoproto/proto" + + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) var ( // defaultOwnerAddress defines a reusable bech32 address for testing purposes defaultOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" - // defaultPortID defines a resuable port identifier for testing purposes + // defaultPortID defines a reusable port identifier for testing purposes defaultPortID, _ = icatypes.NewControllerPortID(defaultOwnerAddress) - // defaultICAVersion defines a resuable interchainaccounts version string for testing purposes + // defaultICAVersion defines a reusable interchainaccounts version string for testing purposes defaultICAVersion = icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) ) @@ -39,7 +40,7 @@ func NewIncentivizedICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Pa path.EndpointA.ChannelConfig.Version = feeICAVersion path.EndpointB.ChannelConfig.Version = feeICAVersion path.EndpointA.ChannelConfig.PortID = defaultPortID - path.EndpointB.ChannelConfig.PortID = icatypes.PortID + path.EndpointB.ChannelConfig.PortID = icatypes.HostPortID return path } @@ -118,7 +119,7 @@ func (suite *FeeTestSuite) TestFeeInterchainAccounts() { postEscrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom) suite.Require().Equal(postEscrowBalance.AddAmount(expectedFee.Total().AmountOf(sdk.DefaultBondDenom)), preEscrowBalance) - packetID := channeltypes.NewPacketId(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1) packetFees, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetFeesInEscrow(suite.chainA.GetContext(), packetID) suite.Require().True(found) suite.Require().Equal(expectedFee, packetFees.PacketFees[0].Fee) @@ -146,7 +147,7 @@ func (suite *FeeTestSuite) TestFeeInterchainAccounts() { Amount: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(5000)), } - data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []sdk.Msg{msgDelegate}) + data, err := icatypes.SerializeCosmosTx(suite.chainA.GetSimApp().AppCodec(), []proto.Message{msgDelegate}) suite.Require().NoError(err) icaPacketData := icatypes.InterchainAccountPacketData{ @@ -189,7 +190,7 @@ func buildInterchainAccountsPacket(path *ibctesting.Path, data []byte, seq uint6 path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, - clienttypes.NewHeight(0, 100), + clienttypes.NewHeight(1, 100), 0, ) diff --git a/modules/apps/29-fee/keeper/escrow.go b/modules/apps/29-fee/keeper/escrow.go index fed2398f142..8f3f8bd417f 100644 --- a/modules/apps/29-fee/keeper/escrow.go +++ b/modules/apps/29-fee/keeper/escrow.go @@ -4,11 +4,11 @@ import ( "bytes" "fmt" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // escrowPacketFee sends the packet fee to the 29-fee module account to hold in escrow @@ -21,7 +21,7 @@ func (k Keeper) escrowPacketFee(ctx sdk.Context, packetID channeltypes.PacketId, refundAcc := k.authKeeper.GetAccount(ctx, refundAddr) if refundAcc == nil { - return sdkerrors.Wrapf(types.ErrRefundAccNotFound, "account with address: %s not found", packetFee.RefundAddress) + return errorsmod.Wrapf(types.ErrRefundAccNotFound, "account with address: %s not found", packetFee.RefundAddress) } coins := packetFee.Fee.Total() @@ -39,7 +39,7 @@ func (k Keeper) escrowPacketFee(ctx sdk.Context, packetID channeltypes.PacketId, packetFees := types.NewPacketFees(fees) k.SetFeesInEscrow(ctx, packetID, packetFees) - EmitIncentivizedPacketEvent(ctx, packetID, packetFees) + emitIncentivizedPacketEvent(ctx, packetID, packetFees) return nil } @@ -74,9 +74,6 @@ func (k Keeper) DistributePacketFeesOnAcknowledgement(ctx sdk.Context, forwardRe k.distributePacketFeeOnAcknowledgement(cacheCtx, refundAddr, forwardAddr, reverseRelayer, packetFee) } - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - // write the cache writeFn() @@ -130,9 +127,6 @@ func (k Keeper) DistributePacketFeesOnTimeout(ctx sdk.Context, timeoutRelayer sd k.distributePacketFeeOnTimeout(cacheCtx, refundAddr, timeoutRelayer, packetFee) } - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - // write the cache writeFn() @@ -173,13 +167,14 @@ func (k Keeper) distributeFee(ctx sdk.Context, receiver, refundAccAddress sdk.Ac k.Logger(ctx).Error("error refunding fee to the original sender", "refund address", refundAccAddress, "fee", fee) return // if sending to the refund address fails, no-op } + + emitDistributeFeeEvent(ctx, refundAccAddress.String(), fee) + } else { + emitDistributeFeeEvent(ctx, receiver.String(), fee) } // write the cache writeFn() - - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) } // RefundFeesOnChannelClosure will refund all fees associated with the given port and channel identifiers. @@ -228,9 +223,6 @@ func (k Keeper) RefundFeesOnChannelClosure(ctx sdk.Context, portID, channelID st } } - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - // write the cache writeFn() diff --git a/modules/apps/29-fee/keeper/escrow_test.go b/modules/apps/29-fee/keeper/escrow_test.go index b1891e4e4e4..af0ce95902e 100644 --- a/modules/apps/29-fee/keeper/escrow_test.go +++ b/modules/apps/29-fee/keeper/escrow_test.go @@ -4,10 +4,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/crypto/secp256k1" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/testing/mock" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/testing/mock" ) func (suite *KeeperTestSuite) TestDistributeFee() { @@ -36,7 +36,7 @@ func (suite *KeeperTestSuite) TestDistributeFee() { }, func() { // check if fees has been deleted - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) suite.Require().False(suite.chainA.GetSimApp().IBCFeeKeeper.HasFeesInEscrow(suite.chainA.GetContext(), packetID)) // check if the reverse relayer is paid @@ -76,7 +76,7 @@ func (suite *KeeperTestSuite) TestDistributeFee() { }, func() { // check if the refund acc has been refunded the timeoutFee - expectedRefundAccBal := defaultTimeoutFee[0].Add(defaultTimeoutFee[0]) + expectedRefundAccBal := refundAccBal.Add(defaultTimeoutFee[0]).Add(defaultTimeoutFee[0]) balance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), refundAcc, sdk.DefaultBondDenom) suite.Require().Equal(expectedRefundAccBal, balance) }, @@ -90,7 +90,7 @@ func (suite *KeeperTestSuite) TestDistributeFee() { packetFees = append(packetFees, packetFee) }, func() { - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) suite.Require().True(suite.chainA.GetSimApp().IBCFeeKeeper.IsLocked(suite.chainA.GetContext())) suite.Require().True(suite.chainA.GetSimApp().IBCFeeKeeper.HasFeesInEscrow(suite.chainA.GetContext(), packetID)) @@ -176,7 +176,7 @@ func (suite *KeeperTestSuite) TestDistributeFee() { reverseRelayer = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) refundAcc = suite.chainA.SenderAccount.GetAddress() - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) fee = types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) tc.malleate() @@ -238,7 +238,7 @@ func (suite *KeeperTestSuite) TestDistributePacketFeesOnTimeout() { packetFees = append(packetFees, packetFee) }, func() { - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) suite.Require().True(suite.chainA.GetSimApp().IBCFeeKeeper.IsLocked(suite.chainA.GetContext())) suite.Require().True(suite.chainA.GetSimApp().IBCFeeKeeper.HasFeesInEscrow(suite.chainA.GetContext(), packetID)) @@ -287,7 +287,7 @@ func (suite *KeeperTestSuite) TestDistributePacketFeesOnTimeout() { timeoutRelayer = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) refundAcc = suite.chainA.SenderAccount.GetAddress() - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) // escrow the packet fees & store the fees in state @@ -331,7 +331,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { "success", func() { for i := 1; i < 6; i++ { // store the fee in state & update escrow account balance - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(i)) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(i)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, refundAcc.String(), nil)}) identifiedPacketFees := types.NewIdentifiedPacketFees(packetID, packetFees.PacketFees) @@ -348,7 +348,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { "success with undistributed packet fees on a different channel", func() { for i := 1; i < 6; i++ { // store the fee in state & update escrow account balance - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(i)) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(i)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, refundAcc.String(), nil)}) identifiedPacketFees := types.NewIdentifiedPacketFees(packetID, packetFees.PacketFees) @@ -361,7 +361,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { } // set packet fee for a different channel - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, "channel-1", uint64(1)) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, "channel-1", uint64(1)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, refundAcc.String(), nil)}) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), suite.path.EndpointA.ChannelConfig.PortID, "channel-1") @@ -370,7 +370,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { suite.Require().NoError(err) expEscrowBal = fee.Total() - expRefundBal = expRefundBal.Sub(fee.Total()) + expRefundBal = expRefundBal.Sub(fee.Total()...) }, true, }, { @@ -378,7 +378,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { locked = true // store the fee in state without updating escrow account balance - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, refundAcc.String(), nil)}) identifiedPacketFees := types.NewIdentifiedPacketFees(packetID, packetFees.PacketFees) @@ -393,8 +393,8 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { locked = true // store 2 fees in state - packetID1 := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) - packetID2 := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(2)) + packetID1 := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) + packetID2 := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(2)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, refundAcc.String(), nil)}) identifiedPacketFee1 := types.NewIdentifiedPacketFees(packetID1, packetFees.PacketFees) identifiedPacketFee2 := types.NewIdentifiedPacketFees(packetID2, packetFees.PacketFees) @@ -413,7 +413,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { "invalid refund acc address", func() { // store the fee in state & update escrow account balance expectEscrowFeesToBeDeleted = false - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, "invalid refund address", nil)}) identifiedPacketFees := types.NewIdentifiedPacketFees(packetID, packetFees.PacketFees) @@ -425,7 +425,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { expIdentifiedPacketFees = []types.IdentifiedPacketFees{identifiedPacketFees} expEscrowBal = fee.Total() - expRefundBal = expRefundBal.Sub(fee.Total()) + expRefundBal = expRefundBal.Sub(fee.Total()...) }, true, }, { @@ -434,7 +434,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { blockedAddr := suite.chainA.GetSimApp().AccountKeeper.GetModuleAccount(suite.chainA.GetContext(), transfertypes.ModuleName).GetAddress().String() // store the fee in state & update escrow account balance - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, uint64(1)) packetFees := types.NewPacketFees([]types.PacketFee{types.NewPacketFee(fee, blockedAddr, nil)}) identifiedPacketFees := types.NewIdentifiedPacketFees(packetID, packetFees.PacketFees) @@ -446,7 +446,7 @@ func (suite *KeeperTestSuite) TestRefundFeesOnChannelClosure() { expIdentifiedPacketFees = []types.IdentifiedPacketFees{identifiedPacketFees} expEscrowBal = fee.Total() - expRefundBal = expRefundBal.Sub(fee.Total()) + expRefundBal = expRefundBal.Sub(fee.Total()...) }, true, }, } diff --git a/modules/apps/29-fee/keeper/events.go b/modules/apps/29-fee/keeper/events.go index 162542f4e4d..e367482649e 100644 --- a/modules/apps/29-fee/keeper/events.go +++ b/modules/apps/29-fee/keeper/events.go @@ -5,13 +5,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) -// EmitIncentivizedPacketEvent emits an event containing information on the total amount of fees incentivizing +// emitIncentivizedPacketEvent emits an event containing information on the total amount of fees incentivizing // a specific packet. It should be emitted on every fee escrowed for the given packetID. -func EmitIncentivizedPacketEvent(ctx sdk.Context, packetID channeltypes.PacketId, packetFees types.PacketFees) { +func emitIncentivizedPacketEvent(ctx sdk.Context, packetID channeltypes.PacketId, packetFees types.PacketFees) { var ( totalRecvFees sdk.Coins totalAckFees sdk.Coins @@ -44,8 +44,8 @@ func EmitIncentivizedPacketEvent(ctx sdk.Context, packetID channeltypes.PacketId }) } -// EmitRegisterPayeeEvent emits an event containing information of a registered payee for a relayer on a particular channel -func EmitRegisterPayeeEvent(ctx sdk.Context, relayer, payee, channelID string) { +// emitRegisterPayeeEvent emits an event containing information of a registered payee for a relayer on a particular channel +func emitRegisterPayeeEvent(ctx sdk.Context, relayer, payee, channelID string) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeRegisterPayee, @@ -60,8 +60,8 @@ func EmitRegisterPayeeEvent(ctx sdk.Context, relayer, payee, channelID string) { }) } -// EmitRegisterCounterpartyPayeeEvent emits an event containing information of a registered counterparty payee for a relayer on a particular channel -func EmitRegisterCounterpartyPayeeEvent(ctx sdk.Context, relayer, counterpartyPayee, channelID string) { +// emitRegisterCounterpartyPayeeEvent emits an event containing information of a registered counterparty payee for a relayer on a particular channel +func emitRegisterCounterpartyPayeeEvent(ctx sdk.Context, relayer, counterpartyPayee, channelID string) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeRegisterCounterpartyPayee, @@ -75,3 +75,18 @@ func EmitRegisterCounterpartyPayeeEvent(ctx sdk.Context, relayer, counterpartyPa ), }) } + +// emitDistributeFeeEvent emits an event containing a distribution fee and receiver address +func emitDistributeFeeEvent(ctx sdk.Context, receiver string, fee sdk.Coins) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeDistributeFee, + sdk.NewAttribute(types.AttributeKeyReceiver, receiver), + sdk.NewAttribute(types.AttributeKeyFee, fee.String()), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), + ), + }) +} diff --git a/modules/apps/29-fee/keeper/events_test.go b/modules/apps/29-fee/keeper/events_test.go index 2dc1f8c91c4..4fd2b6c62cb 100644 --- a/modules/apps/29-fee/keeper/events_test.go +++ b/modules/apps/29-fee/keeper/events_test.go @@ -4,7 +4,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" abcitypes "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestIncentivizePacketEvent() { @@ -40,15 +45,15 @@ func (suite *KeeperTestSuite) TestIncentivizePacketEvent() { } for _, attr := range incentivizedPacketEvent.Attributes { - switch string(attr.Key) { + switch attr.Key { case types.AttributeKeyRecvFee: - suite.Require().Equal(expRecvFees.String(), string(attr.Value)) + suite.Require().Equal(expRecvFees.String(), attr.Value) case types.AttributeKeyAckFee: - suite.Require().Equal(expAckFees.String(), string(attr.Value)) + suite.Require().Equal(expAckFees.String(), attr.Value) case types.AttributeKeyTimeoutFee: - suite.Require().Equal(expTimeoutFees.String(), string(attr.Value)) + suite.Require().Equal(expTimeoutFees.String(), attr.Value) } } @@ -69,15 +74,95 @@ func (suite *KeeperTestSuite) TestIncentivizePacketEvent() { } for _, attr := range incentivizedPacketEvent.Attributes { - switch string(attr.Key) { + switch attr.Key { case types.AttributeKeyRecvFee: - suite.Require().Equal(expRecvFees.String(), string(attr.Value)) + suite.Require().Equal(expRecvFees.String(), attr.Value) case types.AttributeKeyAckFee: - suite.Require().Equal(expAckFees.String(), string(attr.Value)) + suite.Require().Equal(expAckFees.String(), attr.Value) case types.AttributeKeyTimeoutFee: - suite.Require().Equal(expTimeoutFees.String(), string(attr.Value)) + suite.Require().Equal(expTimeoutFees.String(), attr.Value) } } } + +func (suite *KeeperTestSuite) TestDistributeFeeEvent() { + // create an incentivized transfer path + path := ibctesting.NewPath(suite.chainA, suite.chainB) + feeTransferVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: transfertypes.Version})) + path.EndpointA.ChannelConfig.Version = feeTransferVersion + path.EndpointB.ChannelConfig.Version = feeTransferVersion + path.EndpointA.ChannelConfig.PortID = transfertypes.PortID + path.EndpointB.ChannelConfig.PortID = transfertypes.PortID + + suite.coordinator.Setup(path) + + // send a new MsgPayPacketFee and MsgTransfer to chainA + fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) + msgPayPacketFee := types.NewMsgPayPacketFee( + fee, + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + suite.chainA.SenderAccount.GetAddress().String(), + nil, + ) + + msgTransfer := transfertypes.NewMsgTransfer( + path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, + sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), + clienttypes.NewHeight(1, 100), 0, "", + ) + + res, err := suite.chainA.SendMsgs(msgPayPacketFee, msgTransfer) + suite.Require().NoError(err) + suite.Require().NotNil(res) + + // parse the packet from result events and recv packet on chainB + packet, err := ibctesting.ParsePacketFromEvents(res.GetEvents()) + suite.Require().NoError(err) + suite.Require().NotNil(packet) + + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + res, err = path.EndpointB.RecvPacketWithResult(packet) + suite.Require().NoError(err) + suite.Require().NotNil(res) + + // parse the acknowledgement from result events and acknowledge packet on chainA + ack, err := ibctesting.ParseAckFromEvents(res.GetEvents()) + suite.Require().NoError(err) + suite.Require().NotNil(ack) + + packetKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) + proof, proofHeight := path.EndpointA.Counterparty.QueryProof(packetKey) + + msgAcknowledgement := channeltypes.NewMsgAcknowledgement(packet, ack, proof, proofHeight, path.EndpointA.Chain.SenderAccount.GetAddress().String()) + res, err = suite.chainA.SendMsgs(msgAcknowledgement) + suite.Require().NoError(err) + suite.Require().NotNil(res) + + events := res.GetEvents() + expectedEvents := sdk.Events{ + sdk.NewEvent( + types.EventTypeDistributeFee, + sdk.NewAttribute(types.AttributeKeyReceiver, suite.chainA.SenderAccount.GetAddress().String()), + sdk.NewAttribute(types.AttributeKeyFee, defaultRecvFee.String()), + ), + sdk.NewEvent( + types.EventTypeDistributeFee, + sdk.NewAttribute(types.AttributeKeyReceiver, suite.chainA.SenderAccount.GetAddress().String()), + sdk.NewAttribute(types.AttributeKeyFee, defaultAckFee.String()), + ), + sdk.NewEvent( + types.EventTypeDistributeFee, + sdk.NewAttribute(types.AttributeKeyReceiver, suite.chainA.SenderAccount.GetAddress().String()), + sdk.NewAttribute(types.AttributeKeyFee, defaultTimeoutFee.String()), + ), + } + + for _, evt := range expectedEvents { + suite.Require().Contains(events, evt) + } +} diff --git a/modules/apps/29-fee/keeper/genesis.go b/modules/apps/29-fee/keeper/genesis.go index 150058a734e..256b444e006 100644 --- a/modules/apps/29-fee/keeper/genesis.go +++ b/modules/apps/29-fee/keeper/genesis.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ) // InitGenesis initializes the fee middleware application state from a provided genesis state diff --git a/modules/apps/29-fee/keeper/genesis_test.go b/modules/apps/29-fee/keeper/genesis_test.go index 4aebd5121a9..b2359fc17b0 100644 --- a/modules/apps/29-fee/keeper/genesis_test.go +++ b/modules/apps/29-fee/keeper/genesis_test.go @@ -1,13 +1,13 @@ package keeper_test import ( - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestInitGenesis() { - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) genesisState := types.GenesisState{ IdentifiedFees: []types.IdentifiedPacketFees{ @@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestExportGenesis() { // setup & escrow the packet fee refundAcc := suite.chainA.SenderAccount.GetAddress() - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, refundAcc.String(), []string{}) diff --git a/modules/apps/29-fee/keeper/grpc_query.go b/modules/apps/29-fee/keeper/grpc_query.go index 3f92686f51f..021459e864a 100644 --- a/modules/apps/29-fee/keeper/grpc_query.go +++ b/modules/apps/29-fee/keeper/grpc_query.go @@ -3,14 +3,14 @@ package keeper import ( "context" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ) var _ types.QueryServer = Keeper{} @@ -25,7 +25,7 @@ func (k Keeper) IncentivizedPackets(goCtx context.Context, req *types.QueryIncen var identifiedPackets []types.IdentifiedPacketFees store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte(types.FeesInEscrowPrefix)) - _, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { + pagination, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { packetID, err := types.ParseKeyFeesInEscrow(types.FeesInEscrowPrefix + string(key)) if err != nil { return err @@ -41,6 +41,7 @@ func (k Keeper) IncentivizedPackets(goCtx context.Context, req *types.QueryIncen return &types.QueryIncentivizedPacketsResponse{ IncentivizedPackets: identifiedPackets, + Pagination: pagination, }, nil } @@ -56,7 +57,7 @@ func (k Keeper) IncentivizedPacket(goCtx context.Context, req *types.QueryIncent if !exists { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error()) + errorsmod.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error()) } return &types.QueryIncentivizedPacketResponse{ @@ -75,7 +76,7 @@ func (k Keeper) IncentivizedPacketsForChannel(goCtx context.Context, req *types. var packets []*types.IdentifiedPacketFees keyPrefix := types.KeyFeesInEscrowChannelPrefix(req.PortId, req.ChannelId) store := prefix.NewStore(ctx.KVStore(k.storeKey), keyPrefix) - _, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { + pagination, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { packetID, err := types.ParseKeyFeesInEscrow(string(keyPrefix) + string(key)) if err != nil { return err @@ -94,6 +95,7 @@ func (k Keeper) IncentivizedPacketsForChannel(goCtx context.Context, req *types. return &types.QueryIncentivizedPacketsForChannelResponse{ IncentivizedPackets: packets, + Pagination: pagination, }, nil } @@ -105,7 +107,7 @@ func (k Keeper) TotalRecvFees(goCtx context.Context, req *types.QueryTotalRecvFe if !found { return nil, status.Errorf( codes.NotFound, - sdkerrors.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error(), + errorsmod.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error(), ) } @@ -131,7 +133,7 @@ func (k Keeper) TotalAckFees(goCtx context.Context, req *types.QueryTotalAckFees if !found { return nil, status.Errorf( codes.NotFound, - sdkerrors.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error(), + errorsmod.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error(), ) } @@ -157,7 +159,7 @@ func (k Keeper) TotalTimeoutFees(goCtx context.Context, req *types.QueryTotalTim if !found { return nil, status.Errorf( codes.NotFound, - sdkerrors.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error(), + errorsmod.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error(), ) } @@ -217,7 +219,7 @@ func (k Keeper) FeeEnabledChannels(goCtx context.Context, req *types.QueryFeeEna var feeEnabledChannels []types.FeeEnabledChannel store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte(types.FeeEnabledKeyPrefix)) - _, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { + pagination, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { portID, channelID, err := types.ParseKeyFeeEnabled(types.FeeEnabledKeyPrefix + string(key)) if err != nil { return err @@ -238,6 +240,7 @@ func (k Keeper) FeeEnabledChannels(goCtx context.Context, req *types.QueryFeeEna return &types.QueryFeeEnabledChannelsResponse{ FeeEnabledChannels: feeEnabledChannels, + Pagination: pagination, }, nil } diff --git a/modules/apps/29-fee/keeper/grpc_query_test.go b/modules/apps/29-fee/keeper/grpc_query_test.go index 1286f3c3350..a90b6e829a9 100644 --- a/modules/apps/29-fee/keeper/grpc_query_test.go +++ b/modules/apps/29-fee/keeper/grpc_query_test.go @@ -7,9 +7,9 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" "github.com/tendermint/tendermint/crypto/secp256k1" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestQueryIncentivizedPackets() { @@ -33,7 +33,7 @@ func (suite *KeeperTestSuite) TestQueryIncentivizedPackets() { for i := 0; i < 3; i++ { // escrow packet fees for three different packets - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, uint64(i+1)) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, uint64(i+1)) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), packetID, types.NewPacketFees([]types.PacketFee{packetFee})) expectedPackets = append(expectedPackets, types.NewIdentifiedPacketFees(packetID, []types.PacketFee{packetFee})) @@ -96,7 +96,7 @@ func (suite *KeeperTestSuite) TestQueryIncentivizedPacket() { "fees not found for packet id", func() { req = &types.QueryIncentivizedPacketRequest{ - PacketId: channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 100), + PacketId: channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 100), QueryHeight: 0, } }, @@ -110,7 +110,7 @@ func (suite *KeeperTestSuite) TestQueryIncentivizedPacket() { suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), ibctesting.MockFeePort, ibctesting.FirstChannelID) - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), []string(nil)) @@ -205,9 +205,9 @@ func (suite *KeeperTestSuite) TestQueryIncentivizedPacketsForChannel() { packetFee := types.NewPacketFee(fee, refundAcc.String(), nil) packetFees := types.NewPacketFees([]types.PacketFee{packetFee, packetFee, packetFee}) - identifiedFees1 := types.NewIdentifiedPacketFees(channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1), packetFees.PacketFees) - identifiedFees2 := types.NewIdentifiedPacketFees(channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 2), packetFees.PacketFees) - identifiedFees3 := types.NewIdentifiedPacketFees(channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 3), packetFees.PacketFees) + identifiedFees1 := types.NewIdentifiedPacketFees(channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1), packetFees.PacketFees) + identifiedFees2 := types.NewIdentifiedPacketFees(channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 2), packetFees.PacketFees) + identifiedFees3 := types.NewIdentifiedPacketFees(channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 3), packetFees.PacketFees) expIdentifiedPacketFees = append(expIdentifiedPacketFees, &identifiedFees1, &identifiedFees2, &identifiedFees3) @@ -248,7 +248,7 @@ func (suite *KeeperTestSuite) TestQueryTotalRecvFees() { { "packet not found", func() { - req.PacketId = channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 100) + req.PacketId = channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 100) }, false, }, @@ -260,7 +260,7 @@ func (suite *KeeperTestSuite) TestQueryTotalRecvFees() { suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), ibctesting.MockFeePort, ibctesting.FirstChannelID) - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), []string(nil)) @@ -307,7 +307,7 @@ func (suite *KeeperTestSuite) TestQueryTotalAckFees() { { "packet not found", func() { - req.PacketId = channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 100) + req.PacketId = channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 100) }, false, }, @@ -319,7 +319,7 @@ func (suite *KeeperTestSuite) TestQueryTotalAckFees() { suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), ibctesting.MockFeePort, ibctesting.FirstChannelID) - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), []string(nil)) @@ -366,7 +366,7 @@ func (suite *KeeperTestSuite) TestQueryTotalTimeoutFees() { { "packet not found", func() { - req.PacketId = channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 100) + req.PacketId = channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 100) }, false, }, @@ -378,7 +378,7 @@ func (suite *KeeperTestSuite) TestQueryTotalTimeoutFees() { suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), ibctesting.MockFeePort, ibctesting.FirstChannelID) - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), []string(nil)) @@ -425,14 +425,14 @@ func (suite *KeeperTestSuite) TestQueryPayee() { { "payee address not found: invalid channel", func() { - req.ChannelId = "invalid-channel-id" + req.ChannelId = "invalid-channel-id" //nolint:goconst }, false, }, { "payee address not found: invalid relayer address", func() { - req.Relayer = "invalid-addr" + req.Relayer = "invalid-addr" //nolint:goconst }, false, }, diff --git a/modules/apps/29-fee/keeper/keeper.go b/modules/apps/29-fee/keeper/keeper.go index c60942debea..e2c1691041e 100644 --- a/modules/apps/29-fee/keeper/keeper.go +++ b/modules/apps/29-fee/keeper/keeper.go @@ -2,14 +2,15 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // Middleware must implement types.ChannelKeeper and types.PortKeeper expected interfaces @@ -21,11 +22,11 @@ var ( // Keeper defines the IBC fungible transfer keeper type Keeper struct { - storeKey sdk.StoreKey + storeKey storetypes.StoreKey cdc codec.BinaryCodec authKeeper types.AccountKeeper - ics4Wrapper types.ICS4Wrapper + ics4Wrapper porttypes.ICS4Wrapper channelKeeper types.ChannelKeeper portKeeper types.PortKeeper bankKeeper types.BankKeeper @@ -33,8 +34,9 @@ type Keeper struct { // NewKeeper creates a new 29-fee Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Subspace, - ics4Wrapper types.ICS4Wrapper, channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, + cdc codec.BinaryCodec, key storetypes.StoreKey, + ics4Wrapper porttypes.ICS4Wrapper, channelKeeper types.ChannelKeeper, + portKeeper types.PortKeeper, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, ) Keeper { return Keeper{ cdc: cdc, @@ -49,7 +51,7 @@ func NewKeeper( // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+host.ModuleName+"-"+types.ModuleName) + return ctx.Logger().With("module", "x/"+ibcexported.ModuleName+"-"+types.ModuleName) } // BindPort defines a wrapper function for the port Keeper's function in @@ -121,14 +123,14 @@ func (k Keeper) DeleteFeeEnabled(ctx sdk.Context, portID, channelID string) { // fee enabled flag for the given port and channel identifiers func (k Keeper) IsFeeEnabled(ctx sdk.Context, portID, channelID string) bool { store := ctx.KVStore(k.storeKey) - return store.Get(types.KeyFeeEnabled(portID, channelID)) != nil + return store.Has(types.KeyFeeEnabled(portID, channelID)) } // GetAllFeeEnabledChannels returns a list of all ics29 enabled channels containing portID & channelID that are stored in state func (k Keeper) GetAllFeeEnabledChannels(ctx sdk.Context) []types.FeeEnabledChannel { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(types.FeeEnabledKeyPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) var enabledChArr []types.FeeEnabledChannel for ; iterator.Valid(); iterator.Next() { @@ -169,7 +171,7 @@ func (k Keeper) SetPayeeAddress(ctx sdk.Context, relayerAddr, payeeAddr, channel func (k Keeper) GetAllPayees(ctx sdk.Context) []types.RegisteredPayee { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(types.PayeeKeyPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) var registeredPayees []types.RegisteredPayee for ; iterator.Valid(); iterator.Next() { @@ -214,7 +216,7 @@ func (k Keeper) GetCounterpartyPayeeAddress(ctx sdk.Context, address, channelID func (k Keeper) GetAllCounterpartyPayees(ctx sdk.Context) []types.RegisteredCounterpartyPayee { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(types.CounterpartyPayeeKeyPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) var registeredCounterpartyPayees []types.RegisteredCounterpartyPayee for ; iterator.Valid(); iterator.Next() { @@ -257,7 +259,7 @@ func (k Keeper) GetRelayerAddressForAsyncAck(ctx sdk.Context, packetID channelty func (k Keeper) GetAllForwardRelayerAddresses(ctx sdk.Context) []types.ForwardRelayerAddress { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(types.ForwardRelayerPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) var forwardRelayerAddr []types.ForwardRelayerAddress for ; iterator.Valid(); iterator.Next() { @@ -289,7 +291,7 @@ func (k Keeper) GetFeesInEscrow(ctx sdk.Context, packetID channeltypes.PacketId) store := ctx.KVStore(k.storeKey) key := types.KeyFeesInEscrow(packetID) bz := store.Get(key) - if bz == nil { + if len(bz) == 0 { return types.PacketFees{}, false } @@ -325,7 +327,7 @@ func (k Keeper) GetIdentifiedPacketFeesForChannel(ctx sdk.Context, portID, chann store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, types.KeyFeesInEscrowChannelPrefix(portID, channelID)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { packetID, err := types.ParseKeyFeesInEscrow(string(iterator.Key())) if err != nil { @@ -345,7 +347,7 @@ func (k Keeper) GetIdentifiedPacketFeesForChannel(ctx sdk.Context, portID, chann func (k Keeper) GetAllIdentifiedPacketFees(ctx sdk.Context) []types.IdentifiedPacketFees { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(types.FeesInEscrowPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) var identifiedFees []types.IdentifiedPacketFees for ; iterator.Valid(); iterator.Next() { diff --git a/modules/apps/29-fee/keeper/keeper_test.go b/modules/apps/29-fee/keeper/keeper_test.go index e4a6a8ab0d8..89dfcd7a30e 100644 --- a/modules/apps/29-fee/keeper/keeper_test.go +++ b/modules/apps/29-fee/keeper/keeper_test.go @@ -8,10 +8,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) var ( @@ -114,7 +114,7 @@ func (suite *KeeperTestSuite) TestFeesInEscrow() { suite.coordinator.Setup(suite.path) // escrow five fees for packet sequence 1 - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), nil) @@ -147,9 +147,9 @@ func (suite *KeeperTestSuite) TestGetIdentifiedPacketFeesForChannel() { // escrow a fee refundAcc := suite.chainA.SenderAccount.GetAddress() - packetID1 := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) - packetID2 := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 2) - packetID5 := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 51) + packetID1 := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID2 := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 2) + packetID5 := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 51) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) @@ -161,9 +161,9 @@ func (suite *KeeperTestSuite) TestGetIdentifiedPacketFeesForChannel() { // set fees in escrow for packetIDs on different channel diffChannel := "channel-1" - diffPacketID1 := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, diffChannel, 1) - diffPacketID2 := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, diffChannel, 2) - diffPacketID5 := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, diffChannel, 5) + diffPacketID1 := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, diffChannel, 1) + diffPacketID2 := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, diffChannel, 2) + diffPacketID5 := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, diffChannel, 5) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), diffPacketID1, types.NewPacketFees([]types.PacketFee{packetFee})) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), diffPacketID2, types.NewPacketFees([]types.PacketFee{packetFee})) suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), diffPacketID5, types.NewPacketFees([]types.PacketFee{packetFee})) @@ -211,7 +211,7 @@ func (suite *KeeperTestSuite) TestGetAllIdentifiedPacketFees() { // escrow a fee refundAcc := suite.chainA.SenderAccount.GetAddress() - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) // escrow the packet fee @@ -237,14 +237,14 @@ func (suite *KeeperTestSuite) TestGetAllIdentifiedPacketFees() { } func (suite *KeeperTestSuite) TestGetAllFeeEnabledChannels() { - validPortId := "ibcmoduleport" + validPortID := "ibcmoduleport" // set two channels enabled suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), ibctesting.MockFeePort, ibctesting.FirstChannelID) - suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), validPortId, ibctesting.FirstChannelID) + suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), validPortID, ibctesting.FirstChannelID) expectedCh := []types.FeeEnabledChannel{ { - PortId: validPortId, + PortId: validPortID, ChannelId: ibctesting.FirstChannelID, }, { diff --git a/modules/apps/29-fee/keeper/msg_server.go b/modules/apps/29-fee/keeper/msg_server.go index c2beea28da3..943ee0453fc 100644 --- a/modules/apps/29-fee/keeper/msg_server.go +++ b/modules/apps/29-fee/keeper/msg_server.go @@ -3,11 +3,12 @@ package keeper import ( "context" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) var _ types.MsgServer = Keeper{} @@ -20,6 +21,15 @@ var _ types.MsgServer = Keeper{} func (k Keeper) RegisterPayee(goCtx context.Context, msg *types.MsgRegisterPayee) (*types.MsgRegisterPayeeResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + payee, err := sdk.AccAddressFromBech32(msg.Payee) + if err != nil { + return nil, err + } + + if k.bankKeeper.BlockedAddr(payee) { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "%s is not authorized to be a payee", payee) + } + // only register payee address if the channel exists and is fee enabled if _, found := k.channelKeeper.GetChannel(ctx, msg.PortId, msg.ChannelId); !found { return nil, channeltypes.ErrChannelNotFound @@ -33,7 +43,7 @@ func (k Keeper) RegisterPayee(goCtx context.Context, msg *types.MsgRegisterPayee k.Logger(ctx).Info("registering payee address for relayer", "relayer", msg.Relayer, "payee", msg.Payee, "channel", msg.ChannelId) - EmitRegisterPayeeEvent(ctx, msg.Relayer, msg.Payee, msg.ChannelId) + emitRegisterPayeeEvent(ctx, msg.Relayer, msg.Payee, msg.ChannelId) return &types.MsgRegisterPayeeResponse{}, nil } @@ -59,7 +69,7 @@ func (k Keeper) RegisterCounterpartyPayee(goCtx context.Context, msg *types.MsgR k.Logger(ctx).Info("registering counterparty payee for relayer", "relayer", msg.Relayer, "counterparty payee", msg.CounterpartyPayee, "channel", msg.ChannelId) - EmitRegisterCounterpartyPayeeEvent(ctx, msg.Relayer, msg.CounterpartyPayee, msg.ChannelId) + emitRegisterCounterpartyPayeeEvent(ctx, msg.Relayer, msg.CounterpartyPayee, msg.ChannelId) return &types.MsgRegisterCounterpartyPayeeResponse{}, nil } @@ -78,13 +88,26 @@ func (k Keeper) PayPacketFee(goCtx context.Context, msg *types.MsgPayPacketFee) return nil, types.ErrFeeModuleLocked } + refundAcc, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, err + } + + if err := k.bankKeeper.IsSendEnabledCoins(ctx, msg.Fee.Total()...); err != nil { + return nil, err + } + + if k.bankKeeper.BlockedAddr(refundAcc) { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "%s is not allowed to escrow fees", refundAcc) + } + // get the next sequence sequence, found := k.GetNextSequenceSend(ctx, msg.SourcePortId, msg.SourceChannelId) if !found { return nil, channeltypes.ErrSequenceSendNotFound } - packetID := channeltypes.NewPacketId(msg.SourcePortId, msg.SourceChannelId, sequence) + packetID := channeltypes.NewPacketID(msg.SourcePortId, msg.SourceChannelId, sequence) packetFee := types.NewPacketFee(msg.Fee, msg.Signer, msg.Relayers) if err := k.escrowPacketFee(ctx, packetID, packetFee); err != nil { @@ -110,9 +133,22 @@ func (k Keeper) PayPacketFeeAsync(goCtx context.Context, msg *types.MsgPayPacket return nil, types.ErrFeeModuleLocked } + refundAcc, err := sdk.AccAddressFromBech32(msg.PacketFee.RefundAddress) + if err != nil { + return nil, err + } + + if err := k.bankKeeper.IsSendEnabledCoins(ctx, msg.PacketFee.Fee.Total()...); err != nil { + return nil, err + } + + if k.bankKeeper.BlockedAddr(refundAcc) { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "%s is not allowed to escrow fees", refundAcc) + } + nextSeqSend, found := k.GetNextSequenceSend(ctx, msg.PacketId.PortId, msg.PacketId.ChannelId) if !found { - return nil, sdkerrors.Wrapf(channeltypes.ErrSequenceSendNotFound, "channel does not exist, portID: %s, channelID: %s", msg.PacketId.PortId, msg.PacketId.ChannelId) + return nil, errorsmod.Wrapf(channeltypes.ErrSequenceSendNotFound, "channel does not exist, portID: %s, channelID: %s", msg.PacketId.PortId, msg.PacketId.ChannelId) } // only allow incentivizing of packets which have been sent @@ -122,7 +158,7 @@ func (k Keeper) PayPacketFeeAsync(goCtx context.Context, msg *types.MsgPayPacket // only allow incentivizng of packets which have not completed the packet life cycle if bz := k.GetPacketCommitment(ctx, msg.PacketId.PortId, msg.PacketId.ChannelId, msg.PacketId.Sequence); len(bz) == 0 { - return nil, sdkerrors.Wrapf(channeltypes.ErrPacketCommitmentNotFound, "packet has already been acknowledged or timed out") + return nil, errorsmod.Wrapf(channeltypes.ErrPacketCommitmentNotFound, "packet has already been acknowledged or timed out") } if err := k.escrowPacketFee(ctx, msg.PacketId, msg.PacketFee); err != nil { diff --git a/modules/apps/29-fee/keeper/msg_server_test.go b/modules/apps/29-fee/keeper/msg_server_test.go index e0c84d62c9b..4c7269931ad 100644 --- a/modules/apps/29-fee/keeper/msg_server_test.go +++ b/modules/apps/29-fee/keeper/msg_server_test.go @@ -2,18 +2,18 @@ package keeper_test import ( sdk "github.com/cosmos/cosmos-sdk/types" - disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) func (suite *KeeperTestSuite) TestRegisterPayee() { - var ( - msg *types.MsgRegisterPayee - ) + var msg *types.MsgRegisterPayee testCases := []struct { name string @@ -29,7 +29,7 @@ func (suite *KeeperTestSuite) TestRegisterPayee() { "channel does not exist", false, func() { - msg.ChannelId = "channel-100" + msg.ChannelId = "channel-100" //nolint:goconst }, }, { @@ -39,6 +39,20 @@ func (suite *KeeperTestSuite) TestRegisterPayee() { suite.chainA.GetSimApp().IBCFeeKeeper.DeleteFeeEnabled(suite.chainA.GetContext(), suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID) }, }, + { + "given payee is not an sdk address", + false, + func() { + msg.Payee = "invalid-addr" + }, + }, + { + "payee is a blocked address", + false, + func() { + msg.Payee = suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(transfertypes.ModuleName).String() + }, + }, } for _, tc := range testCases { @@ -171,7 +185,7 @@ func (suite *KeeperTestSuite) TestPayPacketFee() { func() { fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), nil) feesInEscrow := types.NewPacketFees([]types.PacketFee{packetFee}) @@ -184,10 +198,23 @@ func (suite *KeeperTestSuite) TestPayPacketFee() { }, true, }, + { + "bank send enabled for fee denom", + func() { + err := suite.chainA.GetSimApp().BankKeeper.SetParams(suite.chainA.GetContext(), + banktypes.Params{ + SendEnabled: []*banktypes.SendEnabled{{Denom: sdk.DefaultBondDenom, Enabled: true}}, + }, + ) + suite.Require().NoError(err) + }, + true, + }, { "refund account is module account", func() { - msg.Signer = suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(disttypes.ModuleName).String() + suite.chainA.GetSimApp().BankKeeper.SendCoinsFromAccountToModule(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), ibcmock.ModuleName, fee.Total()) //nolint:errcheck // ignore error for testing + msg.Signer = suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(ibcmock.ModuleName).String() expPacketFee := types.NewPacketFee(fee, msg.Signer, nil) expFeesInEscrow = []types.PacketFee{expPacketFee} }, @@ -222,6 +249,26 @@ func (suite *KeeperTestSuite) TestPayPacketFee() { }, false, }, + { + "refund account is a blocked address", + func() { + blockedAddr := suite.chainA.GetSimApp().AccountKeeper.GetModuleAccount(suite.chainA.GetContext(), transfertypes.ModuleName).GetAddress() + msg.Signer = blockedAddr.String() + }, + false, + }, + { + "bank send disabled for fee denom", + func() { + err := suite.chainA.GetSimApp().BankKeeper.SetParams(suite.chainA.GetContext(), + banktypes.Params{ + SendEnabled: []*banktypes.SendEnabled{{Denom: sdk.DefaultBondDenom, Enabled: false}}, + }, + ) + suite.Require().NoError(err) + }, + false, + }, { "acknowledgement fee balance not found", func() { @@ -272,7 +319,7 @@ func (suite *KeeperTestSuite) TestPayPacketFee() { if tc.expPass { suite.Require().NoError(err) // message committed - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) feesInEscrow, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetFeesInEscrow(suite.chainA.GetContext(), packetID) suite.Require().True(found) suite.Require().Equal(expFeesInEscrow, feesInEscrow.PacketFees) @@ -312,7 +359,7 @@ func (suite *KeeperTestSuite) TestPayPacketFeeAsync() { func() { fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), nil) feesInEscrow := types.NewPacketFees([]types.PacketFee{packetFee}) @@ -325,6 +372,18 @@ func (suite *KeeperTestSuite) TestPayPacketFeeAsync() { }, true, }, + { + "bank send enabled for fee denom", + func() { + err := suite.chainA.GetSimApp().BankKeeper.SetParams(suite.chainA.GetContext(), + banktypes.Params{ + SendEnabled: []*banktypes.SendEnabled{{Denom: sdk.DefaultBondDenom, Enabled: true}}, + }, + ) + suite.Require().NoError(err) + }, + true, + }, { "fee module is locked", func() { @@ -354,7 +413,7 @@ func (suite *KeeperTestSuite) TestPayPacketFeeAsync() { { "packet not sent", func() { - msg.PacketId.Sequence = msg.PacketId.Sequence + 1 + msg.PacketId.Sequence++ }, false, }, @@ -369,20 +428,21 @@ func (suite *KeeperTestSuite) TestPayPacketFeeAsync() { { "packet already timed out", func() { - // try to incentivze a packet which is timed out - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, msg.PacketId.Sequence+1) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, packetID.Sequence, packetID.PortId, packetID.ChannelId, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), 0) + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) - err := suite.path.EndpointA.SendPacket(packet) + // try to incentivize a packet which is timed out + sequence, err := suite.path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) // need to update chainA's client representing chainB to prove missing ack err = suite.path.EndpointA.UpdateClient() suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, timeoutHeight, 0) err = suite.path.EndpointA.TimeoutPacket(packet) suite.Require().NoError(err) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, sequence) msg.PacketId = packetID }, false, @@ -401,6 +461,26 @@ func (suite *KeeperTestSuite) TestPayPacketFeeAsync() { }, false, }, + { + "refund account is a blocked address", + func() { + blockedAddr := suite.chainA.GetSimApp().AccountKeeper.GetModuleAccount(suite.chainA.GetContext(), transfertypes.ModuleName).GetAddress() + msg.PacketFee.RefundAddress = blockedAddr.String() + }, + false, + }, + { + "bank send disabled for fee denom", + func() { + err := suite.chainA.GetSimApp().BankKeeper.SetParams(suite.chainA.GetContext(), + banktypes.Params{ + SendEnabled: []*banktypes.SendEnabled{{Denom: sdk.DefaultBondDenom, Enabled: false}}, + }, + ) + suite.Require().NoError(err) + }, + false, + }, { "acknowledgement fee balance not found", func() { @@ -431,11 +511,13 @@ func (suite *KeeperTestSuite) TestPayPacketFeeAsync() { suite.SetupTest() suite.coordinator.Setup(suite.path) // setup channel + timeoutHeight := clienttypes.NewHeight(clienttypes.ParseChainID(suite.chainB.ChainID), 100) + // send a packet to incentivize - packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, packetID.Sequence, packetID.PortId, packetID.ChannelId, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, clienttypes.NewHeight(clienttypes.ParseChainID(suite.chainB.ChainID), 100), 0) - err := suite.path.EndpointA.SendPacket(packet) + sequence, err := suite.path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packetID := channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, sequence) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, packetID.Sequence, packetID.PortId, packetID.ChannelId, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, timeoutHeight, 0) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), nil) diff --git a/modules/apps/29-fee/keeper/relay.go b/modules/apps/29-fee/keeper/relay.go index 8c2e90f89c7..556e056c22d 100644 --- a/modules/apps/29-fee/keeper/relay.go +++ b/modules/apps/29-fee/keeper/relay.go @@ -3,18 +3,27 @@ package keeper import ( "fmt" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) -// SendPacket wraps IBC ChannelKeeper's SendPacket function -func (k Keeper) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) error { - return k.ics4Wrapper.SendPacket(ctx, chanCap, packet) +// SendPacket wraps the ICS4Wrapper SendPacket function +func (k Keeper) SendPacket( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, +) (uint64, error) { + return k.ics4Wrapper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) } // WriteAcknowledgement wraps IBC ChannelKeeper's WriteAcknowledgement function @@ -25,12 +34,12 @@ func (k Keeper) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.C return k.ics4Wrapper.WriteAcknowledgement(ctx, chanCap, packet, acknowledgement) } - packetID := channeltypes.NewPacketId(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) + packetID := channeltypes.NewPacketID(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) // retrieve the forward relayer that was stored in `onRecvPacket` relayer, found := k.GetRelayerAddressForAsyncAck(ctx, packetID) if !found { - return sdkerrors.Wrapf(types.ErrRelayerNotFoundForAsyncAck, "no relayer address stored for async acknowledgement for packet with portID: %s, channelID: %s, sequence: %d", packetID.PortId, packetID.ChannelId, packetID.Sequence) + return errorsmod.Wrapf(types.ErrRelayerNotFoundForAsyncAck, "no relayer address stored for async acknowledgement for packet with portID: %s, channelID: %s, sequence: %d", packetID.PortId, packetID.ChannelId, packetID.Sequence) } // it is possible that a relayer has not registered a counterparty address. diff --git a/modules/apps/29-fee/keeper/relay_test.go b/modules/apps/29-fee/keeper/relay_test.go index ca58b1661af..f4aa8b6b7bd 100644 --- a/modules/apps/29-fee/keeper/relay_test.go +++ b/modules/apps/29-fee/keeper/relay_test.go @@ -1,11 +1,11 @@ package keeper_test import ( - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) func (suite *KeeperTestSuite) TestWriteAcknowledgementAsync() { @@ -17,7 +17,7 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgementAsync() { { "success", func() { - suite.chainB.GetSimApp().IBCFeeKeeper.SetRelayerAddressForAsyncAck(suite.chainB.GetContext(), channeltypes.NewPacketId(suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, 1), suite.chainA.SenderAccount.GetAddress().String()) + suite.chainB.GetSimApp().IBCFeeKeeper.SetRelayerAddressForAsyncAck(suite.chainB.GetContext(), channeltypes.NewPacketID(suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, 1), suite.chainA.SenderAccount.GetAddress().String()) suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyPayeeAddress(suite.chainB.GetContext(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), suite.path.EndpointB.ChannelID) }, true, @@ -63,7 +63,7 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgementAsync() { if tc.expPass { suite.Require().NoError(err) - _, found := suite.chainB.GetSimApp().IBCFeeKeeper.GetRelayerAddressForAsyncAck(suite.chainB.GetContext(), channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1)) + _, found := suite.chainB.GetSimApp().IBCFeeKeeper.GetRelayerAddressForAsyncAck(suite.chainB.GetContext(), channeltypes.NewPacketID(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1)) suite.Require().False(found) expectedAck := types.NewIncentivizedAcknowledgement(suite.chainB.SenderAccount.GetAddress().String(), ack.Acknowledgement(), ack.Success()) diff --git a/modules/apps/29-fee/module.go b/modules/apps/29-fee/module.go index a9bb1ca0d7c..09fea7a74ca 100644 --- a/modules/apps/29-fee/module.go +++ b/modules/apps/29-fee/module.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "math/rand" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -12,14 +11,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/client/cli" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/keeper" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/client/cli" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ) var ( @@ -59,13 +57,12 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod return gs.Validate() } -// RegisterRESTRoutes implements AppModuleBasic interface -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for ics29 fee module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err != nil { + panic(err) + } } // GetTxCmd implements AppModuleBasic interface @@ -95,21 +92,6 @@ func NewAppModule(k keeper.Keeper) AppModule { func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { } -// Route implements the AppModule interface -func (am AppModule) Route() sdk.Route { - return sdk.Route{} -} - -// QuerierRoute implements the AppModule interface -func (AppModule) QuerierRoute() string { - return types.QuerierRoute -} - -// LegacyQuerierHandler implements the AppModule interface -func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { - return nil -} - // RegisterServices registers module services. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), am.keeper) @@ -150,16 +132,6 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V func (AppModule) GenerateGenesisState(_ *module.SimulationState) { } -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized ibc-29-fee param changes for the simulator. -func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { - return nil -} - // RegisterStoreDecoder registers a decoder for 29-fee module's types func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { } diff --git a/modules/apps/29-fee/transfer_test.go b/modules/apps/29-fee/transfer_test.go index 12a7a556e66..7cf070113ec 100644 --- a/modules/apps/29-fee/transfer_test.go +++ b/modules/apps/29-fee/transfer_test.go @@ -3,10 +3,10 @@ package fee_test import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) // Integration test to ensure ics29 works with ics20 @@ -30,7 +30,7 @@ func (suite *FeeTestSuite) TestFeeTransfer() { msgs := []sdk.Msg{ types.NewMsgPayPacketFee(fee, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, suite.chainA.SenderAccount.GetAddress().String(), nil), - transfertypes.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coin, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), clienttypes.NewHeight(0, 100), 0), + transfertypes.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coin, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), clienttypes.NewHeight(1, 100), 0, ""), } res, err := suite.chainA.SendMsgs(msgs...) suite.Require().NoError(err) // message committed @@ -66,6 +66,5 @@ func (suite *FeeTestSuite) TestFeeTransfer() { suite.Require().Equal( fee.AckFee.Add(fee.TimeoutFee...), // ack fee paid, timeout fee refunded - sdk.NewCoins(suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom)).Sub(originalChainASenderAccountBalance), - ) + sdk.NewCoins(suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom)).Sub(originalChainASenderAccountBalance[0])) } diff --git a/modules/apps/29-fee/types/ack.pb.go b/modules/apps/29-fee/types/ack.pb.go index 890ba0b76d0..eec38c21121 100644 --- a/modules/apps/29-fee/types/ack.pb.go +++ b/modules/apps/29-fee/types/ack.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -95,27 +95,27 @@ func init() { proto.RegisterFile("ibc/applications/fee/v1/ack.proto", fileDescri var fileDescriptor_ab2834946fb65ea4 = []byte{ // 330 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xbf, 0x4e, 0xc2, 0x40, - 0x1c, 0xc7, 0x29, 0x26, 0x46, 0x1b, 0xa7, 0x8a, 0x42, 0x30, 0x39, 0xb0, 0x13, 0x0b, 0xbd, 0xe0, - 0x9f, 0x41, 0x37, 0xd8, 0x9c, 0x48, 0xea, 0x62, 0x58, 0x9a, 0xeb, 0xf5, 0x47, 0xbd, 0x70, 0xbd, - 0xbb, 0xdc, 0xb5, 0x25, 0xf5, 0x29, 0x7c, 0x08, 0x1f, 0xc6, 0x91, 0xd1, 0x89, 0x18, 0x78, 0x03, - 0x9e, 0xc0, 0x94, 0x9a, 0x88, 0x06, 0xb7, 0xcb, 0xf7, 0xfb, 0xc9, 0x27, 0x97, 0xdf, 0xd7, 0xbe, - 0x64, 0x21, 0xc5, 0x44, 0x29, 0xce, 0x28, 0x49, 0x99, 0x14, 0x06, 0x4f, 0x01, 0x70, 0x3e, 0xc0, - 0x84, 0xce, 0x3c, 0xa5, 0x65, 0x2a, 0x9d, 0x26, 0x0b, 0xa9, 0xb7, 0x8b, 0x78, 0x53, 0x00, 0x2f, - 0x1f, 0xb4, 0x1b, 0xb1, 0x8c, 0xe5, 0x96, 0xc1, 0xe5, 0xab, 0xc2, 0xdd, 0xb7, 0xba, 0x7d, 0xf1, - 0x20, 0x28, 0x88, 0x94, 0xe5, 0xec, 0x05, 0xa2, 0x21, 0x9d, 0x09, 0x39, 0xe7, 0x10, 0xc5, 0x90, - 0x80, 0x48, 0x9d, 0xb1, 0x7d, 0x4a, 0x94, 0x0a, 0xc8, 0xef, 0xb8, 0x65, 0x75, 0xad, 0xde, 0xc9, - 0x08, 0x6d, 0x96, 0x9d, 0x76, 0x41, 0x12, 0x7e, 0xef, 0xee, 0x81, 0x5c, 0xdf, 0x21, 0x4a, 0xfd, - 0x15, 0x4e, 0xec, 0xe6, 0x54, 0xea, 0x39, 0xd1, 0x51, 0xa0, 0x81, 0x93, 0x02, 0x74, 0x40, 0xa2, - 0x48, 0x83, 0x31, 0xad, 0x7a, 0xd7, 0xea, 0x1d, 0x8f, 0xdc, 0xcd, 0xb2, 0x83, 0x2a, 0xe9, 0x3f, - 0xa0, 0xeb, 0x9f, 0x7d, 0x37, 0x7e, 0x55, 0x0c, 0xab, 0xdc, 0x79, 0xb2, 0xcf, 0x33, 0x11, 0x81, - 0xe6, 0x05, 0x13, 0x71, 0x50, 0x7e, 0xc9, 0x64, 0x94, 0x96, 0xea, 0x83, 0xae, 0xd5, 0x3b, 0xda, - 0x55, 0xef, 0xe7, 0xb8, 0xeb, 0x37, 0x7e, 0x9a, 0xa1, 0x52, 0x8f, 0x55, 0x3e, 0x1a, 0xbf, 0xaf, - 0x90, 0xb5, 0x58, 0x21, 0xeb, 0x73, 0x85, 0xac, 0xd7, 0x35, 0xaa, 0x2d, 0xd6, 0xa8, 0xf6, 0xb1, - 0x46, 0xb5, 0xc9, 0x6d, 0xcc, 0xd2, 0xe7, 0x2c, 0xf4, 0xa8, 0x4c, 0x30, 0x95, 0x26, 0x91, 0x06, - 0xb3, 0x90, 0xf6, 0x63, 0x89, 0xf3, 0x1b, 0x9c, 0xc8, 0x28, 0xe3, 0x60, 0xca, 0xc9, 0x0c, 0xbe, - 0xba, 0xeb, 0x97, 0x6b, 0xa5, 0x85, 0x02, 0x13, 0x1e, 0x6e, 0xcf, 0x7f, 0xfd, 0x15, 0x00, 0x00, - 0xff, 0xff, 0xb3, 0x85, 0x93, 0xfa, 0xd2, 0x01, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xc1, 0x4a, 0xc3, 0x30, + 0x1c, 0xc6, 0xd7, 0x09, 0xa2, 0xc5, 0x53, 0x9d, 0x6e, 0x4c, 0xc8, 0x66, 0x4f, 0xbb, 0xac, 0x61, + 0x8a, 0x88, 0xde, 0xb6, 0x9b, 0xa7, 0x41, 0xbd, 0xc8, 0x2e, 0x25, 0x4d, 0xff, 0xab, 0x61, 0x69, + 0x12, 0x92, 0xb6, 0xa3, 0x3e, 0x85, 0x0f, 0xe1, 0xc3, 0x78, 0xdc, 0xd1, 0xd3, 0x90, 0xed, 0x0d, + 0xf6, 0x04, 0xd2, 0x55, 0x70, 0xca, 0xbc, 0x85, 0xef, 0xfb, 0xf1, 0x23, 0xfc, 0x3f, 0xfb, 0x92, + 0x85, 0x14, 0x13, 0xa5, 0x38, 0xa3, 0x24, 0x65, 0x52, 0x18, 0x3c, 0x05, 0xc0, 0xf9, 0x00, 0x13, + 0x3a, 0xf3, 0x94, 0x96, 0xa9, 0x74, 0x9a, 0x2c, 0xa4, 0xde, 0x2e, 0xe2, 0x4d, 0x01, 0xbc, 0x7c, + 0xd0, 0x6e, 0xc4, 0x32, 0x96, 0x5b, 0x06, 0x97, 0xaf, 0x0a, 0x77, 0xdf, 0xea, 0xf6, 0xc5, 0x83, + 0xa0, 0x20, 0x52, 0x96, 0xb3, 0x17, 0x88, 0x86, 0x74, 0x26, 0xe4, 0x9c, 0x43, 0x14, 0x43, 0x02, + 0x22, 0x75, 0xc6, 0xf6, 0x29, 0x51, 0x2a, 0x20, 0xbf, 0xe3, 0x96, 0xd5, 0xb5, 0x7a, 0x27, 0x23, + 0xb4, 0x59, 0x76, 0xda, 0x05, 0x49, 0xf8, 0xbd, 0xbb, 0x07, 0x72, 0x7d, 0x87, 0x28, 0xf5, 0x57, + 0x38, 0xb1, 0x9b, 0x53, 0xa9, 0xe7, 0x44, 0x47, 0x81, 0x06, 0x4e, 0x0a, 0xd0, 0x01, 0x89, 0x22, + 0x0d, 0xc6, 0xb4, 0xea, 0x5d, 0xab, 0x77, 0x3c, 0x72, 0x37, 0xcb, 0x0e, 0xaa, 0xa4, 0xff, 0x80, + 0xae, 0x7f, 0xf6, 0xdd, 0xf8, 0x55, 0x31, 0xac, 0x72, 0xe7, 0xc9, 0x3e, 0xcf, 0x44, 0x04, 0x9a, + 0x17, 0x4c, 0xc4, 0x41, 0xf9, 0x25, 0x93, 0x51, 0x5a, 0xaa, 0x0f, 0xba, 0x56, 0xef, 0x68, 0x57, + 0xbd, 0x9f, 0xe3, 0xae, 0xdf, 0xf8, 0x69, 0x86, 0x4a, 0x3d, 0x56, 0xf9, 0x68, 0xfc, 0xbe, 0x42, + 0xd6, 0x62, 0x85, 0xac, 0xcf, 0x15, 0xb2, 0x5e, 0xd7, 0xa8, 0xb6, 0x58, 0xa3, 0xda, 0xc7, 0x1a, + 0xd5, 0x26, 0x37, 0x31, 0x4b, 0x9f, 0xb3, 0xd0, 0xa3, 0x32, 0xc1, 0x54, 0x9a, 0x44, 0x1a, 0xcc, + 0x42, 0xda, 0x8f, 0x25, 0xce, 0x6f, 0x71, 0x22, 0xa3, 0x8c, 0x83, 0x29, 0x27, 0x33, 0xf8, 0xea, + 0xae, 0x5f, 0xae, 0x95, 0x16, 0x0a, 0x4c, 0x78, 0xb8, 0x3d, 0xff, 0xf5, 0x57, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xaa, 0xbb, 0x40, 0x71, 0xd2, 0x01, 0x00, 0x00, } func (m *IncentivizedAcknowledgement) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/29-fee/types/errors.go b/modules/apps/29-fee/types/errors.go index 0ac40e5f824..26167c71016 100644 --- a/modules/apps/29-fee/types/errors.go +++ b/modules/apps/29-fee/types/errors.go @@ -1,19 +1,19 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // 29-fee sentinel errors var ( - ErrInvalidVersion = sdkerrors.Register(ModuleName, 2, "invalid ICS29 middleware version") - ErrRefundAccNotFound = sdkerrors.Register(ModuleName, 3, "no account found for given refund address") - ErrBalanceNotFound = sdkerrors.Register(ModuleName, 4, "balance not found for given account address") - ErrFeeNotFound = sdkerrors.Register(ModuleName, 5, "there is no fee escrowed for the given packetID") - ErrRelayersNotNil = sdkerrors.Register(ModuleName, 6, "relayers must be nil. This feature is not supported") - ErrCounterpartyPayeeEmpty = sdkerrors.Register(ModuleName, 7, "counterparty payee must not be empty") - ErrForwardRelayerAddressNotFound = sdkerrors.Register(ModuleName, 8, "forward relayer address not found") - ErrFeeNotEnabled = sdkerrors.Register(ModuleName, 9, "fee module is not enabled for this channel. If this error occurs after channel setup, fee module may not be enabled") - ErrRelayerNotFoundForAsyncAck = sdkerrors.Register(ModuleName, 10, "relayer address must be stored for async WriteAcknowledgement") - ErrFeeModuleLocked = sdkerrors.Register(ModuleName, 11, "the fee module is currently locked, a severe bug has been detected") + ErrInvalidVersion = errorsmod.Register(ModuleName, 2, "invalid ICS29 middleware version") + ErrRefundAccNotFound = errorsmod.Register(ModuleName, 3, "no account found for given refund address") + ErrBalanceNotFound = errorsmod.Register(ModuleName, 4, "balance not found for given account address") + ErrFeeNotFound = errorsmod.Register(ModuleName, 5, "there is no fee escrowed for the given packetID") + ErrRelayersNotEmpty = errorsmod.Register(ModuleName, 6, "relayers must not be set. This feature is not supported") + ErrCounterpartyPayeeEmpty = errorsmod.Register(ModuleName, 7, "counterparty payee must not be empty") + ErrForwardRelayerAddressNotFound = errorsmod.Register(ModuleName, 8, "forward relayer address not found") + ErrFeeNotEnabled = errorsmod.Register(ModuleName, 9, "fee module is not enabled for this channel. If this error occurs after channel setup, fee module may not be enabled") + ErrRelayerNotFoundForAsyncAck = errorsmod.Register(ModuleName, 10, "relayer address must be stored for async WriteAcknowledgement") + ErrFeeModuleLocked = errorsmod.Register(ModuleName, 11, "the fee module is currently locked, a severe bug has been detected") ) diff --git a/modules/apps/29-fee/types/events.go b/modules/apps/29-fee/types/events.go index cffca5dabdd..ea9cdd0f870 100644 --- a/modules/apps/29-fee/types/events.go +++ b/modules/apps/29-fee/types/events.go @@ -5,6 +5,7 @@ const ( EventTypeIncentivizedPacket = "incentivized_ibc_packet" EventTypeRegisterPayee = "register_payee" EventTypeRegisterCounterpartyPayee = "register_counterparty_payee" + EventTypeDistributeFee = "distribute_fee" AttributeKeyRecvFee = "recv_fee" AttributeKeyAckFee = "ack_fee" @@ -13,4 +14,6 @@ const ( AttributeKeyRelayer = "relayer" AttributeKeyPayee = "payee" AttributeKeyCounterpartyPayee = "counterparty_payee" + AttributeKeyReceiver = "receiver" + AttributeKeyFee = "fee" ) diff --git a/modules/apps/29-fee/types/expected_keepers.go b/modules/apps/29-fee/types/expected_keepers.go index 9e6abfd358b..589224b9d2f 100644 --- a/modules/apps/29-fee/types/expected_keepers.go +++ b/modules/apps/29-fee/types/expected_keepers.go @@ -5,8 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // AccountKeeper defines the contract required for account APIs. @@ -15,13 +14,6 @@ type AccountKeeper interface { GetAccount(sdk.Context, sdk.AccAddress) types.AccountI } -// ICS4Wrapper defines the expected ICS4Wrapper for middleware -type ICS4Wrapper interface { - WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, acknowledgement ibcexported.Acknowledgement) error - SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error - GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) -} - // ChannelKeeper defines the expected IBC channel keeper type ChannelKeeper interface { GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) @@ -41,4 +33,5 @@ type BankKeeper interface { SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error BlockedAddr(sdk.AccAddress) bool + IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error } diff --git a/modules/apps/29-fee/types/fee.go b/modules/apps/29-fee/types/fee.go index 774d8857e56..81948ebdcbc 100644 --- a/modules/apps/29-fee/types/fee.go +++ b/modules/apps/29-fee/types/fee.go @@ -3,13 +3,14 @@ package types import ( "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) -// NewPacketFee creates and returns a new PacketFee struct including the incentivization fees, refund addres and relayers +// NewPacketFee creates and returns a new PacketFee struct including the incentivization fees, refund address and relayers func NewPacketFee(fee Fee, refundAddr string, relayers []string) PacketFee { return PacketFee{ Fee: fee, @@ -22,12 +23,12 @@ func NewPacketFee(fee Fee, refundAddr string, relayers []string) PacketFee { func (p PacketFee) Validate() error { _, err := sdk.AccAddressFromBech32(p.RefundAddress) if err != nil { - return sdkerrors.Wrap(err, "failed to convert RefundAddress into sdk.AccAddress") + return errorsmod.Wrap(err, "failed to convert RefundAddress into sdk.AccAddress") } - // enforce relayer is nil - if p.Relayers != nil { - return ErrRelayersNotNil + // enforce relayers are not set + if len(p.Relayers) != 0 { + return ErrRelayersNotEmpty } if err := p.Fee.Validate(); err != nil { @@ -67,25 +68,25 @@ func (f Fee) Total() sdk.Coins { } // Validate asserts that each Fee is valid and all three Fees are not empty or zero -func (fee Fee) Validate() error { +func (f Fee) Validate() error { var errFees []string - if !fee.AckFee.IsValid() { + if !f.AckFee.IsValid() { errFees = append(errFees, "ack fee invalid") } - if !fee.RecvFee.IsValid() { + if !f.RecvFee.IsValid() { errFees = append(errFees, "recv fee invalid") } - if !fee.TimeoutFee.IsValid() { + if !f.TimeoutFee.IsValid() { errFees = append(errFees, "timeout fee invalid") } if len(errFees) > 0 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "contains invalid fees: %s", strings.Join(errFees, " , ")) + return errorsmod.Wrapf(ibcerrors.ErrInvalidCoins, "contains invalid fees: %s", strings.Join(errFees, " , ")) } // if all three fee's are zero or empty return an error - if fee.AckFee.IsZero() && fee.RecvFee.IsZero() && fee.TimeoutFee.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "all fees are zero") + if f.AckFee.IsZero() && f.RecvFee.IsZero() && f.TimeoutFee.IsZero() { + return errorsmod.Wrap(ibcerrors.ErrInvalidCoins, "all fees are zero") } return nil diff --git a/modules/apps/29-fee/types/fee.pb.go b/modules/apps/29-fee/types/fee.pb.go index d36f5e7cb18..7268ecfb746 100644 --- a/modules/apps/29-fee/types/fee.pb.go +++ b/modules/apps/29-fee/types/fee.pb.go @@ -7,9 +7,9 @@ import ( fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types "github.com/cosmos/cosmos-sdk/types" - types1 "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types1 "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" io "io" math "math" math_bits "math/bits" @@ -266,39 +266,39 @@ func init() { proto.RegisterFile("ibc/applications/fee/v1/fee.proto", fileDescri var fileDescriptor_cb3319f1af2a53e5 = []byte{ // 525 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x31, 0x6f, 0x13, 0x31, - 0x14, 0xc7, 0x73, 0x09, 0x6a, 0x1b, 0x47, 0x14, 0x74, 0x2a, 0x22, 0x8d, 0xe0, 0x52, 0x3c, 0x65, - 0x89, 0xad, 0x84, 0x32, 0xc0, 0x04, 0x57, 0x29, 0x52, 0x27, 0xd0, 0x89, 0x89, 0x25, 0xf2, 0xd9, - 0x2f, 0xa9, 0x95, 0xdc, 0xf9, 0x74, 0xbe, 0x44, 0xca, 0xca, 0x27, 0xe0, 0x1b, 0xb0, 0xf3, 0x49, - 0xba, 0x20, 0x75, 0x64, 0x0a, 0x28, 0xf9, 0x06, 0xdd, 0x91, 0x90, 0x7d, 0x4e, 0x94, 0x82, 0xaa, - 0xaa, 0x12, 0xd3, 0xf9, 0xd9, 0xef, 0xef, 0xdf, 0xb3, 0xdf, 0xff, 0x8c, 0x5e, 0xc8, 0x98, 0x53, - 0x96, 0x65, 0x53, 0xc9, 0x59, 0x21, 0x55, 0xaa, 0xe9, 0x08, 0x80, 0xce, 0x7b, 0xe6, 0x43, 0xb2, - 0x5c, 0x15, 0xca, 0x7f, 0x2a, 0x63, 0x4e, 0x76, 0x53, 0x88, 0x59, 0x9b, 0xf7, 0x5a, 0x01, 0x57, - 0x3a, 0x51, 0x9a, 0xc6, 0x4c, 0x1b, 0x49, 0x0c, 0x05, 0xeb, 0x51, 0xae, 0x64, 0x5a, 0x0a, 0x5b, - 0x47, 0x63, 0x35, 0x56, 0x76, 0x48, 0xcd, 0xc8, 0xcd, 0x5a, 0x22, 0x57, 0x39, 0x50, 0x7e, 0xc1, - 0xd2, 0x14, 0xa6, 0x86, 0xe6, 0x86, 0x65, 0x0a, 0xfe, 0x5d, 0x45, 0xb5, 0x01, 0x80, 0xbf, 0x40, - 0x07, 0x39, 0xf0, 0xf9, 0x70, 0x04, 0xd0, 0xf4, 0x4e, 0x6a, 0x9d, 0x46, 0xff, 0x98, 0x94, 0x4c, - 0x62, 0x98, 0xc4, 0x31, 0xc9, 0x99, 0x92, 0x69, 0x78, 0x76, 0xb9, 0x6c, 0x57, 0xae, 0x97, 0xed, - 0x47, 0x0b, 0x96, 0x4c, 0xdf, 0xe0, 0x8d, 0x10, 0x7f, 0xfb, 0xd9, 0xee, 0x8c, 0x65, 0x71, 0x31, - 0x8b, 0x09, 0x57, 0x09, 0x75, 0x35, 0x97, 0x9f, 0xae, 0x16, 0x13, 0x5a, 0x2c, 0x32, 0xd0, 0x76, - 0x0f, 0x1d, 0xed, 0x1b, 0x99, 0x41, 0xcf, 0xd1, 0x3e, 0xe3, 0x13, 0x4b, 0xae, 0xde, 0x45, 0x0e, - 0x1d, 0xf9, 0xb0, 0x24, 0x3b, 0xdd, 0xfd, 0xc0, 0x7b, 0x8c, 0x4f, 0x0c, 0xf7, 0xb3, 0x87, 0x1a, - 0x85, 0x4c, 0x40, 0xcd, 0x0a, 0x0b, 0xaf, 0xdd, 0x05, 0x1f, 0x38, 0xb8, 0x5f, 0xc2, 0x77, 0xb4, - 0xf7, 0x2b, 0x00, 0x39, 0xe5, 0x00, 0x00, 0x7f, 0xf5, 0x50, 0xfd, 0x03, 0xe3, 0x13, 0x30, 0x91, - 0x7f, 0x8a, 0x6a, 0x65, 0x03, 0xbc, 0x4e, 0xa3, 0xff, 0x8c, 0xdc, 0xe2, 0x06, 0x32, 0x00, 0x08, - 0x1f, 0x98, 0x62, 0x22, 0x93, 0xee, 0xbf, 0x45, 0x87, 0x39, 0x8c, 0x66, 0xa9, 0x18, 0x32, 0x21, - 0x72, 0xd0, 0xba, 0x59, 0x3d, 0xf1, 0x3a, 0xf5, 0xf0, 0xf8, 0x7a, 0xd9, 0x7e, 0xb2, 0x69, 0xd1, - 0xee, 0x3a, 0x8e, 0x1e, 0x96, 0x13, 0xef, 0xca, 0xd8, 0x6f, 0x99, 0xee, 0x4f, 0xd9, 0x02, 0x72, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x41, 0x8b, 0x13, 0x31, + 0x14, 0xc7, 0x3b, 0xad, 0xec, 0x6e, 0x53, 0x5c, 0x65, 0x58, 0xb1, 0x5b, 0x74, 0xba, 0xe6, 0xd4, + 0x4b, 0x13, 0x5a, 0x15, 0xd1, 0x93, 0xce, 0x42, 0x61, 0x4f, 0xca, 0xe0, 0xc9, 0x4b, 0xc9, 0x24, + 0xaf, 0xdd, 0xd0, 0xce, 0x64, 0x98, 0x4c, 0x0b, 0xbd, 0xfa, 0x09, 0xfc, 0x06, 0xde, 0xfd, 0x24, + 0x7b, 0x11, 0xf6, 0xe8, 0xa9, 0x4a, 0xfb, 0x0d, 0xf6, 0x2e, 0x48, 0x32, 0x69, 0xe9, 0x2a, 0xcb, + 0xb2, 0xe0, 0x69, 0xf2, 0x92, 0xf7, 0xcf, 0xef, 0x25, 0xef, 0x3f, 0x41, 0xcf, 0x64, 0xcc, 0x29, + 0xcb, 0xb2, 0xa9, 0xe4, 0xac, 0x90, 0x2a, 0xd5, 0x74, 0x04, 0x40, 0xe7, 0x3d, 0xf3, 0x21, 0x59, + 0xae, 0x0a, 0xe5, 0x3f, 0x96, 0x31, 0x27, 0xbb, 0x29, 0xc4, 0xac, 0xcd, 0x7b, 0xad, 0x80, 0x2b, + 0x9d, 0x28, 0x4d, 0x63, 0xa6, 0x8d, 0x24, 0x86, 0x82, 0xf5, 0x28, 0x57, 0x32, 0x2d, 0x85, 0xad, + 0xa3, 0xb1, 0x1a, 0x2b, 0x3b, 0xa4, 0x66, 0xe4, 0x66, 0x2d, 0x91, 0xab, 0x1c, 0x28, 0x3f, 0x67, + 0x69, 0x0a, 0x53, 0x43, 0x73, 0xc3, 0x32, 0x05, 0xff, 0xae, 0xa2, 0xda, 0x00, 0xc0, 0x5f, 0xa0, + 0x83, 0x1c, 0xf8, 0x7c, 0x38, 0x02, 0x68, 0x7a, 0x27, 0xb5, 0x4e, 0xa3, 0x7f, 0x4c, 0x4a, 0x26, + 0x31, 0x4c, 0xe2, 0x98, 0xe4, 0x54, 0xc9, 0x34, 0x3c, 0xbd, 0x58, 0xb6, 0x2b, 0x57, 0xcb, 0xf6, + 0x83, 0x05, 0x4b, 0xa6, 0x6f, 0xf0, 0x46, 0x88, 0xbf, 0xfd, 0x6c, 0x77, 0xc6, 0xb2, 0x38, 0x9f, + 0xc5, 0x84, 0xab, 0x84, 0xba, 0x9a, 0xcb, 0x4f, 0x57, 0x8b, 0x09, 0x2d, 0x16, 0x19, 0x68, 0xbb, + 0x87, 0x8e, 0xf6, 0x8d, 0xcc, 0xa0, 0xe7, 0x68, 0x9f, 0xf1, 0x89, 0x25, 0x57, 0x6f, 0x23, 0x87, + 0x8e, 0x7c, 0x58, 0x92, 0x9d, 0xee, 0x6e, 0xe0, 0x3d, 0xc6, 0x27, 0x86, 0xfb, 0xd9, 0x43, 0x8d, + 0x42, 0x26, 0xa0, 0x66, 0x85, 0x85, 0xd7, 0x6e, 0x83, 0x0f, 0x1c, 0xdc, 0x2f, 0xe1, 0x3b, 0xda, + 0xbb, 0x15, 0x80, 0x9c, 0x72, 0x00, 0x80, 0xbf, 0x7a, 0xa8, 0xfe, 0x81, 0xf1, 0x09, 0x98, 0xc8, + 0x7f, 0x81, 0x6a, 0x65, 0x03, 0xbc, 0x4e, 0xa3, 0xff, 0x84, 0xdc, 0xe0, 0x06, 0x32, 0x00, 0x08, + 0xef, 0x99, 0x62, 0x22, 0x93, 0xee, 0xbf, 0x45, 0x87, 0x39, 0x8c, 0x66, 0xa9, 0x18, 0x32, 0x21, + 0x72, 0xd0, 0xba, 0x59, 0x3d, 0xf1, 0x3a, 0xf5, 0xf0, 0xf8, 0x6a, 0xd9, 0x7e, 0xb4, 0x69, 0xd1, + 0xee, 0x3a, 0x8e, 0xee, 0x97, 0x13, 0xef, 0xca, 0xd8, 0x6f, 0x99, 0xee, 0x4f, 0xd9, 0x02, 0x72, 0x6d, 0xaf, 0xa1, 0x1e, 0x6d, 0x63, 0x9c, 0x20, 0xb4, 0x2d, 0x50, 0xfb, 0x43, 0xd4, 0xc8, 0x6c, - 0x64, 0x8e, 0xad, 0x9d, 0x55, 0xf0, 0xad, 0x95, 0x6e, 0x95, 0x61, 0xeb, 0xe6, 0xe5, 0xed, 0x6c, - 0x82, 0x23, 0x94, 0x6d, 0x01, 0xf8, 0xbb, 0x87, 0x8e, 0xce, 0x05, 0xa4, 0x85, 0x1c, 0x49, 0x10, - 0x3b, 0xe4, 0x8f, 0xa8, 0xee, 0x44, 0x52, 0xb8, 0x1b, 0x7a, 0x6e, 0xb9, 0xc6, 0xe0, 0x64, 0xe3, - 0xea, 0x2d, 0xf3, 0x5c, 0x84, 0x4d, 0x87, 0x7c, 0x7c, 0x03, 0x29, 0x05, 0x8e, 0x0e, 0x32, 0x97, - 0xf3, 0xf7, 0x79, 0xaa, 0xff, 0xfb, 0x3c, 0xe1, 0xfb, 0xcb, 0x55, 0xe0, 0x5d, 0xad, 0x02, 0xef, - 0xd7, 0x2a, 0xf0, 0xbe, 0xac, 0x83, 0xca, 0xd5, 0x3a, 0xa8, 0xfc, 0x58, 0x07, 0x95, 0x4f, 0xaf, - 0xfe, 0x35, 0x8c, 0x8c, 0x79, 0x77, 0xac, 0xe8, 0xfc, 0x94, 0x26, 0x4a, 0xcc, 0xa6, 0xa0, 0xcd, - 0x7b, 0xa1, 0x69, 0xff, 0x75, 0xd7, 0x3c, 0x15, 0xd6, 0x43, 0xf1, 0x9e, 0xfd, 0x71, 0x5f, 0xfe, - 0x09, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x01, 0xeb, 0x42, 0x4f, 0x04, 0x00, 0x00, + 0x64, 0x8e, 0xad, 0x9d, 0x55, 0xf0, 0x8d, 0x95, 0x6e, 0x95, 0x61, 0xeb, 0xfa, 0xe5, 0xed, 0x6c, + 0x82, 0x23, 0x94, 0x6d, 0x01, 0xf8, 0xbb, 0x87, 0x8e, 0xce, 0x04, 0xa4, 0x85, 0x1c, 0x49, 0x10, + 0x3b, 0xe4, 0x8f, 0xa8, 0xee, 0x44, 0x52, 0xb8, 0x1b, 0x7a, 0x6a, 0xb9, 0xc6, 0xe0, 0x64, 0xe3, + 0xea, 0x2d, 0xf3, 0x4c, 0x84, 0x4d, 0x87, 0x7c, 0x78, 0x0d, 0x29, 0x05, 0x8e, 0x0e, 0x32, 0x97, + 0xf3, 0xf7, 0x79, 0xaa, 0xff, 0xfb, 0x3c, 0xe1, 0xfb, 0x8b, 0x55, 0xe0, 0x5d, 0xae, 0x02, 0xef, + 0xd7, 0x2a, 0xf0, 0xbe, 0xac, 0x83, 0xca, 0xe5, 0x3a, 0xa8, 0xfc, 0x58, 0x07, 0x95, 0x4f, 0x2f, + 0xff, 0x35, 0x8c, 0x8c, 0x79, 0x77, 0xac, 0xe8, 0xfc, 0x15, 0x4d, 0x94, 0x98, 0x4d, 0x41, 0x9b, + 0xf7, 0x42, 0xd3, 0xfe, 0xeb, 0xae, 0x79, 0x2a, 0xac, 0x87, 0xe2, 0x3d, 0xfb, 0xe3, 0x3e, 0xff, + 0x13, 0x00, 0x00, 0xff, 0xff, 0x63, 0x3f, 0x38, 0xc9, 0x4f, 0x04, 0x00, 0x00, } func (m *Fee) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/29-fee/types/fee_test.go b/modules/apps/29-fee/types/fee_test.go index 3abe0e382b3..71758559baa 100644 --- a/modules/apps/29-fee/types/fee_test.go +++ b/modules/apps/29-fee/types/fee_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/secp256k1" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" ) var ( @@ -27,6 +27,8 @@ var ( defaultAccAddress = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() ) +const invalidAddress = "invalid-address" + func TestFeeTotal(t *testing.T) { fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) @@ -47,10 +49,17 @@ func TestPacketFeeValidation(t *testing.T) { func() {}, true, }, + { + "success with empty slice for Relayers", + func() { + packetFee.Relayers = []string{} + }, + true, + }, { "should fail when refund address is invalid", func() { - packetFee.RefundAddress = "invalid-address" + packetFee.RefundAddress = invalidAddress }, false, }, @@ -102,6 +111,13 @@ func TestPacketFeeValidation(t *testing.T) { }, false, }, + { + "should fail with non empty Relayers", + func() { + packetFee.Relayers = []string{"relayer"} + }, + false, + }, } for _, tc := range testCases { @@ -113,9 +129,9 @@ func TestPacketFeeValidation(t *testing.T) { err := packetFee.Validate() if tc.expPass { - require.NoError(t, err) + require.NoError(t, err, tc.name) } else { - require.Error(t, err) + require.Error(t, err, tc.name) } } } diff --git a/modules/apps/29-fee/types/genesis.go b/modules/apps/29-fee/types/genesis.go index 8c9281faa15..e08d457367d 100644 --- a/modules/apps/29-fee/types/genesis.go +++ b/modules/apps/29-fee/types/genesis.go @@ -3,10 +3,11 @@ package types import ( "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // NewGenesisState creates a 29-fee GenesisState instance. @@ -56,36 +57,36 @@ func (gs GenesisState) Validate() error { // Validate FeeEnabledChannels for _, feeCh := range gs.FeeEnabledChannels { if err := host.PortIdentifierValidator(feeCh.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid source port ID") + return errorsmod.Wrap(err, "invalid source port ID") } if err := host.ChannelIdentifierValidator(feeCh.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid source channel ID") + return errorsmod.Wrap(err, "invalid source channel ID") } } // Validate RegisteredPayees for _, registeredPayee := range gs.RegisteredPayees { if registeredPayee.Relayer == registeredPayee.Payee { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "relayer address and payee address must not be equal") + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "relayer address and payee address must not be equal") } if _, err := sdk.AccAddressFromBech32(registeredPayee.Relayer); err != nil { - return sdkerrors.Wrap(err, "failed to convert relayer address into sdk.AccAddress") + return errorsmod.Wrap(err, "failed to convert relayer address into sdk.AccAddress") } if _, err := sdk.AccAddressFromBech32(registeredPayee.Payee); err != nil { - return sdkerrors.Wrap(err, "failed to convert payee address into sdk.AccAddress") + return errorsmod.Wrap(err, "failed to convert payee address into sdk.AccAddress") } if err := host.ChannelIdentifierValidator(registeredPayee.ChannelId); err != nil { - return sdkerrors.Wrapf(err, "invalid channel identifier: %s", registeredPayee.ChannelId) + return errorsmod.Wrapf(err, "invalid channel identifier: %s", registeredPayee.ChannelId) } } // Validate RegisteredCounterpartyPayees for _, registeredCounterpartyPayee := range gs.RegisteredCounterpartyPayees { if _, err := sdk.AccAddressFromBech32(registeredCounterpartyPayee.Relayer); err != nil { - return sdkerrors.Wrap(err, "failed to convert relayer address into sdk.AccAddress") + return errorsmod.Wrap(err, "failed to convert relayer address into sdk.AccAddress") } if strings.TrimSpace(registeredCounterpartyPayee.CounterpartyPayee) == "" { @@ -93,14 +94,14 @@ func (gs GenesisState) Validate() error { } if err := host.ChannelIdentifierValidator(registeredCounterpartyPayee.ChannelId); err != nil { - return sdkerrors.Wrapf(err, "invalid channel identifier: %s", registeredCounterpartyPayee.ChannelId) + return errorsmod.Wrapf(err, "invalid channel identifier: %s", registeredCounterpartyPayee.ChannelId) } } // Validate ForwardRelayers for _, rel := range gs.ForwardRelayers { if _, err := sdk.AccAddressFromBech32(rel.Address); err != nil { - return sdkerrors.Wrap(err, "failed to convert forward relayer address into sdk.AccAddress") + return errorsmod.Wrap(err, "failed to convert forward relayer address into sdk.AccAddress") } if err := rel.PacketId.Validate(); err != nil { diff --git a/modules/apps/29-fee/types/genesis.pb.go b/modules/apps/29-fee/types/genesis.pb.go index 4fc869a658c..8bca28ff748 100644 --- a/modules/apps/29-fee/types/genesis.pb.go +++ b/modules/apps/29-fee/types/genesis.pb.go @@ -5,9 +5,9 @@ package types import ( fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" io "io" math "math" math_bits "math/bits" @@ -358,48 +358,48 @@ func init() { } var fileDescriptor_7191992e856dff95 = []byte{ - // 649 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcf, 0x4e, 0xd4, 0x4e, - 0x1c, 0xdf, 0xc2, 0x0f, 0xf8, 0x31, 0x18, 0x60, 0x27, 0x20, 0x15, 0xa4, 0x8b, 0x63, 0x48, 0x88, - 0x66, 0xdb, 0x80, 0x78, 0xd0, 0x9b, 0x25, 0x62, 0x36, 0x31, 0x91, 0x8c, 0x9e, 0xbc, 0x6c, 0xba, - 0xed, 0xb7, 0x4b, 0xe3, 0x6e, 0xa7, 0x99, 0x19, 0x96, 0xac, 0x37, 0x4f, 0x5e, 0x7d, 0x0d, 0xe3, - 0x23, 0xf8, 0x02, 0x1c, 0x39, 0x7a, 0xda, 0x18, 0x78, 0x83, 0x7d, 0x02, 0x33, 0x9d, 0x29, 0x2c, - 0xbb, 0xd4, 0x70, 0xf0, 0x36, 0xd3, 0xf9, 0xfc, 0x9b, 0x7e, 0x26, 0x5f, 0xb4, 0x9d, 0xb4, 0x42, - 0x2f, 0xc8, 0xb2, 0x4e, 0x12, 0x06, 0x32, 0x61, 0xa9, 0xf0, 0x62, 0x00, 0xaf, 0xb7, 0xeb, 0xb5, - 0x21, 0x05, 0x91, 0x08, 0x37, 0xe3, 0x4c, 0x32, 0xbc, 0x96, 0xb4, 0x42, 0x77, 0x14, 0xe6, 0xc6, - 0x00, 0x6e, 0x6f, 0x77, 0x7d, 0xa5, 0xcd, 0xda, 0x2c, 0xc7, 0x78, 0x6a, 0xa5, 0xe1, 0xeb, 0x8f, - 0xca, 0x54, 0x15, 0x6b, 0x04, 0x12, 0x32, 0x0e, 0x5e, 0x78, 0x1c, 0xa4, 0x29, 0x74, 0xd4, 0xb1, - 0x59, 0x6a, 0x08, 0xf9, 0x31, 0x83, 0xee, 0xbd, 0xd1, 0x31, 0xde, 0xcb, 0x40, 0x02, 0xee, 0xa1, - 0xa5, 0x24, 0x82, 0x54, 0x26, 0x71, 0x02, 0x51, 0x33, 0x06, 0x10, 0xb6, 0xb5, 0x35, 0xbd, 0xb3, - 0xb0, 0x57, 0x77, 0x4b, 0xf2, 0xb9, 0x8d, 0x2b, 0xfc, 0x51, 0x10, 0x7e, 0x02, 0x79, 0x08, 0x20, - 0x7c, 0xe7, 0x6c, 0x50, 0xab, 0x0c, 0x07, 0xb5, 0xfb, 0xfd, 0xa0, 0xdb, 0x79, 0x49, 0xc6, 0x34, - 0x09, 0x5d, 0xbc, 0xfe, 0xa2, 0xf0, 0xf8, 0x8b, 0x85, 0x56, 0x62, 0x80, 0x26, 0xa4, 0x41, 0xab, - 0x03, 0x51, 0xd3, 0xc4, 0x14, 0xf6, 0x54, 0xee, 0xfe, 0xa4, 0xd4, 0xfd, 0x10, 0xe0, 0xb5, 0xe6, - 0x1c, 0x68, 0x8a, 0xff, 0xd8, 0x58, 0x6f, 0x68, 0xeb, 0xdb, 0x54, 0x09, 0xc5, 0xf1, 0x38, 0x4f, - 0xe0, 0x53, 0x54, 0xe5, 0xd0, 0x4e, 0x84, 0x04, 0x0e, 0x51, 0x33, 0x0b, 0xfa, 0xea, 0xf6, 0xd3, - 0xb9, 0xff, 0x4e, 0xa9, 0x3f, 0xbd, 0x62, 0x1c, 0x29, 0x82, 0xbf, 0x65, 0xdc, 0x6d, 0xed, 0x3e, - 0x21, 0x48, 0xe8, 0x32, 0xbf, 0x49, 0x11, 0xf8, 0xbb, 0x85, 0x9c, 0x11, 0x60, 0xc8, 0x4e, 0x52, - 0x09, 0x3c, 0x0b, 0xb8, 0xec, 0x17, 0x31, 0xfe, 0xcb, 0x63, 0xec, 0xdf, 0x21, 0xc6, 0xc1, 0x08, - 0x5b, 0x47, 0xaa, 0x9b, 0x48, 0xdb, 0x13, 0x91, 0x6e, 0x71, 0x22, 0xf4, 0x21, 0x2f, 0xd7, 0x12, - 0xf8, 0x33, 0x5a, 0x8e, 0x19, 0x3f, 0x0d, 0x78, 0xd4, 0xe4, 0xd0, 0x09, 0xfa, 0xc0, 0x85, 0x3d, - 0x93, 0x87, 0x73, 0xcb, 0x3b, 0xd2, 0x04, 0xaa, 0xf1, 0xaf, 0xa2, 0x88, 0x83, 0x10, 0x7e, 0xcd, - 0xc4, 0x5a, 0x33, 0x3d, 0x8d, 0xa9, 0x12, 0xba, 0x14, 0xdf, 0xe0, 0x09, 0xd2, 0x43, 0xd5, 0x89, - 0xba, 0xf1, 0x53, 0x34, 0x97, 0x31, 0x2e, 0x9b, 0x49, 0x64, 0x5b, 0x5b, 0xd6, 0xce, 0xbc, 0x8f, - 0x87, 0x83, 0xda, 0xa2, 0xd6, 0x34, 0x07, 0x84, 0xce, 0xaa, 0x55, 0x23, 0xc2, 0xfb, 0x08, 0x99, - 0x37, 0xa0, 0xf0, 0x53, 0x39, 0x7e, 0x75, 0x38, 0xa8, 0x55, 0x35, 0xfe, 0xfa, 0x8c, 0xd0, 0x79, - 0xb3, 0x69, 0x44, 0xe4, 0x14, 0x2d, 0x8d, 0xd5, 0x3c, 0x26, 0x64, 0xdd, 0x4d, 0x08, 0xdb, 0x68, - 0xce, 0x5c, 0x4f, 0x7b, 0xd3, 0x62, 0x8b, 0x57, 0xd0, 0x4c, 0xfe, 0xff, 0xed, 0xe9, 0xfc, 0xbb, - 0xde, 0x90, 0x9f, 0x16, 0xda, 0xf8, 0x4b, 0xb3, 0xff, 0x3c, 0xc5, 0x5b, 0x84, 0x27, 0x9f, 0x84, - 0x8e, 0xe4, 0x6f, 0x0e, 0x07, 0xb5, 0x07, 0x46, 0x77, 0x02, 0x43, 0x68, 0x35, 0x1c, 0x4f, 0x47, - 0xbe, 0x5a, 0x68, 0xf5, 0xd6, 0xea, 0x55, 0x82, 0x40, 0x2f, 0x75, 0x68, 0x5a, 0x6c, 0xf1, 0x07, - 0x34, 0x9f, 0xe5, 0x53, 0xa4, 0xe8, 0x67, 0x61, 0x6f, 0x33, 0x7f, 0x57, 0x6a, 0x8e, 0xb9, 0xc5, - 0xf0, 0xea, 0xed, 0xba, 0x7a, 0xd6, 0x34, 0x22, 0xdf, 0x36, 0xcf, 0x68, 0xd9, 0x54, 0x5e, 0xb0, - 0x09, 0xfd, 0x3f, 0x2b, 0x30, 0xef, 0xce, 0x2e, 0x1c, 0xeb, 0xfc, 0xc2, 0xb1, 0x7e, 0x5f, 0x38, - 0xd6, 0xb7, 0x4b, 0xa7, 0x72, 0x7e, 0xe9, 0x54, 0x7e, 0x5d, 0x3a, 0x95, 0x8f, 0xcf, 0xdb, 0x89, - 0x3c, 0x3e, 0x69, 0xb9, 0x21, 0xeb, 0x7a, 0x21, 0x13, 0x5d, 0x26, 0xbc, 0xa4, 0x15, 0xd6, 0xdb, - 0xcc, 0xeb, 0xed, 0x7b, 0x5d, 0x16, 0x9d, 0x74, 0x40, 0xa8, 0x31, 0x2b, 0xbc, 0xbd, 0x17, 0x75, - 0x35, 0x61, 0x65, 0x3f, 0x03, 0xd1, 0x9a, 0xcd, 0xc7, 0xe7, 0xb3, 0x3f, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x3c, 0x18, 0x93, 0x1b, 0xdc, 0x05, 0x00, 0x00, + // 648 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcd, 0x4e, 0xd4, 0x40, + 0x1c, 0xdf, 0x82, 0x80, 0x0c, 0x06, 0xd8, 0x09, 0x48, 0x05, 0xe9, 0xe2, 0x18, 0x12, 0xa2, 0xd9, + 0x36, 0x20, 0xc6, 0xe8, 0xcd, 0x12, 0x31, 0x9b, 0x98, 0x48, 0x46, 0x4f, 0x5e, 0x36, 0xdd, 0xf6, + 0xdf, 0xa5, 0x71, 0xb7, 0xd3, 0xcc, 0x0c, 0x4b, 0xd6, 0x9b, 0x27, 0xaf, 0xbe, 0x86, 0xf1, 0x11, + 0x7c, 0x01, 0x8e, 0x1c, 0x3d, 0x6d, 0x0c, 0xbc, 0xc1, 0x3e, 0x81, 0x99, 0xce, 0x14, 0x96, 0xfd, + 0x30, 0x1c, 0xbc, 0xcd, 0x74, 0x7e, 0x5f, 0xd3, 0xdf, 0xe4, 0x8f, 0xb6, 0x93, 0x46, 0xe8, 0x05, + 0x59, 0xd6, 0x4a, 0xc2, 0x40, 0x26, 0x2c, 0x15, 0x5e, 0x0c, 0xe0, 0x75, 0x76, 0xbd, 0x26, 0xa4, + 0x20, 0x12, 0xe1, 0x66, 0x9c, 0x49, 0x86, 0xd7, 0x92, 0x46, 0xe8, 0x0e, 0xc2, 0xdc, 0x18, 0xc0, + 0xed, 0xec, 0xae, 0xaf, 0x34, 0x59, 0x93, 0xe5, 0x18, 0x4f, 0xad, 0x34, 0x7c, 0xfd, 0xd1, 0x24, + 0x55, 0xc5, 0x1a, 0x80, 0x84, 0x8c, 0x83, 0x17, 0x1e, 0x07, 0x69, 0x0a, 0x2d, 0x75, 0x6c, 0x96, + 0x1a, 0x42, 0x7e, 0xce, 0xa0, 0x7b, 0x6f, 0x75, 0x8c, 0x0f, 0x32, 0x90, 0x80, 0x3b, 0x68, 0x29, + 0x89, 0x20, 0x95, 0x49, 0x9c, 0x40, 0x54, 0x8f, 0x01, 0x84, 0x6d, 0x6d, 0x4d, 0xef, 0x2c, 0xec, + 0x55, 0xdd, 0x09, 0xf9, 0xdc, 0xda, 0x15, 0xfe, 0x28, 0x08, 0x3f, 0x83, 0x3c, 0x04, 0x10, 0xbe, + 0x73, 0xd6, 0xab, 0x94, 0xfa, 0xbd, 0xca, 0xfd, 0x6e, 0xd0, 0x6e, 0xbd, 0x22, 0x43, 0x9a, 0x84, + 0x2e, 0x5e, 0x7f, 0x51, 0x78, 0xfc, 0xd5, 0x42, 0x2b, 0x31, 0x40, 0x1d, 0xd2, 0xa0, 0xd1, 0x82, + 0xa8, 0x6e, 0x62, 0x0a, 0x7b, 0x2a, 0x77, 0x7f, 0x32, 0xd1, 0xfd, 0x10, 0xe0, 0x8d, 0xe6, 0x1c, + 0x68, 0x8a, 0xff, 0xd8, 0x58, 0x6f, 0x68, 0xeb, 0x71, 0xaa, 0x84, 0xe2, 0x78, 0x98, 0x27, 0xf0, + 0x29, 0x2a, 0x73, 0x68, 0x26, 0x42, 0x02, 0x87, 0xa8, 0x9e, 0x05, 0x5d, 0x75, 0xfb, 0xe9, 0xdc, + 0x7f, 0x67, 0xa2, 0x3f, 0xbd, 0x62, 0x1c, 0x29, 0x82, 0xbf, 0x65, 0xdc, 0x6d, 0xed, 0x3e, 0x22, + 0x48, 0xe8, 0x32, 0xbf, 0x49, 0x11, 0xf8, 0x87, 0x85, 0x9c, 0x01, 0x60, 0xc8, 0x4e, 0x52, 0x09, + 0x3c, 0x0b, 0xb8, 0xec, 0x16, 0x31, 0xee, 0xe4, 0x31, 0xf6, 0x6f, 0x11, 0xe3, 0x60, 0x80, 0xad, + 0x23, 0x55, 0x4d, 0xa4, 0xed, 0x91, 0x48, 0x63, 0x9c, 0x08, 0x7d, 0xc8, 0x27, 0x6b, 0x09, 0xfc, + 0x05, 0x2d, 0xc7, 0x8c, 0x9f, 0x06, 0x3c, 0xaa, 0x73, 0x68, 0x05, 0x5d, 0xe0, 0xc2, 0x9e, 0xc9, + 0xc3, 0xb9, 0x93, 0x3b, 0xd2, 0x04, 0xaa, 0xf1, 0xaf, 0xa3, 0x88, 0x83, 0x10, 0x7e, 0xc5, 0xc4, + 0x5a, 0x33, 0x3d, 0x0d, 0xa9, 0x12, 0xba, 0x14, 0xdf, 0xe0, 0x09, 0xd2, 0x41, 0xe5, 0x91, 0xba, + 0xf1, 0x53, 0x34, 0x97, 0x31, 0x2e, 0xeb, 0x49, 0x64, 0x5b, 0x5b, 0xd6, 0xce, 0xbc, 0x8f, 0xfb, + 0xbd, 0xca, 0xa2, 0xd6, 0x34, 0x07, 0x84, 0xce, 0xaa, 0x55, 0x2d, 0xc2, 0xfb, 0x08, 0x99, 0x37, + 0xa0, 0xf0, 0x53, 0x39, 0x7e, 0xb5, 0xdf, 0xab, 0x94, 0x35, 0xfe, 0xfa, 0x8c, 0xd0, 0x79, 0xb3, + 0xa9, 0x45, 0xe4, 0x14, 0x2d, 0x0d, 0xd5, 0x3c, 0x24, 0x64, 0xdd, 0x4e, 0x08, 0xdb, 0x68, 0xce, + 0x5c, 0x4f, 0x7b, 0xd3, 0x62, 0x8b, 0x57, 0xd0, 0x4c, 0xfe, 0xff, 0xed, 0xe9, 0xfc, 0xbb, 0xde, + 0x90, 0x5f, 0x16, 0xda, 0xf8, 0x47, 0xb3, 0xff, 0x3d, 0xc5, 0x3b, 0x84, 0x47, 0x9f, 0x84, 0x8e, + 0xe4, 0x6f, 0xf6, 0x7b, 0x95, 0x07, 0x46, 0x77, 0x04, 0x43, 0x68, 0x39, 0x1c, 0x4e, 0x47, 0xbe, + 0x59, 0x68, 0x75, 0x6c, 0xf5, 0x2a, 0x41, 0xa0, 0x97, 0x3a, 0x34, 0x2d, 0xb6, 0xf8, 0x23, 0x9a, + 0xcf, 0xf2, 0x29, 0x52, 0xf4, 0xb3, 0xb0, 0xb7, 0x99, 0xbf, 0x2b, 0x35, 0xc7, 0xdc, 0x62, 0x78, + 0x75, 0x76, 0x5d, 0x3d, 0x6b, 0x6a, 0x91, 0x6f, 0x9b, 0x67, 0xb4, 0x6c, 0x2a, 0x2f, 0xd8, 0x84, + 0xde, 0xcd, 0x0a, 0xcc, 0xfb, 0xb3, 0x0b, 0xc7, 0x3a, 0xbf, 0x70, 0xac, 0x3f, 0x17, 0x8e, 0xf5, + 0xfd, 0xd2, 0x29, 0x9d, 0x5f, 0x3a, 0xa5, 0xdf, 0x97, 0x4e, 0xe9, 0xd3, 0xf3, 0x66, 0x22, 0x8f, + 0x4f, 0x1a, 0x6e, 0xc8, 0xda, 0x5e, 0xc8, 0x44, 0x9b, 0x09, 0x2f, 0x69, 0x84, 0xd5, 0x26, 0xf3, + 0x3a, 0x2f, 0xbc, 0x36, 0x8b, 0x4e, 0x5a, 0x20, 0xd4, 0x98, 0x15, 0xde, 0xde, 0xcb, 0xaa, 0x9a, + 0xb0, 0xb2, 0x9b, 0x81, 0x68, 0xcc, 0xe6, 0xe3, 0xf3, 0xd9, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x25, 0x26, 0x40, 0x90, 0xdc, 0x05, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/29-fee/types/genesis_test.go b/modules/apps/29-fee/types/genesis_test.go index bbec115baf7..cdf217f3afd 100644 --- a/modules/apps/29-fee/types/genesis_test.go +++ b/modules/apps/29-fee/types/genesis_test.go @@ -7,9 +7,9 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/secp256k1" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func TestValidateDefaultGenesis(t *testing.T) { @@ -33,21 +33,21 @@ func TestValidateGenesis(t *testing.T) { { "invalid packetID: invalid port ID", func() { - genState.IdentifiedFees[0].PacketId = channeltypes.NewPacketId("", ibctesting.FirstChannelID, 1) + genState.IdentifiedFees[0].PacketId = channeltypes.NewPacketID("", ibctesting.FirstChannelID, 1) }, false, }, { "invalid packetID: invalid channel ID", func() { - genState.IdentifiedFees[0].PacketId = channeltypes.NewPacketId(ibctesting.MockFeePort, "", 1) + genState.IdentifiedFees[0].PacketId = channeltypes.NewPacketID(ibctesting.MockFeePort, "", 1) }, false, }, { "invalid packetID: invalid sequence", func() { - genState.IdentifiedFees[0].PacketId = channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 0) + genState.IdentifiedFees[0].PacketId = channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 0) }, false, }, @@ -134,7 +134,7 @@ func TestValidateGenesis(t *testing.T) { genState = &types.GenesisState{ IdentifiedFees: []types.IdentifiedPacketFees{ { - PacketId: channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1), + PacketId: channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1), PacketFees: []types.PacketFee{types.NewPacketFee(types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee), defaultAccAddress, nil)}, }, }, @@ -154,7 +154,7 @@ func TestValidateGenesis(t *testing.T) { ForwardRelayers: []types.ForwardRelayerAddress{ { Address: defaultAccAddress, - PacketId: channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1), + PacketId: channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1), }, }, RegisteredPayees: []types.RegisteredPayee{ diff --git a/modules/apps/29-fee/types/keys.go b/modules/apps/29-fee/types/keys.go index c547432400b..823fe951071 100644 --- a/modules/apps/29-fee/types/keys.go +++ b/modules/apps/29-fee/types/keys.go @@ -5,9 +5,10 @@ import ( "strconv" "strings" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) const ( @@ -58,13 +59,13 @@ func KeyFeeEnabled(portID, channelID string) []byte { func ParseKeyFeeEnabled(key string) (portID, channelID string, err error) { keySplit := strings.Split(key, "/") if len(keySplit) != 3 { - return "", "", sdkerrors.Wrapf( - sdkerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 3, len(keySplit), + return "", "", errorsmod.Wrapf( + ibcerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 3, len(keySplit), ) } if keySplit[0] != FeeEnabledKeyPrefix { - return "", "", sdkerrors.Wrapf(sdkerrors.ErrLogic, "key prefix is incorrect: expected %s, got %s", FeeEnabledKeyPrefix, keySplit[0]) + return "", "", errorsmod.Wrapf(ibcerrors.ErrLogic, "key prefix is incorrect: expected %s, got %s", FeeEnabledKeyPrefix, keySplit[0]) } portID = keySplit[1] @@ -82,8 +83,8 @@ func KeyPayee(relayerAddr, channelID string) []byte { func ParseKeyPayeeAddress(key string) (relayerAddr, channelID string, err error) { keySplit := strings.Split(key, "/") if len(keySplit) != 3 { - return "", "", sdkerrors.Wrapf( - sdkerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 3, len(keySplit), + return "", "", errorsmod.Wrapf( + ibcerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 3, len(keySplit), ) } @@ -99,8 +100,8 @@ func KeyCounterpartyPayee(address, channelID string) []byte { func ParseKeyCounterpartyPayee(key string) (address string, channelID string, error error) { keySplit := strings.Split(key, "/") if len(keySplit) != 3 { - return "", "", sdkerrors.Wrapf( - sdkerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 3, len(keySplit), + return "", "", errorsmod.Wrapf( + ibcerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 3, len(keySplit), ) } @@ -116,8 +117,8 @@ func KeyRelayerAddressForAsyncAck(packetID channeltypes.PacketId) []byte { func ParseKeyRelayerAddressForAsyncAck(key string) (channeltypes.PacketId, error) { keySplit := strings.Split(key, "/") if len(keySplit) != 4 { - return channeltypes.PacketId{}, sdkerrors.Wrapf( - sdkerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 4, len(keySplit), + return channeltypes.PacketId{}, errorsmod.Wrapf( + ibcerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 4, len(keySplit), ) } @@ -126,7 +127,7 @@ func ParseKeyRelayerAddressForAsyncAck(key string) (channeltypes.PacketId, error return channeltypes.PacketId{}, err } - packetID := channeltypes.NewPacketId(keySplit[1], keySplit[2], seq) + packetID := channeltypes.NewPacketID(keySplit[1], keySplit[2], seq) return packetID, nil } @@ -139,8 +140,8 @@ func KeyFeesInEscrow(packetID channeltypes.PacketId) []byte { func ParseKeyFeesInEscrow(key string) (channeltypes.PacketId, error) { keySplit := strings.Split(key, "/") if len(keySplit) != 4 { - return channeltypes.PacketId{}, sdkerrors.Wrapf( - sdkerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 4, len(keySplit), + return channeltypes.PacketId{}, errorsmod.Wrapf( + ibcerrors.ErrLogic, "key provided is incorrect: the key split has incorrect length, expected %d, got %d", 4, len(keySplit), ) } @@ -149,7 +150,7 @@ func ParseKeyFeesInEscrow(key string) (channeltypes.PacketId, error) { return channeltypes.PacketId{}, err } - packetID := channeltypes.NewPacketId(keySplit[1], keySplit[2], seq) + packetID := channeltypes.NewPacketID(keySplit[1], keySplit[2], seq) return packetID, nil } diff --git a/modules/apps/29-fee/types/keys_test.go b/modules/apps/29-fee/types/keys_test.go index 26c9158fd7f..d9965c4bf98 100644 --- a/modules/apps/29-fee/types/keys_test.go +++ b/modules/apps/29-fee/types/keys_test.go @@ -6,12 +6,12 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) -var validPacketID = channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) +var validPacketID = channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) func TestKeyPayee(t *testing.T) { key := types.KeyPayee("relayer-address", ibctesting.FirstChannelID) diff --git a/modules/apps/29-fee/types/metadata.pb.go b/modules/apps/29-fee/types/metadata.pb.go index 5715cc7e676..5d89eaa8719 100644 --- a/modules/apps/29-fee/types/metadata.pb.go +++ b/modules/apps/29-fee/types/metadata.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -101,10 +101,10 @@ var fileDescriptor_03d0f000eda681ce = []byte{ 0x95, 0x58, 0x50, 0x00, 0xd5, 0xe8, 0xe4, 0x7f, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xa6, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0xf9, - 0xc5, 0xb9, 0xf9, 0xc5, 0xfa, 0x99, 0x49, 0xc9, 0xba, 0xe9, 0xf9, 0xfa, 0x65, 0x26, 0xfa, 0xb9, + 0xc5, 0xb9, 0xf9, 0xc5, 0xfa, 0x99, 0x49, 0xc9, 0xba, 0xe9, 0xf9, 0xfa, 0x65, 0xe6, 0xfa, 0xb9, 0xf9, 0x29, 0xa5, 0x39, 0xa9, 0xc5, 0xa0, 0xe0, 0x28, 0xd6, 0x37, 0xb2, 0xd4, 0x05, 0x85, 0x44, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x57, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xbf, 0xe9, 0x11, 0xe3, 0x2e, 0x01, 0x00, 0x00, + 0xa6, 0xd7, 0xc2, 0x68, 0x2e, 0x01, 0x00, 0x00, } func (m *Metadata) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/29-fee/types/msgs.go b/modules/apps/29-fee/types/msgs.go index 4b0fd331c9d..0828beba868 100644 --- a/modules/apps/29-fee/types/msgs.go +++ b/modules/apps/29-fee/types/msgs.go @@ -3,17 +3,12 @@ package types import ( "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" -) - -// msg types -const ( - TypeMsgPayPacketFee = "payPacketFee" - TypeMsgPayPacketFeeAsync = "payPacketFeeAsync" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // NewMsgRegisterPayee creates a new instance of MsgRegisterPayee @@ -37,17 +32,17 @@ func (msg MsgRegisterPayee) ValidateBasic() error { } if msg.Relayer == msg.Payee { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "relayer address and payee must not be equal") + return errorsmod.Wrap(ibcerrors.ErrInvalidRequest, "relayer address and payee must not be equal") } _, err := sdk.AccAddressFromBech32(msg.Relayer) if err != nil { - return sdkerrors.Wrap(err, "failed to create sdk.AccAddress from relayer address") + return errorsmod.Wrap(err, "failed to create sdk.AccAddress from relayer address") } _, err = sdk.AccAddressFromBech32(msg.Payee) if err != nil { - return sdkerrors.Wrap(err, "failed to create sdk.AccAddress from payee address") + return errorsmod.Wrap(err, "failed to create sdk.AccAddress from payee address") } return nil @@ -85,7 +80,7 @@ func (msg MsgRegisterCounterpartyPayee) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Relayer) if err != nil { - return sdkerrors.Wrap(err, "failed to create sdk.AccAddress from relayer address") + return errorsmod.Wrap(err, "failed to create sdk.AccAddress from relayer address") } if strings.TrimSpace(msg.CounterpartyPayee) == "" { @@ -106,11 +101,11 @@ func (msg MsgRegisterCounterpartyPayee) GetSigners() []sdk.AccAddress { } // NewMsgPayPacketFee creates a new instance of MsgPayPacketFee -func NewMsgPayPacketFee(fee Fee, sourcePortId, sourceChannelId, signer string, relayers []string) *MsgPayPacketFee { +func NewMsgPayPacketFee(fee Fee, sourcePortID, sourceChannelID, signer string, relayers []string) *MsgPayPacketFee { return &MsgPayPacketFee{ Fee: fee, - SourcePortId: sourcePortId, - SourceChannelId: sourceChannelId, + SourcePortId: sourcePortID, + SourceChannelId: sourceChannelID, Signer: signer, Relayers: relayers, } @@ -130,12 +125,12 @@ func (msg MsgPayPacketFee) ValidateBasic() error { // signer check if _, err := sdk.AccAddressFromBech32(msg.Signer); err != nil { - return sdkerrors.Wrap(err, "failed to convert msg.Signer into sdk.AccAddress") + return errorsmod.Wrap(err, "failed to convert msg.Signer into sdk.AccAddress") } - // enforce relayer is nil - if msg.Relayers != nil { - return ErrRelayersNotNil + // enforce relayer is not set + if len(msg.Relayers) != 0 { + return ErrRelayersNotEmpty } if err := msg.Fee.Validate(); err != nil { @@ -159,11 +154,6 @@ func (msg MsgPayPacketFee) Route() string { return RouterKey } -// Type implements sdk.Msg -func (msg MsgPayPacketFee) Type() string { - return TypeMsgPayPacketFee -} - // GetSignBytes implements sdk.Msg. func (msg MsgPayPacketFee) GetSignBytes() []byte { return sdk.MustSortJSON(AminoCdc.MustMarshalJSON(&msg)) @@ -205,11 +195,6 @@ func (msg MsgPayPacketFeeAsync) Route() string { return RouterKey } -// Type implements sdk.Msg -func (msg MsgPayPacketFeeAsync) Type() string { - return TypeMsgPayPacketFeeAsync -} - // GetSignBytes implements sdk.Msg. func (msg MsgPayPacketFeeAsync) GetSignBytes() []byte { return sdk.MustSortJSON(AminoCdc.MustMarshalJSON(&msg)) diff --git a/modules/apps/29-fee/types/msgs_test.go b/modules/apps/29-fee/types/msgs_test.go index 93573e354a8..2bba74bff42 100644 --- a/modules/apps/29-fee/types/msgs_test.go +++ b/modules/apps/29-fee/types/msgs_test.go @@ -4,13 +4,12 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/secp256k1" + + "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func TestMsgRegisterPayeeValidation(t *testing.T) { @@ -51,14 +50,14 @@ func TestMsgRegisterPayeeValidation(t *testing.T) { { "invalid relayer address", func() { - msg.Relayer = "invalid-address" + msg.Relayer = invalidAddress }, false, }, { "invalid payee address", func() { - msg.Payee = "invalid-address" + msg.Payee = invalidAddress }, false, }, @@ -85,7 +84,7 @@ func TestMsgRegisterPayeeValidation(t *testing.T) { func TestRegisterPayeeGetSigners(t *testing.T) { accAddress := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) msg := types.NewMsgRegisterPayee(ibctesting.MockPort, ibctesting.FirstChannelID, accAddress.String(), defaultAccAddress) - require.Equal(t, []sdk.AccAddress{sdk.AccAddress(accAddress)}, msg.GetSigners()) + require.Equal(t, []sdk.AccAddress{accAddress}, msg.GetSigners()) } func TestMsgRegisterCountepartyPayeeValidation(t *testing.T) { @@ -118,7 +117,7 @@ func TestMsgRegisterCountepartyPayeeValidation(t *testing.T) { { "validate with incorrect destination relayer address", func() { - msg.Relayer = "invalid-address" + msg.Relayer = invalidAddress }, false, }, @@ -156,7 +155,7 @@ func TestMsgRegisterCountepartyPayeeValidation(t *testing.T) { func TestRegisterCountepartyAddressGetSigners(t *testing.T) { accAddress := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) msg := types.NewMsgRegisterCounterpartyPayee(ibctesting.MockPort, ibctesting.FirstChannelID, accAddress.String(), defaultAccAddress) - require.Equal(t, []sdk.AccAddress{sdk.AccAddress(accAddress)}, msg.GetSigners()) + require.Equal(t, []sdk.AccAddress{accAddress}, msg.GetSigners()) } func TestMsgPayPacketFeeValidation(t *testing.T) { @@ -172,6 +171,13 @@ func TestMsgPayPacketFeeValidation(t *testing.T) { func() {}, true, }, + { + "success with empty relayers", + func() { + msg.Relayers = []string{} + }, + true, + }, { "invalid channelID", func() { @@ -196,7 +202,7 @@ func TestMsgPayPacketFeeValidation(t *testing.T) { { "invalid signer address", func() { - msg.Signer = "invalid-address" + msg.Signer = invalidAddress }, false, }, @@ -211,9 +217,9 @@ func TestMsgPayPacketFeeValidation(t *testing.T) { err := msg.ValidateBasic() if tc.expPass { - require.NoError(t, err) + require.NoError(t, err, tc.name) } else { - require.Error(t, err) + require.Error(t, err, tc.name) } } } @@ -231,11 +237,6 @@ func TestMsgPayPacketFeeRoute(t *testing.T) { require.Equal(t, types.RouterKey, msg.Route()) } -func TestMsgPayPacketFeeType(t *testing.T) { - var msg types.MsgPayPacketFee - require.Equal(t, "payPacketFee", msg.Type()) -} - func TestMsgPayPacketFeeGetSignBytes(t *testing.T) { fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) msg := types.NewMsgPayPacketFee(fee, ibctesting.MockFeePort, ibctesting.FirstChannelID, defaultAccAddress, nil) @@ -258,6 +259,13 @@ func TestMsgPayPacketFeeAsyncValidation(t *testing.T) { func() {}, true, }, + { + "success with empty relayers", + func() { + msg.PacketFee.Relayers = []string{} + }, + true, + }, { "invalid channelID", func() { @@ -344,7 +352,7 @@ func TestMsgPayPacketFeeAsyncValidation(t *testing.T) { } for _, tc := range testCases { - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, defaultAccAddress, nil) @@ -355,16 +363,16 @@ func TestMsgPayPacketFeeAsyncValidation(t *testing.T) { err := msg.ValidateBasic() if tc.expPass { - require.NoError(t, err) + require.NoError(t, err, tc.name) } else { - require.Error(t, err) + require.Error(t, err, tc.name) } } } func TestPayPacketFeeAsyncGetSigners(t *testing.T) { refundAddr := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, refundAddr.String(), nil) @@ -378,13 +386,8 @@ func TestMsgPayPacketFeeAsyncRoute(t *testing.T) { require.Equal(t, types.RouterKey, msg.Route()) } -func TestMsgPayPacketFeeAsyncType(t *testing.T) { - var msg types.MsgPayPacketFeeAsync - require.Equal(t, "payPacketFeeAsync", msg.Type()) -} - func TestMsgPayPacketFeeAsyncGetSignBytes(t *testing.T) { - packetID := channeltypes.NewPacketId(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) + packetID := channeltypes.NewPacketID(ibctesting.MockFeePort, ibctesting.FirstChannelID, 1) fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) packetFee := types.NewPacketFee(fee, defaultAccAddress, nil) diff --git a/modules/apps/29-fee/types/query.pb.go b/modules/apps/29-fee/types/query.pb.go index 87a5f18f894..379d32bca12 100644 --- a/modules/apps/29-fee/types/query.pb.go +++ b/modules/apps/29-fee/types/query.pb.go @@ -9,10 +9,10 @@ import ( github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types1 "github.com/cosmos/cosmos-sdk/types" query "github.com/cosmos/cosmos-sdk/types/query" - types "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -92,6 +92,8 @@ func (m *QueryIncentivizedPacketsRequest) GetQueryHeight() uint64 { type QueryIncentivizedPacketsResponse struct { // list of identified fees for incentivized packets IncentivizedPackets []IdentifiedPacketFees `protobuf:"bytes,1,rep,name=incentivized_packets,json=incentivizedPackets,proto3" json:"incentivized_packets"` + // pagination defines the pagination in the response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryIncentivizedPacketsResponse) Reset() { *m = QueryIncentivizedPacketsResponse{} } @@ -134,6 +136,13 @@ func (m *QueryIncentivizedPacketsResponse) GetIncentivizedPackets() []Identified return nil } +func (m *QueryIncentivizedPacketsResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + // QueryIncentivizedPacketRequest defines the request type for the IncentivizedPacket rpc type QueryIncentivizedPacketRequest struct { // unique packet identifier comprised of channel ID, port ID and sequence @@ -315,6 +324,8 @@ func (m *QueryIncentivizedPacketsForChannelRequest) GetQueryHeight() uint64 { type QueryIncentivizedPacketsForChannelResponse struct { // Map of all incentivized_packets IncentivizedPackets []*IdentifiedPacketFees `protobuf:"bytes,1,rep,name=incentivized_packets,json=incentivizedPackets,proto3" json:"incentivized_packets,omitempty"` + // pagination defines the pagination in the response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryIncentivizedPacketsForChannelResponse) Reset() { @@ -361,6 +372,13 @@ func (m *QueryIncentivizedPacketsForChannelResponse) GetIncentivizedPackets() [] return nil } +func (m *QueryIncentivizedPacketsForChannelResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + // QueryTotalRecvFeesRequest defines the request type for the TotalRecvFees rpc type QueryTotalRecvFeesRequest struct { // the packet identifier for the associated fees @@ -898,6 +916,8 @@ func (m *QueryFeeEnabledChannelsRequest) GetQueryHeight() uint64 { type QueryFeeEnabledChannelsResponse struct { // list of fee enabled channels FeeEnabledChannels []FeeEnabledChannel `protobuf:"bytes,1,rep,name=fee_enabled_channels,json=feeEnabledChannels,proto3" json:"fee_enabled_channels" yaml:"fee_enabled_channels"` + // pagination defines the pagination in the response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryFeeEnabledChannelsResponse) Reset() { *m = QueryFeeEnabledChannelsResponse{} } @@ -940,6 +960,13 @@ func (m *QueryFeeEnabledChannelsResponse) GetFeeEnabledChannels() []FeeEnabledCh return nil } +func (m *QueryFeeEnabledChannelsResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + // QueryFeeEnabledChannelRequest defines the request type for the FeeEnabledChannel rpc type QueryFeeEnabledChannelRequest struct { // unique port identifier @@ -1069,91 +1096,92 @@ func init() { } var fileDescriptor_0638a8a78ca2503c = []byte{ - // 1340 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0x5f, 0x6f, 0xdb, 0xd4, - 0x1b, 0xee, 0xe9, 0xba, 0xb5, 0x3d, 0xed, 0x7e, 0xbf, 0xe5, 0xb4, 0xb0, 0x34, 0xb4, 0x49, 0xe7, - 0x31, 0x28, 0x9d, 0x6a, 0xab, 0xd9, 0x46, 0x37, 0x24, 0x04, 0x4d, 0x47, 0x47, 0x61, 0x40, 0xc9, - 0x7a, 0x03, 0x02, 0x65, 0x8e, 0x73, 0x92, 0x5a, 0x4d, 0x7d, 0x3c, 0xdb, 0x89, 0xc8, 0xba, 0x02, - 0x9b, 0xa8, 0x40, 0x80, 0x00, 0x09, 0x89, 0x0b, 0xee, 0x11, 0x02, 0x89, 0x0f, 0xc0, 0x37, 0xd8, - 0x15, 0xaa, 0xc4, 0x0d, 0xe2, 0x22, 0xa0, 0x16, 0xf1, 0x01, 0x72, 0xc5, 0x05, 0x48, 0xc8, 0xe7, - 0xbc, 0x4e, 0x9c, 0xd9, 0x6e, 0x93, 0x52, 0xca, 0x55, 0x6d, 0x9f, 0xf7, 0xcf, 0xf3, 0x3c, 0xe7, - 0xb5, 0xcf, 0x93, 0xe2, 0xb3, 0x7a, 0x5e, 0x53, 0x54, 0xd3, 0x2c, 0xeb, 0x9a, 0xea, 0xe8, 0xcc, - 0xb0, 0x95, 0x22, 0xa5, 0x4a, 0x75, 0x56, 0xb9, 0x55, 0xa1, 0x56, 0x4d, 0x36, 0x2d, 0xe6, 0x30, - 0x72, 0x5a, 0xcf, 0x6b, 0xb2, 0x3f, 0x48, 0x2e, 0x52, 0x2a, 0x57, 0x67, 0x13, 0xa3, 0x25, 0x56, - 0x62, 0x3c, 0x46, 0x71, 0xaf, 0x44, 0x78, 0x62, 0xbc, 0xc4, 0x58, 0xa9, 0x4c, 0x15, 0xd5, 0xd4, - 0x15, 0xd5, 0x30, 0x98, 0x03, 0x49, 0x62, 0x35, 0xa9, 0x31, 0x7b, 0x9d, 0xd9, 0x4a, 0x5e, 0xb5, - 0xdd, 0x46, 0x79, 0xea, 0xa8, 0xb3, 0x8a, 0xc6, 0x74, 0x03, 0xd6, 0xa7, 0xfd, 0xeb, 0x1c, 0x45, - 0x33, 0xca, 0x54, 0x4b, 0xba, 0xc1, 0x8b, 0x41, 0xec, 0x99, 0x28, 0xf4, 0x2e, 0x3e, 0x11, 0x72, - 0x2e, 0x2a, 0xa4, 0x44, 0x0d, 0x6a, 0xeb, 0xb6, 0xbf, 0x92, 0xc6, 0x2c, 0xaa, 0x68, 0xab, 0xaa, - 0x61, 0xd0, 0xb2, 0x1b, 0x02, 0x97, 0x22, 0x44, 0xfa, 0x18, 0xe1, 0xd4, 0xab, 0x2e, 0x9e, 0x25, - 0x43, 0xa3, 0x86, 0xa3, 0x57, 0xf5, 0xdb, 0xb4, 0xb0, 0xac, 0x6a, 0x6b, 0xd4, 0xb1, 0xb3, 0xf4, - 0x56, 0x85, 0xda, 0x0e, 0x59, 0xc4, 0xb8, 0x05, 0x32, 0x8e, 0x26, 0xd1, 0xd4, 0x50, 0xfa, 0x31, - 0x59, 0x30, 0x92, 0x5d, 0x46, 0xb2, 0xd0, 0x15, 0x18, 0xc9, 0xcb, 0x6a, 0x89, 0x42, 0x6e, 0xd6, - 0x97, 0x49, 0xce, 0xe0, 0x61, 0x1e, 0x98, 0x5b, 0xa5, 0x7a, 0x69, 0xd5, 0x89, 0xf7, 0x4e, 0xa2, - 0xa9, 0xbe, 0xec, 0x10, 0x7f, 0xf6, 0x3c, 0x7f, 0x24, 0x7d, 0x88, 0xf0, 0x64, 0x34, 0x1c, 0xdb, - 0x64, 0x86, 0x4d, 0x49, 0x11, 0x8f, 0xea, 0xbe, 0xe5, 0x9c, 0x29, 0xd6, 0xe3, 0x68, 0xf2, 0xd8, - 0xd4, 0x50, 0x7a, 0x46, 0x8e, 0xd8, 0x58, 0x79, 0xa9, 0xe0, 0xe6, 0x14, 0x75, 0xaf, 0xe2, 0x22, - 0xa5, 0x76, 0xa6, 0xef, 0x7e, 0x3d, 0xd5, 0x93, 0x1d, 0xd1, 0x83, 0xfd, 0xa4, 0x2d, 0x84, 0x93, - 0x11, 0x60, 0x3c, 0x69, 0x9e, 0xc5, 0x83, 0xa2, 0x7b, 0x4e, 0x2f, 0x80, 0x32, 0x13, 0xbc, 0xbf, - 0xab, 0xba, 0xec, 0x49, 0x5d, 0x75, 0x35, 0x71, 0xa3, 0x96, 0x0a, 0xd0, 0x6f, 0xc0, 0x84, 0xfb, - 0x4e, 0x44, 0x79, 0x3f, 0x7a, 0x8f, 0x9a, 0x9a, 0x14, 0xf0, 0x48, 0x88, 0x26, 0x00, 0xe9, 0x40, - 0x92, 0x90, 0xa0, 0x24, 0xd2, 0x0f, 0x08, 0x3f, 0x11, 0xb5, 0x3d, 0x8b, 0xcc, 0x5a, 0x10, 0x7c, - 0x0f, 0x7b, 0x6e, 0x4e, 0xe3, 0x7e, 0x93, 0x59, 0x5c, 0x62, 0x57, 0x9d, 0xc1, 0xec, 0x09, 0xf7, - 0x76, 0xa9, 0x40, 0x26, 0x30, 0x06, 0x89, 0xdd, 0xb5, 0x63, 0x7c, 0x6d, 0x10, 0x9e, 0x84, 0x48, - 0xdb, 0x17, 0x94, 0xf6, 0x13, 0x84, 0xa7, 0x3b, 0x21, 0x04, 0x2a, 0xdf, 0x3c, 0xc4, 0xc9, 0x0b, - 0x9f, 0xb9, 0x37, 0xf1, 0x18, 0xc7, 0xb3, 0xc2, 0x1c, 0xb5, 0x9c, 0xa5, 0x5a, 0x95, 0x87, 0x1e, - 0xd6, 0xb4, 0x49, 0x5f, 0x22, 0x9c, 0x08, 0xab, 0x0f, 0xfc, 0xee, 0xe0, 0x41, 0x8b, 0x6a, 0xd5, - 0x5c, 0x91, 0x52, 0x8f, 0xd4, 0x58, 0xdb, 0x86, 0x79, 0x5b, 0xb5, 0xc0, 0x74, 0x23, 0x73, 0xd5, - 0x2d, 0xde, 0xa8, 0xa7, 0x4e, 0xd5, 0xd4, 0xf5, 0xf2, 0x53, 0x52, 0x33, 0x53, 0xfa, 0xf6, 0x97, - 0xd4, 0x54, 0x49, 0x77, 0x56, 0x2b, 0x79, 0x59, 0x63, 0xeb, 0x0a, 0x7c, 0xfb, 0xc4, 0x9f, 0x19, - 0xbb, 0xb0, 0xa6, 0x38, 0x35, 0x93, 0xda, 0xbc, 0x88, 0x9d, 0x1d, 0xb0, 0x00, 0x85, 0xf4, 0x06, - 0x8e, 0xb7, 0xb0, 0xcd, 0x6b, 0x6b, 0x87, 0x4b, 0xfd, 0x0b, 0xe4, 0x97, 0xb6, 0x59, 0x1e, 0x98, - 0xd7, 0xf0, 0x80, 0xaa, 0xad, 0x75, 0x48, 0x7c, 0x01, 0x88, 0xff, 0x5f, 0x10, 0xf7, 0x12, 0xbb, - 0xe3, 0xdd, 0xaf, 0x0a, 0x08, 0xd2, 0x4d, 0x3c, 0xde, 0xc2, 0xb5, 0xa2, 0xaf, 0x53, 0x56, 0x71, - 0x0e, 0x97, 0xfa, 0xd7, 0x08, 0x4f, 0x44, 0xb4, 0x00, 0xfa, 0x5b, 0x08, 0x0f, 0x3b, 0xe2, 0x79, - 0x87, 0x1a, 0x5c, 0x03, 0x0d, 0x46, 0x84, 0x06, 0xfe, 0xe4, 0xee, 0x74, 0x18, 0x72, 0x5a, 0x78, - 0x24, 0x0d, 0xc7, 0x38, 0xd0, 0x65, 0xb5, 0x46, 0xbd, 0x6f, 0x01, 0xb9, 0xd8, 0xf6, 0x9a, 0xbb, - 0x0a, 0x0c, 0x66, 0x1e, 0x6a, 0xd4, 0x53, 0x31, 0xd1, 0xba, 0xb5, 0x26, 0xf9, 0xdf, 0xfe, 0x38, - 0xee, 0xb7, 0x68, 0x59, 0xad, 0x51, 0x0b, 0xbe, 0x1a, 0xde, 0xad, 0x74, 0x03, 0x13, 0x7f, 0x13, - 0x90, 0xe0, 0x69, 0x7c, 0xd2, 0x74, 0x1f, 0xe4, 0xd4, 0x42, 0xc1, 0xa2, 0xb6, 0x0d, 0x8d, 0xe2, - 0x8d, 0x7a, 0x6a, 0x54, 0x34, 0x6a, 0x5b, 0x96, 0xb2, 0xc3, 0xfc, 0x7e, 0x1e, 0x6e, 0x19, 0x48, - 0xbc, 0xc0, 0x2a, 0x86, 0x43, 0x2d, 0x53, 0xb5, 0x9c, 0x7f, 0x97, 0x85, 0x01, 0x87, 0x53, 0x48, - 0x43, 0x60, 0x74, 0x1d, 0x13, 0xcd, 0xb7, 0x98, 0xe3, 0x78, 0xa1, 0xf3, 0x44, 0xa3, 0x9e, 0x1a, - 0x83, 0xce, 0x81, 0x18, 0x29, 0x1b, 0xd3, 0x1e, 0xac, 0x2a, 0x7d, 0xe4, 0x9d, 0x86, 0x8b, 0x94, - 0x3e, 0x67, 0xa8, 0xf9, 0x32, 0x2d, 0xc0, 0xe7, 0xf1, 0xbf, 0x30, 0x0a, 0x5f, 0x79, 0x67, 0x62, - 0x18, 0x1a, 0xe0, 0x7f, 0x17, 0xe1, 0xd1, 0x22, 0xa5, 0x39, 0x2a, 0xd6, 0x73, 0xa0, 0xaa, 0x37, - 0xdc, 0xd3, 0x91, 0x9f, 0xeb, 0x40, 0xcd, 0xcc, 0x59, 0x98, 0xf6, 0x47, 0x84, 0x64, 0x61, 0x55, - 0xa5, 0x2c, 0x29, 0x06, 0xb0, 0x48, 0xf7, 0xbc, 0x57, 0x2f, 0x50, 0xd3, 0x13, 0xed, 0x7c, 0xeb, - 0x74, 0x13, 0x5b, 0x43, 0x1a, 0xf5, 0xd4, 0xff, 0x60, 0xe2, 0xc4, 0x82, 0xd4, 0x3c, 0xf1, 0xda, - 0x87, 0xa8, 0xb7, 0xb3, 0x21, 0x92, 0x5e, 0x8b, 0xda, 0xb9, 0xa6, 0x54, 0x73, 0x78, 0xc8, 0xc7, - 0x89, 0x03, 0x19, 0xc8, 0x3c, 0xdc, 0xa8, 0xa7, 0x48, 0x80, 0xb0, 0x94, 0xc5, 0x2d, 0x9e, 0xe9, - 0xdf, 0x63, 0xf8, 0x38, 0xaf, 0x4d, 0xbe, 0x47, 0x78, 0x24, 0xe4, 0x14, 0x25, 0x97, 0x23, 0x65, - 0xde, 0xc7, 0x77, 0x26, 0xae, 0x1c, 0x20, 0x53, 0xf0, 0x91, 0x66, 0xee, 0xfd, 0xf8, 0xdb, 0xe7, - 0xbd, 0x8f, 0x93, 0x73, 0x0a, 0x38, 0xe5, 0xa6, 0x43, 0x0e, 0x3b, 0xbf, 0xc9, 0xa7, 0xbd, 0x98, - 0x04, 0xcb, 0x91, 0xb9, 0x6e, 0x01, 0x78, 0xc8, 0x2f, 0x77, 0x9f, 0x08, 0xc0, 0xb7, 0x10, 0x47, - 0xfe, 0x0e, 0xd9, 0x0c, 0x20, 0xf7, 0x06, 0x4d, 0xd9, 0x68, 0x1e, 0x07, 0x72, 0x6b, 0xc3, 0x37, - 0x15, 0x77, 0x44, 0xda, 0x16, 0x61, 0x7a, 0x36, 0x15, 0xdb, 0x85, 0x65, 0x68, 0xb4, 0x6d, 0xd5, - 0x7b, 0xb8, 0x19, 0x26, 0x09, 0xf9, 0x0b, 0xe1, 0x89, 0x3d, 0x3d, 0x11, 0xc9, 0x74, 0xbd, 0x3b, - 0x01, 0x87, 0x98, 0x58, 0xf8, 0x47, 0x35, 0x40, 0xb2, 0x1b, 0x5c, 0xb1, 0x97, 0xc8, 0x8b, 0x7b, - 0x28, 0x16, 0xa6, 0x93, 0xa7, 0x4e, 0xe8, 0x44, 0xfc, 0x89, 0xf0, 0xc9, 0x36, 0x8f, 0x44, 0xd2, - 0x7b, 0x63, 0x0d, 0x33, 0x6c, 0x89, 0x0b, 0x5d, 0xe5, 0x00, 0x9f, 0xbb, 0x62, 0x04, 0x36, 0x48, - 0xed, 0xe8, 0x46, 0xc0, 0x71, 0x91, 0xe4, 0x9a, 0x0e, 0x8e, 0xfc, 0x81, 0xf0, 0xb0, 0xdf, 0x27, - 0x91, 0xd9, 0x0e, 0x98, 0xb4, 0x5b, 0xb6, 0x44, 0xba, 0x9b, 0x14, 0xe0, 0xfe, 0xae, 0xe0, 0x7e, - 0x9b, 0xbc, 0x75, 0xd4, 0xdc, 0x3d, 0x13, 0x47, 0x3e, 0xe8, 0xc5, 0xa7, 0x1e, 0xf4, 0x49, 0xe4, - 0x52, 0x07, 0x5c, 0x82, 0xd6, 0x2d, 0xf1, 0x64, 0xb7, 0x69, 0x20, 0xc3, 0x7b, 0x42, 0x86, 0xb7, - 0xc9, 0x9d, 0xa3, 0x96, 0xc1, 0xef, 0xe3, 0xc8, 0x37, 0x08, 0x1f, 0xe7, 0x87, 0x3f, 0x99, 0xde, - 0x9b, 0x88, 0xdf, 0xe8, 0x24, 0xce, 0x77, 0x14, 0x0b, 0x4c, 0xaf, 0x71, 0xa2, 0xf3, 0xe4, 0x99, - 0x0e, 0x5f, 0x5e, 0x70, 0x3f, 0xb6, 0xb2, 0x01, 0x57, 0x9b, 0x0a, 0xb7, 0x2c, 0xe4, 0x67, 0x84, - 0x63, 0x01, 0x2b, 0x44, 0xf6, 0xd9, 0x80, 0x28, 0xb3, 0x96, 0x98, 0xeb, 0x3a, 0x0f, 0xf8, 0xac, - 0x70, 0x3e, 0x2f, 0x93, 0xeb, 0x07, 0xe7, 0x13, 0xf4, 0x63, 0xe4, 0x3b, 0x84, 0x49, 0xd0, 0xe8, - 0xec, 0x77, 0x3e, 0x45, 0x1a, 0xb5, 0xfd, 0xce, 0xa7, 0x68, 0x4f, 0x25, 0x3d, 0xca, 0xf9, 0x25, - 0xc9, 0x78, 0x80, 0x9f, 0xcf, 0x22, 0x90, 0x6d, 0x84, 0x63, 0x81, 0x22, 0xfb, 0x6d, 0x46, 0x94, - 0x43, 0x4a, 0xcc, 0x75, 0x9d, 0x07, 0x60, 0x5f, 0xe0, 0x60, 0xaf, 0x92, 0xcc, 0x01, 0x4f, 0x06, - 0x1f, 0xa5, 0xcc, 0x2b, 0xf7, 0x77, 0x92, 0x68, 0x7b, 0x27, 0x89, 0x7e, 0xdd, 0x49, 0xa2, 0xcf, - 0x76, 0x93, 0x3d, 0xdb, 0xbb, 0xc9, 0x9e, 0x9f, 0x76, 0x93, 0x3d, 0xaf, 0x5f, 0x0a, 0xfe, 0xd4, - 0xd1, 0xf3, 0xda, 0x4c, 0x89, 0x29, 0xd5, 0x8b, 0xca, 0x3a, 0x2b, 0x54, 0xca, 0xd4, 0x16, 0xcd, - 0xd3, 0x57, 0x66, 0xdc, 0xfe, 0xfc, 0xd7, 0x4f, 0xfe, 0x04, 0xff, 0x07, 0xdc, 0x85, 0xbf, 0x03, - 0x00, 0x00, 0xff, 0xff, 0xae, 0x96, 0x61, 0xf5, 0xad, 0x14, 0x00, 0x00, + // 1358 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0x51, 0x6f, 0xdb, 0x54, + 0x14, 0xee, 0xcd, 0xba, 0xb5, 0xbd, 0xed, 0x60, 0xb9, 0x2d, 0x2c, 0x0d, 0x6d, 0xd2, 0x79, 0x8c, + 0x95, 0x4e, 0xb5, 0xd5, 0x8c, 0xd1, 0x0d, 0x09, 0x41, 0xd3, 0xd1, 0x52, 0x18, 0x50, 0xb2, 0xbe, + 0x80, 0x40, 0x99, 0xe3, 0xdc, 0xa4, 0x56, 0x53, 0xdb, 0xb3, 0x9d, 0x88, 0xac, 0x2b, 0xb0, 0x89, + 0x0a, 0x24, 0x90, 0x40, 0x42, 0xe2, 0x81, 0x3f, 0x80, 0x40, 0xe2, 0x07, 0xf0, 0x0f, 0xf6, 0x84, + 0x2a, 0xed, 0x01, 0xc4, 0x43, 0x40, 0x2d, 0xe2, 0x91, 0x87, 0x3c, 0xf1, 0x00, 0x12, 0xf2, 0xbd, + 0xc7, 0x89, 0x33, 0xdb, 0x4d, 0x52, 0xb2, 0xf2, 0xd4, 0xd8, 0xe7, 0x9e, 0x73, 0xbe, 0xef, 0xbb, + 0x27, 0xf7, 0x7e, 0x29, 0x3e, 0xab, 0xe6, 0x14, 0x49, 0x36, 0x8c, 0x92, 0xaa, 0xc8, 0xb6, 0xaa, + 0x6b, 0x96, 0x54, 0xa0, 0x54, 0xaa, 0xcc, 0x49, 0x37, 0xcb, 0xd4, 0xac, 0x8a, 0x86, 0xa9, 0xdb, + 0x3a, 0x39, 0xad, 0xe6, 0x14, 0xd1, 0xbb, 0x48, 0x2c, 0x50, 0x2a, 0x56, 0xe6, 0xe2, 0x63, 0x45, + 0xbd, 0xa8, 0xb3, 0x35, 0x92, 0xf3, 0x89, 0x2f, 0x8f, 0x4f, 0x14, 0x75, 0xbd, 0x58, 0xa2, 0x92, + 0x6c, 0xa8, 0x92, 0xac, 0x69, 0xba, 0x0d, 0x49, 0x3c, 0x9a, 0x50, 0x74, 0x6b, 0x53, 0xb7, 0xa4, + 0x9c, 0x6c, 0x39, 0x8d, 0x72, 0xd4, 0x96, 0xe7, 0x24, 0x45, 0x57, 0x35, 0x88, 0xcf, 0x78, 0xe3, + 0x0c, 0x45, 0x63, 0x95, 0x21, 0x17, 0x55, 0x8d, 0x15, 0x83, 0xb5, 0x67, 0xc2, 0xd0, 0x3b, 0xf8, + 0xf8, 0x92, 0x73, 0x61, 0x4b, 0x8a, 0x54, 0xa3, 0x96, 0x6a, 0x79, 0x2b, 0x29, 0xba, 0x49, 0x25, + 0x65, 0x5d, 0xd6, 0x34, 0x5a, 0x72, 0x96, 0xc0, 0x47, 0xbe, 0x44, 0xf8, 0x0c, 0xe1, 0xe4, 0x9b, + 0x0e, 0x9e, 0x15, 0x4d, 0xa1, 0x9a, 0xad, 0x56, 0xd4, 0x5b, 0x34, 0xbf, 0x2a, 0x2b, 0x1b, 0xd4, + 0xb6, 0x32, 0xf4, 0x66, 0x99, 0x5a, 0x36, 0x59, 0xc2, 0xb8, 0x09, 0x32, 0x86, 0xa6, 0xd0, 0xf4, + 0x70, 0xea, 0x29, 0x91, 0x33, 0x12, 0x1d, 0x46, 0x22, 0xd7, 0x15, 0x18, 0x89, 0xab, 0x72, 0x91, + 0x42, 0x6e, 0xc6, 0x93, 0x49, 0xce, 0xe0, 0x11, 0xb6, 0x30, 0xbb, 0x4e, 0xd5, 0xe2, 0xba, 0x1d, + 0x8b, 0x4c, 0xa1, 0xe9, 0xfe, 0xcc, 0x30, 0x7b, 0xf7, 0x32, 0x7b, 0x25, 0xdc, 0x47, 0x78, 0x2a, + 0x1c, 0x8e, 0x65, 0xe8, 0x9a, 0x45, 0x49, 0x01, 0x8f, 0xa9, 0x9e, 0x70, 0xd6, 0xe0, 0xf1, 0x18, + 0x9a, 0x3a, 0x36, 0x3d, 0x9c, 0x9a, 0x15, 0x43, 0x36, 0x56, 0x5c, 0xc9, 0x3b, 0x39, 0x05, 0xd5, + 0xad, 0xb8, 0x44, 0xa9, 0x95, 0xee, 0xbf, 0x57, 0x4b, 0xf6, 0x65, 0x46, 0x55, 0x7f, 0x3f, 0xb2, + 0xdc, 0xc2, 0x3b, 0xc2, 0x78, 0x9f, 0x6f, 0xcb, 0x9b, 0x83, 0xf4, 0x12, 0x17, 0x76, 0x10, 0x4e, + 0x84, 0xb0, 0x72, 0x35, 0x7e, 0x11, 0x0f, 0x71, 0x1a, 0x59, 0x35, 0x0f, 0x12, 0x4f, 0x32, 0x22, + 0xce, 0xf6, 0x89, 0xee, 0x9e, 0x55, 0x9c, 0x26, 0xce, 0xaa, 0x95, 0x3c, 0x00, 0x1f, 0x34, 0xe0, + 0xb9, 0x13, 0x75, 0x3f, 0x0e, 0xdf, 0xec, 0x86, 0xb8, 0x79, 0x3c, 0x1a, 0x20, 0x2e, 0x40, 0x3a, + 0x94, 0xb6, 0xc4, 0xaf, 0xad, 0xf0, 0x23, 0xc2, 0x4f, 0x87, 0xed, 0xf3, 0x92, 0x6e, 0x2e, 0x72, + 0xbe, 0xbd, 0x1e, 0xc0, 0xd3, 0x78, 0xc0, 0xd0, 0x4d, 0x26, 0xb1, 0xa3, 0xce, 0x50, 0xe6, 0x84, + 0xf3, 0xb8, 0x92, 0x27, 0x93, 0x18, 0x83, 0xc4, 0x4e, 0xec, 0x18, 0x8b, 0x0d, 0xc1, 0x9b, 0x00, + 0x69, 0xfb, 0xfd, 0xd2, 0xfe, 0x84, 0xf0, 0x4c, 0x27, 0x84, 0x40, 0xe5, 0x1b, 0x3d, 0x1c, 0xe1, + 0x87, 0x3c, 0xbc, 0xef, 0xe2, 0x71, 0x46, 0x6c, 0x4d, 0xb7, 0xe5, 0x52, 0x86, 0x2a, 0x15, 0xd6, + 0xb3, 0x57, 0x63, 0x2b, 0x7c, 0x8d, 0x70, 0x3c, 0xa8, 0x3e, 0x08, 0x75, 0x1b, 0x0f, 0x99, 0x54, + 0xa9, 0x64, 0x0b, 0x94, 0xba, 0xea, 0x8c, 0xb7, 0xb0, 0x70, 0xf1, 0x2f, 0xea, 0xaa, 0x96, 0xbe, + 0xea, 0x14, 0xaf, 0xd7, 0x92, 0xa7, 0xaa, 0xf2, 0x66, 0xe9, 0x39, 0xa1, 0x91, 0x29, 0x7c, 0xf7, + 0x6b, 0x72, 0xba, 0xa8, 0xda, 0xeb, 0xe5, 0x9c, 0xa8, 0xe8, 0x9b, 0x12, 0x9c, 0xc6, 0xfc, 0xcf, + 0xac, 0x95, 0xdf, 0x90, 0xec, 0xaa, 0x41, 0x2d, 0x56, 0xc4, 0xca, 0x0c, 0x9a, 0x80, 0x42, 0x78, + 0x07, 0xc7, 0x9a, 0xd8, 0x16, 0x94, 0x8d, 0xde, 0x52, 0xff, 0x0a, 0x79, 0xa5, 0x6d, 0x94, 0x07, + 0xe6, 0x55, 0x3c, 0x28, 0x2b, 0x1b, 0x1d, 0x12, 0x5f, 0x04, 0xe2, 0x8f, 0x72, 0xe2, 0x6e, 0x62, + 0x77, 0xbc, 0x07, 0x64, 0x0e, 0x41, 0xb8, 0x81, 0x27, 0x9a, 0xb8, 0xd6, 0xd4, 0x4d, 0xaa, 0x97, + 0xed, 0xde, 0x52, 0xff, 0x06, 0xe1, 0xc9, 0x90, 0x16, 0x40, 0x7f, 0x07, 0xe1, 0x11, 0x9b, 0xbf, + 0xef, 0x50, 0x83, 0x65, 0xd0, 0x60, 0x94, 0x6b, 0xe0, 0x4d, 0xee, 0x4e, 0x87, 0x61, 0xbb, 0x89, + 0x47, 0x50, 0x70, 0x94, 0x01, 0x5d, 0x95, 0xab, 0xd4, 0x3d, 0x54, 0xc8, 0x33, 0x2d, 0xe7, 0x85, + 0xa3, 0xc0, 0x50, 0xfa, 0xb1, 0x7a, 0x2d, 0x19, 0xe5, 0xad, 0x9b, 0x31, 0xc1, 0x7b, 0x8c, 0xc4, + 0xf0, 0x80, 0x49, 0x4b, 0x72, 0x95, 0x9a, 0x70, 0xfc, 0xb8, 0x8f, 0xc2, 0x75, 0x4c, 0xbc, 0x4d, + 0x40, 0x82, 0xe7, 0xf1, 0x49, 0xc3, 0x79, 0x91, 0x95, 0xf3, 0x79, 0x93, 0x5a, 0x16, 0x34, 0x8a, + 0xd5, 0x6b, 0xc9, 0x31, 0xde, 0xa8, 0x25, 0x2c, 0x64, 0x46, 0xd8, 0xf3, 0x02, 0x3c, 0xea, 0x20, + 0xf1, 0xa2, 0x5e, 0xd6, 0x6c, 0x6a, 0x1a, 0xb2, 0x69, 0x3f, 0x5c, 0x16, 0x1a, 0xdc, 0x72, 0x01, + 0x0d, 0x81, 0xd1, 0x35, 0x4c, 0x14, 0x4f, 0x30, 0xcb, 0xf0, 0x42, 0xe7, 0xc9, 0x7a, 0x2d, 0x39, + 0x0e, 0x9d, 0x7d, 0x6b, 0x84, 0x4c, 0x54, 0x79, 0xb0, 0xaa, 0xf0, 0xa9, 0x7b, 0xad, 0x2e, 0x51, + 0xfa, 0x92, 0x26, 0xe7, 0x4a, 0x34, 0x0f, 0xe7, 0xec, 0xff, 0x61, 0x5d, 0xfe, 0x74, 0x2f, 0xd7, + 0x20, 0x34, 0xc0, 0xff, 0x0e, 0xc2, 0x63, 0x05, 0x4a, 0xb3, 0x94, 0xc7, 0xb3, 0xa0, 0xaa, 0x3b, + 0xdc, 0x33, 0xa1, 0xe7, 0xbe, 0xaf, 0x66, 0xfa, 0x2c, 0x4c, 0xfb, 0x13, 0x5c, 0xb2, 0xa0, 0xaa, + 0x42, 0x86, 0x14, 0x7c, 0x58, 0x7a, 0x77, 0x31, 0xdc, 0x75, 0xbf, 0xc3, 0x3e, 0x70, 0xae, 0xfa, + 0x17, 0x9a, 0xf7, 0x2d, 0xdf, 0x63, 0x52, 0xaf, 0x25, 0x1f, 0x81, 0xd1, 0xe5, 0x01, 0xa1, 0x71, + 0x07, 0xb7, 0x4e, 0x63, 0xa4, 0xb3, 0x69, 0x14, 0xde, 0x0a, 0x1b, 0x81, 0x86, 0xe6, 0xf3, 0x78, + 0xd8, 0x23, 0x0e, 0x03, 0x32, 0x98, 0x7e, 0xbc, 0x5e, 0x4b, 0x12, 0x9f, 0x72, 0x42, 0x06, 0x37, + 0x05, 0x4b, 0xfd, 0x11, 0xc5, 0xc7, 0x59, 0x6d, 0xf2, 0x03, 0xc2, 0xa3, 0x01, 0xf7, 0x3a, 0xb9, + 0x1c, 0xba, 0x5f, 0x6d, 0x2c, 0x75, 0xfc, 0xca, 0x21, 0x32, 0x39, 0x1f, 0x61, 0xf6, 0xee, 0xfd, + 0xdf, 0xbf, 0x8c, 0x9c, 0x27, 0xe7, 0x24, 0xf8, 0x11, 0xd0, 0x30, 0xff, 0x41, 0x8e, 0x82, 0x7c, + 0x1e, 0xc1, 0xc4, 0x5f, 0x8e, 0xcc, 0x77, 0x0b, 0xc0, 0x45, 0x7e, 0xb9, 0xfb, 0x44, 0x00, 0xbe, + 0x83, 0x18, 0xf2, 0x0f, 0xc8, 0xb6, 0x0f, 0xb9, 0x3b, 0xb1, 0xd2, 0x56, 0xe3, 0x5e, 0x11, 0x9b, + 0x1b, 0xbe, 0x2d, 0x39, 0x23, 0xd2, 0x12, 0x84, 0xe9, 0xd9, 0x96, 0x2c, 0x07, 0x96, 0xa6, 0xd0, + 0x96, 0xa8, 0xfb, 0x72, 0x3b, 0x48, 0x12, 0xf2, 0x0f, 0xc2, 0x93, 0x07, 0xba, 0x34, 0x92, 0xee, + 0x7a, 0x77, 0x7c, 0x9e, 0x35, 0xbe, 0xf8, 0x9f, 0x6a, 0x80, 0x64, 0xd7, 0x99, 0x62, 0xaf, 0x91, + 0x57, 0x0f, 0x50, 0x2c, 0x48, 0x27, 0x57, 0x9d, 0xc0, 0x89, 0xf8, 0x1b, 0xe1, 0x93, 0x2d, 0x66, + 0x8b, 0xa4, 0x0e, 0xc6, 0x1a, 0xe4, 0xfc, 0xe2, 0x17, 0xbb, 0xca, 0x01, 0x3e, 0x77, 0xf8, 0x08, + 0x6c, 0x91, 0xea, 0xd1, 0x8d, 0x80, 0xed, 0x20, 0xc9, 0x36, 0xac, 0x20, 0xf9, 0x0b, 0xe1, 0x11, + 0xaf, 0xe1, 0x22, 0x73, 0x1d, 0x30, 0x69, 0xf5, 0x7e, 0xf1, 0x54, 0x37, 0x29, 0xc0, 0xfd, 0x43, + 0xce, 0xfd, 0x16, 0x79, 0xef, 0xa8, 0xb9, 0xbb, 0x6e, 0x90, 0x7c, 0x12, 0xc1, 0xa7, 0x1e, 0x34, + 0x5c, 0xe4, 0x52, 0x07, 0x5c, 0xfc, 0x1e, 0x30, 0xfe, 0x6c, 0xb7, 0x69, 0x20, 0xc3, 0x47, 0x5c, + 0x86, 0xf7, 0xc9, 0xed, 0xa3, 0x96, 0xc1, 0x6b, 0x08, 0xc9, 0xb7, 0x08, 0x1f, 0x67, 0x2e, 0x82, + 0xcc, 0x1c, 0x4c, 0xc4, 0xeb, 0x98, 0xe2, 0x17, 0x3a, 0x5a, 0x0b, 0x4c, 0x97, 0x19, 0xd1, 0x05, + 0xf2, 0x42, 0x87, 0x5f, 0x5e, 0xb0, 0x51, 0x96, 0xb4, 0x05, 0x9f, 0xb6, 0x25, 0xe6, 0x7d, 0xc8, + 0x2f, 0x08, 0x47, 0x7d, 0x9e, 0x8a, 0xb4, 0xd9, 0x80, 0x30, 0xd7, 0x17, 0x9f, 0xef, 0x3a, 0x0f, + 0xf8, 0xac, 0x31, 0x3e, 0xaf, 0x93, 0x6b, 0x87, 0xe7, 0xe3, 0x37, 0x76, 0xe4, 0x7b, 0x84, 0x89, + 0xdf, 0x31, 0xb5, 0xbb, 0x9f, 0x42, 0x1d, 0x5f, 0xbb, 0xfb, 0x29, 0xdc, 0x9c, 0x09, 0x4f, 0x32, + 0x7e, 0x09, 0x32, 0xe1, 0xe3, 0xe7, 0xb1, 0x08, 0x64, 0x17, 0xe1, 0xa8, 0xaf, 0x48, 0xbb, 0xcd, + 0x08, 0x73, 0x48, 0xf1, 0xf9, 0xae, 0xf3, 0x00, 0xec, 0x2b, 0x0c, 0xec, 0x55, 0x92, 0x3e, 0xe4, + 0xcd, 0xe0, 0xa1, 0x94, 0x7e, 0xe3, 0xde, 0x5e, 0x02, 0xed, 0xee, 0x25, 0xd0, 0x6f, 0x7b, 0x09, + 0xf4, 0xc5, 0x7e, 0xa2, 0x6f, 0x77, 0x3f, 0xd1, 0xf7, 0xf3, 0x7e, 0xa2, 0xef, 0xed, 0x4b, 0xfe, + 0xdf, 0x4c, 0x6a, 0x4e, 0x99, 0x2d, 0xea, 0x52, 0x65, 0x5e, 0xda, 0xd4, 0xf3, 0xe5, 0x12, 0xb5, + 0x78, 0xf3, 0xd4, 0x95, 0x59, 0xa7, 0x3f, 0xfb, 0x19, 0x95, 0x3b, 0xc1, 0xfe, 0xb7, 0x78, 0xf1, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x67, 0x6b, 0x48, 0x88, 0x15, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1640,6 +1668,18 @@ func (m *QueryIncentivizedPacketsResponse) MarshalToSizedBuffer(dAtA []byte) (in _ = i var l int _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } if len(m.IncentivizedPackets) > 0 { for iNdEx := len(m.IncentivizedPackets) - 1; iNdEx >= 0; iNdEx-- { { @@ -1802,6 +1842,18 @@ func (m *QueryIncentivizedPacketsForChannelResponse) MarshalToSizedBuffer(dAtA [ _ = i var l int _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } if len(m.IncentivizedPackets) > 0 { for iNdEx := len(m.IncentivizedPackets) - 1; iNdEx >= 0; iNdEx-- { { @@ -2223,6 +2275,18 @@ func (m *QueryFeeEnabledChannelsResponse) MarshalToSizedBuffer(dAtA []byte) (int _ = i var l int _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } if len(m.FeeEnabledChannels) > 0 { for iNdEx := len(m.FeeEnabledChannels) - 1; iNdEx >= 0; iNdEx-- { { @@ -2349,6 +2413,10 @@ func (m *QueryIncentivizedPacketsResponse) Size() (n int) { n += 1 + l + sovQuery(uint64(l)) } } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } return n } @@ -2413,6 +2481,10 @@ func (m *QueryIncentivizedPacketsForChannelResponse) Size() (n int) { n += 1 + l + sovQuery(uint64(l)) } } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } return n } @@ -2582,6 +2654,10 @@ func (m *QueryFeeEnabledChannelsResponse) Size() (n int) { n += 1 + l + sovQuery(uint64(l)) } } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } return n } @@ -2788,6 +2864,42 @@ func (m *QueryIncentivizedPacketsResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -3226,6 +3338,42 @@ func (m *QueryIncentivizedPacketsForChannelResponse) Unmarshal(dAtA []byte) erro return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4308,6 +4456,42 @@ func (m *QueryFeeEnabledChannelsResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/modules/apps/29-fee/types/query.pb.gw.go b/modules/apps/29-fee/types/query.pb.gw.go index d6e723f9bdd..46554122eb5 100644 --- a/modules/apps/29-fee/types/query.pb.gw.go +++ b/modules/apps/29-fee/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join var ( filter_Query_IncentivizedPackets_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} @@ -892,12 +894,14 @@ func local_request_Query_FeeEnabledChannel_0(ctx context.Context, marshaler runt // 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. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_IncentivizedPackets_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 { @@ -905,6 +909,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_IncentivizedPackets_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) @@ -918,6 +923,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_IncentivizedPacket_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 { @@ -925,6 +932,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_IncentivizedPacket_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) @@ -938,6 +946,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_IncentivizedPacketsForChannel_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 { @@ -945,6 +955,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_IncentivizedPacketsForChannel_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) @@ -958,6 +969,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_TotalRecvFees_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 { @@ -965,6 +978,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_TotalRecvFees_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) @@ -978,6 +992,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_TotalAckFees_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 { @@ -985,6 +1001,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_TotalAckFees_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) @@ -998,6 +1015,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_TotalTimeoutFees_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 { @@ -1005,6 +1024,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_TotalTimeoutFees_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) @@ -1018,6 +1038,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_Payee_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 { @@ -1025,6 +1047,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Payee_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) @@ -1038,6 +1061,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_CounterpartyPayee_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 { @@ -1045,6 +1070,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_CounterpartyPayee_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) @@ -1058,6 +1084,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_FeeEnabledChannels_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 { @@ -1065,6 +1093,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_FeeEnabledChannels_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) @@ -1078,6 +1107,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_FeeEnabledChannel_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 { @@ -1085,6 +1116,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_FeeEnabledChannel_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) @@ -1340,25 +1372,25 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_IncentivizedPackets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "fee", "v1", "incentivized_packets"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_IncentivizedPackets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "fee", "v1", "incentivized_packets"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_IncentivizedPacket_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "apps", "fee", "v1", "channels", "packet_id.channel_id", "ports", "packet_id.port_id", "sequences", "packet_id.sequence", "incentivized_packet"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_IncentivizedPacket_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "apps", "fee", "v1", "channels", "packet_id.channel_id", "ports", "packet_id.port_id", "sequences", "packet_id.sequence", "incentivized_packet"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_IncentivizedPacketsForChannel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "fee", "v1", "channels", "channel_id", "ports", "port_id", "incentivized_packets"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_IncentivizedPacketsForChannel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "fee", "v1", "channels", "channel_id", "ports", "port_id", "incentivized_packets"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_TotalRecvFees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "apps", "fee", "v1", "channels", "packet_id.channel_id", "ports", "packet_id.port_id", "sequences", "packet_id.sequence", "total_recv_fees"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_TotalRecvFees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "apps", "fee", "v1", "channels", "packet_id.channel_id", "ports", "packet_id.port_id", "sequences", "packet_id.sequence", "total_recv_fees"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_TotalAckFees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "apps", "fee", "v1", "channels", "packet_id.channel_id", "ports", "packet_id.port_id", "sequences", "packet_id.sequence", "total_ack_fees"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_TotalAckFees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "apps", "fee", "v1", "channels", "packet_id.channel_id", "ports", "packet_id.port_id", "sequences", "packet_id.sequence", "total_ack_fees"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_TotalTimeoutFees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "apps", "fee", "v1", "channels", "packet_id.channel_id", "ports", "packet_id.port_id", "sequences", "packet_id.sequence", "total_timeout_fees"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_TotalTimeoutFees_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "apps", "fee", "v1", "channels", "packet_id.channel_id", "ports", "packet_id.port_id", "sequences", "packet_id.sequence", "total_timeout_fees"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Payee_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "fee", "v1", "channels", "channel_id", "relayers", "relayer", "payee"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Payee_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "fee", "v1", "channels", "channel_id", "relayers", "relayer", "payee"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_CounterpartyPayee_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "fee", "v1", "channels", "channel_id", "relayers", "relayer", "counterparty_payee"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_CounterpartyPayee_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "fee", "v1", "channels", "channel_id", "relayers", "relayer", "counterparty_payee"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_FeeEnabledChannels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "fee", "v1", "fee_enabled"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_FeeEnabledChannels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "fee", "v1", "fee_enabled"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_FeeEnabledChannel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "fee", "v1", "channels", "channel_id", "ports", "port_id", "fee_enabled"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_FeeEnabledChannel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "fee", "v1", "channels", "channel_id", "ports", "port_id", "fee_enabled"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/modules/apps/29-fee/types/tx.pb.go b/modules/apps/29-fee/types/tx.pb.go index 4eec969d2c2..721250beacc 100644 --- a/modules/apps/29-fee/types/tx.pb.go +++ b/modules/apps/29-fee/types/tx.pb.go @@ -6,10 +6,10 @@ package types import ( context "context" fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -372,51 +372,51 @@ func init() { func init() { proto.RegisterFile("ibc/applications/fee/v1/tx.proto", fileDescriptor_05c93128649f1b96) } var fileDescriptor_05c93128649f1b96 = []byte{ - // 698 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xcf, 0x6e, 0xd3, 0x4c, - 0x10, 0x8f, 0x9b, 0xfe, 0xcb, 0xb4, 0x5f, 0xdb, 0xac, 0xda, 0xaf, 0x8e, 0xd5, 0xc6, 0xfd, 0xac, - 0x4f, 0xa8, 0x08, 0xd5, 0x26, 0xa1, 0x3d, 0x50, 0x09, 0x21, 0x5c, 0xa9, 0xa2, 0x12, 0x15, 0x91, - 0xc5, 0x09, 0x21, 0x55, 0x8e, 0xb3, 0x71, 0x0d, 0x89, 0xd7, 0xf2, 0x3a, 0x11, 0x7e, 0x03, 0x8e, - 0xe5, 0x0d, 0xfa, 0x06, 0xbc, 0x46, 0x8f, 0x3d, 0x70, 0xe0, 0x64, 0xa1, 0xf6, 0xc2, 0x0d, 0x29, - 0xbc, 0x00, 0x5a, 0x7b, 0x6d, 0x9c, 0x44, 0xa9, 0x02, 0x27, 0x6e, 0x3b, 0x33, 0xbf, 0xf9, 0xed, - 0xcc, 0xcf, 0x33, 0x5e, 0xd8, 0x71, 0x9a, 0x96, 0x66, 0x7a, 0x5e, 0xc7, 0xb1, 0xcc, 0xc0, 0x21, - 0x2e, 0xd5, 0xda, 0x18, 0x6b, 0xfd, 0x9a, 0x16, 0xbc, 0x57, 0x3d, 0x9f, 0x04, 0x04, 0x6d, 0x3a, - 0x4d, 0x4b, 0xcd, 0x23, 0xd4, 0x36, 0xc6, 0x6a, 0xbf, 0x26, 0xad, 0xdb, 0xc4, 0x26, 0x31, 0x46, - 0x63, 0xa7, 0x04, 0x2e, 0xfd, 0x37, 0x89, 0x90, 0x65, 0xe5, 0x20, 0x16, 0xf1, 0xb1, 0x66, 0x9d, - 0x9b, 0xae, 0x8b, 0x3b, 0x2c, 0xcc, 0x8f, 0x09, 0x44, 0xf9, 0x24, 0xc0, 0xda, 0x29, 0xb5, 0x0d, - 0x6c, 0x3b, 0x34, 0xc0, 0x7e, 0xc3, 0x0c, 0x31, 0x46, 0x0f, 0x60, 0xc1, 0x23, 0x7e, 0x70, 0xe6, - 0xb4, 0x44, 0x61, 0x47, 0xd8, 0x2d, 0xe9, 0x68, 0x10, 0xc9, 0x2b, 0xa1, 0xd9, 0xed, 0x1c, 0x2a, - 0x3c, 0xa0, 0x18, 0xf3, 0xec, 0x74, 0xd2, 0x42, 0xfb, 0x00, 0x9c, 0x92, 0xe1, 0x67, 0x62, 0xfc, - 0xc6, 0x20, 0x92, 0xcb, 0x09, 0xfe, 0x57, 0x4c, 0x31, 0x4a, 0xdc, 0x38, 0x69, 0x21, 0x11, 0x16, - 0x7c, 0xdc, 0x31, 0x43, 0xec, 0x8b, 0x45, 0x96, 0x62, 0xa4, 0x26, 0x5a, 0x87, 0x39, 0x8f, 0x55, - 0x21, 0xce, 0xc6, 0xfe, 0xc4, 0x38, 0x5c, 0xfc, 0x70, 0x29, 0x17, 0xbe, 0x5d, 0xca, 0x05, 0x45, - 0x02, 0x71, 0xb4, 0x60, 0x03, 0x53, 0x8f, 0xb8, 0x14, 0x2b, 0x3f, 0x04, 0xd8, 0xca, 0x05, 0x8f, - 0x48, 0xcf, 0x0d, 0xb0, 0xef, 0x99, 0x7e, 0x10, 0xfe, 0x05, 0x9d, 0xbd, 0x00, 0x64, 0xe5, 0x2a, - 0x3a, 0xcb, 0xb5, 0xa9, 0x6f, 0x0f, 0x22, 0xb9, 0xc2, 0x79, 0xc7, 0x30, 0x8a, 0x51, 0xb6, 0x46, - 0x5b, 0xc9, 0x29, 0x72, 0x0f, 0xfe, 0xbf, 0xab, 0xe9, 0x4c, 0x9d, 0x8b, 0x19, 0x58, 0x3d, 0xa5, - 0x76, 0xc3, 0x0c, 0x1b, 0xa6, 0xf5, 0x0e, 0x07, 0xc7, 0x18, 0xa3, 0x7d, 0x28, 0xb6, 0x31, 0x8e, - 0xc5, 0x58, 0xaa, 0x6f, 0xa9, 0x13, 0x46, 0x50, 0x3d, 0xc6, 0x58, 0x9f, 0xbd, 0x8a, 0xe4, 0x82, - 0xc1, 0xe0, 0xe8, 0x29, 0xac, 0x50, 0xd2, 0xf3, 0x2d, 0x7c, 0x96, 0xaa, 0x99, 0xa8, 0x53, 0x19, - 0x44, 0xf2, 0x46, 0xd2, 0xc5, 0x70, 0x5c, 0x31, 0x96, 0x13, 0x47, 0x23, 0x91, 0xf6, 0x39, 0x94, - 0x39, 0x20, 0xa7, 0x70, 0x2c, 0x97, 0xbe, 0x35, 0x88, 0x64, 0x71, 0x88, 0x23, 0x2f, 0xf4, 0x6a, - 0xe2, 0x3b, 0xca, 0xe4, 0xfe, 0x17, 0xe6, 0xa9, 0x63, 0xbb, 0xd8, 0xe7, 0xf3, 0xc2, 0x2d, 0x24, - 0xc1, 0x22, 0xd7, 0x9d, 0x8a, 0x73, 0x3b, 0xc5, 0xdd, 0x92, 0x91, 0xd9, 0x39, 0xe9, 0x2a, 0xb0, - 0x39, 0xa2, 0x48, 0xa6, 0xd6, 0x67, 0x01, 0xd6, 0x47, 0x62, 0xcf, 0x68, 0xe8, 0x5a, 0xe8, 0x15, - 0x94, 0xbc, 0xd8, 0x93, 0x4e, 0xd1, 0x52, 0x7d, 0x3b, 0x16, 0x8e, 0x6d, 0x9a, 0x9a, 0xae, 0x57, - 0xbf, 0xa6, 0x26, 0x79, 0x27, 0x2d, 0x5d, 0x64, 0xca, 0x0d, 0x22, 0x79, 0x8d, 0x0f, 0x5a, 0x9a, - 0xad, 0x18, 0x8b, 0x1e, 0xc7, 0xa0, 0x37, 0x00, 0xdc, 0xcf, 0xbe, 0xc7, 0x4c, 0x4c, 0xab, 0x4c, - 0xfc, 0x1e, 0x59, 0x49, 0x7a, 0x85, 0x73, 0x97, 0x87, 0xb8, 0xdb, 0x6c, 0x68, 0x78, 0x99, 0xc7, - 0x43, 0xc3, 0x52, 0x8d, 0x37, 0x64, 0xac, 0xab, 0xb4, 0xed, 0xfa, 0xf7, 0x22, 0x14, 0x4f, 0xa9, - 0x8d, 0xba, 0xf0, 0xcf, 0xf0, 0x4f, 0xe1, 0xfe, 0xc4, 0x62, 0x46, 0xd7, 0x51, 0xaa, 0x4d, 0x0d, - 0x4d, 0xaf, 0x45, 0x1f, 0x05, 0xa8, 0x4c, 0x5e, 0xdb, 0x83, 0x69, 0x08, 0xc7, 0xd2, 0xa4, 0x27, - 0x7f, 0x94, 0x96, 0xd5, 0xf4, 0x16, 0x96, 0x87, 0x76, 0x65, 0xf7, 0x2e, 0xba, 0x3c, 0x52, 0x7a, - 0x38, 0x2d, 0x32, 0xbb, 0x2b, 0x84, 0xf2, 0xf8, 0xa4, 0xed, 0x4d, 0x4b, 0x13, 0xc3, 0xa5, 0x83, - 0xdf, 0x82, 0xa7, 0x57, 0xeb, 0x2f, 0xaf, 0x6e, 0xaa, 0xc2, 0xf5, 0x4d, 0x55, 0xf8, 0x7a, 0x53, - 0x15, 0x2e, 0x6e, 0xab, 0x85, 0xeb, 0xdb, 0x6a, 0xe1, 0xcb, 0x6d, 0xb5, 0xf0, 0xfa, 0xc0, 0x76, - 0x82, 0xf3, 0x5e, 0x53, 0xb5, 0x48, 0x57, 0xb3, 0x08, 0xed, 0x12, 0xaa, 0x39, 0x4d, 0x6b, 0xcf, - 0x26, 0x5a, 0x7f, 0x5f, 0xeb, 0x92, 0x56, 0xaf, 0x83, 0x29, 0x7b, 0x82, 0xa8, 0x56, 0x7f, 0xbc, - 0xc7, 0x5e, 0x9f, 0x20, 0xf4, 0x30, 0x6d, 0xce, 0xc7, 0x4f, 0xcb, 0xa3, 0x9f, 0x01, 0x00, 0x00, - 0xff, 0xff, 0xe2, 0x94, 0x3a, 0xbf, 0xf3, 0x06, 0x00, 0x00, + // 699 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0x4f, 0x6b, 0xdb, 0x4a, + 0x10, 0xb7, 0xe2, 0xfc, 0xf3, 0x24, 0x2f, 0x89, 0x97, 0xe4, 0x45, 0x16, 0x89, 0x95, 0x27, 0x1e, + 0x8f, 0x3c, 0x4a, 0xa4, 0xda, 0x4d, 0x28, 0x0d, 0x94, 0x52, 0x05, 0x42, 0x03, 0x0d, 0x35, 0xa2, + 0xa7, 0x52, 0x08, 0xb2, 0xbc, 0x56, 0xd4, 0xda, 0x5a, 0xa1, 0x95, 0x4d, 0xf5, 0x0d, 0x7a, 0x4c, + 0xbf, 0x41, 0xbe, 0x41, 0xbf, 0x46, 0x8e, 0x39, 0xf4, 0xd0, 0x93, 0x28, 0xc9, 0xa5, 0xb7, 0x82, + 0xfb, 0x05, 0xca, 0x4a, 0x2b, 0x55, 0xb6, 0x71, 0x70, 0x7b, 0xea, 0x6d, 0x67, 0xe6, 0x37, 0xbf, + 0x9d, 0xf9, 0x69, 0x46, 0x0b, 0x3b, 0x4e, 0xd3, 0xd2, 0x4c, 0xcf, 0xeb, 0x38, 0x96, 0x19, 0x38, + 0xc4, 0xa5, 0x5a, 0x1b, 0x63, 0xad, 0x5f, 0xd3, 0x82, 0x77, 0xaa, 0xe7, 0x93, 0x80, 0xa0, 0x4d, + 0xa7, 0x69, 0xa9, 0x79, 0x84, 0xda, 0xc6, 0x58, 0xed, 0xd7, 0xa4, 0x75, 0x9b, 0xd8, 0x24, 0xc6, + 0x68, 0xec, 0x94, 0xc0, 0xa5, 0x7f, 0x26, 0x11, 0xb2, 0xac, 0x1c, 0xc4, 0x22, 0x3e, 0xd6, 0xac, + 0x73, 0xd3, 0x75, 0x71, 0x87, 0x85, 0xf9, 0x31, 0x81, 0x28, 0x1f, 0x05, 0x58, 0x3b, 0xa5, 0xb6, + 0x81, 0x6d, 0x87, 0x06, 0xd8, 0x6f, 0x98, 0x21, 0xc6, 0xe8, 0x1e, 0x2c, 0x78, 0xc4, 0x0f, 0xce, + 0x9c, 0x96, 0x28, 0xec, 0x08, 0xbb, 0x25, 0x1d, 0x0d, 0x22, 0x79, 0x25, 0x34, 0xbb, 0x9d, 0x43, + 0x85, 0x07, 0x14, 0x63, 0x9e, 0x9d, 0x4e, 0x5a, 0x68, 0x1f, 0x80, 0x53, 0x32, 0xfc, 0x4c, 0x8c, + 0xdf, 0x18, 0x44, 0x72, 0x39, 0xc1, 0xff, 0x8c, 0x29, 0x46, 0x89, 0x1b, 0x27, 0x2d, 0x24, 0xc2, + 0x82, 0x8f, 0x3b, 0x66, 0x88, 0x7d, 0xb1, 0xc8, 0x52, 0x8c, 0xd4, 0x44, 0xeb, 0x30, 0xe7, 0xb1, + 0x2a, 0xc4, 0xd9, 0xd8, 0x9f, 0x18, 0x87, 0x8b, 0xef, 0x2f, 0xe5, 0xc2, 0xd7, 0x4b, 0xb9, 0xa0, + 0x48, 0x20, 0x8e, 0x16, 0x6c, 0x60, 0xea, 0x11, 0x97, 0x62, 0xe5, 0xbb, 0x00, 0x5b, 0xb9, 0xe0, + 0x11, 0xe9, 0xb9, 0x01, 0xf6, 0x3d, 0xd3, 0x0f, 0xc2, 0x3f, 0xa0, 0xb3, 0xe7, 0x80, 0xac, 0x5c, + 0x45, 0x67, 0xb9, 0x36, 0xf5, 0xed, 0x41, 0x24, 0x57, 0x38, 0xef, 0x18, 0x46, 0x31, 0xca, 0xd6, + 0x68, 0x2b, 0x39, 0x45, 0xfe, 0x83, 0x7f, 0xef, 0x6a, 0x3a, 0x53, 0xe7, 0x62, 0x06, 0x56, 0x4f, + 0xa9, 0xdd, 0x30, 0xc3, 0x86, 0x69, 0xbd, 0xc5, 0xc1, 0x31, 0xc6, 0x68, 0x1f, 0x8a, 0x6d, 0x8c, + 0x63, 0x31, 0x96, 0xea, 0x5b, 0xea, 0x84, 0x11, 0x54, 0x8f, 0x31, 0xd6, 0x67, 0xaf, 0x22, 0xb9, + 0x60, 0x30, 0x38, 0x7a, 0x02, 0x2b, 0x94, 0xf4, 0x7c, 0x0b, 0x9f, 0xa5, 0x6a, 0x26, 0xea, 0x54, + 0x06, 0x91, 0xbc, 0x91, 0x74, 0x31, 0x1c, 0x57, 0x8c, 0xe5, 0xc4, 0xd1, 0x48, 0xa4, 0x7d, 0x06, + 0x65, 0x0e, 0xc8, 0x29, 0x1c, 0xcb, 0xa5, 0x6f, 0x0d, 0x22, 0x59, 0x1c, 0xe2, 0xc8, 0x0b, 0xbd, + 0x9a, 0xf8, 0x8e, 0x32, 0xb9, 0xff, 0x86, 0x79, 0xea, 0xd8, 0x2e, 0xf6, 0xf9, 0xbc, 0x70, 0x0b, + 0x49, 0xb0, 0xc8, 0x75, 0xa7, 0xe2, 0xdc, 0x4e, 0x71, 0xb7, 0x64, 0x64, 0x76, 0x4e, 0xba, 0x0a, + 0x6c, 0x8e, 0x28, 0x92, 0xa9, 0xf5, 0x49, 0x80, 0xf5, 0x91, 0xd8, 0x53, 0x1a, 0xba, 0x16, 0x7a, + 0x09, 0x25, 0x2f, 0xf6, 0xa4, 0x53, 0xb4, 0x54, 0xdf, 0x8e, 0x85, 0x63, 0x9b, 0xa6, 0xa6, 0xeb, + 0xd5, 0xaf, 0xa9, 0x49, 0xde, 0x49, 0x4b, 0x17, 0x99, 0x72, 0x83, 0x48, 0x5e, 0xe3, 0x83, 0x96, + 0x66, 0x2b, 0xc6, 0xa2, 0xc7, 0x31, 0xe8, 0x35, 0x00, 0xf7, 0xb3, 0xef, 0x31, 0x13, 0xd3, 0x2a, + 0x13, 0xbf, 0x47, 0x56, 0x92, 0x5e, 0xe1, 0xdc, 0xe5, 0x21, 0xee, 0x36, 0x1b, 0x1a, 0x5e, 0xe6, + 0xf1, 0xd0, 0xb0, 0x54, 0xe3, 0x0d, 0x19, 0xeb, 0x2a, 0x6d, 0xbb, 0xfe, 0xad, 0x08, 0xc5, 0x53, + 0x6a, 0xa3, 0x2e, 0xfc, 0x35, 0xfc, 0x53, 0xf8, 0x7f, 0x62, 0x31, 0xa3, 0xeb, 0x28, 0xd5, 0xa6, + 0x86, 0xa6, 0xd7, 0xa2, 0x0f, 0x02, 0x54, 0x26, 0xaf, 0xed, 0xc1, 0x34, 0x84, 0x63, 0x69, 0xd2, + 0xe3, 0xdf, 0x4a, 0xcb, 0x6a, 0x7a, 0x03, 0xcb, 0x43, 0xbb, 0xb2, 0x7b, 0x17, 0x5d, 0x1e, 0x29, + 0xdd, 0x9f, 0x16, 0x99, 0xdd, 0x15, 0x42, 0x79, 0x7c, 0xd2, 0xf6, 0xa6, 0xa5, 0x89, 0xe1, 0xd2, + 0xc1, 0x2f, 0xc1, 0xd3, 0xab, 0xf5, 0x17, 0x57, 0x37, 0x55, 0xe1, 0xfa, 0xa6, 0x2a, 0x7c, 0xb9, + 0xa9, 0x0a, 0x17, 0xb7, 0xd5, 0xc2, 0xf5, 0x6d, 0xb5, 0xf0, 0xf9, 0xb6, 0x5a, 0x78, 0x75, 0x60, + 0x3b, 0xc1, 0x79, 0xaf, 0xa9, 0x5a, 0xa4, 0xab, 0x59, 0x84, 0x76, 0x09, 0xd5, 0x9c, 0xa6, 0xb5, + 0x67, 0x13, 0xad, 0xff, 0x50, 0xeb, 0x92, 0x56, 0xaf, 0x83, 0x29, 0x7b, 0x82, 0xa8, 0x56, 0x7f, + 0xb4, 0xc7, 0x5e, 0x9f, 0x20, 0xf4, 0x30, 0x6d, 0xce, 0xc7, 0x4f, 0xcb, 0x83, 0x1f, 0x01, 0x00, + 0x00, 0xff, 0xff, 0xfb, 0xaa, 0xe9, 0x34, 0xf3, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/apps/transfer/client/cli/cli.go b/modules/apps/transfer/client/cli/cli.go index de83f4d4736..52102df81a1 100644 --- a/modules/apps/transfer/client/cli/cli.go +++ b/modules/apps/transfer/client/cli/cli.go @@ -1,9 +1,8 @@ package cli import ( - "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/cobra" ) // GetQueryCmd returns the query commands for IBC connections diff --git a/modules/apps/transfer/client/cli/query.go b/modules/apps/transfer/client/cli/query.go index 9f9ce97be71..e87998e5573 100644 --- a/modules/apps/transfer/client/cli/query.go +++ b/modules/apps/transfer/client/cli/query.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // GetCmdQueryDenomTrace defines the command to query a a denomination trace from a given trace hash or ibc denom. diff --git a/modules/apps/transfer/client/cli/tx.go b/modules/apps/transfer/client/cli/tx.go index cddff4b4d9a..452aa214ae1 100644 --- a/modules/apps/transfer/client/cli/tx.go +++ b/modules/apps/transfer/client/cli/tx.go @@ -13,15 +13,16 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channelutils "github.com/cosmos/ibc-go/v4/modules/core/04-channel/client/utils" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + channelutils "github.com/cosmos/ibc-go/v7/modules/core/04-channel/client/utils" ) const ( flagPacketTimeoutHeight = "packet-timeout-height" flagPacketTimeoutTimestamp = "packet-timeout-timestamp" flagAbsoluteTimeouts = "absolute-timeouts" + flagMemo = "memo" ) // NewTransferTxCmd returns the command to create a NewMsgTransfer transaction @@ -76,6 +77,11 @@ corresponding to the counterparty channel. Any timeout set to 0 is disabled.`), return err } + memo, err := cmd.Flags().GetString(flagMemo) + if err != nil { + return err + } + // if the timeouts are not absolute, retrieve latest block height and block timestamp // for the consensus state connected to the destination port/channel if !absoluteTimeouts { @@ -111,7 +117,7 @@ corresponding to the counterparty channel. Any timeout set to 0 is disabled.`), } msg := types.NewMsgTransfer( - srcPort, srcChannel, coin, sender, receiver, timeoutHeight, timeoutTimestamp, + srcPort, srcChannel, coin, sender, receiver, timeoutHeight, timeoutTimestamp, memo, ) return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, @@ -120,6 +126,7 @@ corresponding to the counterparty channel. Any timeout set to 0 is disabled.`), cmd.Flags().String(flagPacketTimeoutHeight, types.DefaultRelativePacketTimeoutHeight, "Packet timeout block height. The timeout is disabled when set to 0-0.") cmd.Flags().Uint64(flagPacketTimeoutTimestamp, types.DefaultRelativePacketTimeoutTimestamp, "Packet timeout timestamp in nanoseconds from now. Default is 10 minutes. The timeout is disabled when set to 0.") cmd.Flags().Bool(flagAbsoluteTimeouts, false, "Timeout flags are used as absolute timeouts.") + cmd.Flags().String(flagMemo, "", "Memo to be sent along with the packet.") flags.AddTxFlagsToCmd(cmd) return cmd diff --git a/modules/apps/transfer/doc.go b/modules/apps/transfer/doc.go new file mode 100644 index 00000000000..e1e1d79b424 --- /dev/null +++ b/modules/apps/transfer/doc.go @@ -0,0 +1,8 @@ +/* +Package transfer implements the packet data structure, state machine handling logic, +and encoding details for the transfer of fungible tokens over an IBC channel between +two modules on separate chains. +This implementation is based off the ICS 20 specification +(https://github.com/cosmos/ibc/blob/main/spec/app/ics-020-fungible-token-transfer) +*/ +package transfer diff --git a/modules/apps/transfer/ibc_module.go b/modules/apps/transfer/ibc_module.go index 96505e05ee6..3503f51da20 100644 --- a/modules/apps/transfer/ibc_module.go +++ b/modules/apps/transfer/ibc_module.go @@ -5,16 +5,17 @@ import ( "math" "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" + "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" ) // IBCModule implements the ICS26 interface for transfer given the transfer keeper. @@ -46,16 +47,16 @@ func ValidateTransferChannelParams( return err } if channelSequence > uint64(math.MaxUint32) { - return sdkerrors.Wrapf(types.ErrMaxTransferChannels, "channel sequence %d is greater than max allowed transfer channels %d", channelSequence, uint64(math.MaxUint32)) + return errorsmod.Wrapf(types.ErrMaxTransferChannels, "channel sequence %d is greater than max allowed transfer channels %d", channelSequence, uint64(math.MaxUint32)) } if order != channeltypes.UNORDERED { - return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.UNORDERED, order) + return errorsmod.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.UNORDERED, order) } // Require portID is the portID transfer module is bound 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 @@ -81,7 +82,7 @@ func (im IBCModule) OnChanOpenInit( } 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) } // Claim channel capability passed back by IBC module @@ -108,7 +109,7 @@ func (im IBCModule) OnChanOpenTry( } if counterpartyVersion != types.Version { - return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: got: %s, expected %s", counterpartyVersion, types.Version) + return "", errorsmod.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: got: %s, expected %s", counterpartyVersion, types.Version) } // OpenTry must claim the channelCapability that IBC passes into the callback @@ -128,7 +129,7 @@ func (im IBCModule) OnChanOpenAck( counterpartyVersion string, ) error { if counterpartyVersion != types.Version { - return sdkerrors.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: %s, expected %s", counterpartyVersion, types.Version) + return errorsmod.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: %s, expected %s", counterpartyVersion, types.Version) } return nil } @@ -149,7 +150,7 @@ func (im IBCModule) OnChanCloseInit( channelID string, ) error { // Disallow user-initiated channel closing for transfer channels - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user cannot close channel") + return errorsmod.Wrap(ibcerrors.ErrInvalidRequest, "user cannot close channel") } // OnChanCloseConfirm implements the IBCModule interface @@ -169,12 +170,14 @@ func (im IBCModule) OnRecvPacket( packet channeltypes.Packet, relayer sdk.AccAddress, ) ibcexported.Acknowledgement { + logger := im.keeper.Logger(ctx) ack := channeltypes.NewResultAcknowledgement([]byte{byte(1)}) var data types.FungibleTokenPacketData var ackErr error if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { - ackErr = sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data") + ackErr = errorsmod.Wrapf(ibcerrors.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data") + logger.Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), packet.Sequence)) ack = channeltypes.NewErrorAcknowledgement(ackErr) } @@ -185,6 +188,9 @@ func (im IBCModule) OnRecvPacket( if err != nil { ack = channeltypes.NewErrorAcknowledgement(err) ackErr = err + logger.Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), packet.Sequence)) + } else { + logger.Info("successfully handled ICS-20 packet sequence: %d", packet.Sequence) } } @@ -194,6 +200,7 @@ func (im IBCModule) OnRecvPacket( sdk.NewAttribute(types.AttributeKeyReceiver, data.Receiver), sdk.NewAttribute(types.AttributeKeyDenom, data.Denom), sdk.NewAttribute(types.AttributeKeyAmount, data.Amount), + sdk.NewAttribute(types.AttributeKeyMemo, data.Memo), sdk.NewAttribute(types.AttributeKeyAckSuccess, fmt.Sprintf("%t", ack.Success())), } @@ -221,11 +228,11 @@ func (im IBCModule) OnAcknowledgementPacket( ) error { var ack channeltypes.Acknowledgement if err := types.ModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet acknowledgement: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet acknowledgement: %v", err) } var data types.FungibleTokenPacketData if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) + return errorsmod.Wrapf(ibcerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) } if err := im.keeper.OnAcknowledgementPacket(ctx, packet, data, ack); err != nil { @@ -240,6 +247,7 @@ func (im IBCModule) OnAcknowledgementPacket( sdk.NewAttribute(types.AttributeKeyReceiver, data.Receiver), sdk.NewAttribute(types.AttributeKeyDenom, data.Denom), sdk.NewAttribute(types.AttributeKeyAmount, data.Amount), + sdk.NewAttribute(types.AttributeKeyMemo, data.Memo), sdk.NewAttribute(types.AttributeKeyAck, ack.String()), ), ) @@ -272,7 +280,7 @@ func (im IBCModule) OnTimeoutPacket( ) error { var data types.FungibleTokenPacketData if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) + return errorsmod.Wrapf(ibcerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data: %s", err.Error()) } // refund tokens if err := im.keeper.OnTimeoutPacket(ctx, packet, data); err != nil { @@ -286,6 +294,7 @@ func (im IBCModule) OnTimeoutPacket( sdk.NewAttribute(types.AttributeKeyRefundReceiver, data.Sender), sdk.NewAttribute(types.AttributeKeyRefundDenom, data.Denom), sdk.NewAttribute(types.AttributeKeyRefundAmount, data.Amount), + sdk.NewAttribute(types.AttributeKeyMemo, data.Memo), ), ) diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go index 3ff7b25679e..5e43397596c 100644 --- a/modules/apps/transfer/ibc_module_test.go +++ b/modules/apps/transfer/ibc_module_test.go @@ -5,11 +5,11 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *TransferTestSuite) TestOnChanOpenInit() { @@ -50,7 +50,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() { }, { "invalid version", func() { - channel.Version = "version" + channel.Version = "version" //nolint:goconst }, false, }, { diff --git a/modules/apps/transfer/keeper/MBT_README.md b/modules/apps/transfer/keeper/MBT_README.md index c2a62599f36..564d87bc6af 100644 --- a/modules/apps/transfer/keeper/MBT_README.md +++ b/modules/apps/transfer/keeper/MBT_README.md @@ -1,31 +1,31 @@ -## Token Transfer Model-based Testing Guide +# Token Transfer Model-based Testing Guide -In the process of IBC Audit performed by Informal Systems, we have implemented +In the process of IBC Audit performed by Informal Systems, we have implemented a preliminary set of model-based tests for the ICS-20 Token Transfer implementation. Model-based tests are based on the formal `TLA+` model of the Token transfer relay functions: see [relay.tla](relay_model/relay.tla). -The tests themselves are simple `TLA+` assertions, that describe the desired shape of execution that send or receive tokens; -see [relay_tests.tla](relay_model/relay_tests.tla) for some examples. -To be able to specify test assertions the TLA+ model contains the `history` variable, -which records the whole execution history. +The tests themselves are simple `TLA+` assertions, that describe the desired shape of execution that send or receive tokens; +see [relay_tests.tla](relay_model/relay_tests.tla) for some examples. +To be able to specify test assertions the TLA+ model contains the `history` variable, +which records the whole execution history. So, by way of referring to `history` you simply specify declaratively what execution history you want to see. After you have specified your `TLA+` test, you can run it using [Apalache model checker](https://github.com/informalsystems/apalache). -E.g. for the test `TestUnescrowTokens` run +E.g. for the test `TestUnescrowTokens` run ```bash apalache-mc check --inv=TestUnescrowTokensInv relay_tests.tla ``` - -In case there are no error in the TLA+ model or in the test assertions, this will produce a couple of so-called _counterexamples_. + +In case there are no error in the TLA+ model or in the test assertions, this will produce a couple of so-called _counterexamples_. This is a terminology from the model-checking community; for the testing purposes they can be considered simply as model executions. See the files `counterexample.tla` for human-readable representation, and `counterexample.json` for machine-readable one. -In order to execute the produced test, you need to translate it into another format. -For that translation you need the tool [Jsonatr (JSON Arrifact Translator)](https://github.com/informalsystems/jsonatr). +In order to execute the produced test, you need to translate it into another format. +For that translation you need the tool [Jsonatr (JSON Arrifact Translator)](https://github.com/informalsystems/jsonatr). It performs the translation using this [transformation spec](relay_model/apalache-to-relay-test2.json); -To transform a counterexample into a test, run +To transform a counterexample into a test, run ```bash jsonatr --use apalache-to-relay-test2.json --in counterexample.json --out model_based_tests/YourTestName.json @@ -34,18 +34,16 @@ jsonatr --use apalache-to-relay-test2.json --in counterexample.json --out model_ Now, if you run `go test` in this directory, the file you have produced above should be picked up by the [model-based test driver](mbt_relay_test.go), and executed automatically. - -The easiest way to run Apalache is by -[using a Docker image](https://apalache.informal.systems/docs/apalache/installation/docker.html); -to run Jsonatr you need to locally clone the repository, and then, -after building it, add the `target/debug` directory into your `PATH`. +The easiest way to run Apalache is by +[using a Docker image](https://apalache.informal.systems/docs/apalache/installation/docker.html); +to run Jsonatr you need to locally clone the repository, and then, +after building it, add the `target/debug` directory into your `PATH`. To wrap Apalache docker image into an executable you might create the following executable bash script `apalache-mc`: ```bash #!/bin/bash docker run --rm -v $(pwd):/var/apalache apalache/mc $@ -``` - +``` In case of any questions please don't hesitate to contact Andrey Kuprianov (andrey@informal.systems). diff --git a/modules/apps/transfer/keeper/encoding.go b/modules/apps/transfer/keeper/encoding.go index 0dfa979cb91..32f52bd651a 100644 --- a/modules/apps/transfer/keeper/encoding.go +++ b/modules/apps/transfer/keeper/encoding.go @@ -1,7 +1,7 @@ package keeper import ( - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // UnmarshalDenomTrace attempts to decode and return an DenomTrace object from diff --git a/modules/apps/transfer/keeper/genesis.go b/modules/apps/transfer/keeper/genesis.go index a3506e4e22d..ce0a45155e1 100644 --- a/modules/apps/transfer/keeper/genesis.go +++ b/modules/apps/transfer/keeper/genesis.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // InitGenesis initializes the ibc-transfer state and binds to PortID. diff --git a/modules/apps/transfer/keeper/genesis_test.go b/modules/apps/transfer/keeper/genesis_test.go index e734967863c..3bc35144943 100644 --- a/modules/apps/transfer/keeper/genesis_test.go +++ b/modules/apps/transfer/keeper/genesis_test.go @@ -3,7 +3,7 @@ package keeper_test import ( "fmt" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) func (suite *KeeperTestSuite) TestGenesis() { diff --git a/modules/apps/transfer/keeper/grpc_query.go b/modules/apps/transfer/keeper/grpc_query.go index 5564ef04614..d6a1eaefdaa 100644 --- a/modules/apps/transfer/keeper/grpc_query.go +++ b/modules/apps/transfer/keeper/grpc_query.go @@ -5,14 +5,14 @@ import ( "fmt" "strings" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) var _ types.QueryServer = Keeper{} @@ -33,7 +33,7 @@ func (q Keeper) DenomTrace(c context.Context, req *types.QueryDenomTraceRequest) if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrap(types.ErrTraceNotFound, req.Hash).Error(), + errorsmod.Wrap(types.ErrTraceNotFound, req.Hash).Error(), ) } @@ -100,7 +100,7 @@ func (q Keeper) DenomHash(c context.Context, req *types.QueryDenomHashRequest) ( if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrap(types.ErrTraceNotFound, req.Trace).Error(), + errorsmod.Wrap(types.ErrTraceNotFound, req.Trace).Error(), ) } diff --git a/modules/apps/transfer/keeper/grpc_query_test.go b/modules/apps/transfer/keeper/grpc_query_test.go index 92dfbe24370..ffb4833d25e 100644 --- a/modules/apps/transfer/keeper/grpc_query_test.go +++ b/modules/apps/transfer/keeper/grpc_query_test.go @@ -6,8 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestQueryDenomTrace() { @@ -24,8 +24,8 @@ func (suite *KeeperTestSuite) TestQueryDenomTrace() { { "success: correct ibc denom", func() { - expTrace.Path = "transfer/channelToA/transfer/channelToB" - expTrace.BaseDenom = "uatom" + expTrace.Path = "transfer/channelToA/transfer/channelToB" //nolint:goconst + expTrace.BaseDenom = "uatom" //nolint:goconst suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), expTrace) req = &types.QueryDenomTraceRequest{ @@ -223,9 +223,7 @@ func (suite *KeeperTestSuite) TestQueryDenomHash() { } func (suite *KeeperTestSuite) TestEscrowAddress() { - var ( - req *types.QueryEscrowAddressRequest - ) + var req *types.QueryEscrowAddressRequest testCases := []struct { msg string diff --git a/modules/apps/transfer/keeper/keeper.go b/modules/apps/transfer/keeper/keeper.go index 2a9c5c16db0..c478b5a6eea 100644 --- a/modules/apps/transfer/keeper/keeper.go +++ b/modules/apps/transfer/keeper/keeper.go @@ -3,36 +3,38 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" tmbytes "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // Keeper defines the IBC fungible transfer keeper type Keeper struct { - storeKey sdk.StoreKey + storeKey storetypes.StoreKey cdc codec.BinaryCodec paramSpace paramtypes.Subspace - ics4Wrapper types.ICS4Wrapper + ics4Wrapper porttypes.ICS4Wrapper channelKeeper types.ChannelKeeper portKeeper types.PortKeeper authKeeper types.AccountKeeper bankKeeper types.BankKeeper - scopedKeeper capabilitykeeper.ScopedKeeper + scopedKeeper exported.ScopedKeeper } // NewKeeper creates a new IBC transfer Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Subspace, - ics4Wrapper types.ICS4Wrapper, channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper, - authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, scopedKeeper capabilitykeeper.ScopedKeeper, + cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, + ics4Wrapper porttypes.ICS4Wrapper, channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper, + authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, scopedKeeper exported.ScopedKeeper, ) Keeper { // ensure ibc transfer module account is set if addr := authKeeper.GetModuleAddress(types.ModuleName); addr == nil { @@ -59,7 +61,7 @@ func NewKeeper( // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+host.ModuleName+"-"+types.ModuleName) + return ctx.Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName) } // IsBound checks if the transfer module is already bound to the desired port @@ -91,7 +93,7 @@ func (k Keeper) SetPort(ctx sdk.Context, portID string) { func (k Keeper) GetDenomTrace(ctx sdk.Context, denomTraceHash tmbytes.HexBytes) (types.DenomTrace, bool) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomTraceKey) bz := store.Get(denomTraceHash) - if bz == nil { + if len(bz) == 0 { return types.DenomTrace{}, false } @@ -129,7 +131,7 @@ func (k Keeper) IterateDenomTraces(ctx sdk.Context, cb func(denomTrace types.Den store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, types.DenomTraceKey) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { denomTrace := k.MustUnmarshalDenomTrace(iterator.Value()) diff --git a/modules/apps/transfer/keeper/keeper_test.go b/modules/apps/transfer/keeper/keeper_test.go index 051f3952234..6e56dbbd4bc 100644 --- a/modules/apps/transfer/keeper/keeper_test.go +++ b/modules/apps/transfer/keeper/keeper_test.go @@ -6,8 +6,8 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/stretchr/testify/suite" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type KeeperTestSuite struct { diff --git a/modules/apps/transfer/keeper/mbt_relay_test.go b/modules/apps/transfer/keeper/mbt_relay_test.go index 16aa831b37d..ef016dff3c3 100644 --- a/modules/apps/transfer/keeper/mbt_relay_test.go +++ b/modules/apps/transfer/keeper/mbt_relay_test.go @@ -7,18 +7,20 @@ package keeper_test import ( "encoding/json" "fmt" - "io/ioutil" + "os" "strconv" "strings" + errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/tendermint/tendermint/crypto" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type TlaBalance struct { @@ -83,10 +85,10 @@ type OwnedCoin struct { } type Balance struct { - Id string + ID string Address string Denom string - Amount sdk.Int + Amount math.Int } func AddressFromString(address string) string { @@ -98,7 +100,7 @@ func AddressFromTla(addr []string) string { panic("failed to convert from TLA+ address: wrong number of address components") } s := "" - if len(addr[0]) == 0 && len(addr[1]) == 0 { + if len(addr[0]) == 0 && len(addr[1]) == 0 { //nolint:gocritic // simple address: id s = addr[2] } else if len(addr[2]) == 0 { @@ -120,7 +122,7 @@ func DenomFromTla(denom []string) string { func BalanceFromTla(balance TlaBalance) Balance { return Balance{ - Id: AddressFromTla(balance.Address), + ID: AddressFromTla(balance.Address), Address: AddressFromString(AddressFromTla(balance.Address)), Denom: DenomFromTla(balance.Denom), Amount: sdk.NewInt(balance.Amount), @@ -145,7 +147,8 @@ func FungibleTokenPacketFromTla(packet TlaFungibleTokenPacket) FungibleTokenPack DenomFromTla(packet.Data.Denom), packet.Data.Amount, AddressFromString(packet.Data.Sender), - AddressFromString(packet.Data.Receiver)), + AddressFromString(packet.Data.Receiver), + ""), } } @@ -163,12 +166,12 @@ func OnRecvPacketTestCaseFromTla(tc TlaOnRecvPacketTestCase) OnRecvPacketTestCas var addressMap = make(map[string]string) type Bank struct { - balances map[OwnedCoin]sdk.Int + balances map[OwnedCoin]math.Int } // Make an empty bank func MakeBank() Bank { - return Bank{balances: make(map[OwnedCoin]sdk.Int)} + return Bank{balances: make(map[OwnedCoin]math.Int)} } // Subtract other bank from this bank @@ -191,7 +194,7 @@ func (bank *Bank) Sub(other *Bank) Bank { } // Set specific bank balance -func (bank *Bank) SetBalance(address string, denom string, amount sdk.Int) { +func (bank *Bank) SetBalance(address string, denom string, amount math.Int) { bank.balances[OwnedCoin{address, denom}] = amount } @@ -199,7 +202,7 @@ func (bank *Bank) SetBalance(address string, denom string, amount sdk.Int) { func (bank *Bank) SetBalances(balances []Balance) { for _, balance := range balances { bank.balances[OwnedCoin{balance.Address, balance.Denom}] = balance.Amount - addressMap[balance.Address] = balance.Id + addressMap[balance.Address] = balance.ID } } @@ -217,7 +220,7 @@ func BankFromBalances(balances []Balance) Bank { coin := OwnedCoin{balance.Address, balance.Denom} if coin != NullCoin() { // ignore null coin bank.balances[coin] = balance.Amount - addressMap[balance.Address] = balance.Id + addressMap[balance.Address] = balance.ID } } return bank @@ -268,27 +271,27 @@ func (suite *KeeperTestSuite) CheckBankBalances(chain *ibctesting.TestChain, ban diff := bankChange.Sub(expectedBankChange) NonZeroString := diff.NonZeroString() if len(NonZeroString) != 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "Unexpected changes in the bank: \n"+NonZeroString) + return errorsmod.Wrap(ibcerrors.ErrInvalidCoins, "Unexpected changes in the bank: \n"+NonZeroString) } return nil } func (suite *KeeperTestSuite) TestModelBasedRelay() { dirname := "model_based_tests/" - files, err := ioutil.ReadDir(dirname) + files, err := os.ReadDir(dirname) if err != nil { panic(fmt.Errorf("Failed to read model-based test files: %w", err)) } - for _, file_info := range files { + for _, fileInfo := range files { tlaTestCases := []TlaOnRecvPacketTestCase{} - if !strings.HasSuffix(file_info.Name(), ".json") { + if !strings.HasSuffix(fileInfo.Name(), ".json") { continue } - jsonBlob, err := ioutil.ReadFile(dirname + file_info.Name()) + jsonBlob, err := os.ReadFile(dirname + fileInfo.Name()) if err != nil { panic(fmt.Errorf("Failed to read JSON test fixture: %w", err)) } - err = json.Unmarshal([]byte(jsonBlob), &tlaTestCases) + err = json.Unmarshal(jsonBlob, &tlaTestCases) if err != nil { panic(fmt.Errorf("Failed to parse JSON test fixture: %w", err)) } @@ -301,7 +304,7 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() { for i, tlaTc := range tlaTestCases { tc := OnRecvPacketTestCaseFromTla(tlaTc) - registerDenom := func() { + registerDenomFn := func() { denomTrace := types.ParseDenomTrace(tc.packet.Data.Denom) traceHash := denomTrace.Hash() if !suite.chainB.GetSimApp().TransferKeeper.HasDenomTrace(suite.chainB.GetContext(), traceHash) { @@ -309,10 +312,10 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() { } } - description := file_info.Name() + " # " + strconv.Itoa(i+1) + description := fileInfo.Name() + " # " + strconv.Itoa(i+1) suite.Run(fmt.Sprintf("Case %s", description), func() { seq := uint64(1) - packet := channeltypes.NewPacket(tc.packet.Data.GetBytes(), seq, tc.packet.SourcePort, tc.packet.SourceChannel, tc.packet.DestPort, tc.packet.DestChannel, clienttypes.NewHeight(0, 100), 0) + packet := channeltypes.NewPacket(tc.packet.Data.GetBytes(), seq, tc.packet.SourcePort, tc.packet.SourceChannel, tc.packet.DestPort, tc.packet.DestChannel, clienttypes.NewHeight(1, 100), 0) bankBefore := BankFromBalances(tc.bankBefore) realBankBefore := BankOfChain(suite.chainB) // First validate the packet itself (mimics what happens when the packet is being sent and/or received) @@ -328,7 +331,7 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() { if err != nil { panic("MBT failed to convert sender address") } - registerDenom() + registerDenomFn() denomTrace := types.ParseDenomTrace(tc.packet.Data.Denom) denom := denomTrace.IBCDenom() err = sdk.ValidateDenom(denom) @@ -337,27 +340,30 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() { if !ok { panic("MBT failed to parse amount from string") } - err = suite.chainB.GetSimApp().TransferKeeper.SendTransfer( - suite.chainB.GetContext(), + msg := types.NewMsgTransfer( tc.packet.SourcePort, tc.packet.SourceChannel, sdk.NewCoin(denom, amount), - sender, + sender.String(), tc.packet.Data.Receiver, - clienttypes.NewHeight(0, 110), - 0) + suite.chainA.GetTimeoutHeight(), 0, // only use timeout height + "", + ) + + _, err = suite.chainB.GetSimApp().TransferKeeper.Transfer(sdk.WrapSDKContext(suite.chainB.GetContext()), msg) + } case "OnRecvPacket": err = suite.chainB.GetSimApp().TransferKeeper.OnRecvPacket(suite.chainB.GetContext(), packet, tc.packet.Data) case "OnTimeoutPacket": - registerDenom() + registerDenomFn() err = suite.chainB.GetSimApp().TransferKeeper.OnTimeoutPacket(suite.chainB.GetContext(), packet, tc.packet.Data) case "OnRecvAcknowledgementResult": err = suite.chainB.GetSimApp().TransferKeeper.OnAcknowledgementPacket( suite.chainB.GetContext(), packet, tc.packet.Data, channeltypes.NewResultAcknowledgement(nil)) case "OnRecvAcknowledgementError": - registerDenom() + registerDenomFn() err = suite.chainB.GetSimApp().TransferKeeper.OnAcknowledgementPacket( suite.chainB.GetContext(), packet, tc.packet.Data, channeltypes.NewErrorAcknowledgement(fmt.Errorf("MBT Error Acknowledgement"))) diff --git a/modules/apps/transfer/keeper/migrations.go b/modules/apps/transfer/keeper/migrations.go index a1f3654f170..c0399a2ad34 100644 --- a/modules/apps/transfer/keeper/migrations.go +++ b/modules/apps/transfer/keeper/migrations.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // Migrator is a struct for handling in-place store migrations. @@ -20,7 +20,6 @@ func NewMigrator(keeper Keeper) Migrator { // MigrateTraces migrates the DenomTraces to the correct format, accounting for slashes in the BaseDenom. func (m Migrator) MigrateTraces(ctx sdk.Context) error { - // list of traces that must replace the old traces in store var newTraces []types.DenomTrace m.keeper.IterateDenomTraces(ctx, diff --git a/modules/apps/transfer/keeper/migrations_test.go b/modules/apps/transfer/keeper/migrations_test.go index ff7da8ca089..ac0097e617a 100644 --- a/modules/apps/transfer/keeper/migrations_test.go +++ b/modules/apps/transfer/keeper/migrations_test.go @@ -3,18 +3,16 @@ package keeper_test import ( "fmt" - transferkeeper "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper" - transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + transferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) func (suite *KeeperTestSuite) TestMigratorMigrateTraces() { - testCases := []struct { msg string malleate func() expectedTraces transfertypes.Traces }{ - { "success: two slashes in base denom", func() { @@ -118,6 +116,6 @@ func (suite *KeeperTestSuite) TestMigratorMigrateTracesCorruptionDetection() { migrator := transferkeeper.NewMigrator(suite.chainA.GetSimApp().TransferKeeper) suite.Panics(func() { - migrator.MigrateTraces(suite.chainA.GetContext()) + migrator.MigrateTraces(suite.chainA.GetContext()) //nolint:errcheck // we shouldn't check the error here because we want to ensure that a panic occurs. }) } diff --git a/modules/apps/transfer/keeper/msg_server.go b/modules/apps/transfer/keeper/msg_server.go index eab992e958f..8eb436ba6ec 100644 --- a/modules/apps/transfer/keeper/msg_server.go +++ b/modules/apps/transfer/keeper/msg_server.go @@ -3,26 +3,40 @@ package keeper import ( "context" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) var _ types.MsgServer = Keeper{} -// See createOutgoingPacket in spec:https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#packet-relay - -// Transfer defines a rpc handler method for MsgTransfer. +// Transfer defines an rpc handler method for MsgTransfer. func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.MsgTransferResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + if !k.GetSendEnabled(ctx) { + return nil, types.ErrSendDisabled + } + sender, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { return nil, err } - if err := k.SendTransfer( + + if !k.bankKeeper.IsSendEnabledCoin(ctx, msg.Token) { + return nil, errorsmod.Wrapf(types.ErrSendDisabled, "%s transfers are currently disabled", msg.Token.Denom) + } + + if k.bankKeeper.BlockedAddr(sender) { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "%s is not allowed to send funds", sender) + } + + sequence, err := k.sendTransfer( ctx, msg.SourcePort, msg.SourceChannel, msg.Token, sender, msg.Receiver, msg.TimeoutHeight, msg.TimeoutTimestamp, - ); err != nil { + msg.Memo) + if err != nil { return nil, err } @@ -33,6 +47,9 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types. types.EventTypeTransfer, sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), sdk.NewAttribute(types.AttributeKeyReceiver, msg.Receiver), + sdk.NewAttribute(types.AttributeKeyAmount, msg.Token.Amount.String()), + sdk.NewAttribute(types.AttributeKeyDenom, msg.Token.Denom), + sdk.NewAttribute(types.AttributeKeyMemo, msg.Memo), ), sdk.NewEvent( sdk.EventTypeMessage, @@ -40,5 +57,5 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types. ), }) - return &types.MsgTransferResponse{}, nil + return &types.MsgTransferResponse{Sequence: sequence}, nil } diff --git a/modules/apps/transfer/keeper/msg_server_test.go b/modules/apps/transfer/keeper/msg_server_test.go new file mode 100644 index 00000000000..61f5ec9395b --- /dev/null +++ b/modules/apps/transfer/keeper/msg_server_test.go @@ -0,0 +1,127 @@ +package keeper_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" +) + +func (suite *KeeperTestSuite) TestMsgTransfer() { + var msg *types.MsgTransfer + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "bank send enabled for denom", + func() { + err := suite.chainA.GetSimApp().BankKeeper.SetParams(suite.chainA.GetContext(), + banktypes.Params{ + SendEnabled: []*banktypes.SendEnabled{{Denom: sdk.DefaultBondDenom, Enabled: true}}, + }, + ) + suite.Require().NoError(err) + }, + true, + }, + { + "send transfers disabled", + func() { + suite.chainA.GetSimApp().TransferKeeper.SetParams(suite.chainA.GetContext(), + types.Params{ + SendEnabled: false, + }, + ) + }, + false, + }, + { + "invalid sender", + func() { + msg.Sender = "address" + }, + false, + }, + { + "sender is a blocked address", + func() { + msg.Sender = suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(types.ModuleName).String() + }, + false, + }, + { + "bank send disabled for denom", + func() { + err := suite.chainA.GetSimApp().BankKeeper.SetParams(suite.chainA.GetContext(), + banktypes.Params{ + SendEnabled: []*banktypes.SendEnabled{{Denom: sdk.DefaultBondDenom, Enabled: false}}, + }, + ) + suite.Require().NoError(err) + }, + false, + }, + { + "channel does not exist", + func() { + msg.SourceChannel = "channel-100" + }, + false, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + suite.SetupTest() + + path := NewTransferPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + coin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) + msg = types.NewMsgTransfer( + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + coin, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), + suite.chainB.GetTimeoutHeight(), 0, // only use timeout height + "memo", + ) + + tc.malleate() + + ctx := suite.chainA.GetContext() + res, err := suite.chainA.GetSimApp().TransferKeeper.Transfer(sdk.WrapSDKContext(ctx), msg) + + // Verify events + events := ctx.EventManager().Events() + expEvents := ibctesting.EventsMap{ + "ibc_transfer": { + "sender": suite.chainA.SenderAccount.GetAddress().String(), + "receiver": suite.chainB.SenderAccount.GetAddress().String(), + "amount": coin.Amount.String(), + "denom": coin.Denom, + "memo": "memo", + }, + } + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().NotEqual(res.Sequence, uint64(0)) + ibctesting.AssertEvents(&suite.Suite, expEvents, events) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + suite.Require().Len(events, 0) + } + }) + } +} diff --git a/modules/apps/transfer/keeper/params.go b/modules/apps/transfer/keeper/params.go index 9589ae04ec9..c7e69c9311d 100644 --- a/modules/apps/transfer/keeper/params.go +++ b/modules/apps/transfer/keeper/params.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // GetSendEnabled retrieves the send enabled boolean from the paramstore diff --git a/modules/apps/transfer/keeper/params_test.go b/modules/apps/transfer/keeper/params_test.go index e52f15cb247..921e857d319 100644 --- a/modules/apps/transfer/keeper/params_test.go +++ b/modules/apps/transfer/keeper/params_test.go @@ -1,6 +1,6 @@ package keeper_test -import "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" +import "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" func (suite *KeeperTestSuite) TestParams() { expParams := types.DefaultParams() diff --git a/modules/apps/transfer/keeper/relay.go b/modules/apps/transfer/keeper/relay.go index 8c023ebac5a..62d4135e072 100644 --- a/modules/apps/transfer/keeper/relay.go +++ b/modules/apps/transfer/keeper/relay.go @@ -4,19 +4,20 @@ import ( "fmt" "strings" - "github.com/armon/go-metrics" + errorsmod "cosmossdk.io/errors" + metrics "github.com/armon/go-metrics" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - coretypes "github.com/cosmos/ibc-go/v4/modules/core/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "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" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + coretypes "github.com/cosmos/ibc-go/v7/modules/core/types" ) -// SendTransfer handles transfer sending logic. There are 2 possible cases: +// sendTransfer handles transfer sending logic. There are 2 possible cases: // // 1. Sender chain is acting as the source zone. The coins are transferred // to an escrow address (i.e locked) on the sender chain and then transferred @@ -48,7 +49,7 @@ import ( // 4. A -> C : sender chain is sink zone. Denom upon receiving: 'C/B/denom' // 5. C -> B : sender chain is sink zone. Denom upon receiving: 'B/denom' // 6. B -> A : sender chain is sink zone. Denom upon receiving: 'denom' -func (k Keeper) SendTransfer( +func (k Keeper) sendTransfer( ctx sdk.Context, sourcePort, sourceChannel string, @@ -57,33 +58,21 @@ func (k Keeper) SendTransfer( receiver string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, -) error { - if !k.GetSendEnabled(ctx) { - return types.ErrSendDisabled - } - - sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) + memo string, +) (uint64, error) { + channel, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel) if !found { - return sdkerrors.Wrapf(channeltypes.ErrChannelNotFound, "port ID (%s) channel ID (%s)", sourcePort, sourceChannel) + return 0, errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "port ID (%s) channel ID (%s)", sourcePort, sourceChannel) } - destinationPort := sourceChannelEnd.GetCounterparty().GetPortID() - destinationChannel := sourceChannelEnd.GetCounterparty().GetChannelID() - - // get the next sequence - sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel) - if !found { - return sdkerrors.Wrapf( - channeltypes.ErrSequenceSendNotFound, - "source port: %s, source channel: %s", sourcePort, sourceChannel, - ) - } + destinationPort := channel.GetCounterparty().GetPortID() + destinationChannel := channel.GetCounterparty().GetChannelID() // begin createOutgoingPacket logic // See spec for this logic: https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#packet-relay channelCap, ok := k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(sourcePort, sourceChannel)) if !ok { - return sdkerrors.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") + return 0, errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") } // NOTE: denomination and hex hash correctness checked during msg.ValidateBasic @@ -96,7 +85,7 @@ func (k Keeper) SendTransfer( if strings.HasPrefix(token.Denom, "ibc/") { fullDenomPath, err = k.DenomPathFromHash(ctx, token.Denom) if err != nil { - return err + return 0, err } } @@ -119,9 +108,8 @@ func (k Keeper) SendTransfer( if err := k.bankKeeper.SendCoins( ctx, sender, escrowAddress, sdk.NewCoins(token), ); err != nil { - return err + return 0, err } - } else { labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "false")) @@ -129,7 +117,7 @@ func (k Keeper) SendTransfer( if err := k.bankKeeper.SendCoinsFromAccountToModule( ctx, sender, types.ModuleName, sdk.NewCoins(token), ); err != nil { - return err + return 0, err } if err := k.bankKeeper.BurnCoins( @@ -143,22 +131,12 @@ func (k Keeper) SendTransfer( } packetData := types.NewFungibleTokenPacketData( - fullDenomPath, token.Amount.String(), sender.String(), receiver, - ) - - packet := channeltypes.NewPacket( - packetData.GetBytes(), - sequence, - sourcePort, - sourceChannel, - destinationPort, - destinationChannel, - timeoutHeight, - timeoutTimestamp, + fullDenomPath, token.Amount.String(), sender.String(), receiver, memo, ) - if err := k.ics4Wrapper.SendPacket(ctx, channelCap, packet); err != nil { - return err + sequence, err := k.ics4Wrapper.SendPacket(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, packetData.GetBytes()) + if err != nil { + return 0, err } defer func() { @@ -177,7 +155,7 @@ func (k Keeper) SendTransfer( ) }() - return nil + return sequence, nil } // OnRecvPacket processes a cross chain fungible token transfer. If the @@ -188,7 +166,7 @@ func (k Keeper) SendTransfer( func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data types.FungibleTokenPacketData) error { // validate packet data upon receiving if err := data.ValidateBasic(); err != nil { - return err + return errorsmod.Wrapf(err, "error validating ICS-20 transfer packet data") } if !k.GetReceiveEnabled(ctx) { @@ -198,13 +176,13 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t // decode the receiver address receiver, err := sdk.AccAddressFromBech32(data.Receiver) if err != nil { - return err + return errorsmod.Wrapf(err, "failed to decode receiver address: %s", data.Receiver) } // parse the transfer amount transferAmount, ok := sdk.NewIntFromString(data.Amount) if !ok { - return sdkerrors.Wrapf(types.ErrInvalidAmount, "unable to parse transfer amount (%s) into sdk.Int", data.Amount) + return errorsmod.Wrapf(types.ErrInvalidAmount, "unable to parse transfer amount: %s", data.Amount) } labels := []metrics.Label{ @@ -239,7 +217,7 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t token := sdk.NewCoin(denom, transferAmount) if k.bankKeeper.BlockedAddr(receiver) { - return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", receiver) + return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "%s is not allowed to receive funds", receiver) } // unescrow tokens @@ -249,7 +227,7 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t // counterparty module. The bug may occur in bank or any part of the code that allows // the escrow address to be drained. A malicious counterparty module could drain the // escrow address by allowing more tokens to be sent back then were escrowed. - return sdkerrors.Wrap(err, "unable to unescrow tokens, this may be caused by a malicious counterparty module or a bug: please open an issue on counterparty module") + return errorsmod.Wrap(err, "unable to unescrow tokens, this may be caused by a malicious counterparty module or a bug: please open an issue on counterparty module") } defer func() { @@ -302,14 +280,14 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t if err := k.bankKeeper.MintCoins( ctx, types.ModuleName, sdk.NewCoins(voucher), ); err != nil { - return err + return errorsmod.Wrap(err, "failed to mint IBC tokens") } // send to receiver if err := k.bankKeeper.SendCoinsFromModuleToAccount( ctx, types.ModuleName, receiver, sdk.NewCoins(voucher), ); err != nil { - return err + return errorsmod.Wrapf(err, "failed to send coins to receiver %s", receiver.String()) } defer func() { @@ -367,7 +345,7 @@ func (k Keeper) refundPacketToken(ctx sdk.Context, packet channeltypes.Packet, d // parse the transfer amount transferAmount, ok := sdk.NewIntFromString(data.Amount) if !ok { - return sdkerrors.Wrapf(types.ErrInvalidAmount, "unable to parse transfer amount (%s) into sdk.Int", data.Amount) + return errorsmod.Wrapf(types.ErrInvalidAmount, "unable to parse transfer amount (%s) into math.Int", data.Amount) } token := sdk.NewCoin(trace.IBCDenom(), transferAmount) @@ -385,7 +363,7 @@ func (k Keeper) refundPacketToken(ctx sdk.Context, packet channeltypes.Packet, d // counterparty module. The bug may occur in bank or any part of the code that allows // the escrow address to be drained. A malicious counterparty module could drain the // escrow address by allowing more tokens to be sent back then were escrowed. - return sdkerrors.Wrap(err, "unable to unescrow tokens, this may be caused by a malicious counterparty module or a bug: please open an issue on counterparty module") + return errorsmod.Wrap(err, "unable to unescrow tokens, this may be caused by a malicious counterparty module or a bug: please open an issue on counterparty module") } return nil @@ -413,12 +391,12 @@ func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error) hash, err := types.ParseHexHash(hexHash) if err != nil { - return "", sdkerrors.Wrap(types.ErrInvalidDenomForTransfer, err.Error()) + return "", errorsmod.Wrap(types.ErrInvalidDenomForTransfer, err.Error()) } denomTrace, found := k.GetDenomTrace(ctx, hash) if !found { - return "", sdkerrors.Wrap(types.ErrTraceNotFound, hexHash) + return "", errorsmod.Wrap(types.ErrTraceNotFound, hexHash) } fullDenomPath := denomTrace.GetFullDenomPath() diff --git a/modules/apps/transfer/keeper/relay_test.go b/modules/apps/transfer/keeper/relay_test.go index ac60ed3964b..a09a73037b1 100644 --- a/modules/apps/transfer/keeper/relay_test.go +++ b/modules/apps/transfer/keeper/relay_test.go @@ -3,142 +3,147 @@ package keeper_test import ( "fmt" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "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" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) // test sending from chainA to chainB using both coin that orignate on // chainA and coin that orignate on chainB func (suite *KeeperTestSuite) TestSendTransfer() { var ( - amount sdk.Coin - path *ibctesting.Path - err error + coin sdk.Coin + path *ibctesting.Path + sender sdk.AccAddress + timeoutHeight clienttypes.Height + memo string ) testCases := []struct { - msg string - malleate func() - sendFromSource bool - expPass bool + name string + malleate func() + expPass bool }{ { - "successful transfer from source chain", + "successful transfer with native token", + func() {}, true, + }, + { + "successful transfer from source chain with memo", func() { - suite.coordinator.CreateTransferChannels(path) - amount = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) - }, true, true, + memo = "memo" //nolint:goconst + }, true, }, { - "successful transfer with coin from counterparty chain", + "successful transfer with IBC token", + func() { - // send coin from chainA back to chainB - suite.coordinator.CreateTransferChannels(path) - amount = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.DefaultBondDenom, sdk.NewInt(100)) - }, false, true, + // send IBC token back to chainB + coin = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coin.Denom, coin.Amount) + }, true, + }, + { + "successful transfer with IBC token and memo", + func() { + // send IBC token back to chainB + coin = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coin.Denom, coin.Amount) + memo = "memo" + }, true, }, { "source channel not found", func() { // channel references wrong ID - suite.coordinator.CreateTransferChannels(path) path.EndpointA.ChannelID = ibctesting.InvalidID - amount = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) - }, true, false, + }, false, }, { - "next seq send not found", + "transfer failed - sender account is blocked", func() { - path.EndpointA.ChannelID = "channel-0" - path.EndpointB.ChannelID = "channel-0" - // manually create channel so next seq send is never set - suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetChannel( - suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, - channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{path.EndpointA.ConnectionID}, ibctesting.DefaultChannelVersion), - ) - suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - amount = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) - }, true, false, + sender = suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(types.ModuleName) + }, false, }, - - // createOutgoingPacket tests - // - source chain { "send coin failed", func() { - suite.coordinator.CreateTransferChannels(path) - amount = sdk.NewCoin("randomdenom", sdk.NewInt(100)) - }, true, false, + coin = sdk.NewCoin("randomdenom", sdk.NewInt(100)) + }, false, }, - // - receiving chain { - "send from module account failed", + "failed to parse coin denom", func() { - suite.coordinator.CreateTransferChannels(path) - amount = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, " randomdenom", sdk.NewInt(100)) - }, false, false, + coin = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, "randomdenom", coin.Amount) + }, false, + }, + { + "send from module account failed, insufficient balance", + func() { + coin = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coin.Denom, coin.Amount.Add(sdk.NewInt(1))) + }, false, }, { "channel capability not found", func() { - suite.coordinator.CreateTransferChannels(path) cap := suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) // Release channel capability - suite.chainA.GetSimApp().ScopedTransferKeeper.ReleaseCapability(suite.chainA.GetContext(), cap) - amount = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) - }, true, false, + suite.chainA.GetSimApp().ScopedTransferKeeper.ReleaseCapability(suite.chainA.GetContext(), cap) //nolint:errcheck // ignore error for testing + }, false, + }, + { + "SendPacket fails, timeout height and timeout timestamp are zero", + func() { + timeoutHeight = clienttypes.ZeroHeight() + }, false, }, } for _, tc := range testCases { - tc := tc - - suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.Run(tc.name, func() { suite.SetupTest() // reset + path = NewTransferPath(suite.chainA, suite.chainB) - suite.coordinator.SetupConnections(path) + suite.coordinator.Setup(path) - tc.malleate() + coin = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) + sender = suite.chainA.SenderAccount.GetAddress() + memo = "" + timeoutHeight = suite.chainB.GetTimeoutHeight() - if !tc.sendFromSource { - // send coin from chainB to chainA - coinFromBToA := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) - transferMsg := types.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinFromBToA, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String(), clienttypes.NewHeight(0, 110), 0) - _, err = suite.chainB.SendMsgs(transferMsg) - suite.Require().NoError(err) // message committed + // create IBC token on chainA + transferMsg := types.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coin, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainA.GetTimeoutHeight(), 0, "") + result, err := suite.chainB.SendMsgs(transferMsg) + suite.Require().NoError(err) // message committed - // receive coin on chainA from chainB - fungibleTokenPacket := types.NewFungibleTokenPacketData(coinFromBToA.Denom, coinFromBToA.Amount.String(), suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) - packet := channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, clienttypes.NewHeight(0, 110), 0) + packet, err := ibctesting.ParsePacketFromEvents(result.GetEvents()) + suite.Require().NoError(err) - // get proof of packet commitment from chainB - err = path.EndpointA.UpdateClient() - suite.Require().NoError(err) - packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - proof, proofHeight := path.EndpointB.QueryProof(packetKey) + err = path.RelayPacket(packet) + suite.Require().NoError(err) - recvMsg := channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, suite.chainA.SenderAccount.GetAddress().String()) - _, err = suite.chainA.SendMsgs(recvMsg) - suite.Require().NoError(err) // message committed - } + tc.malleate() - err = suite.chainA.GetSimApp().TransferKeeper.SendTransfer( - suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, amount, - suite.chainA.SenderAccount.GetAddress(), suite.chainB.SenderAccount.GetAddress().String(), clienttypes.NewHeight(0, 110), 0, + msg := types.NewMsgTransfer( + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + coin, sender.String(), suite.chainB.SenderAccount.GetAddress().String(), + timeoutHeight, 0, // only use timeout height + memo, ) + res, err := suite.chainA.GetSimApp().TransferKeeper.Transfer(sdk.WrapSDKContext(suite.chainA.GetContext()), msg) + if tc.expPass { suite.Require().NoError(err) + suite.Require().NotNil(res) } else { suite.Require().Error(err) + suite.Require().Nil(res) } }) } @@ -151,8 +156,9 @@ func (suite *KeeperTestSuite) TestSendTransfer() { func (suite *KeeperTestSuite) TestOnRecvPacket() { var ( trace types.DenomTrace - amount sdk.Int + amount math.Int receiver string + memo string ) testCases := []struct { @@ -162,7 +168,13 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { expPass bool }{ {"success receive on source chain", func() {}, true, true}, + {"success receive on source chain with memo", func() { + memo = "memo" + }, true, true}, {"success receive with coin from another chain as source", func() {}, false, true}, + {"success receive with coin from another chain as source with memo", func() { + memo = "memo" + }, false, true}, {"empty coin", func() { trace = types.DenomTrace{} amount = sdk.ZeroInt() @@ -203,13 +215,14 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { suite.coordinator.Setup(path) receiver = suite.chainB.SenderAccount.GetAddress().String() // must be explicitly changed in malleate + memo = "" // can be explicitly changed in malleate amount = sdk.NewInt(100) // must be explicitly changed in malleate seq := uint64(1) if tc.recvIsSource { // send coin from chainB to chainA, receive them, acknowledge them, and send back to chainB coinFromBToA := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) - transferMsg := types.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinFromBToA, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String(), clienttypes.NewHeight(0, 110), 0) + transferMsg := types.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinFromBToA, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String(), clienttypes.NewHeight(1, 110), 0, memo) res, err := suite.chainB.SendMsgs(transferMsg) suite.Require().NoError(err) // message committed @@ -228,14 +241,14 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { } // send coin from chainA to chainB - transferMsg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.NewCoin(trace.IBCDenom(), amount), suite.chainA.SenderAccount.GetAddress().String(), receiver, clienttypes.NewHeight(0, 110), 0) + transferMsg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.NewCoin(trace.IBCDenom(), amount), suite.chainA.SenderAccount.GetAddress().String(), receiver, clienttypes.NewHeight(1, 110), 0, memo) _, err := suite.chainA.SendMsgs(transferMsg) suite.Require().NoError(err) // message committed tc.malleate() - data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), suite.chainA.SenderAccount.GetAddress().String(), receiver) - packet := channeltypes.NewPacket(data.GetBytes(), seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) + data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), suite.chainA.SenderAccount.GetAddress().String(), receiver, memo) + packet := channeltypes.NewPacket(data.GetBytes(), seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(1, 100), 0) err = suite.chainB.GetSimApp().TransferKeeper.OnRecvPacket(suite.chainB.GetContext(), packet, data) @@ -257,7 +270,7 @@ func (suite *KeeperTestSuite) TestOnAcknowledgementPacket() { successAck = channeltypes.NewResultAcknowledgement([]byte{byte(1)}) failedAck = channeltypes.NewErrorAcknowledgement(fmt.Errorf("failed packet transfer")) trace types.DenomTrace - amount sdk.Int + amount math.Int path *ibctesting.Path ) @@ -276,7 +289,7 @@ func (suite *KeeperTestSuite) TestOnAcknowledgementPacket() { trace = types.ParseDenomTrace(sdk.DefaultBondDenom) coin := sdk.NewCoin(sdk.DefaultBondDenom, amount) - suite.Require().NoError(simapp.FundAccount(suite.chainA.GetSimApp(), suite.chainA.GetContext(), escrow, sdk.NewCoins(coin))) + suite.Require().NoError(banktestutil.FundAccount(suite.chainA.GetSimApp().BankKeeper, suite.chainA.GetContext(), escrow, sdk.NewCoins(coin))) }, false, true}, { "unsuccessful refund from source", failedAck, @@ -291,7 +304,7 @@ func (suite *KeeperTestSuite) TestOnAcknowledgementPacket() { trace = types.ParseDenomTrace(types.GetPrefixedDenom(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.DefaultBondDenom)) coin := sdk.NewCoin(trace.IBCDenom(), amount) - suite.Require().NoError(simapp.FundAccount(suite.chainA.GetSimApp(), suite.chainA.GetContext(), escrow, sdk.NewCoins(coin))) + suite.Require().NoError(banktestutil.FundAccount(suite.chainA.GetSimApp().BankKeeper, suite.chainA.GetContext(), escrow, sdk.NewCoins(coin))) }, false, true, }, } @@ -307,8 +320,8 @@ func (suite *KeeperTestSuite) TestOnAcknowledgementPacket() { tc.malleate() - data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String()) - packet := channeltypes.NewPacket(data.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) + data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), "") + packet := channeltypes.NewPacket(data.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(1, 100), 0) preCoin := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), trace.IBCDenom()) @@ -339,7 +352,7 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacket() { var ( trace types.DenomTrace path *ibctesting.Path - amount sdk.Int + amount math.Int sender string ) @@ -355,7 +368,7 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacket() { trace = types.ParseDenomTrace(sdk.DefaultBondDenom) coin := sdk.NewCoin(trace.IBCDenom(), amount) - suite.Require().NoError(simapp.FundAccount(suite.chainA.GetSimApp(), suite.chainA.GetContext(), escrow, sdk.NewCoins(coin))) + suite.Require().NoError(banktestutil.FundAccount(suite.chainA.GetSimApp().BankKeeper, suite.chainA.GetContext(), escrow, sdk.NewCoins(coin))) }, true, }, { @@ -365,7 +378,7 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacket() { trace = types.ParseDenomTrace(types.GetPrefixedDenom(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, sdk.DefaultBondDenom)) coin := sdk.NewCoin(trace.IBCDenom(), amount) - suite.Require().NoError(simapp.FundAccount(suite.chainA.GetSimApp(), suite.chainA.GetContext(), escrow, sdk.NewCoins(coin))) + suite.Require().NoError(banktestutil.FundAccount(suite.chainA.GetSimApp().BankKeeper, suite.chainA.GetContext(), escrow, sdk.NewCoins(coin))) }, true, }, { @@ -403,8 +416,8 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacket() { tc.malleate() - data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), sender, suite.chainB.SenderAccount.GetAddress().String()) - packet := channeltypes.NewPacket(data.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) + data := types.NewFungibleTokenPacketData(trace.GetFullDenomPath(), amount.String(), sender, suite.chainB.SenderAccount.GetAddress().String(), "") + packet := channeltypes.NewPacket(data.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(1, 100), 0) preCoin := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), trace.IBCDenom()) diff --git a/modules/apps/transfer/module.go b/modules/apps/transfer/module.go index 9503a06d926..fcf5ac7267f 100644 --- a/modules/apps/transfer/module.go +++ b/modules/apps/transfer/module.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "math/rand" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -12,16 +11,15 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/client/cli" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/simulation" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/client/cli" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/simulation" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" ) var ( @@ -64,13 +62,12 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod return gs.Validate() } -// RegisterRESTRoutes implements AppModuleBasic interface -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { -} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-transfer module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err != nil { + panic(err) + } } // GetTxCmd implements AppModuleBasic interface @@ -101,21 +98,6 @@ func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { // TODO } -// Route implements the AppModule interface -func (am AppModule) Route() sdk.Route { - return sdk.Route{} -} - -// QuerierRoute implements the AppModule interface -func (AppModule) QuerierRoute() string { - return types.QuerierRoute -} - -// LegacyQuerierHandler implements the AppModule interface -func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { - return nil -} - // RegisterServices registers module services. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), am.keeper) @@ -162,16 +144,6 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { simulation.RandomizedGenState(simState) } -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { - return nil -} - -// RandomizedParams creates randomized ibc-transfer param changes for the simulator. -func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { - return simulation.ParamChanges(r) -} - // RegisterStoreDecoder registers a decoder for transfer module's types func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { sdr[types.StoreKey] = simulation.NewDecodeStore(am.keeper) diff --git a/modules/apps/transfer/simulation/decoder.go b/modules/apps/transfer/simulation/decoder.go index 6e1fe37feeb..ea67c509e3d 100644 --- a/modules/apps/transfer/simulation/decoder.go +++ b/modules/apps/transfer/simulation/decoder.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // TransferUnmarshaler defines the expected encoding store functions. diff --git a/modules/apps/transfer/simulation/decoder_test.go b/modules/apps/transfer/simulation/decoder_test.go index 13afd462be7..26d7dbf4b94 100644 --- a/modules/apps/transfer/simulation/decoder_test.go +++ b/modules/apps/transfer/simulation/decoder_test.go @@ -7,9 +7,9 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/simulation" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/simulation" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) func TestDecodeStore(t *testing.T) { diff --git a/modules/apps/transfer/simulation/genesis.go b/modules/apps/transfer/simulation/genesis.go index 693864ce12b..220cdddd470 100644 --- a/modules/apps/transfer/simulation/genesis.go +++ b/modules/apps/transfer/simulation/genesis.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // Simulation parameter constants diff --git a/modules/apps/transfer/simulation/genesis_test.go b/modules/apps/transfer/simulation/genesis_test.go index 5b46c88f9d8..01c933c17a5 100644 --- a/modules/apps/transfer/simulation/genesis_test.go +++ b/modules/apps/transfer/simulation/genesis_test.go @@ -5,20 +5,23 @@ import ( "math/rand" "testing" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/simulation" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/simulation" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // TestRandomizedGenState tests the normal scenario of applying RandomizedGenState. // Abonormal scenarios are not tested here. func TestRandomizedGenState(t *testing.T) { interfaceRegistry := codectypes.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(interfaceRegistry) cdc := codec.NewProtoCodec(interfaceRegistry) s := rand.NewSource(1) @@ -30,7 +33,7 @@ func TestRandomizedGenState(t *testing.T) { Rand: r, NumBonded: 3, Accounts: simtypes.RandomAccounts(r, 3), - InitialStake: 1000, + InitialStake: math.NewInt(1000), GenState: make(map[string]json.RawMessage), } diff --git a/modules/apps/transfer/simulation/params.go b/modules/apps/transfer/simulation/params.go deleted file mode 100644 index 838015ae498..00000000000 --- a/modules/apps/transfer/simulation/params.go +++ /dev/null @@ -1,31 +0,0 @@ -package simulation - -import ( - "fmt" - "math/rand" - - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/cosmos-sdk/x/simulation" - gogotypes "github.com/gogo/protobuf/types" - - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" -) - -// ParamChanges defines the parameters that can be modified by param change proposals -// on the simulation -func ParamChanges(r *rand.Rand) []simtypes.ParamChange { - return []simtypes.ParamChange{ - simulation.NewSimParamChange(types.ModuleName, string(types.KeySendEnabled), - func(r *rand.Rand) string { - sendEnabled := RadomEnabled(r) - return fmt.Sprintf("%s", types.ModuleCdc.MustMarshalJSON(&gogotypes.BoolValue{Value: sendEnabled})) - }, - ), - simulation.NewSimParamChange(types.ModuleName, string(types.KeyReceiveEnabled), - func(r *rand.Rand) string { - receiveEnabled := RadomEnabled(r) - return fmt.Sprintf("%s", types.ModuleCdc.MustMarshalJSON(&gogotypes.BoolValue{Value: receiveEnabled})) - }, - ), - } -} diff --git a/modules/apps/transfer/simulation/params_test.go b/modules/apps/transfer/simulation/params_test.go deleted file mode 100644 index 86c16c67c5c..00000000000 --- a/modules/apps/transfer/simulation/params_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package simulation_test - -import ( - "math/rand" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/simulation" -) - -func TestParamChanges(t *testing.T) { - s := rand.NewSource(1) - r := rand.New(s) - - expected := []struct { - composedKey string - key string - simValue string - subspace string - }{ - {"transfer/SendEnabled", "SendEnabled", "false", "transfer"}, - {"transfer/ReceiveEnabled", "ReceiveEnabled", "true", "transfer"}, - } - - paramChanges := simulation.ParamChanges(r) - - require.Len(t, paramChanges, 2) - - for i, p := range paramChanges { - require.Equal(t, expected[i].composedKey, p.ComposedKey()) - require.Equal(t, expected[i].key, p.Key()) - require.Equal(t, expected[i].simValue, p.SimValue()(r), p.Key()) - require.Equal(t, expected[i].subspace, p.Subspace()) - } -} diff --git a/modules/apps/transfer/transfer_test.go b/modules/apps/transfer/transfer_test.go index d1089f0ee82..0d50d3cd0fd 100644 --- a/modules/apps/transfer/transfer_test.go +++ b/modules/apps/transfer/transfer_test.go @@ -6,9 +6,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type TransferTestSuite struct { @@ -47,14 +47,14 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { suite.coordinator.Setup(path) // originalBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), sdk.DefaultBondDenom) - timeoutHeight := clienttypes.NewHeight(0, 110) + timeoutHeight := clienttypes.NewHeight(1, 110) amount, ok := sdk.NewIntFromString("9223372036854775808") // 2^63 (one above int64) suite.Require().True(ok) coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, amount) // send from chainA to chainB - msg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coinToSendToB, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0) + msg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coinToSendToB, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0, "") res, err := suite.chainA.SendMsgs(msg) suite.Require().NoError(err) // message committed @@ -80,7 +80,7 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { suite.coordinator.Setup(pathBtoC) // send from chainB to chainC - msg = types.NewMsgTransfer(pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, coinSentFromAToB, suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String(), timeoutHeight, 0) + msg = types.NewMsgTransfer(pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, coinSentFromAToB, suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String(), timeoutHeight, 0, "") res, err = suite.chainB.SendMsgs(msg) suite.Require().NoError(err) // message committed @@ -104,7 +104,7 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { suite.Require().Zero(balance.Amount.Int64()) // send from chainC back to chainB - msg = types.NewMsgTransfer(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, coinSentFromBToC, suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0) + msg = types.NewMsgTransfer(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, coinSentFromBToC, suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0, "") res, err = suite.chainC.SendMsgs(msg) suite.Require().NoError(err) // message committed diff --git a/modules/apps/transfer/types/authz.pb.go b/modules/apps/transfer/types/authz.pb.go new file mode 100644 index 00000000000..95f24eca332 --- /dev/null +++ b/modules/apps/transfer/types/authz.pb.go @@ -0,0 +1,695 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/transfer/v1/authz.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Allocation defines the spend limit for a particular port and channel +type Allocation struct { + // the port on which the packet will be sent + SourcePort string `protobuf:"bytes,1,opt,name=source_port,json=sourcePort,proto3" json:"source_port,omitempty" yaml:"source_port"` + // the channel by which the packet will be sent + SourceChannel string `protobuf:"bytes,2,opt,name=source_channel,json=sourceChannel,proto3" json:"source_channel,omitempty" yaml:"source_channel"` + // spend limitation on the channel + SpendLimit github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=spend_limit,json=spendLimit,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"spend_limit"` + // allow list of receivers, an empty allow list permits any receiver address + AllowList []string `protobuf:"bytes,4,rep,name=allow_list,json=allowList,proto3" json:"allow_list,omitempty"` +} + +func (m *Allocation) Reset() { *m = Allocation{} } +func (m *Allocation) String() string { return proto.CompactTextString(m) } +func (*Allocation) ProtoMessage() {} +func (*Allocation) Descriptor() ([]byte, []int) { + return fileDescriptor_b1a28b55d17325aa, []int{0} +} +func (m *Allocation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Allocation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Allocation.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 *Allocation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Allocation.Merge(m, src) +} +func (m *Allocation) XXX_Size() int { + return m.Size() +} +func (m *Allocation) XXX_DiscardUnknown() { + xxx_messageInfo_Allocation.DiscardUnknown(m) +} + +var xxx_messageInfo_Allocation proto.InternalMessageInfo + +func (m *Allocation) GetSourcePort() string { + if m != nil { + return m.SourcePort + } + return "" +} + +func (m *Allocation) GetSourceChannel() string { + if m != nil { + return m.SourceChannel + } + return "" +} + +func (m *Allocation) GetSpendLimit() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.SpendLimit + } + return nil +} + +func (m *Allocation) GetAllowList() []string { + if m != nil { + return m.AllowList + } + return nil +} + +// TransferAuthorization allows the grantee to spend up to spend_limit coins from +// the granter's account for ibc transfer on a specific channel +type TransferAuthorization struct { + // port and channel amounts + Allocations []Allocation `protobuf:"bytes,1,rep,name=allocations,proto3" json:"allocations"` +} + +func (m *TransferAuthorization) Reset() { *m = TransferAuthorization{} } +func (m *TransferAuthorization) String() string { return proto.CompactTextString(m) } +func (*TransferAuthorization) ProtoMessage() {} +func (*TransferAuthorization) Descriptor() ([]byte, []int) { + return fileDescriptor_b1a28b55d17325aa, []int{1} +} +func (m *TransferAuthorization) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TransferAuthorization) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TransferAuthorization.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 *TransferAuthorization) XXX_Merge(src proto.Message) { + xxx_messageInfo_TransferAuthorization.Merge(m, src) +} +func (m *TransferAuthorization) XXX_Size() int { + return m.Size() +} +func (m *TransferAuthorization) XXX_DiscardUnknown() { + xxx_messageInfo_TransferAuthorization.DiscardUnknown(m) +} + +var xxx_messageInfo_TransferAuthorization proto.InternalMessageInfo + +func (m *TransferAuthorization) GetAllocations() []Allocation { + if m != nil { + return m.Allocations + } + return nil +} + +func init() { + proto.RegisterType((*Allocation)(nil), "ibc.applications.transfer.v1.Allocation") + proto.RegisterType((*TransferAuthorization)(nil), "ibc.applications.transfer.v1.TransferAuthorization") +} + +func init() { + proto.RegisterFile("ibc/applications/transfer/v1/authz.proto", fileDescriptor_b1a28b55d17325aa) +} + +var fileDescriptor_b1a28b55d17325aa = []byte{ + // 435 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0x4d, 0x6e, 0xd3, 0x40, + 0x14, 0x8e, 0x9b, 0x0a, 0x29, 0x13, 0xc1, 0xc2, 0xa2, 0xc8, 0xa9, 0xc0, 0x89, 0xbc, 0x40, 0xde, + 0x64, 0x86, 0xc0, 0x22, 0x52, 0x57, 0x34, 0xdd, 0x76, 0x51, 0x2c, 0x56, 0x6c, 0xa2, 0xf1, 0x64, + 0xb0, 0x47, 0x8c, 0xfd, 0x2c, 0xcf, 0xd8, 0xa8, 0x3d, 0x05, 0x48, 0x9c, 0x82, 0x35, 0x87, 0xa8, + 0x58, 0x75, 0xc9, 0x2a, 0xa0, 0xe4, 0x06, 0x3d, 0x01, 0xf2, 0xcc, 0x14, 0x5c, 0x21, 0xb1, 0xb2, + 0xdf, 0xcf, 0xf7, 0xde, 0xf7, 0xbe, 0xf9, 0x50, 0x2c, 0x52, 0x46, 0x68, 0x55, 0x49, 0xc1, 0xa8, + 0x16, 0x50, 0x2a, 0xa2, 0x6b, 0x5a, 0xaa, 0xf7, 0xbc, 0x26, 0xed, 0x82, 0xd0, 0x46, 0xe7, 0x57, + 0xb8, 0xaa, 0x41, 0x83, 0xff, 0x54, 0xa4, 0x0c, 0xf7, 0x3b, 0xf1, 0x5d, 0x27, 0x6e, 0x17, 0xc7, + 0x13, 0x06, 0xaa, 0x00, 0xb5, 0x36, 0xbd, 0xc4, 0x06, 0x16, 0x78, 0xfc, 0x38, 0x83, 0x0c, 0x6c, + 0xbe, 0xfb, 0x73, 0xd9, 0xd0, 0xf6, 0x90, 0x94, 0x2a, 0x4e, 0xda, 0x45, 0xca, 0x35, 0x5d, 0x10, + 0x06, 0xa2, 0xb4, 0xf5, 0xe8, 0xcb, 0x01, 0x42, 0xa7, 0x52, 0x82, 0x5d, 0xe6, 0x2f, 0xd1, 0x58, + 0x41, 0x53, 0x33, 0xbe, 0xae, 0xa0, 0xd6, 0x81, 0x37, 0xf3, 0xe2, 0xd1, 0xea, 0xc9, 0xed, 0x76, + 0xea, 0x5f, 0xd2, 0x42, 0x9e, 0x44, 0xbd, 0x62, 0x94, 0x20, 0x1b, 0x5d, 0x40, 0xad, 0xfd, 0xd7, + 0xe8, 0x91, 0xab, 0xb1, 0x9c, 0x96, 0x25, 0x97, 0xc1, 0x81, 0xc1, 0x4e, 0x6e, 0xb7, 0xd3, 0xa3, + 0x7b, 0x58, 0x57, 0x8f, 0x92, 0x87, 0x36, 0x71, 0x66, 0x63, 0x5f, 0xa2, 0xb1, 0xaa, 0x78, 0xb9, + 0x59, 0x4b, 0x51, 0x08, 0x1d, 0x0c, 0x67, 0xc3, 0x78, 0xfc, 0x72, 0x82, 0xdd, 0x8d, 0x1d, 0x7f, + 0xec, 0xf8, 0xe3, 0x33, 0x10, 0xe5, 0xea, 0xc5, 0xf5, 0x76, 0x3a, 0xf8, 0xfa, 0x73, 0x1a, 0x67, + 0x42, 0xe7, 0x4d, 0x8a, 0x19, 0x14, 0x4e, 0x10, 0xf7, 0x99, 0xab, 0xcd, 0x07, 0xa2, 0x2f, 0x2b, + 0xae, 0x0c, 0x40, 0x25, 0xc8, 0xcc, 0x3f, 0xef, 0xc6, 0xfb, 0xcf, 0x10, 0xa2, 0x52, 0xc2, 0xc7, + 0xb5, 0x14, 0x4a, 0x07, 0x87, 0xb3, 0x61, 0x3c, 0x4a, 0x46, 0x26, 0x73, 0x2e, 0x94, 0x8e, 0x3e, + 0x7b, 0xe8, 0xe8, 0xad, 0xd3, 0xfd, 0xb4, 0xd1, 0x39, 0xd4, 0xe2, 0xca, 0x2a, 0x74, 0x81, 0xc6, + 0xf4, 0x8f, 0x5e, 0x2a, 0xf0, 0x0c, 0xcd, 0x18, 0xff, 0xef, 0xd5, 0xf0, 0x5f, 0x81, 0x57, 0x87, + 0x1d, 0xeb, 0xa4, 0x3f, 0xe2, 0xe4, 0xf9, 0xf7, 0x6f, 0xf3, 0xc8, 0x9d, 0x69, 0x9d, 0x70, 0x77, + 0xe7, 0xbd, 0xcd, 0xab, 0x37, 0xd7, 0xbb, 0xd0, 0xbb, 0xd9, 0x85, 0xde, 0xaf, 0x5d, 0xe8, 0x7d, + 0xda, 0x87, 0x83, 0x9b, 0x7d, 0x38, 0xf8, 0xb1, 0x0f, 0x07, 0xef, 0x96, 0xff, 0x4a, 0x20, 0x52, + 0x36, 0xcf, 0x80, 0xb4, 0x4b, 0x52, 0xc0, 0xa6, 0x91, 0x5c, 0x75, 0xee, 0xeb, 0xb9, 0xce, 0xe8, + 0x92, 0x3e, 0x30, 0x26, 0x78, 0xf5, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x61, 0xe8, 0x65, 0x9c, 0x9f, + 0x02, 0x00, 0x00, +} + +func (m *Allocation) 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 *Allocation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Allocation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AllowList) > 0 { + for iNdEx := len(m.AllowList) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AllowList[iNdEx]) + copy(dAtA[i:], m.AllowList[iNdEx]) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.AllowList[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } + if len(m.SpendLimit) > 0 { + for iNdEx := len(m.SpendLimit) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.SpendLimit[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.SourceChannel) > 0 { + i -= len(m.SourceChannel) + copy(dAtA[i:], m.SourceChannel) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.SourceChannel))) + i-- + dAtA[i] = 0x12 + } + if len(m.SourcePort) > 0 { + i -= len(m.SourcePort) + copy(dAtA[i:], m.SourcePort) + i = encodeVarintAuthz(dAtA, i, uint64(len(m.SourcePort))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TransferAuthorization) 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 *TransferAuthorization) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TransferAuthorization) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Allocations) > 0 { + for iNdEx := len(m.Allocations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Allocations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAuthz(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintAuthz(dAtA []byte, offset int, v uint64) int { + offset -= sovAuthz(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Allocation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SourcePort) + if l > 0 { + n += 1 + l + sovAuthz(uint64(l)) + } + l = len(m.SourceChannel) + if l > 0 { + n += 1 + l + sovAuthz(uint64(l)) + } + if len(m.SpendLimit) > 0 { + for _, e := range m.SpendLimit { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + if len(m.AllowList) > 0 { + for _, s := range m.AllowList { + l = len(s) + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func (m *TransferAuthorization) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Allocations) > 0 { + for _, e := range m.Allocations { + l = e.Size() + n += 1 + l + sovAuthz(uint64(l)) + } + } + return n +} + +func sovAuthz(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozAuthz(x uint64) (n int) { + return sovAuthz(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Allocation) 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 ErrIntOverflowAuthz + } + 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: Allocation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Allocation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourcePort", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + 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 ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourcePort = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceChannel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + 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 ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourceChannel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpendLimit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpendLimit = append(m.SpendLimit, types.Coin{}) + if err := m.SpendLimit[len(m.SpendLimit)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowList", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + 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 ErrInvalidLengthAuthz + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AllowList = append(m.AllowList, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TransferAuthorization) 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 ErrIntOverflowAuthz + } + 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: TransferAuthorization: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TransferAuthorization: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allocations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuthz + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAuthz + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAuthz + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allocations = append(m.Allocations, Allocation{}) + if err := m.Allocations[len(m.Allocations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuthz(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAuthz + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAuthz(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuthz + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthAuthz + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAuthz + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAuthz + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAuthz = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAuthz = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAuthz = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/transfer/types/codec.go b/modules/apps/transfer/types/codec.go index 24ad7e5a902..92ed91ef58a 100644 --- a/modules/apps/transfer/types/codec.go +++ b/modules/apps/transfer/types/codec.go @@ -1,6 +1,12 @@ package types import ( + "bytes" + + "github.com/cosmos/cosmos-sdk/x/authz" + "github.com/cosmos/gogoproto/jsonpb" + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -18,6 +24,11 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterImplementations((*sdk.Msg)(nil), &MsgTransfer{}) + registry.RegisterImplementations( + (*authz.Authorization)(nil), + &TransferAuthorization{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } @@ -39,3 +50,32 @@ func init() { RegisterLegacyAminoCodec(amino) amino.Seal() } + +// mustProtoMarshalJSON provides an auxiliary function to return Proto3 JSON encoded +// bytes of a message. +// NOTE: Copied from https://github.com/cosmos/cosmos-sdk/blob/971c542453e0972ef1dfc5a80159ad5049c7211c/codec/json.go +// and modified in order to allow `EmitDefaults` to be set to false for ics20 packet marshalling. +// This allows for the introduction of the memo field to be backwards compatible. +func mustProtoMarshalJSON(msg proto.Message) []byte { + anyResolver := codectypes.NewInterfaceRegistry() + + // EmitDefaults is set to false to prevent marshalling of unpopulated fields (memo) + // OrigName and the anyResovler match the fields the original SDK function would expect + // in order to minimize changes. + + // OrigName is true since there is no particular reason to use camel case + // The any resolver is empty, but provided anyways. + jm := &jsonpb.Marshaler{OrigName: true, EmitDefaults: false, AnyResolver: anyResolver} + + err := codectypes.UnpackInterfaces(msg, codectypes.ProtoJSONPacker{JSONPBMarshaler: jm}) + if err != nil { + panic(err) + } + + buf := new(bytes.Buffer) + if err := jm.Marshal(buf, msg); err != nil { + panic(err) + } + + return buf.Bytes() +} diff --git a/modules/apps/transfer/types/codec_test.go b/modules/apps/transfer/types/codec_test.go new file mode 100644 index 00000000000..05620ede27a --- /dev/null +++ b/modules/apps/transfer/types/codec_test.go @@ -0,0 +1,25 @@ +package types_test + +import ( + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" +) + +// TestMustMarshalProtoJSON tests that the memo field is only emitted (marshalled) if it is populated +func (suite *TypesTestSuite) TestMustMarshalProtoJSON() { + memo := "memo" + packetData := types.NewFungibleTokenPacketData(sdk.DefaultBondDenom, "1", suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), memo) + + bz := packetData.GetBytes() + exists := strings.Contains(string(bz), memo) + suite.Require().True(exists) + + packetData.Memo = "" + + bz = packetData.GetBytes() + exists = strings.Contains(string(bz), memo) + suite.Require().False(exists) +} diff --git a/modules/apps/transfer/types/coin.go b/modules/apps/transfer/types/coin.go index d6329541103..6abc5367cbe 100644 --- a/modules/apps/transfer/types/coin.go +++ b/modules/apps/transfer/types/coin.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -41,7 +42,7 @@ func GetPrefixedDenom(portID, channelID, baseDenom string) string { // GetTransferCoin creates a transfer coin with the port ID and channel ID // prefixed to the base denom. -func GetTransferCoin(portID, channelID, baseDenom string, amount sdk.Int) sdk.Coin { +func GetTransferCoin(portID, channelID, baseDenom string, amount math.Int) sdk.Coin { denomTrace := ParseDenomTrace(GetPrefixedDenom(portID, channelID, baseDenom)) return sdk.NewCoin(denomTrace.IBCDenom(), amount) } diff --git a/modules/apps/transfer/types/errors.go b/modules/apps/transfer/types/errors.go index 0f0cb7c42a4..d62134b27cd 100644 --- a/modules/apps/transfer/types/errors.go +++ b/modules/apps/transfer/types/errors.go @@ -1,17 +1,18 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // IBC transfer sentinel errors var ( - ErrInvalidPacketTimeout = sdkerrors.Register(ModuleName, 2, "invalid packet timeout") - ErrInvalidDenomForTransfer = sdkerrors.Register(ModuleName, 3, "invalid denomination for cross-chain transfer") - ErrInvalidVersion = sdkerrors.Register(ModuleName, 4, "invalid ICS20 version") - ErrInvalidAmount = sdkerrors.Register(ModuleName, 5, "invalid token amount") - ErrTraceNotFound = sdkerrors.Register(ModuleName, 6, "denomination trace not found") - ErrSendDisabled = sdkerrors.Register(ModuleName, 7, "fungible token transfers from this chain are disabled") - ErrReceiveDisabled = sdkerrors.Register(ModuleName, 8, "fungible token transfers to this chain are disabled") - ErrMaxTransferChannels = sdkerrors.Register(ModuleName, 9, "max transfer channels") + ErrInvalidPacketTimeout = errorsmod.Register(ModuleName, 2, "invalid packet timeout") + ErrInvalidDenomForTransfer = errorsmod.Register(ModuleName, 3, "invalid denomination for cross-chain transfer") + ErrInvalidVersion = errorsmod.Register(ModuleName, 4, "invalid ICS20 version") + ErrInvalidAmount = errorsmod.Register(ModuleName, 5, "invalid token amount") + ErrTraceNotFound = errorsmod.Register(ModuleName, 6, "denomination trace not found") + ErrSendDisabled = errorsmod.Register(ModuleName, 7, "fungible token transfers from this chain are disabled") + ErrReceiveDisabled = errorsmod.Register(ModuleName, 8, "fungible token transfers to this chain are disabled") + ErrMaxTransferChannels = errorsmod.Register(ModuleName, 9, "max transfer channels") + ErrInvalidAuthorization = errorsmod.Register(ModuleName, 10, "invalid transfer authorization") ) diff --git a/modules/apps/transfer/types/events.go b/modules/apps/transfer/types/events.go index a3ed5b413c7..89964a8a9a4 100644 --- a/modules/apps/transfer/types/events.go +++ b/modules/apps/transfer/types/events.go @@ -18,4 +18,5 @@ const ( AttributeKeyAck = "acknowledgement" AttributeKeyAckError = "error" AttributeKeyTraceHash = "trace_hash" + AttributeKeyMemo = "memo" ) diff --git a/modules/apps/transfer/types/expected_keepers.go b/modules/apps/transfer/types/expected_keepers.go index c696a2d75d8..2d53fc58f8f 100644 --- a/modules/apps/transfer/types/expected_keepers.go +++ b/modules/apps/transfer/types/expected_keepers.go @@ -5,9 +5,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // AccountKeeper defines the contract required for account APIs. @@ -24,11 +24,7 @@ type BankKeeper interface { SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error BlockedAddr(addr sdk.AccAddress) bool -} - -// ICS4Wrapper defines the expected ICS4Wrapper for middleware -type ICS4Wrapper interface { - SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error + IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool } // ChannelKeeper defines the expected IBC channel keeper diff --git a/modules/apps/transfer/types/genesis.go b/modules/apps/transfer/types/genesis.go index db1f5489558..241a6cff005 100644 --- a/modules/apps/transfer/types/genesis.go +++ b/modules/apps/transfer/types/genesis.go @@ -1,7 +1,7 @@ package types import ( - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // NewGenesisState creates a new ibc-transfer GenesisState instance. diff --git a/modules/apps/transfer/types/genesis.pb.go b/modules/apps/transfer/types/genesis.pb.go index bac7416d405..d7cd38dd7a9 100644 --- a/modules/apps/transfer/types/genesis.pb.go +++ b/modules/apps/transfer/types/genesis.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -96,24 +96,24 @@ var fileDescriptor_a4f788affd5bea89 = []byte{ // 324 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xc1, 0x4a, 0xc3, 0x30, 0x1c, 0xc6, 0x1b, 0x27, 0x15, 0xbb, 0xe1, 0xa1, 0x7a, 0x18, 0x43, 0xda, 0x51, 0x14, 0x8a, 0xc3, - 0x84, 0x4d, 0x41, 0xf0, 0x58, 0x04, 0xf1, 0xa6, 0xd3, 0x93, 0x97, 0x91, 0xa6, 0xb1, 0x06, 0xd6, - 0xa6, 0xe4, 0x9f, 0x0d, 0xf6, 0x16, 0x3e, 0x87, 0x4f, 0xb2, 0xe3, 0x8e, 0x9e, 0xa6, 0x6c, 0x6f, - 0x30, 0x5f, 0x40, 0xd2, 0xcd, 0xb1, 0x53, 0x6f, 0x1f, 0xc9, 0xef, 0xfb, 0xbe, 0x3f, 0x9f, 0x73, - 0x21, 0x62, 0x46, 0x68, 0x51, 0x0c, 0x05, 0xa3, 0x5a, 0xc8, 0x1c, 0x88, 0x56, 0x34, 0x87, 0x37, - 0xae, 0xc8, 0xb8, 0x4b, 0x52, 0x9e, 0x73, 0x10, 0x80, 0x0b, 0x25, 0xb5, 0x74, 0x4f, 0x45, 0xcc, - 0xf0, 0x2e, 0x8b, 0xff, 0x59, 0x3c, 0xee, 0xb6, 0x3a, 0x95, 0x49, 0x5b, 0xb2, 0x8c, 0x6a, 0x9d, - 0xa4, 0x32, 0x95, 0xa5, 0x24, 0x46, 0xad, 0x5f, 0x83, 0x5f, 0xe4, 0x34, 0xee, 0xd7, 0x95, 0xcf, - 0x9a, 0x6a, 0xee, 0x76, 0x9c, 0x83, 0x42, 0x2a, 0x3d, 0x10, 0x49, 0x13, 0xb5, 0x51, 0x78, 0x18, - 0xb9, 0xab, 0xb9, 0x7f, 0x34, 0xa1, 0xd9, 0xf0, 0x36, 0xd8, 0x7c, 0x04, 0x7d, 0xdb, 0xa8, 0x87, - 0xc4, 0x55, 0x4e, 0x23, 0xe1, 0xb9, 0xcc, 0x06, 0x5a, 0x51, 0xc6, 0xa1, 0xb9, 0xd7, 0xae, 0x85, - 0xf5, 0x5e, 0x88, 0xab, 0xae, 0xc6, 0x77, 0xc6, 0xf1, 0x62, 0x0c, 0xd1, 0xf9, 0x74, 0xee, 0x5b, - 0xab, 0xb9, 0x7f, 0xbc, 0xce, 0xdf, 0xcd, 0x0a, 0x3e, 0xbf, 0x7d, 0xbb, 0xa4, 0xa0, 0x5f, 0x4f, - 0xb6, 0x16, 0x70, 0x23, 0xc7, 0x2e, 0xa8, 0xa2, 0x19, 0x34, 0x6b, 0x6d, 0x14, 0xd6, 0x7b, 0x67, - 0xd5, 0x6d, 0x8f, 0x25, 0x1b, 0xed, 0x9b, 0xa6, 0xfe, 0xc6, 0x19, 0x3d, 0x4d, 0x17, 0x1e, 0x9a, - 0x2d, 0x3c, 0xf4, 0xb3, 0xf0, 0xd0, 0xc7, 0xd2, 0xb3, 0x66, 0x4b, 0xcf, 0xfa, 0x5a, 0x7a, 0xd6, - 0xeb, 0x4d, 0x2a, 0xf4, 0xfb, 0x28, 0xc6, 0x4c, 0x66, 0x84, 0x49, 0xc8, 0x24, 0x10, 0x11, 0xb3, - 0xcb, 0x54, 0x92, 0xf1, 0x35, 0xc9, 0x64, 0x32, 0x1a, 0x72, 0x30, 0x93, 0xef, 0x4c, 0xad, 0x27, - 0x05, 0x87, 0xd8, 0x2e, 0xf7, 0xbc, 0xfa, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x96, 0x72, 0x43, 0x93, + 0x84, 0xcd, 0xc3, 0xc0, 0x63, 0x11, 0xc4, 0x9b, 0x4e, 0x4f, 0x5e, 0x46, 0x9a, 0xc6, 0x1a, 0x58, + 0x9b, 0x92, 0x7f, 0x36, 0xd8, 0x5b, 0xf8, 0x1c, 0x3e, 0xc9, 0x8e, 0x3b, 0x7a, 0x9a, 0xb2, 0xbd, + 0xc1, 0x7c, 0x01, 0x49, 0x37, 0xc7, 0x4e, 0xbd, 0x7d, 0x24, 0xbf, 0xef, 0xfb, 0xfe, 0x7c, 0xce, + 0x95, 0x88, 0x19, 0xa1, 0x45, 0x31, 0x12, 0x8c, 0x6a, 0x21, 0x73, 0x20, 0x5a, 0xd1, 0x1c, 0xde, + 0xb8, 0x22, 0x93, 0x2e, 0x49, 0x79, 0xce, 0x41, 0x00, 0x2e, 0x94, 0xd4, 0xd2, 0x3d, 0x17, 0x31, + 0xc3, 0xfb, 0x2c, 0xfe, 0x67, 0xf1, 0xa4, 0xdb, 0xea, 0x54, 0x26, 0xed, 0xc8, 0x32, 0xaa, 0x75, + 0x96, 0xca, 0x54, 0x96, 0x92, 0x18, 0xb5, 0x79, 0x0d, 0x7e, 0x91, 0xd3, 0xb8, 0xdf, 0x54, 0x3e, + 0x6b, 0xaa, 0xb9, 0xdb, 0x71, 0x8e, 0x0a, 0xa9, 0xf4, 0x50, 0x24, 0x4d, 0xd4, 0x46, 0xe1, 0x71, + 0xe4, 0xae, 0x17, 0xfe, 0xc9, 0x94, 0x66, 0xa3, 0xdb, 0x60, 0xfb, 0x11, 0x0c, 0x6c, 0xa3, 0x1e, + 0x12, 0x57, 0x39, 0x8d, 0x84, 0xe7, 0x32, 0x1b, 0x6a, 0x45, 0x19, 0x87, 0xe6, 0x41, 0xbb, 0x16, + 0xd6, 0x7b, 0x21, 0xae, 0xba, 0x1a, 0xdf, 0x19, 0xc7, 0x8b, 0x31, 0x44, 0x97, 0xb3, 0x85, 0x6f, + 0xad, 0x17, 0xfe, 0xe9, 0x26, 0x7f, 0x3f, 0x2b, 0xf8, 0xfc, 0xf6, 0xed, 0x92, 0x82, 0x41, 0x3d, + 0xd9, 0x59, 0xc0, 0x8d, 0x1c, 0xbb, 0xa0, 0x8a, 0x66, 0xd0, 0xac, 0xb5, 0x51, 0x58, 0xef, 0x5d, + 0x54, 0xb7, 0x3d, 0x96, 0x6c, 0x74, 0x68, 0x9a, 0x06, 0x5b, 0x67, 0xf4, 0x34, 0x5b, 0x7a, 0x68, + 0xbe, 0xf4, 0xd0, 0xcf, 0xd2, 0x43, 0x1f, 0x2b, 0xcf, 0x9a, 0xaf, 0x3c, 0xeb, 0x6b, 0xe5, 0x59, + 0xaf, 0xfd, 0x54, 0xe8, 0xf7, 0x71, 0x8c, 0x99, 0xcc, 0x08, 0x93, 0x90, 0x49, 0x20, 0x22, 0x66, + 0xd7, 0xa9, 0x24, 0x93, 0x3e, 0xc9, 0x64, 0x32, 0x1e, 0x71, 0x30, 0x93, 0xef, 0x4d, 0xad, 0xa7, + 0x05, 0x87, 0xd8, 0x2e, 0xf7, 0xbc, 0xf9, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xf6, 0x4d, 0x22, 0xc9, 0xde, 0x01, 0x00, 0x00, } diff --git a/modules/apps/transfer/types/genesis_test.go b/modules/apps/transfer/types/genesis_test.go index fb63fbede64..415ba2b9b27 100644 --- a/modules/apps/transfer/types/genesis_test.go +++ b/modules/apps/transfer/types/genesis_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) func TestValidateGenesis(t *testing.T) { diff --git a/modules/apps/transfer/types/keys_test.go b/modules/apps/transfer/types/keys_test.go index d69dc6e30c6..e19765ed57c 100644 --- a/modules/apps/transfer/types/keys_test.go +++ b/modules/apps/transfer/types/keys_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) // Test that there is domain separation between the port id and the channel id otherwise an diff --git a/modules/apps/transfer/types/msgs.go b/modules/apps/transfer/types/msgs.go index 00ef9fe5386..de573544257 100644 --- a/modules/apps/transfer/types/msgs.go +++ b/modules/apps/transfer/types/msgs.go @@ -3,24 +3,22 @@ package types import ( "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" -) - -// msg types -const ( - TypeMsgTransfer = "transfer" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // NewMsgTransfer creates a new MsgTransfer instance +// //nolint:interfacer func NewMsgTransfer( sourcePort, sourceChannel string, token sdk.Coin, sender, receiver string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, + memo string, ) *MsgTransfer { return &MsgTransfer{ SourcePort: sourcePort, @@ -30,6 +28,7 @@ func NewMsgTransfer( Receiver: receiver, TimeoutHeight: timeoutHeight, TimeoutTimestamp: timeoutTimestamp, + Memo: memo, } } @@ -38,35 +37,30 @@ func (MsgTransfer) Route() string { return RouterKey } -// Type implements sdk.Msg -func (MsgTransfer) Type() string { - return TypeMsgTransfer -} - // ValidateBasic performs a basic check of the MsgTransfer fields. // NOTE: timeout height or timestamp values can be 0 to disable the timeout. // NOTE: The recipient addresses format is not validated as the format defined by // the chain is not known to IBC. func (msg MsgTransfer) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.SourcePort); err != nil { - return sdkerrors.Wrap(err, "invalid source port ID") + return errorsmod.Wrap(err, "invalid source port ID") } if err := host.ChannelIdentifierValidator(msg.SourceChannel); err != nil { - return sdkerrors.Wrap(err, "invalid source channel ID") + return errorsmod.Wrap(err, "invalid source channel ID") } if !msg.Token.IsValid() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, msg.Token.String()) + return errorsmod.Wrap(ibcerrors.ErrInvalidCoins, msg.Token.String()) } if !msg.Token.IsPositive() { - return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, msg.Token.String()) + return errorsmod.Wrap(ibcerrors.ErrInsufficientFunds, msg.Token.String()) } // NOTE: sender format must be validated as it is required by the GetSigners function. _, err := sdk.AccAddressFromBech32(msg.Sender) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } if strings.TrimSpace(msg.Receiver) == "" { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "missing recipient address") + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing recipient address") } return ValidateIBCDenom(msg.Token.Denom) } diff --git a/modules/apps/transfer/types/msgs_test.go b/modules/apps/transfer/types/msgs_test.go index 929de3a4d6f..e32d0f4a6c7 100644 --- a/modules/apps/transfer/types/msgs_test.go +++ b/modules/apps/transfer/types/msgs_test.go @@ -1,4 +1,4 @@ -package types +package types_test import ( "fmt" @@ -8,7 +8,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) // define constants used for testing @@ -41,20 +42,13 @@ var ( // TestMsgTransferRoute tests Route for MsgTransfer func TestMsgTransferRoute(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0) + msg := types.NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, "") - require.Equal(t, RouterKey, msg.Route()) -} - -// TestMsgTransferType tests Type for MsgTransfer -func TestMsgTransferType(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0) - - require.Equal(t, "transfer", msg.Type()) + require.Equal(t, types.RouterKey, msg.Route()) } func TestMsgTransferGetSignBytes(t *testing.T) { - msg := NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0) + msg := types.NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, "") expected := fmt.Sprintf(`{"type":"cosmos-sdk/MsgTransfer","value":{"receiver":"%s","sender":"%s","source_channel":"testchannel","source_port":"testportid","timeout_height":{"revision_height":"10"},"token":{"amount":"100","denom":"atom"}}}`, addr2, addr1) require.NotPanics(t, func() { res := msg.GetSignBytes() @@ -66,23 +60,23 @@ func TestMsgTransferGetSignBytes(t *testing.T) { func TestMsgTransferValidation(t *testing.T) { testCases := []struct { name string - msg *MsgTransfer + msg *types.MsgTransfer expPass bool }{ - {"valid msg with base denom", NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0), true}, - {"valid msg with trace hash", NewMsgTransfer(validPort, validChannel, ibcCoin, addr1, addr2, timeoutHeight, 0), true}, - {"invalid ibc denom", NewMsgTransfer(validPort, validChannel, invalidIBCCoin, addr1, addr2, timeoutHeight, 0), false}, - {"too short port id", NewMsgTransfer(invalidShortPort, validChannel, coin, addr1, addr2, timeoutHeight, 0), false}, - {"too long port id", NewMsgTransfer(invalidLongPort, validChannel, coin, addr1, addr2, timeoutHeight, 0), false}, - {"port id contains non-alpha", NewMsgTransfer(invalidPort, validChannel, coin, addr1, addr2, timeoutHeight, 0), false}, - {"too short channel id", NewMsgTransfer(validPort, invalidShortChannel, coin, addr1, addr2, timeoutHeight, 0), false}, - {"too long channel id", NewMsgTransfer(validPort, invalidLongChannel, coin, addr1, addr2, timeoutHeight, 0), false}, - {"channel id contains non-alpha", NewMsgTransfer(validPort, invalidChannel, coin, addr1, addr2, timeoutHeight, 0), false}, - {"invalid denom", NewMsgTransfer(validPort, validChannel, invalidDenomCoin, addr1, addr2, timeoutHeight, 0), false}, - {"zero coin", NewMsgTransfer(validPort, validChannel, zeroCoin, addr1, addr2, timeoutHeight, 0), false}, - {"missing sender address", NewMsgTransfer(validPort, validChannel, coin, emptyAddr, addr2, timeoutHeight, 0), false}, - {"missing recipient address", NewMsgTransfer(validPort, validChannel, coin, addr1, "", timeoutHeight, 0), false}, - {"empty coin", NewMsgTransfer(validPort, validChannel, sdk.Coin{}, addr1, addr2, timeoutHeight, 0), false}, + {"valid msg with base denom", types.NewMsgTransfer(validPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, ""), true}, + {"valid msg with trace hash", types.NewMsgTransfer(validPort, validChannel, ibcCoin, addr1, addr2, timeoutHeight, 0, ""), true}, + {"invalid ibc denom", types.NewMsgTransfer(validPort, validChannel, invalidIBCCoin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"too short port id", types.NewMsgTransfer(invalidShortPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"too long port id", types.NewMsgTransfer(invalidLongPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"port id contains non-alpha", types.NewMsgTransfer(invalidPort, validChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"too short channel id", types.NewMsgTransfer(validPort, invalidShortChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"too long channel id", types.NewMsgTransfer(validPort, invalidLongChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"channel id contains non-alpha", types.NewMsgTransfer(validPort, invalidChannel, coin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"invalid denom", types.NewMsgTransfer(validPort, validChannel, invalidDenomCoin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"zero coin", types.NewMsgTransfer(validPort, validChannel, zeroCoin, addr1, addr2, timeoutHeight, 0, ""), false}, + {"missing sender address", types.NewMsgTransfer(validPort, validChannel, coin, emptyAddr, addr2, timeoutHeight, 0, ""), false}, + {"missing recipient address", types.NewMsgTransfer(validPort, validChannel, coin, addr1, "", timeoutHeight, 0, ""), false}, + {"empty coin", types.NewMsgTransfer(validPort, validChannel, sdk.Coin{}, addr1, addr2, timeoutHeight, 0, ""), false}, } for i, tc := range testCases { @@ -99,7 +93,7 @@ func TestMsgTransferValidation(t *testing.T) { func TestMsgTransferGetSigners(t *testing.T) { addr := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) - msg := NewMsgTransfer(validPort, validChannel, coin, addr.String(), addr2, timeoutHeight, 0) + msg := types.NewMsgTransfer(validPort, validChannel, coin, addr.String(), addr2, timeoutHeight, 0, "") res := msg.GetSigners() require.Equal(t, []sdk.AccAddress{addr}, res) diff --git a/modules/apps/transfer/types/packet.go b/modules/apps/transfer/types/packet.go index a7384c47486..ec795fa2482 100644 --- a/modules/apps/transfer/types/packet.go +++ b/modules/apps/transfer/types/packet.go @@ -4,8 +4,10 @@ import ( "strings" "time" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" ) var ( @@ -25,12 +27,14 @@ var ( func NewFungibleTokenPacketData( denom string, amount string, sender, receiver string, + memo string, ) FungibleTokenPacketData { return FungibleTokenPacketData{ Denom: denom, Amount: amount, Sender: sender, Receiver: receiver, + Memo: memo, } } @@ -40,21 +44,21 @@ func NewFungibleTokenPacketData( func (ftpd FungibleTokenPacketData) ValidateBasic() error { amount, ok := sdk.NewIntFromString(ftpd.Amount) if !ok { - return sdkerrors.Wrapf(ErrInvalidAmount, "unable to parse transfer amount (%s) into sdk.Int", ftpd.Amount) + return errorsmod.Wrapf(ErrInvalidAmount, "unable to parse transfer amount (%s) into math.Int", ftpd.Amount) } if !amount.IsPositive() { - return sdkerrors.Wrapf(ErrInvalidAmount, "amount must be strictly positive: got %d", amount) + return errorsmod.Wrapf(ErrInvalidAmount, "amount must be strictly positive: got %d", amount) } if strings.TrimSpace(ftpd.Sender) == "" { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "sender address cannot be blank") + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "sender address cannot be blank") } if strings.TrimSpace(ftpd.Receiver) == "" { - return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "receiver address cannot be blank") + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "receiver address cannot be blank") } return ValidatePrefixedDenom(ftpd.Denom) } // GetBytes is a helper for serialising func (ftpd FungibleTokenPacketData) GetBytes() []byte { - return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&ftpd)) + return sdk.MustSortJSON(mustProtoMarshalJSON(&ftpd)) } diff --git a/modules/apps/transfer/types/packet.pb.go b/modules/apps/transfer/types/packet.pb.go index ca0ffa46e9e..574e4880453 100644 --- a/modules/apps/transfer/types/packet.pb.go +++ b/modules/apps/transfer/types/packet.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -34,6 +34,8 @@ type FungibleTokenPacketData struct { Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,omitempty"` // the recipient address on the destination chain Receiver string `protobuf:"bytes,4,opt,name=receiver,proto3" json:"receiver,omitempty"` + // optional memo + Memo string `protobuf:"bytes,5,opt,name=memo,proto3" json:"memo,omitempty"` } func (m *FungibleTokenPacketData) Reset() { *m = FungibleTokenPacketData{} } @@ -97,6 +99,13 @@ func (m *FungibleTokenPacketData) GetReceiver() string { return "" } +func (m *FungibleTokenPacketData) GetMemo() string { + if m != nil { + return m.Memo + } + return "" +} + func init() { proto.RegisterType((*FungibleTokenPacketData)(nil), "ibc.applications.transfer.v2.FungibleTokenPacketData") } @@ -106,23 +115,23 @@ func init() { } var fileDescriptor_653ca2ce9a5ca313 = []byte{ - // 242 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x8f, 0xbd, 0x4a, 0x04, 0x31, - 0x14, 0x46, 0x27, 0xfe, 0x2c, 0x9a, 0x72, 0x10, 0x1d, 0x44, 0x82, 0x58, 0x69, 0x61, 0x02, 0xab, - 0x60, 0x2f, 0x62, 0xad, 0x62, 0x65, 0x97, 0x64, 0xae, 0x63, 0xd8, 0x49, 0x6e, 0x48, 0x32, 0x03, - 0xe2, 0x4b, 0xf8, 0x58, 0x96, 0x5b, 0x5a, 0xca, 0xcc, 0x8b, 0xc8, 0x66, 0x74, 0xd9, 0xf2, 0x9c, - 0xfb, 0xdd, 0xe2, 0xd0, 0x0b, 0xa3, 0xb4, 0x90, 0xde, 0xb7, 0x46, 0xcb, 0x64, 0xd0, 0x45, 0x91, - 0x82, 0x74, 0xf1, 0x15, 0x82, 0xe8, 0xe7, 0xc2, 0x4b, 0xbd, 0x80, 0xc4, 0x7d, 0xc0, 0x84, 0xe5, - 0x89, 0x51, 0x9a, 0x6f, 0x4e, 0xf9, 0xff, 0x94, 0xf7, 0xf3, 0xb3, 0x0f, 0x7a, 0x74, 0xdf, 0xb9, - 0xc6, 0xa8, 0x16, 0x9e, 0x71, 0x01, 0xee, 0x21, 0xbf, 0xde, 0xc9, 0x24, 0xcb, 0x03, 0xba, 0x5b, - 0x83, 0x43, 0x5b, 0x91, 0x53, 0x72, 0xbe, 0xff, 0x34, 0x41, 0x79, 0x48, 0x67, 0xd2, 0x62, 0xe7, - 0x52, 0xb5, 0x95, 0xf5, 0x1f, 0xad, 0x7c, 0x04, 0x57, 0x43, 0xa8, 0xb6, 0x27, 0x3f, 0x51, 0x79, - 0x4c, 0xf7, 0x02, 0x68, 0x30, 0x3d, 0x84, 0x6a, 0x27, 0x5f, 0xd6, 0x7c, 0xfb, 0xf8, 0x35, 0x30, - 0xb2, 0x1c, 0x18, 0xf9, 0x19, 0x18, 0xf9, 0x1c, 0x59, 0xb1, 0x1c, 0x59, 0xf1, 0x3d, 0xb2, 0xe2, - 0xe5, 0xa6, 0x31, 0xe9, 0xad, 0x53, 0x5c, 0xa3, 0x15, 0x1a, 0xa3, 0xc5, 0x28, 0x8c, 0xd2, 0x97, - 0x0d, 0x8a, 0xfe, 0x5a, 0x58, 0xac, 0xbb, 0x16, 0xe2, 0xaa, 0x7f, 0xa3, 0x3b, 0xbd, 0x7b, 0x88, - 0x6a, 0x96, 0xa3, 0xaf, 0x7e, 0x03, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x0b, 0x30, 0xf2, 0x21, 0x01, - 0x00, 0x00, + // 254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xb1, 0x4a, 0x34, 0x31, + 0x14, 0x46, 0x27, 0xff, 0xbf, 0xbb, 0x68, 0xca, 0x20, 0x3a, 0x88, 0x04, 0xb1, 0xd2, 0xc2, 0x09, + 0xac, 0xc5, 0xf6, 0x22, 0xd6, 0x2a, 0x56, 0x76, 0x49, 0xe6, 0x3a, 0x86, 0x9d, 0xe4, 0x86, 0x24, + 0x33, 0xe0, 0x53, 0xe8, 0x63, 0x59, 0x6e, 0x69, 0x29, 0x33, 0x2f, 0x22, 0x9b, 0x51, 0xd9, 0x2e, + 0xe7, 0xe4, 0xbb, 0xcd, 0xa1, 0x17, 0x46, 0x69, 0x21, 0xbd, 0x6f, 0x8d, 0x96, 0xc9, 0xa0, 0x8b, + 0x22, 0x05, 0xe9, 0xe2, 0x33, 0x04, 0xd1, 0x2f, 0x85, 0x97, 0x7a, 0x0d, 0xa9, 0xf2, 0x01, 0x13, + 0xb2, 0x13, 0xa3, 0x74, 0xb5, 0x3b, 0xad, 0x7e, 0xa7, 0x55, 0xbf, 0x3c, 0x7b, 0x23, 0xf4, 0xe8, + 0xb6, 0x73, 0x8d, 0x51, 0x2d, 0x3c, 0xe2, 0x1a, 0xdc, 0x5d, 0xbe, 0xbd, 0x91, 0x49, 0xb2, 0x03, + 0x3a, 0xaf, 0xc1, 0xa1, 0x2d, 0xc9, 0x29, 0x39, 0xdf, 0x7f, 0x98, 0x80, 0x1d, 0xd2, 0x85, 0xb4, + 0xd8, 0xb9, 0x54, 0xfe, 0xcb, 0xfa, 0x87, 0xb6, 0x3e, 0x82, 0xab, 0x21, 0x94, 0xff, 0x27, 0x3f, + 0x11, 0x3b, 0xa6, 0x7b, 0x01, 0x34, 0x98, 0x1e, 0x42, 0x39, 0xcb, 0x3f, 0x7f, 0xcc, 0x18, 0x9d, + 0x59, 0xb0, 0x58, 0xce, 0xb3, 0xcf, 0xef, 0xeb, 0xfb, 0x8f, 0x81, 0x93, 0xcd, 0xc0, 0xc9, 0xd7, + 0xc0, 0xc9, 0xfb, 0xc8, 0x8b, 0xcd, 0xc8, 0x8b, 0xcf, 0x91, 0x17, 0x4f, 0xab, 0xc6, 0xa4, 0x97, + 0x4e, 0x55, 0x1a, 0xad, 0xd0, 0x18, 0x2d, 0x46, 0x61, 0x94, 0xbe, 0x6c, 0x50, 0xf4, 0x2b, 0x61, + 0xb1, 0xee, 0x5a, 0x88, 0xdb, 0x28, 0x3b, 0x31, 0xd2, 0xab, 0x87, 0xa8, 0x16, 0xb9, 0xc4, 0xd5, + 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x32, 0xf9, 0x52, 0xde, 0x36, 0x01, 0x00, 0x00, } func (m *FungibleTokenPacketData) Marshal() (dAtA []byte, err error) { @@ -145,6 +154,13 @@ func (m *FungibleTokenPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Memo))) + i-- + dAtA[i] = 0x2a + } if len(m.Receiver) > 0 { i -= len(m.Receiver) copy(dAtA[i:], m.Receiver) @@ -209,6 +225,10 @@ func (m *FungibleTokenPacketData) Size() (n int) { if l > 0 { n += 1 + l + sovPacket(uint64(l)) } + l = len(m.Memo) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } return n } @@ -375,6 +395,38 @@ func (m *FungibleTokenPacketData) Unmarshal(dAtA []byte) error { } m.Receiver = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + 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 ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Memo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPacket(dAtA[iNdEx:]) diff --git a/modules/apps/transfer/types/packet_test.go b/modules/apps/transfer/types/packet_test.go index e5d21d648d2..067169a4ba2 100644 --- a/modules/apps/transfer/types/packet_test.go +++ b/modules/apps/transfer/types/packet_test.go @@ -1,9 +1,11 @@ -package types +package types_test import ( "testing" "github.com/stretchr/testify/require" + + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) const ( @@ -17,18 +19,19 @@ const ( func TestFungibleTokenPacketDataValidateBasic(t *testing.T) { testCases := []struct { name string - packetData FungibleTokenPacketData + packetData types.FungibleTokenPacketData expPass bool }{ - {"valid packet", NewFungibleTokenPacketData(denom, amount, addr1, addr2), true}, - {"valid packet with large amount", NewFungibleTokenPacketData(denom, largeAmount, addr1, addr2), true}, - {"invalid denom", NewFungibleTokenPacketData("", amount, addr1, addr2), false}, - {"invalid empty amount", NewFungibleTokenPacketData(denom, "", addr1, addr2), false}, - {"invalid zero amount", NewFungibleTokenPacketData(denom, "0", addr1, addr2), false}, - {"invalid negative amount", NewFungibleTokenPacketData(denom, "-1", addr1, addr2), false}, - {"invalid large amount", NewFungibleTokenPacketData(denom, invalidLargeAmount, addr1, addr2), false}, - {"missing sender address", NewFungibleTokenPacketData(denom, amount, emptyAddr, addr2), false}, - {"missing recipient address", NewFungibleTokenPacketData(denom, amount, addr1, emptyAddr), false}, + {"valid packet", types.NewFungibleTokenPacketData(denom, amount, addr1, addr2, ""), true}, + {"valid packet with memo", types.NewFungibleTokenPacketData(denom, amount, addr1, addr2, "memo"), true}, + {"valid packet with large amount", types.NewFungibleTokenPacketData(denom, largeAmount, addr1, addr2, ""), true}, + {"invalid denom", types.NewFungibleTokenPacketData("", amount, addr1, addr2, ""), false}, + {"invalid empty amount", types.NewFungibleTokenPacketData(denom, "", addr1, addr2, ""), false}, + {"invalid zero amount", types.NewFungibleTokenPacketData(denom, "0", addr1, addr2, ""), false}, + {"invalid negative amount", types.NewFungibleTokenPacketData(denom, "-1", addr1, addr2, ""), false}, + {"invalid large amount", types.NewFungibleTokenPacketData(denom, invalidLargeAmount, addr1, addr2, ""), false}, + {"missing sender address", types.NewFungibleTokenPacketData(denom, amount, emptyAddr, addr2, ""), false}, + {"missing recipient address", types.NewFungibleTokenPacketData(denom, amount, addr1, emptyAddr, ""), false}, } for i, tc := range testCases { diff --git a/modules/apps/transfer/types/params.go b/modules/apps/transfer/types/params.go index 4ecdfab77e7..5b5fded0b4d 100644 --- a/modules/apps/transfer/types/params.go +++ b/modules/apps/transfer/types/params.go @@ -40,22 +40,22 @@ func DefaultParams() Params { // Validate all ibc-transfer module parameters func (p Params) Validate() error { - if err := validateEnabled(p.SendEnabled); err != nil { + if err := validateEnabledType(p.SendEnabled); err != nil { return err } - return validateEnabled(p.ReceiveEnabled) + return validateEnabledType(p.ReceiveEnabled) } // ParamSetPairs implements params.ParamSet func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ - paramtypes.NewParamSetPair(KeySendEnabled, p.SendEnabled, validateEnabled), - paramtypes.NewParamSetPair(KeyReceiveEnabled, p.ReceiveEnabled, validateEnabled), + paramtypes.NewParamSetPair(KeySendEnabled, p.SendEnabled, validateEnabledType), + paramtypes.NewParamSetPair(KeyReceiveEnabled, p.ReceiveEnabled, validateEnabledType), } } -func validateEnabled(i interface{}) error { +func validateEnabledType(i interface{}) error { _, ok := i.(bool) if !ok { return fmt.Errorf("invalid parameter type: %T", i) diff --git a/modules/apps/transfer/types/params_test.go b/modules/apps/transfer/types/params_test.go index 825efb825c1..836cf973b01 100644 --- a/modules/apps/transfer/types/params_test.go +++ b/modules/apps/transfer/types/params_test.go @@ -1,12 +1,14 @@ -package types +package types_test import ( "testing" "github.com/stretchr/testify/require" + + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) func TestValidateParams(t *testing.T) { - require.NoError(t, DefaultParams().Validate()) - require.NoError(t, NewParams(true, false).Validate()) + require.NoError(t, types.DefaultParams().Validate()) + require.NoError(t, types.NewParams(true, false).Validate()) } diff --git a/modules/apps/transfer/types/query.pb.go b/modules/apps/transfer/types/query.pb.go index d654e4b30a5..f8c4543eee3 100644 --- a/modules/apps/transfer/types/query.pb.go +++ b/modules/apps/transfer/types/query.pb.go @@ -7,9 +7,9 @@ import ( context "context" fmt "fmt" query "github.com/cosmos/cosmos-sdk/types/query" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -523,52 +523,52 @@ func init() { } var fileDescriptor_a638e2800a01538c = []byte{ - // 715 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xcd, 0x6e, 0xd3, 0x4c, - 0x14, 0x8d, 0xfb, 0x7d, 0x0d, 0xca, 0x0d, 0xed, 0x62, 0x28, 0xb4, 0x58, 0xc5, 0xad, 0xac, 0x02, - 0xa5, 0x3f, 0x1e, 0xd2, 0x16, 0xca, 0x82, 0x0d, 0xe5, 0xb7, 0x88, 0x45, 0x9b, 0xb2, 0x82, 0x45, - 0x35, 0xb6, 0x07, 0xc7, 0x52, 0xe2, 0x71, 0x3d, 0x4e, 0x50, 0x55, 0x65, 0xc3, 0x13, 0x20, 0xf5, - 0x25, 0x50, 0xc5, 0x43, 0xb0, 0xec, 0xb2, 0x12, 0x12, 0x62, 0x05, 0xa8, 0xe5, 0x35, 0x90, 0x90, - 0x67, 0x26, 0x89, 0x4d, 0xa3, 0x34, 0xde, 0x8d, 0x67, 0xee, 0xb9, 0xf7, 0x9c, 0x73, 0xef, 0x95, - 0x61, 0xde, 0xb7, 0x1d, 0x4c, 0xc2, 0xb0, 0xee, 0x3b, 0x24, 0xf6, 0x59, 0xc0, 0x71, 0x1c, 0x91, - 0x80, 0xbf, 0xa3, 0x11, 0x6e, 0x55, 0xf0, 0x5e, 0x93, 0x46, 0xfb, 0x56, 0x18, 0xb1, 0x98, 0xa1, - 0x69, 0xdf, 0x76, 0xac, 0x74, 0xa4, 0xd5, 0x89, 0xb4, 0x5a, 0x15, 0x7d, 0xc2, 0x63, 0x1e, 0x13, - 0x81, 0x38, 0x39, 0x49, 0x8c, 0xbe, 0xe0, 0x30, 0xde, 0x60, 0x1c, 0xdb, 0x84, 0x53, 0x99, 0x0c, - 0xb7, 0x2a, 0x36, 0x8d, 0x49, 0x05, 0x87, 0xc4, 0xf3, 0x03, 0x91, 0x48, 0xc5, 0x2e, 0x0e, 0x64, - 0xd2, 0xad, 0x25, 0x83, 0xa7, 0x3d, 0xc6, 0xbc, 0x3a, 0xc5, 0x24, 0xf4, 0x31, 0x09, 0x02, 0x16, - 0x2b, 0x4a, 0xe2, 0xd5, 0x5c, 0x82, 0x6b, 0xdb, 0x49, 0xb1, 0x27, 0x34, 0x60, 0x8d, 0xd7, 0x11, - 0x71, 0x68, 0x95, 0xee, 0x35, 0x29, 0x8f, 0x11, 0x82, 0xff, 0x6b, 0x84, 0xd7, 0xa6, 0xb4, 0x59, - 0x6d, 0xbe, 0x54, 0x15, 0x67, 0xd3, 0x85, 0xc9, 0x73, 0xd1, 0x3c, 0x64, 0x01, 0xa7, 0x68, 0x13, - 0xca, 0x6e, 0x72, 0xbb, 0x1b, 0x27, 0xd7, 0x02, 0x55, 0x5e, 0x99, 0xb7, 0x06, 0x39, 0x61, 0xa5, - 0xd2, 0x80, 0xdb, 0x3d, 0x9b, 0xe4, 0x5c, 0x15, 0xde, 0x21, 0xf5, 0x0c, 0xa0, 0xe7, 0x86, 0x2a, - 0x72, 0xcb, 0x92, 0xd6, 0x59, 0x89, 0x75, 0x96, 0xec, 0x83, 0xb2, 0xce, 0xda, 0x22, 0x5e, 0x47, - 0x50, 0x35, 0x85, 0x34, 0xbf, 0x68, 0x30, 0x75, 0xbe, 0x86, 0x92, 0xf2, 0x16, 0x2e, 0xa7, 0xa4, - 0xf0, 0x29, 0x6d, 0xf6, 0xbf, 0x3c, 0x5a, 0x36, 0xc6, 0x8f, 0x7f, 0xcc, 0x14, 0x8e, 0x7e, 0xce, - 0x14, 0x55, 0xde, 0x72, 0x4f, 0x1b, 0x47, 0xcf, 0x33, 0x0a, 0x46, 0x84, 0x82, 0xdb, 0x17, 0x2a, - 0x90, 0xcc, 0x32, 0x12, 0x26, 0x00, 0x09, 0x05, 0x5b, 0x24, 0x22, 0x8d, 0x8e, 0x41, 0xe6, 0x0e, - 0x5c, 0xc9, 0xdc, 0x2a, 0x49, 0x0f, 0xa1, 0x18, 0x8a, 0x1b, 0xe5, 0xd9, 0xdc, 0x60, 0x31, 0x0a, - 0xad, 0x30, 0xe6, 0x32, 0x5c, 0xed, 0x99, 0xf5, 0x82, 0xf0, 0x5a, 0xa7, 0x1d, 0x13, 0x30, 0xda, - 0x6b, 0x77, 0xa9, 0x2a, 0x3f, 0xb2, 0x33, 0x25, 0xc3, 0x15, 0x8d, 0x7e, 0x33, 0xb5, 0x03, 0xd7, - 0x45, 0xf4, 0x53, 0xee, 0x44, 0xec, 0xfd, 0x23, 0xd7, 0x8d, 0x28, 0xef, 0xf6, 0x7b, 0x12, 0x2e, - 0x85, 0x2c, 0x8a, 0x77, 0x7d, 0x57, 0x61, 0x8a, 0xc9, 0xe7, 0xa6, 0x8b, 0x6e, 0x00, 0x38, 0x35, - 0x12, 0x04, 0xb4, 0x9e, 0xbc, 0x8d, 0x88, 0xb7, 0x92, 0xba, 0xd9, 0x74, 0xcd, 0xc7, 0xa0, 0xf7, - 0x4b, 0xaa, 0x68, 0xdc, 0x84, 0x71, 0x2a, 0x1e, 0x76, 0x89, 0x7c, 0x51, 0xc9, 0xc7, 0x68, 0x3a, - 0x7c, 0xe5, 0x4f, 0x11, 0x46, 0x45, 0x16, 0xf4, 0x59, 0x03, 0xe8, 0x35, 0x18, 0xad, 0x0d, 0x76, - 0xaf, 0xff, 0x42, 0xe9, 0xf7, 0x72, 0xa2, 0x24, 0x59, 0xb3, 0xf2, 0xe1, 0xeb, 0xef, 0xc3, 0x91, - 0x45, 0x74, 0x07, 0xab, 0xad, 0xcf, 0x6e, 0x7b, 0x7a, 0x52, 0xf1, 0x41, 0xe2, 0x68, 0x1b, 0x7d, - 0xd2, 0xa0, 0x9c, 0x1a, 0x6c, 0x94, 0xaf, 0x72, 0xc7, 0x7c, 0xfd, 0x7e, 0x5e, 0x98, 0x62, 0xbc, - 0x20, 0x18, 0xcf, 0x21, 0xf3, 0x62, 0xc6, 0xe8, 0x50, 0x83, 0xa2, 0x9c, 0x36, 0x74, 0x77, 0x88, - 0x72, 0x99, 0x61, 0xd7, 0x2b, 0x39, 0x10, 0x8a, 0xdb, 0x9c, 0xe0, 0x66, 0xa0, 0xe9, 0xfe, 0xdc, - 0xe4, 0xc0, 0xa3, 0x23, 0x0d, 0x4a, 0xdd, 0xe9, 0x45, 0xab, 0xc3, 0xfa, 0x90, 0x5a, 0x0d, 0x7d, - 0x2d, 0x1f, 0x48, 0xd1, 0x5b, 0x11, 0xf4, 0x96, 0xd0, 0xc2, 0x20, 0xeb, 0x92, 0x26, 0x27, 0xcd, - 0x16, 0x16, 0xb6, 0xd1, 0x37, 0x0d, 0xc6, 0x32, 0x73, 0x8e, 0xd6, 0x87, 0xa8, 0xdd, 0x6f, 0xdd, - 0xf4, 0x07, 0xf9, 0x81, 0x8a, 0x78, 0x55, 0x10, 0x7f, 0x85, 0x5e, 0xf6, 0x27, 0xae, 0x36, 0x93, - 0xe3, 0x83, 0xde, 0xd6, 0xb6, 0x71, 0xb2, 0xcb, 0x1c, 0x1f, 0xa8, 0x0d, 0x6f, 0xe3, 0xec, 0x52, - 0x6e, 0x6c, 0x1f, 0x9f, 0x1a, 0xda, 0xc9, 0xa9, 0xa1, 0xfd, 0x3a, 0x35, 0xb4, 0x8f, 0x67, 0x46, - 0xe1, 0xe4, 0xcc, 0x28, 0x7c, 0x3f, 0x33, 0x0a, 0x6f, 0xd6, 0x3d, 0x3f, 0xae, 0x35, 0x6d, 0xcb, - 0x61, 0x0d, 0xac, 0xfe, 0x9b, 0xbe, 0xed, 0x2c, 0x7b, 0x0c, 0xb7, 0xd6, 0x70, 0x83, 0xb9, 0xcd, - 0x3a, 0xe5, 0xff, 0x90, 0x88, 0xf7, 0x43, 0xca, 0xed, 0xa2, 0xf8, 0xeb, 0xad, 0xfe, 0x0d, 0x00, - 0x00, 0xff, 0xff, 0xed, 0xd2, 0x70, 0xd6, 0xcc, 0x07, 0x00, 0x00, + // 718 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x4f, 0x4f, 0xd4, 0x40, + 0x14, 0xdf, 0xa2, 0x2c, 0xd9, 0xb7, 0xc2, 0x61, 0x44, 0xc1, 0x06, 0x0b, 0x69, 0x50, 0xc9, 0x0a, + 0x1d, 0x97, 0x3f, 0xe2, 0x41, 0x0f, 0xe2, 0x5f, 0x8c, 0x07, 0x58, 0x3c, 0xe9, 0x81, 0x4c, 0xdb, + 0xb1, 0xdb, 0x64, 0xb7, 0x53, 0x3a, 0xdd, 0x35, 0x84, 0x70, 0xd1, 0x2f, 0x60, 0xc2, 0x97, 0x30, + 0x26, 0xc6, 0xaf, 0xe0, 0x91, 0x23, 0x89, 0x89, 0xf1, 0xa4, 0x06, 0xfc, 0x20, 0xa6, 0x33, 0xb3, + 0xbb, 0xad, 0x6c, 0x16, 0x7a, 0x9b, 0xce, 0xbc, 0xdf, 0x7b, 0xbf, 0xdf, 0xef, 0xbd, 0x97, 0xc2, + 0x9c, 0x6f, 0x3b, 0x98, 0x84, 0x61, 0xc3, 0x77, 0x48, 0xec, 0xb3, 0x80, 0xe3, 0x38, 0x22, 0x01, + 0x7f, 0x4b, 0x23, 0xdc, 0xae, 0xe2, 0x9d, 0x16, 0x8d, 0x76, 0xad, 0x30, 0x62, 0x31, 0x43, 0x53, + 0xbe, 0xed, 0x58, 0xe9, 0x48, 0xab, 0x13, 0x69, 0xb5, 0xab, 0xfa, 0xb8, 0xc7, 0x3c, 0x26, 0x02, + 0x71, 0x72, 0x92, 0x18, 0xbd, 0xe2, 0x30, 0xde, 0x64, 0x1c, 0xdb, 0x84, 0x53, 0x99, 0x0c, 0xb7, + 0xab, 0x36, 0x8d, 0x49, 0x15, 0x87, 0xc4, 0xf3, 0x03, 0x91, 0x48, 0xc5, 0xde, 0x1e, 0xc8, 0xa4, + 0x5b, 0x4b, 0x06, 0x4f, 0x79, 0x8c, 0x79, 0x0d, 0x8a, 0x49, 0xe8, 0x63, 0x12, 0x04, 0x2c, 0x56, + 0x94, 0xc4, 0xab, 0x39, 0x0f, 0x57, 0x37, 0x93, 0x62, 0x8f, 0x69, 0xc0, 0x9a, 0xaf, 0x22, 0xe2, + 0xd0, 0x1a, 0xdd, 0x69, 0x51, 0x1e, 0x23, 0x04, 0x17, 0xeb, 0x84, 0xd7, 0x27, 0xb5, 0x19, 0x6d, + 0xae, 0x54, 0x13, 0x67, 0xd3, 0x85, 0x89, 0x53, 0xd1, 0x3c, 0x64, 0x01, 0xa7, 0x68, 0x1d, 0xca, + 0x6e, 0x72, 0xbb, 0x1d, 0x27, 0xd7, 0x02, 0x55, 0x5e, 0x9c, 0xb3, 0x06, 0x39, 0x61, 0xa5, 0xd2, + 0x80, 0xdb, 0x3d, 0x9b, 0xe4, 0x54, 0x15, 0xde, 0x21, 0xf5, 0x14, 0xa0, 0xe7, 0x86, 0x2a, 0x72, + 0xd3, 0x92, 0xd6, 0x59, 0x89, 0x75, 0x96, 0xec, 0x83, 0xb2, 0xce, 0xda, 0x20, 0x5e, 0x47, 0x50, + 0x2d, 0x85, 0x34, 0xbf, 0x69, 0x30, 0x79, 0xba, 0x86, 0x92, 0xf2, 0x06, 0x2e, 0xa5, 0xa4, 0xf0, + 0x49, 0x6d, 0xe6, 0x42, 0x1e, 0x2d, 0x6b, 0x63, 0x87, 0xbf, 0xa6, 0x0b, 0x9f, 0x7f, 0x4f, 0x17, + 0x55, 0xde, 0x72, 0x4f, 0x1b, 0x47, 0xcf, 0x32, 0x0a, 0x86, 0x84, 0x82, 0x5b, 0x67, 0x2a, 0x90, + 0xcc, 0x32, 0x12, 0xc6, 0x01, 0x09, 0x05, 0x1b, 0x24, 0x22, 0xcd, 0x8e, 0x41, 0xe6, 0x16, 0x5c, + 0xce, 0xdc, 0x2a, 0x49, 0xf7, 0xa1, 0x18, 0x8a, 0x1b, 0xe5, 0xd9, 0xec, 0x60, 0x31, 0x0a, 0xad, + 0x30, 0xe6, 0x02, 0x5c, 0xe9, 0x99, 0xf5, 0x9c, 0xf0, 0x7a, 0xa7, 0x1d, 0xe3, 0x30, 0xdc, 0x6b, + 0x77, 0xa9, 0x26, 0x3f, 0xb2, 0x33, 0x25, 0xc3, 0x15, 0x8d, 0x7e, 0x33, 0xb5, 0x05, 0xd7, 0x44, + 0xf4, 0x13, 0xee, 0x44, 0xec, 0xdd, 0x43, 0xd7, 0x8d, 0x28, 0xef, 0xf6, 0x7b, 0x02, 0x46, 0x42, + 0x16, 0xc5, 0xdb, 0xbe, 0xab, 0x30, 0xc5, 0xe4, 0x73, 0xdd, 0x45, 0xd7, 0x01, 0x9c, 0x3a, 0x09, + 0x02, 0xda, 0x48, 0xde, 0x86, 0xc4, 0x5b, 0x49, 0xdd, 0xac, 0xbb, 0xe6, 0x23, 0xd0, 0xfb, 0x25, + 0x55, 0x34, 0x6e, 0xc0, 0x18, 0x15, 0x0f, 0xdb, 0x44, 0xbe, 0xa8, 0xe4, 0xa3, 0x34, 0x1d, 0xbe, + 0xf8, 0x61, 0x04, 0x86, 0x45, 0x16, 0xf4, 0x55, 0x03, 0xe8, 0x35, 0x18, 0x2d, 0x0f, 0x76, 0xaf, + 0xff, 0x42, 0xe9, 0x2b, 0x39, 0x51, 0x92, 0xac, 0xb9, 0xfc, 0xfe, 0xfb, 0xdf, 0x83, 0x21, 0x0b, + 0xcd, 0x63, 0xb5, 0xf5, 0xd9, 0x6d, 0x4f, 0x4f, 0x2a, 0xde, 0x4b, 0x1c, 0x7d, 0x50, 0xa9, 0xec, + 0xa3, 0x4f, 0x1a, 0x94, 0x53, 0xb3, 0x8d, 0xf2, 0x15, 0xef, 0xf8, 0xaf, 0xdf, 0xcd, 0x0b, 0x53, + 0xa4, 0x2b, 0x82, 0xf4, 0x2c, 0x32, 0xcf, 0x26, 0x8d, 0x0e, 0x34, 0x28, 0xca, 0x81, 0x43, 0x77, + 0xce, 0x51, 0x2e, 0x33, 0xef, 0x7a, 0x35, 0x07, 0x42, 0x71, 0x9b, 0x15, 0xdc, 0x0c, 0x34, 0xd5, + 0x9f, 0x9b, 0x9c, 0x79, 0xf4, 0x45, 0x83, 0x52, 0x77, 0x80, 0xd1, 0xd2, 0x79, 0x7d, 0x48, 0x6d, + 0x87, 0xbe, 0x9c, 0x0f, 0xa4, 0xe8, 0xad, 0x08, 0x7a, 0x18, 0x2d, 0x0c, 0xb2, 0x2e, 0xe9, 0x73, + 0xd2, 0x6f, 0x61, 0xa1, 0x68, 0xf8, 0x0f, 0x0d, 0x46, 0x33, 0xd3, 0x8e, 0x56, 0xcf, 0x51, 0xbe, + 0xdf, 0xd2, 0xe9, 0xf7, 0xf2, 0x03, 0x15, 0xf7, 0x9a, 0xe0, 0xfe, 0x12, 0xbd, 0xe8, 0xcf, 0x5d, + 0xed, 0x27, 0xc7, 0x7b, 0xbd, 0xdd, 0xdd, 0xc7, 0xc9, 0x46, 0x73, 0xbc, 0xa7, 0xf6, 0x7c, 0x1f, + 0x67, 0x57, 0x73, 0x6d, 0xf3, 0xf0, 0xd8, 0xd0, 0x8e, 0x8e, 0x0d, 0xed, 0xcf, 0xb1, 0xa1, 0x7d, + 0x3c, 0x31, 0x0a, 0x47, 0x27, 0x46, 0xe1, 0xe7, 0x89, 0x51, 0x78, 0xbd, 0xea, 0xf9, 0x71, 0xbd, + 0x65, 0x5b, 0x0e, 0x6b, 0x62, 0xf5, 0xf7, 0xf4, 0x6d, 0x67, 0xc1, 0x63, 0xb8, 0xbd, 0x8a, 0x9b, + 0xcc, 0x6d, 0x35, 0x28, 0xff, 0x8f, 0x44, 0xbc, 0x1b, 0x52, 0x6e, 0x17, 0xc5, 0xbf, 0x6f, 0xe9, + 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x47, 0x7a, 0xbb, 0x0b, 0xd2, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/apps/transfer/types/query.pb.gw.go b/modules/apps/transfer/types/query.pb.gw.go index 71474a1b2fc..35d95239e65 100644 --- a/modules/apps/transfer/types/query.pb.gw.go +++ b/modules/apps/transfer/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join func request_Query_DenomTrace_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryDenomTraceRequest @@ -272,12 +274,14 @@ func local_request_Query_EscrowAddress_0(ctx context.Context, marshaler runtime. // 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. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_DenomTrace_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 { @@ -285,6 +289,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_DenomTrace_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) @@ -298,6 +303,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_DenomTraces_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 { @@ -305,6 +312,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_DenomTraces_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) @@ -318,6 +326,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_Params_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 { @@ -325,6 +335,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Params_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) @@ -338,6 +349,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_DenomHash_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 { @@ -345,6 +358,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_DenomHash_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) @@ -358,6 +372,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_EscrowAddress_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 { @@ -365,6 +381,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_EscrowAddress_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) @@ -520,15 +537,15 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_DenomTrace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "apps", "transfer", "v1", "denom_traces", "hash"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_DenomTrace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 3, 0, 4, 1, 5, 5}, []string{"ibc", "apps", "transfer", "v1", "denom_traces", "hash"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_DenomTraces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "transfer", "v1", "denom_traces"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_DenomTraces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "transfer", "v1", "denom_traces"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "transfer", "v1", "params"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "transfer", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_DenomHash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "apps", "transfer", "v1", "denom_hashes", "trace"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_DenomHash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 3, 0, 4, 1, 5, 5}, []string{"ibc", "apps", "transfer", "v1", "denom_hashes", "trace"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_EscrowAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "transfer", "v1", "channels", "channel_id", "ports", "port_id", "escrow_address"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_EscrowAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "apps", "transfer", "v1", "channels", "channel_id", "ports", "port_id", "escrow_address"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/modules/apps/transfer/types/trace.go b/modules/apps/transfer/types/trace.go index 24f10c232a9..7145ff15d96 100644 --- a/modules/apps/transfer/types/trace.go +++ b/modules/apps/transfer/types/trace.go @@ -7,13 +7,13 @@ import ( "sort" "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmtypes "github.com/tendermint/tendermint/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // ParseDenomTrace parses a string with the ibc prefix (denom trace) and the base denomination @@ -84,8 +84,8 @@ func extractPathAndBaseFromFullDenom(fullDenomItems []string) (string, string) { ) length := len(fullDenomItems) - for i := 0; i < length; i = i + 2 { - // The IBC specification does not guarentee the expected format of the + for i := 0; i < length; i += 2 { + // The IBC specification does not guarantee the expected format of the // destination port or destination channel identifier. A short term solution // to determine base denomination is to expect the channel identifier to be the // one ibc-go specifies. A longer term solution is to separate the path and base @@ -113,10 +113,10 @@ func validateTraceIdentifiers(identifiers []string) error { // validate correctness of port and channel identifiers for i := 0; i < len(identifiers); i += 2 { if err := host.PortIdentifierValidator(identifiers[i]); err != nil { - return sdkerrors.Wrapf(err, "invalid port ID at position %d", i) + return errorsmod.Wrapf(err, "invalid port ID at position %d", i) } if err := host.ChannelIdentifierValidator(identifiers[i+1]); err != nil { - return sdkerrors.Wrapf(err, "invalid channel ID at position %d", i) + return errorsmod.Wrapf(err, "invalid channel ID at position %d", i) } } return nil @@ -151,7 +151,7 @@ func (t Traces) Validate() error { } if err := trace.Validate(); err != nil { - return sdkerrors.Wrapf(err, "failed denom trace %d validation", i) + return errorsmod.Wrapf(err, "failed denom trace %d validation", i) } seenTraces[hash] = true } @@ -178,8 +178,8 @@ func (t Traces) Sort() Traces { // ValidatePrefixedDenom checks that the denomination for an IBC fungible token packet denom is correctly prefixed. // The function will return no error if the given string follows one of the two formats: // -// - Prefixed denomination: '{portIDN}/{channelIDN}/.../{portID0}/{channelID0}/baseDenom' -// - Unprefixed denomination: 'baseDenom' +// - Prefixed denomination: '{portIDN}/{channelIDN}/.../{portID0}/{channelID0}/baseDenom' +// - Unprefixed denomination: 'baseDenom' // // 'baseDenom' may or may not contain '/'s func ValidatePrefixedDenom(denom string) error { @@ -190,7 +190,7 @@ func ValidatePrefixedDenom(denom string) error { } if strings.TrimSpace(denomSplit[len(denomSplit)-1]) == "" { - return sdkerrors.Wrap(ErrInvalidDenomForTransfer, "base denomination cannot be blank") + return errorsmod.Wrap(ErrInvalidDenomForTransfer, "base denomination cannot be blank") } path, _ := extractPathAndBaseFromFullDenom(denomSplit) @@ -205,8 +205,8 @@ func ValidatePrefixedDenom(denom string) error { // ValidateIBCDenom validates that the given denomination is either: // -// - A valid base denomination (eg: 'uatom' or 'gamm/pool/1' as in https://github.com/cosmos/ibc-go/issues/894) -// - A valid fungible token representation (i.e 'ibc/{hash}') per ADR 001 https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-001-coin-source-tracing.md +// - A valid base denomination (eg: 'uatom' or 'gamm/pool/1' as in https://github.com/cosmos/ibc-go/issues/894) +// - A valid fungible token representation (i.e 'ibc/{hash}') per ADR 001 https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-001-coin-source-tracing.md func ValidateIBCDenom(denom string) error { if err := sdk.ValidateDenom(denom); err != nil { return err @@ -216,15 +216,15 @@ func ValidateIBCDenom(denom string) error { switch { case denom == DenomPrefix: - return sdkerrors.Wrapf(ErrInvalidDenomForTransfer, "denomination should be prefixed with the format 'ibc/{hash(trace + \"/\" + %s)}'", denom) + return errorsmod.Wrapf(ErrInvalidDenomForTransfer, "denomination should be prefixed with the format 'ibc/{hash(trace + \"/\" + %s)}'", denom) case len(denomSplit) == 2 && denomSplit[0] == DenomPrefix: if strings.TrimSpace(denomSplit[1]) == "" { - return sdkerrors.Wrapf(ErrInvalidDenomForTransfer, "denomination should be prefixed with the format 'ibc/{hash(trace + \"/\" + %s)}'", denom) + return errorsmod.Wrapf(ErrInvalidDenomForTransfer, "denomination should be prefixed with the format 'ibc/{hash(trace + \"/\" + %s)}'", denom) } if _, err := ParseHexHash(denomSplit[1]); err != nil { - return sdkerrors.Wrapf(err, "invalid denom trace hash %s", denomSplit[1]) + return errorsmod.Wrapf(err, "invalid denom trace hash %s", denomSplit[1]) } } diff --git a/modules/apps/transfer/types/trace_test.go b/modules/apps/transfer/types/trace_test.go index ba0690423bd..21e9892a2c3 100644 --- a/modules/apps/transfer/types/trace_test.go +++ b/modules/apps/transfer/types/trace_test.go @@ -1,43 +1,45 @@ -package types +package types_test import ( "testing" "github.com/stretchr/testify/require" + + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" ) func TestParseDenomTrace(t *testing.T) { testCases := []struct { name string denom string - expTrace DenomTrace + expTrace types.DenomTrace }{ - {"empty denom", "", DenomTrace{}}, - {"base denom", "uatom", DenomTrace{BaseDenom: "uatom"}}, - {"base denom ending with '/'", "uatom/", DenomTrace{BaseDenom: "uatom/"}}, - {"base denom with single '/'s", "gamm/pool/1", DenomTrace{BaseDenom: "gamm/pool/1"}}, - {"base denom with double '/'s", "gamm//pool//1", DenomTrace{BaseDenom: "gamm//pool//1"}}, - {"trace info", "transfer/channel-1/uatom", DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1"}}, - {"trace info with custom port", "customtransfer/channel-1/uatom", DenomTrace{BaseDenom: "uatom", Path: "customtransfer/channel-1"}}, - {"trace info with base denom ending in '/'", "transfer/channel-1/uatom/", DenomTrace{BaseDenom: "uatom/", Path: "transfer/channel-1"}}, - {"trace info with single '/' in base denom", "transfer/channel-1/erc20/0x85bcBCd7e79Ec36f4fBBDc54F90C643d921151AA", DenomTrace{BaseDenom: "erc20/0x85bcBCd7e79Ec36f4fBBDc54F90C643d921151AA", Path: "transfer/channel-1"}}, - {"trace info with multiple '/'s in base denom", "transfer/channel-1/gamm/pool/1", DenomTrace{BaseDenom: "gamm/pool/1", Path: "transfer/channel-1"}}, - {"trace info with multiple double '/'s in base denom", "transfer/channel-1/gamm//pool//1", DenomTrace{BaseDenom: "gamm//pool//1", Path: "transfer/channel-1"}}, - {"trace info with multiple port/channel pairs", "transfer/channel-1/transfer/channel-2/uatom", DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}}, - {"trace info with multiple custom ports", "customtransfer/channel-1/alternativetransfer/channel-2/uatom", DenomTrace{BaseDenom: "uatom", Path: "customtransfer/channel-1/alternativetransfer/channel-2"}}, - {"incomplete path", "transfer/uatom", DenomTrace{BaseDenom: "transfer/uatom"}}, - {"invalid path (1)", "transfer//uatom", DenomTrace{BaseDenom: "transfer//uatom", Path: ""}}, - {"invalid path (2)", "channel-1/transfer/uatom", DenomTrace{BaseDenom: "channel-1/transfer/uatom"}}, - {"invalid path (3)", "uatom/transfer", DenomTrace{BaseDenom: "uatom/transfer"}}, - {"invalid path (4)", "transfer/channel-1", DenomTrace{BaseDenom: "transfer/channel-1"}}, - {"invalid path (5)", "transfer/channel-1/", DenomTrace{Path: "transfer/channel-1"}}, - {"invalid path (6)", "transfer/channel-1/transfer", DenomTrace{BaseDenom: "transfer", Path: "transfer/channel-1"}}, - {"invalid path (7)", "transfer/channel-1/transfer/channel-2", DenomTrace{Path: "transfer/channel-1/transfer/channel-2"}}, - {"invalid path (8)", "transfer/channelToA/uatom", DenomTrace{BaseDenom: "transfer/channelToA/uatom", Path: ""}}, + {"empty denom", "", types.DenomTrace{}}, + {"base denom", "uatom", types.DenomTrace{BaseDenom: "uatom"}}, + {"base denom ending with '/'", "uatom/", types.DenomTrace{BaseDenom: "uatom/"}}, + {"base denom with single '/'s", "gamm/pool/1", types.DenomTrace{BaseDenom: "gamm/pool/1"}}, + {"base denom with double '/'s", "gamm//pool//1", types.DenomTrace{BaseDenom: "gamm//pool//1"}}, + {"trace info", "transfer/channel-1/uatom", types.DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1"}}, + {"trace info with custom port", "customtransfer/channel-1/uatom", types.DenomTrace{BaseDenom: "uatom", Path: "customtransfer/channel-1"}}, + {"trace info with base denom ending in '/'", "transfer/channel-1/uatom/", types.DenomTrace{BaseDenom: "uatom/", Path: "transfer/channel-1"}}, + {"trace info with single '/' in base denom", "transfer/channel-1/erc20/0x85bcBCd7e79Ec36f4fBBDc54F90C643d921151AA", types.DenomTrace{BaseDenom: "erc20/0x85bcBCd7e79Ec36f4fBBDc54F90C643d921151AA", Path: "transfer/channel-1"}}, + {"trace info with multiple '/'s in base denom", "transfer/channel-1/gamm/pool/1", types.DenomTrace{BaseDenom: "gamm/pool/1", Path: "transfer/channel-1"}}, + {"trace info with multiple double '/'s in base denom", "transfer/channel-1/gamm//pool//1", types.DenomTrace{BaseDenom: "gamm//pool//1", Path: "transfer/channel-1"}}, + {"trace info with multiple port/channel pairs", "transfer/channel-1/transfer/channel-2/uatom", types.DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}}, + {"trace info with multiple custom ports", "customtransfer/channel-1/alternativetransfer/channel-2/uatom", types.DenomTrace{BaseDenom: "uatom", Path: "customtransfer/channel-1/alternativetransfer/channel-2"}}, + {"incomplete path", "transfer/uatom", types.DenomTrace{BaseDenom: "transfer/uatom"}}, + {"invalid path (1)", "transfer//uatom", types.DenomTrace{BaseDenom: "transfer//uatom", Path: ""}}, + {"invalid path (2)", "channel-1/transfer/uatom", types.DenomTrace{BaseDenom: "channel-1/transfer/uatom"}}, + {"invalid path (3)", "uatom/transfer", types.DenomTrace{BaseDenom: "uatom/transfer"}}, + {"invalid path (4)", "transfer/channel-1", types.DenomTrace{BaseDenom: "transfer/channel-1"}}, + {"invalid path (5)", "transfer/channel-1/", types.DenomTrace{Path: "transfer/channel-1"}}, + {"invalid path (6)", "transfer/channel-1/transfer", types.DenomTrace{BaseDenom: "transfer", Path: "transfer/channel-1"}}, + {"invalid path (7)", "transfer/channel-1/transfer/channel-2", types.DenomTrace{Path: "transfer/channel-1/transfer/channel-2"}}, + {"invalid path (8)", "transfer/channelToA/uatom", types.DenomTrace{BaseDenom: "transfer/channelToA/uatom", Path: ""}}, } for _, tc := range testCases { - trace := ParseDenomTrace(tc.denom) + trace := types.ParseDenomTrace(tc.denom) require.Equal(t, tc.expTrace, trace, tc.name) } } @@ -45,11 +47,11 @@ func TestParseDenomTrace(t *testing.T) { func TestDenomTrace_IBCDenom(t *testing.T) { testCases := []struct { name string - trace DenomTrace + trace types.DenomTrace expDenom string }{ - {"base denom", DenomTrace{BaseDenom: "uatom"}, "uatom"}, - {"trace info", DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1"}, "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9"}, + {"base denom", types.DenomTrace{BaseDenom: "uatom"}, "uatom"}, + {"trace info", types.DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1"}, "ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9"}, } for _, tc := range testCases { @@ -61,19 +63,19 @@ func TestDenomTrace_IBCDenom(t *testing.T) { func TestDenomTrace_Validate(t *testing.T) { testCases := []struct { name string - trace DenomTrace + trace types.DenomTrace expError bool }{ - {"base denom only", DenomTrace{BaseDenom: "uatom"}, false}, - {"base denom only with single '/'", DenomTrace{BaseDenom: "erc20/0x85bcBCd7e79Ec36f4fBBDc54F90C643d921151AA"}, false}, - {"base denom only with multiple '/'s", DenomTrace{BaseDenom: "gamm/pool/1"}, false}, - {"empty DenomTrace", DenomTrace{}, true}, - {"valid single trace info", DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1"}, false}, - {"valid multiple trace info", DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}, false}, - {"single trace identifier", DenomTrace{BaseDenom: "uatom", Path: "transfer"}, true}, - {"invalid port ID", DenomTrace{BaseDenom: "uatom", Path: "(transfer)/channel-1"}, true}, - {"invalid channel ID", DenomTrace{BaseDenom: "uatom", Path: "transfer/(channel-1)"}, true}, - {"empty base denom with trace", DenomTrace{BaseDenom: "", Path: "transfer/channel-1"}, true}, + {"base denom only", types.DenomTrace{BaseDenom: "uatom"}, false}, + {"base denom only with single '/'", types.DenomTrace{BaseDenom: "erc20/0x85bcBCd7e79Ec36f4fBBDc54F90C643d921151AA"}, false}, + {"base denom only with multiple '/'s", types.DenomTrace{BaseDenom: "gamm/pool/1"}, false}, + {"empty DenomTrace", types.DenomTrace{}, true}, + {"valid single trace info", types.DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1"}, false}, + {"valid multiple trace info", types.DenomTrace{BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}, false}, + {"single trace identifier", types.DenomTrace{BaseDenom: "uatom", Path: "transfer"}, true}, + {"invalid port ID", types.DenomTrace{BaseDenom: "uatom", Path: "(transfer)/channel-1"}, true}, + {"invalid channel ID", types.DenomTrace{BaseDenom: "uatom", Path: "transfer/(channel-1)"}, true}, + {"empty base denom with trace", types.DenomTrace{BaseDenom: "", Path: "transfer/channel-1"}, true}, } for _, tc := range testCases { @@ -89,20 +91,20 @@ func TestDenomTrace_Validate(t *testing.T) { func TestTraces_Validate(t *testing.T) { testCases := []struct { name string - traces Traces + traces types.Traces expError bool }{ - {"empty Traces", Traces{}, false}, - {"valid multiple trace info", Traces{{BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}}, false}, + {"empty Traces", types.Traces{}, false}, + {"valid multiple trace info", types.Traces{{BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}}, false}, { "valid multiple trace info", - Traces{ + types.Traces{ {BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}, {BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}, }, true, }, - {"empty base denom with trace", Traces{{BaseDenom: "", Path: "transfer/channel-1"}}, true}, + {"empty base denom with trace", types.Traces{{BaseDenom: "", Path: "transfer/channel-1"}}, true}, } for _, tc := range testCases { @@ -134,7 +136,7 @@ func TestValidatePrefixedDenom(t *testing.T) { } for _, tc := range testCases { - err := ValidatePrefixedDenom(tc.denom) + err := types.ValidatePrefixedDenom(tc.denom) if tc.expError { require.Error(t, err, tc.name) } else { @@ -162,7 +164,7 @@ func TestValidateIBCDenom(t *testing.T) { } for _, tc := range testCases { - err := ValidateIBCDenom(tc.denom) + err := types.ValidateIBCDenom(tc.denom) if tc.expError { require.Error(t, err, tc.name) continue diff --git a/modules/apps/transfer/types/transfer.pb.go b/modules/apps/transfer/types/transfer.pb.go index 9ef18d9d5b0..6669bda8872 100644 --- a/modules/apps/transfer/types/transfer.pb.go +++ b/modules/apps/transfer/types/transfer.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -153,23 +153,23 @@ var fileDescriptor_5041673e96e97901 = []byte{ // 300 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xc1, 0x4a, 0x2b, 0x31, 0x14, 0x86, 0x9b, 0x72, 0x29, 0xb7, 0x51, 0x14, 0xa2, 0x68, 0x29, 0x9a, 0xca, 0xac, 0x04, 0x71, - 0x42, 0x51, 0x10, 0xba, 0x11, 0xaa, 0xee, 0xb5, 0xb8, 0x72, 0x53, 0x92, 0xcc, 0x71, 0x1a, 0x98, - 0x4c, 0x86, 0x24, 0x1d, 0xe8, 0x23, 0xb8, 0xf3, 0xb1, 0x5c, 0x76, 0xe9, 0xaa, 0x48, 0xfb, 0x06, - 0x7d, 0x02, 0x99, 0xb4, 0x94, 0xc1, 0xdd, 0x7f, 0xce, 0xf9, 0xbe, 0xb3, 0xf8, 0xf1, 0x95, 0x12, - 0x92, 0xf1, 0xa2, 0xc8, 0x94, 0xe4, 0x5e, 0x99, 0xdc, 0x31, 0x6f, 0x79, 0xee, 0xde, 0xc1, 0xb2, - 0xb2, 0xbf, 0xcb, 0x71, 0x61, 0x8d, 0x37, 0xe4, 0x4c, 0x09, 0x19, 0xd7, 0xe1, 0x78, 0x07, 0x94, - 0xfd, 0xee, 0x71, 0x6a, 0x52, 0x13, 0x40, 0x56, 0xa5, 0x8d, 0x13, 0xdd, 0x63, 0xfc, 0x08, 0xb9, - 0xd1, 0xaf, 0x96, 0x4b, 0x20, 0x04, 0xff, 0x2b, 0xb8, 0x9f, 0x74, 0xd0, 0x05, 0xba, 0x6c, 0x8f, - 0x42, 0x26, 0xe7, 0x18, 0x0b, 0xee, 0x60, 0x9c, 0x54, 0x58, 0xa7, 0x19, 0x2e, 0xed, 0x6a, 0x13, - 0xbc, 0xe8, 0x03, 0xe1, 0xd6, 0x33, 0xb7, 0x5c, 0x3b, 0x32, 0xc0, 0xfb, 0x0e, 0xf2, 0x64, 0x0c, - 0x39, 0x17, 0x19, 0x24, 0xe1, 0xcb, 0xff, 0xe1, 0xe9, 0x7a, 0xd1, 0x3b, 0x9a, 0x71, 0x9d, 0x0d, - 0xa2, 0xfa, 0x35, 0x1a, 0xed, 0x55, 0xe3, 0xd3, 0x66, 0x22, 0x0f, 0xf8, 0xd0, 0x82, 0x04, 0x55, - 0xc2, 0x4e, 0x6f, 0x06, 0xbd, 0xbb, 0x5e, 0xf4, 0x4e, 0x36, 0xfa, 0x1f, 0x20, 0x1a, 0x1d, 0x6c, - 0x37, 0xdb, 0x27, 0xc3, 0x97, 0xaf, 0x25, 0x45, 0xf3, 0x25, 0x45, 0x3f, 0x4b, 0x8a, 0x3e, 0x57, - 0xb4, 0x31, 0x5f, 0xd1, 0xc6, 0xf7, 0x8a, 0x36, 0xde, 0xee, 0x52, 0xe5, 0x27, 0x53, 0x11, 0x4b, - 0xa3, 0x99, 0x34, 0x4e, 0x1b, 0xc7, 0x94, 0x90, 0xd7, 0xa9, 0x61, 0xe5, 0x2d, 0xd3, 0x26, 0x99, - 0x66, 0xe0, 0xaa, 0x9e, 0x6b, 0xfd, 0xfa, 0x59, 0x01, 0x4e, 0xb4, 0x42, 0x4d, 0x37, 0xbf, 0x01, - 0x00, 0x00, 0xff, 0xff, 0x71, 0xb6, 0xa1, 0xba, 0x89, 0x01, 0x00, 0x00, + 0x42, 0x71, 0x51, 0xe8, 0x46, 0xa8, 0xba, 0xd7, 0xe2, 0xca, 0x4d, 0x49, 0x32, 0xc7, 0x69, 0x60, + 0x32, 0x19, 0x92, 0x74, 0xa0, 0x8f, 0xe0, 0xce, 0xc7, 0x72, 0xd9, 0xa5, 0xab, 0x22, 0xed, 0x1b, + 0xf4, 0x09, 0x64, 0xd2, 0x52, 0x06, 0x77, 0xff, 0x39, 0xe7, 0xfb, 0xce, 0xe2, 0xc7, 0x37, 0x4a, + 0x48, 0xc6, 0x8b, 0x22, 0x53, 0x92, 0x7b, 0x65, 0x72, 0xc7, 0xbc, 0xe5, 0xb9, 0x7b, 0x07, 0xcb, + 0xca, 0xfe, 0x3e, 0xc7, 0x85, 0x35, 0xde, 0x90, 0x0b, 0x25, 0x64, 0x5c, 0x87, 0xe3, 0x3d, 0x50, + 0xf6, 0xbb, 0xa7, 0xa9, 0x49, 0x4d, 0x00, 0x59, 0x95, 0xb6, 0x4e, 0x74, 0x8f, 0xf1, 0x23, 0xe4, + 0x46, 0xbf, 0x5a, 0x2e, 0x81, 0x10, 0xfc, 0xaf, 0xe0, 0x7e, 0xda, 0x41, 0x57, 0xe8, 0xba, 0x3d, + 0x0e, 0x99, 0x5c, 0x62, 0x2c, 0xb8, 0x83, 0x49, 0x52, 0x61, 0x9d, 0x66, 0xb8, 0xb4, 0xab, 0x4d, + 0xf0, 0xa2, 0x0f, 0x84, 0x5b, 0xcf, 0xdc, 0x72, 0xed, 0xc8, 0x10, 0x1f, 0x3a, 0xc8, 0x93, 0x09, + 0xe4, 0x5c, 0x64, 0x90, 0x84, 0x2f, 0xff, 0x47, 0xe7, 0x9b, 0x65, 0xef, 0x64, 0xce, 0x75, 0x36, + 0x8c, 0xea, 0xd7, 0x68, 0x7c, 0x50, 0x8d, 0x4f, 0xdb, 0x89, 0x3c, 0xe0, 0x63, 0x0b, 0x12, 0x54, + 0x09, 0x7b, 0xbd, 0x19, 0xf4, 0xee, 0x66, 0xd9, 0x3b, 0xdb, 0xea, 0x7f, 0x80, 0x68, 0x7c, 0xb4, + 0xdb, 0xec, 0x9e, 0x8c, 0x5e, 0xbe, 0x56, 0x14, 0x2d, 0x56, 0x14, 0xfd, 0xac, 0x28, 0xfa, 0x5c, + 0xd3, 0xc6, 0x62, 0x4d, 0x1b, 0xdf, 0x6b, 0xda, 0x78, 0x1b, 0xa4, 0xca, 0x4f, 0x67, 0x22, 0x96, + 0x46, 0x33, 0x69, 0x9c, 0x36, 0x8e, 0x29, 0x21, 0x6f, 0x53, 0xc3, 0xca, 0x01, 0xd3, 0x26, 0x99, + 0x65, 0xe0, 0xaa, 0x9e, 0x6b, 0xfd, 0xfa, 0x79, 0x01, 0x4e, 0xb4, 0x42, 0x4d, 0x77, 0xbf, 0x01, + 0x00, 0x00, 0xff, 0xff, 0x11, 0x89, 0xc0, 0xe0, 0x89, 0x01, 0x00, 0x00, } func (m *DenomTrace) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/transfer/types/transfer_authorization.go b/modules/apps/transfer/types/transfer_authorization.go new file mode 100644 index 00000000000..709972afc49 --- /dev/null +++ b/modules/apps/transfer/types/transfer_authorization.go @@ -0,0 +1,128 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" + + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" +) + +const gasCostPerIteration = uint64(10) + +var _ authz.Authorization = &TransferAuthorization{} + +// NewTransferAuthorization creates a new TransferAuthorization object. +func NewTransferAuthorization(allocations ...Allocation) *TransferAuthorization { + return &TransferAuthorization{ + Allocations: allocations, + } +} + +// MsgTypeURL implements Authorization.MsgTypeURL. +func (a TransferAuthorization) MsgTypeURL() string { + return sdk.MsgTypeURL(&MsgTransfer{}) +} + +// Accept implements Authorization.Accept. +func (a TransferAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authz.AcceptResponse, error) { + msgTransfer, ok := msg.(*MsgTransfer) + if !ok { + return authz.AcceptResponse{}, errorsmod.Wrap(ibcerrors.ErrInvalidType, "type mismatch") + } + + for index, allocation := range a.Allocations { + if allocation.SourceChannel == msgTransfer.SourceChannel && allocation.SourcePort == msgTransfer.SourcePort { + limitLeft, isNegative := allocation.SpendLimit.SafeSub(msgTransfer.Token) + if isNegative { + return authz.AcceptResponse{}, errorsmod.Wrapf(ibcerrors.ErrInsufficientFunds, "requested amount is more than spend limit") + } + + if !isAllowedAddress(ctx, msgTransfer.Receiver, allocation.AllowList) { + return authz.AcceptResponse{}, errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "not allowed address for transfer") + } + + if limitLeft.IsZero() { + a.Allocations = append(a.Allocations[:index], a.Allocations[index+1:]...) + if len(a.Allocations) == 0 { + return authz.AcceptResponse{Accept: true, Delete: true}, nil + } + return authz.AcceptResponse{Accept: true, Delete: false, Updated: &TransferAuthorization{ + Allocations: a.Allocations, + }}, nil + } + a.Allocations[index] = Allocation{ + SourcePort: allocation.SourcePort, + SourceChannel: allocation.SourceChannel, + SpendLimit: limitLeft, + AllowList: allocation.AllowList, + } + + return authz.AcceptResponse{Accept: true, Delete: false, Updated: &TransferAuthorization{ + Allocations: a.Allocations, + }}, nil + } + } + return authz.AcceptResponse{}, errorsmod.Wrapf(ibcerrors.ErrNotFound, "requested port and channel allocation does not exist") +} + +// ValidateBasic implements Authorization.ValidateBasic. +func (a TransferAuthorization) ValidateBasic() error { + if len(a.Allocations) == 0 { + return errorsmod.Wrap(ErrInvalidAuthorization, "allocations cannot be empty") + } + + foundChannels := make(map[string]bool, 0) + + for _, allocation := range a.Allocations { + if _, found := foundChannels[allocation.SourceChannel]; found { + return errorsmod.Wrapf(channeltypes.ErrInvalidChannel, "duplicate source channel ID: %s", allocation.SourceChannel) + } + + foundChannels[allocation.SourceChannel] = true + + if allocation.SpendLimit == nil { + return errorsmod.Wrap(ibcerrors.ErrInvalidCoins, "spend limit cannot be nil") + } + + if err := allocation.SpendLimit.Validate(); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidCoins, err.Error()) + } + + if err := host.PortIdentifierValidator(allocation.SourcePort); err != nil { + return errorsmod.Wrap(err, "invalid source port ID") + } + + if err := host.ChannelIdentifierValidator(allocation.SourceChannel); err != nil { + return errorsmod.Wrap(err, "invalid source channel ID") + } + + found := make(map[string]bool, 0) + for i := 0; i < len(allocation.AllowList); i++ { + if found[allocation.AllowList[i]] { + return errorsmod.Wrapf(ErrInvalidAuthorization, "duplicate entry in allow list %s", allocation.AllowList[i]) + } + found[allocation.AllowList[i]] = true + } + } + + return nil +} + +// isAllowedAddress returns a boolean indicating if the receiver address is valid for transfer. +// gasCostPerIteration gas is consumed for each iteration. +func isAllowedAddress(ctx sdk.Context, receiver string, allowedAddrs []string) bool { + if len(allowedAddrs) == 0 { + return true + } + + for _, addr := range allowedAddrs { + ctx.GasMeter().ConsumeGas(gasCostPerIteration, "transfer authorization") + if addr == receiver { + return true + } + } + return false +} diff --git a/modules/apps/transfer/types/transfer_authorization_test.go b/modules/apps/transfer/types/transfer_authorization_test.go new file mode 100644 index 00000000000..f0f7f3ab0b9 --- /dev/null +++ b/modules/apps/transfer/types/transfer_authorization_test.go @@ -0,0 +1,282 @@ +package types_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" + + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/cosmos/ibc-go/v7/testing/mock" +) + +func (suite *TypesTestSuite) TestTransferAuthorizationAccept() { + var ( + msgTransfer types.MsgTransfer + transferAuthz types.TransferAuthorization + ) + + testCases := []struct { + name string + malleate func() + assertResult func(res authz.AcceptResponse, err error) + }{ + { + "success", + func() {}, + func(res authz.AcceptResponse, err error) { + suite.Require().NoError(err) + + suite.Require().True(res.Accept) + suite.Require().True(res.Delete) + suite.Require().Nil(res.Updated) + }, + }, + { + "success: with spend limit updated", + func() { + msgTransfer.Token = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(50)) + }, + func(res authz.AcceptResponse, err error) { + suite.Require().NoError(err) + + suite.Require().True(res.Accept) + suite.Require().False(res.Delete) + + updatedAuthz, ok := res.Updated.(*types.TransferAuthorization) + suite.Require().True(ok) + + isEqual := updatedAuthz.Allocations[0].SpendLimit.IsEqual(sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(50)))) + suite.Require().True(isEqual) + }, + }, + { + "success: with empty allow list", + func() { + transferAuthz.Allocations[0].AllowList = []string{} + }, + func(res authz.AcceptResponse, err error) { + suite.Require().NoError(err) + + suite.Require().True(res.Accept) + suite.Require().True(res.Delete) + suite.Require().Nil(res.Updated) + }, + }, + { + "success: with multiple allocations", + func() { + alloc := types.Allocation{ + SourcePort: ibctesting.MockPort, + SourceChannel: "channel-9", + SpendLimit: ibctesting.TestCoins, + } + + transferAuthz.Allocations = append(transferAuthz.Allocations, alloc) + }, + func(res authz.AcceptResponse, err error) { + suite.Require().NoError(err) + + suite.Require().True(res.Accept) + suite.Require().False(res.Delete) + + updatedAuthz, ok := res.Updated.(*types.TransferAuthorization) + suite.Require().True(ok) + + // assert spent spendlimit is removed from the list + suite.Require().Len(updatedAuthz.Allocations, 1) + }, + }, + { + "no spend limit set for MsgTransfer port/channel", + func() { + msgTransfer.SourcePort = ibctesting.MockPort + msgTransfer.SourceChannel = "channel-9" + }, + func(res authz.AcceptResponse, err error) { + suite.Require().Error(err) + }, + }, + { + "requested transfer amount is more than the spend limit", + func() { + msgTransfer.Token = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1000)) + }, + func(res authz.AcceptResponse, err error) { + suite.Require().Error(err) + }, + }, + { + "receiver address not permitted via allow list", + func() { + msgTransfer.Receiver = suite.chainB.SenderAccount.GetAddress().String() + }, + func(res authz.AcceptResponse, err error) { + suite.Require().Error(err) + }, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + suite.SetupTest() + + path := NewTransferPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + transferAuthz = types.TransferAuthorization{ + Allocations: []types.Allocation{ + { + SourcePort: path.EndpointA.ChannelConfig.PortID, + SourceChannel: path.EndpointA.ChannelID, + SpendLimit: ibctesting.TestCoins, + AllowList: []string{ibctesting.TestAccAddress}, + }, + }, + } + + msgTransfer = types.MsgTransfer{ + SourcePort: path.EndpointA.ChannelConfig.PortID, + SourceChannel: path.EndpointA.ChannelID, + Token: ibctesting.TestCoin, + Sender: suite.chainA.SenderAccount.GetAddress().String(), + Receiver: ibctesting.TestAccAddress, + TimeoutHeight: suite.chainB.GetTimeoutHeight(), + } + + tc.malleate() + + res, err := transferAuthz.Accept(suite.chainA.GetContext(), &msgTransfer) + tc.assertResult(res, err) + }) + } +} + +func (suite *TypesTestSuite) TestTransferAuthorizationMsgTypeURL() { + var transferAuthz types.TransferAuthorization + suite.Require().Equal(sdk.MsgTypeURL(&types.MsgTransfer{}), transferAuthz.MsgTypeURL(), "invalid type url for transfer authorization") +} + +func (suite *TypesTestSuite) TestTransferAuthorizationValidateBasic() { + var transferAuthz types.TransferAuthorization + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "success: empty allow list", + func() { + transferAuthz.Allocations[0].AllowList = []string{} + }, + true, + }, + { + "success: with multiple allocations", + func() { + allocation := types.Allocation{ + SourcePort: types.PortID, + SourceChannel: "channel-1", + SpendLimit: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), + AllowList: []string{}, + } + + transferAuthz.Allocations = append(transferAuthz.Allocations, allocation) + }, + true, + }, + { + "empty allocations", + func() { + transferAuthz = types.TransferAuthorization{Allocations: []types.Allocation{}} + }, + false, + }, + { + "nil allocations", + func() { + transferAuthz = types.TransferAuthorization{} + }, + false, + }, + { + "nil spend limit coins", + func() { + transferAuthz.Allocations[0].SpendLimit = nil + }, + false, + }, + { + "invalid spend limit coins", + func() { + transferAuthz.Allocations[0].SpendLimit = sdk.Coins{sdk.Coin{Denom: ""}} + }, + false, + }, + { + "duplicate entry in allow list", + func() { + transferAuthz.Allocations[0].AllowList = []string{ibctesting.TestAccAddress, ibctesting.TestAccAddress} + }, + false, + }, + { + "invalid port identifier", + func() { + transferAuthz.Allocations[0].SourcePort = "" + }, + false, + }, + { + "invalid channel identifier", + func() { + transferAuthz.Allocations[0].SourceChannel = "" + }, + false, + }, + { + name: "duplicate channel ID", + malleate: func() { + allocation := types.Allocation{ + SourcePort: mock.PortID, + SourceChannel: transferAuthz.Allocations[0].SourceChannel, + SpendLimit: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), + AllowList: []string{ibctesting.TestAccAddress}, + } + + transferAuthz.Allocations = append(transferAuthz.Allocations, allocation) + }, + expPass: false, + }, + } + + for _, tc := range testCases { + suite.Run(tc.name, func() { + transferAuthz = types.TransferAuthorization{ + Allocations: []types.Allocation{ + { + SourcePort: mock.PortID, + SourceChannel: ibctesting.FirstChannelID, + SpendLimit: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), + AllowList: []string{ibctesting.TestAccAddress}, + }, + }, + } + + tc.malleate() + + err := transferAuthz.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} diff --git a/modules/apps/transfer/types/tx.pb.go b/modules/apps/transfer/types/tx.pb.go index 1cf3dcabc22..077de524251 100644 --- a/modules/apps/transfer/types/tx.pb.go +++ b/modules/apps/transfer/types/tx.pb.go @@ -7,10 +7,10 @@ import ( context "context" fmt "fmt" types "github.com/cosmos/cosmos-sdk/types" - types1 "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types1 "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -50,6 +50,8 @@ type MsgTransfer struct { // Timeout timestamp in absolute nanoseconds since unix epoch. // The timeout is disabled when set to 0. TimeoutTimestamp uint64 `protobuf:"varint,7,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty" yaml:"timeout_timestamp"` + // optional memo + Memo string `protobuf:"bytes,8,opt,name=memo,proto3" json:"memo,omitempty"` } func (m *MsgTransfer) Reset() { *m = MsgTransfer{} } @@ -87,6 +89,8 @@ var xxx_messageInfo_MsgTransfer proto.InternalMessageInfo // MsgTransferResponse defines the Msg/Transfer response type. type MsgTransferResponse struct { + // sequence number of the transfer packet sent + Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` } func (m *MsgTransferResponse) Reset() { *m = MsgTransferResponse{} } @@ -122,6 +126,13 @@ func (m *MsgTransferResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgTransferResponse proto.InternalMessageInfo +func (m *MsgTransferResponse) GetSequence() uint64 { + if m != nil { + return m.Sequence + } + return 0 +} + func init() { proto.RegisterType((*MsgTransfer)(nil), "ibc.applications.transfer.v1.MsgTransfer") proto.RegisterType((*MsgTransferResponse)(nil), "ibc.applications.transfer.v1.MsgTransferResponse") @@ -132,38 +143,40 @@ func init() { } var fileDescriptor_7401ed9bed2f8e09 = []byte{ - // 494 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0xc7, 0x6d, 0x92, 0x86, 0x70, 0x51, 0x2b, 0x30, 0xb4, 0x72, 0xa3, 0x62, 0x47, 0x96, 0x90, - 0xc2, 0xc0, 0x9d, 0x5c, 0x40, 0x95, 0x3a, 0xa1, 0x74, 0x81, 0xa1, 0x12, 0x58, 0x9d, 0x58, 0x8a, - 0x7d, 0x3d, 0x9c, 0x13, 0xf1, 0x3d, 0xeb, 0xee, 0x62, 0xd1, 0x6f, 0xc0, 0xc8, 0x47, 0xe8, 0xcc, - 0x27, 0xe9, 0xd8, 0x91, 0x29, 0x42, 0xc9, 0xc2, 0x9c, 0x4f, 0x80, 0xce, 0xbe, 0x84, 0x64, 0x41, - 0x4c, 0xf6, 0x7b, 0xff, 0xdf, 0xbb, 0xbf, 0xde, 0xbd, 0x77, 0xe8, 0x19, 0xcf, 0x28, 0x49, 0xcb, - 0x72, 0xc2, 0x69, 0xaa, 0x39, 0x08, 0x45, 0xb4, 0x4c, 0x85, 0xfa, 0xcc, 0x24, 0xa9, 0x62, 0xa2, - 0xbf, 0xe2, 0x52, 0x82, 0x06, 0xef, 0x88, 0x67, 0x14, 0x6f, 0x62, 0x78, 0x85, 0xe1, 0x2a, 0xee, - 0x3f, 0xc9, 0x21, 0x87, 0x1a, 0x24, 0xe6, 0xaf, 0xa9, 0xe9, 0x07, 0x14, 0x54, 0x01, 0x8a, 0x64, - 0xa9, 0x62, 0xa4, 0x8a, 0x33, 0xa6, 0xd3, 0x98, 0x50, 0xe0, 0xc2, 0xea, 0xa1, 0xb1, 0xa6, 0x20, - 0x19, 0xa1, 0x13, 0xce, 0x84, 0x36, 0x86, 0xcd, 0x5f, 0x03, 0x44, 0x3f, 0x5a, 0xa8, 0x77, 0xae, - 0xf2, 0x0b, 0xeb, 0xe4, 0x9d, 0xa0, 0x9e, 0x82, 0xa9, 0xa4, 0xec, 0xb2, 0x04, 0xa9, 0x7d, 0x77, - 0xe0, 0x0e, 0x1f, 0x8c, 0x0e, 0x96, 0xb3, 0xd0, 0xbb, 0x4e, 0x8b, 0xc9, 0x69, 0xb4, 0x21, 0x46, - 0x09, 0x6a, 0xa2, 0xf7, 0x20, 0xb5, 0xf7, 0x06, 0xed, 0x59, 0x8d, 0x8e, 0x53, 0x21, 0xd8, 0xc4, - 0xbf, 0x57, 0xd7, 0x1e, 0x2e, 0x67, 0xe1, 0xfe, 0x56, 0xad, 0xd5, 0xa3, 0x64, 0xb7, 0x49, 0x9c, - 0x35, 0xb1, 0xf7, 0x1a, 0xed, 0x68, 0xf8, 0xc2, 0x84, 0xdf, 0x1a, 0xb8, 0xc3, 0xde, 0xf1, 0x21, - 0x6e, 0x7a, 0xc3, 0xa6, 0x37, 0x6c, 0x7b, 0xc3, 0x67, 0xc0, 0xc5, 0xa8, 0x7d, 0x3b, 0x0b, 0x9d, - 0xa4, 0xa1, 0xbd, 0x03, 0xd4, 0x51, 0x4c, 0x5c, 0x31, 0xe9, 0xb7, 0x8d, 0x61, 0x62, 0x23, 0xaf, - 0x8f, 0xba, 0x92, 0x51, 0xc6, 0x2b, 0x26, 0xfd, 0x9d, 0x5a, 0x59, 0xc7, 0xde, 0x27, 0xb4, 0xa7, - 0x79, 0xc1, 0x60, 0xaa, 0x2f, 0xc7, 0x8c, 0xe7, 0x63, 0xed, 0x77, 0x6a, 0xcf, 0x3e, 0x36, 0x33, - 0x30, 0xf7, 0x85, 0xed, 0x2d, 0x55, 0x31, 0x7e, 0x5b, 0x13, 0xa3, 0xa7, 0xc6, 0xf4, 0x6f, 0x33, - 0xdb, 0xf5, 0x51, 0xb2, 0x6b, 0x13, 0x0d, 0xed, 0xbd, 0x43, 0x8f, 0x56, 0x84, 0xf9, 0x2a, 0x9d, - 0x16, 0xa5, 0x7f, 0x7f, 0xe0, 0x0e, 0xdb, 0xa3, 0xa3, 0xe5, 0x2c, 0xf4, 0xb7, 0x0f, 0x59, 0x23, - 0x51, 0xf2, 0xd0, 0xe6, 0x2e, 0x56, 0xa9, 0xd3, 0xee, 0xb7, 0x9b, 0xd0, 0xf9, 0x7d, 0x13, 0x3a, - 0xd1, 0x3e, 0x7a, 0xbc, 0x31, 0xab, 0x84, 0xa9, 0x12, 0x84, 0x62, 0xc7, 0x80, 0x5a, 0xe7, 0x2a, - 0xf7, 0xc6, 0xa8, 0xbb, 0x1e, 0xe3, 0x73, 0xfc, 0xaf, 0x65, 0xc2, 0x1b, 0xa7, 0xf4, 0xe3, 0xff, - 0x46, 0x57, 0x86, 0xa3, 0x0f, 0xb7, 0xf3, 0xc0, 0xbd, 0x9b, 0x07, 0xee, 0xaf, 0x79, 0xe0, 0x7e, - 0x5f, 0x04, 0xce, 0xdd, 0x22, 0x70, 0x7e, 0x2e, 0x02, 0xe7, 0xe3, 0x49, 0xce, 0xf5, 0x78, 0x9a, - 0x61, 0x0a, 0x05, 0xb1, 0xab, 0xc9, 0x33, 0xfa, 0x22, 0x07, 0x52, 0xbd, 0x22, 0x05, 0x5c, 0x4d, - 0x27, 0x4c, 0x99, 0xa7, 0xb0, 0xf1, 0x04, 0xf4, 0x75, 0xc9, 0x54, 0xd6, 0xa9, 0xd7, 0xf1, 0xe5, - 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd0, 0x6e, 0x0e, 0x0d, 0x2c, 0x03, 0x00, 0x00, + // 517 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xc1, 0x6e, 0xd3, 0x4c, + 0x10, 0xb6, 0xff, 0xa4, 0xf9, 0xc3, 0x46, 0xad, 0x60, 0x81, 0xca, 0x8d, 0x8a, 0x1d, 0x59, 0x42, + 0x0a, 0x07, 0x76, 0xe5, 0x22, 0x14, 0xa9, 0x27, 0x94, 0x5e, 0xe0, 0x50, 0x09, 0xac, 0x9e, 0xb8, + 0x14, 0x7b, 0x3b, 0x38, 0x2b, 0x62, 0x8f, 0xf1, 0x6e, 0x2c, 0xfa, 0x06, 0x1c, 0x79, 0x84, 0x3e, + 0x09, 0xe7, 0x1e, 0x7b, 0xe4, 0x14, 0xa1, 0xe4, 0xc2, 0x39, 0x4f, 0x80, 0xd6, 0x76, 0x42, 0x72, + 0x41, 0x9c, 0x3c, 0x33, 0xdf, 0x37, 0xfe, 0xf6, 0xdb, 0x99, 0x25, 0x4f, 0x65, 0x2c, 0x78, 0x94, + 0xe7, 0x53, 0x29, 0x22, 0x2d, 0x31, 0x53, 0x5c, 0x17, 0x51, 0xa6, 0x3e, 0x42, 0xc1, 0xcb, 0x80, + 0xeb, 0x2f, 0x2c, 0x2f, 0x50, 0x23, 0x3d, 0x96, 0xb1, 0x60, 0xdb, 0x34, 0xb6, 0xa6, 0xb1, 0x32, + 0xe8, 0x3f, 0x4a, 0x30, 0xc1, 0x8a, 0xc8, 0x4d, 0x54, 0xf7, 0xf4, 0x5d, 0x81, 0x2a, 0x45, 0xc5, + 0xe3, 0x48, 0x01, 0x2f, 0x83, 0x18, 0x74, 0x14, 0x70, 0x81, 0x32, 0x6b, 0x70, 0xcf, 0x48, 0x0b, + 0x2c, 0x80, 0x8b, 0xa9, 0x84, 0x4c, 0x1b, 0xc1, 0x3a, 0xaa, 0x09, 0xfe, 0xf7, 0x16, 0xe9, 0x9d, + 0xab, 0xe4, 0xa2, 0x51, 0xa2, 0x23, 0xd2, 0x53, 0x38, 0x2b, 0x04, 0x5c, 0xe6, 0x58, 0x68, 0xc7, + 0x1e, 0xd8, 0xc3, 0x7b, 0xe3, 0xc3, 0xd5, 0xdc, 0xa3, 0xd7, 0x51, 0x3a, 0x3d, 0xf5, 0xb7, 0x40, + 0x3f, 0x24, 0x75, 0xf6, 0x16, 0x0b, 0x4d, 0x5f, 0x91, 0x83, 0x06, 0x13, 0x93, 0x28, 0xcb, 0x60, + 0xea, 0xfc, 0x57, 0xf5, 0x1e, 0xad, 0xe6, 0xde, 0xe3, 0x9d, 0xde, 0x06, 0xf7, 0xc3, 0xfd, 0xba, + 0x70, 0x56, 0xe7, 0xf4, 0x25, 0xd9, 0xd3, 0xf8, 0x09, 0x32, 0xa7, 0x35, 0xb0, 0x87, 0xbd, 0x93, + 0x23, 0x56, 0x7b, 0x63, 0xc6, 0x1b, 0x6b, 0xbc, 0xb1, 0x33, 0x94, 0xd9, 0xb8, 0x7d, 0x3b, 0xf7, + 0xac, 0xb0, 0x66, 0xd3, 0x43, 0xd2, 0x51, 0x90, 0x5d, 0x41, 0xe1, 0xb4, 0x8d, 0x60, 0xd8, 0x64, + 0xb4, 0x4f, 0xba, 0x05, 0x08, 0x90, 0x25, 0x14, 0xce, 0x5e, 0x85, 0x6c, 0x72, 0xfa, 0x81, 0x1c, + 0x68, 0x99, 0x02, 0xce, 0xf4, 0xe5, 0x04, 0x64, 0x32, 0xd1, 0x4e, 0xa7, 0xd2, 0xec, 0x33, 0x33, + 0x03, 0x73, 0x5f, 0xac, 0xb9, 0xa5, 0x32, 0x60, 0xaf, 0x2b, 0xc6, 0xf8, 0x89, 0x11, 0xfd, 0x63, + 0x66, 0xb7, 0xdf, 0x0f, 0xf7, 0x9b, 0x42, 0xcd, 0xa6, 0x6f, 0xc8, 0x83, 0x35, 0xc3, 0x7c, 0x95, + 0x8e, 0xd2, 0xdc, 0xf9, 0x7f, 0x60, 0x0f, 0xdb, 0xe3, 0xe3, 0xd5, 0xdc, 0x73, 0x76, 0x7f, 0xb2, + 0xa1, 0xf8, 0xe1, 0xfd, 0xa6, 0x76, 0xb1, 0x2e, 0x51, 0x4a, 0xda, 0x29, 0xa4, 0xe8, 0x74, 0x2b, + 0x13, 0x55, 0x7c, 0xda, 0xfd, 0x7a, 0xe3, 0x59, 0xbf, 0x6e, 0x3c, 0xcb, 0x0f, 0xc8, 0xc3, 0xad, + 0xf9, 0x85, 0xa0, 0x72, 0xcc, 0x14, 0x18, 0xf7, 0x0a, 0x3e, 0xcf, 0x20, 0x13, 0x50, 0x0d, 0xb1, + 0x1d, 0x6e, 0xf2, 0x13, 0x24, 0xad, 0x73, 0x95, 0xd0, 0x09, 0xe9, 0x6e, 0xc6, 0xfe, 0x8c, 0xfd, + 0x6d, 0xf9, 0xd8, 0x96, 0x42, 0x3f, 0xf8, 0x67, 0xea, 0xfa, 0x30, 0xe3, 0x77, 0xb7, 0x0b, 0xd7, + 0xbe, 0x5b, 0xb8, 0xf6, 0xcf, 0x85, 0x6b, 0x7f, 0x5b, 0xba, 0xd6, 0xdd, 0xd2, 0xb5, 0x7e, 0x2c, + 0x5d, 0xeb, 0xfd, 0x28, 0x91, 0x7a, 0x32, 0x8b, 0x99, 0xc0, 0x94, 0x37, 0xab, 0x2c, 0x63, 0xf1, + 0x3c, 0x41, 0x5e, 0x8e, 0x78, 0x8a, 0x57, 0xb3, 0x29, 0x28, 0xf3, 0x74, 0xb6, 0x9e, 0x8c, 0xbe, + 0xce, 0x41, 0xc5, 0x9d, 0x6a, 0x7d, 0x5f, 0xfc, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xde, 0x3d, 0xc2, + 0x16, 0x5c, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -268,6 +281,13 @@ func (m *MsgTransfer) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintTx(dAtA, i, uint64(len(m.Memo))) + i-- + dAtA[i] = 0x42 + } if m.TimeoutTimestamp != 0 { i = encodeVarintTx(dAtA, i, uint64(m.TimeoutTimestamp)) i-- @@ -344,6 +364,11 @@ func (m *MsgTransferResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Sequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -387,6 +412,10 @@ func (m *MsgTransfer) Size() (n int) { if m.TimeoutTimestamp != 0 { n += 1 + sovTx(uint64(m.TimeoutTimestamp)) } + l = len(m.Memo) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -396,6 +425,9 @@ func (m *MsgTransferResponse) Size() (n int) { } var l int _ = l + if m.Sequence != 0 { + n += 1 + sovTx(uint64(m.Sequence)) + } return n } @@ -647,6 +679,38 @@ func (m *MsgTransfer) Unmarshal(dAtA []byte) error { break } } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memo", 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.Memo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -697,6 +761,25 @@ func (m *MsgTransferResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: MsgTransferResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + m.Sequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/modules/apps/transfer/types/ack_test.go b/modules/apps/transfer/types/types_test.go similarity index 54% rename from modules/apps/transfer/types/ack_test.go rename to modules/apps/transfer/types/types_test.go index b0782dd96ba..86069b1a887 100644 --- a/modules/apps/transfer/types/ack_test.go +++ b/modules/apps/transfer/types/types_test.go @@ -5,7 +5,8 @@ import ( "github.com/stretchr/testify/suite" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type TypesTestSuite struct { @@ -24,6 +25,16 @@ func (suite *TypesTestSuite) SetupTest() { suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) } +func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { + path := ibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig.PortID = types.PortID + path.EndpointB.ChannelConfig.PortID = types.PortID + path.EndpointA.ChannelConfig.Version = types.Version + path.EndpointB.ChannelConfig.Version = types.Version + + return path +} + func TestTypesTestSuite(t *testing.T) { suite.Run(t, new(TypesTestSuite)) } diff --git a/modules/core/02-client/abci.go b/modules/core/02-client/abci.go index 87039aeee10..735834b2f65 100644 --- a/modules/core/02-client/abci.go +++ b/modules/core/02-client/abci.go @@ -3,12 +3,11 @@ package client import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/keeper" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ) -// BeginBlocker updates an existing localhost client with the latest block height. +// BeginBlocker is used to perform IBC client upgrades func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { plan, found := k.GetUpgradePlan(ctx) if found { @@ -20,23 +19,16 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { // within the trusting period of the last block time on this chain. _, exists := k.GetUpgradedClient(ctx, plan.Height) if exists && ctx.BlockHeight() == plan.Height-1 { - upgradedConsState := &ibctmtypes.ConsensusState{ + upgradedConsState := &ibctm.ConsensusState{ Timestamp: ctx.BlockTime(), NextValidatorsHash: ctx.BlockHeader().NextValidatorsHash, } bz := k.MustMarshalConsensusState(upgradedConsState) - k.SetUpgradedConsensusState(ctx, plan.Height, bz) - } - } + // SetUpgradedConsensusState always returns nil, hence the blank here. + _ = k.SetUpgradedConsensusState(ctx, plan.Height, bz) - _, found = k.GetClientState(ctx, exported.Localhost) - if !found { - return - } - - // update the localhost client with the latest block height - if err := k.UpdateClient(ctx, exported.Localhost, nil); err != nil { - panic(err) + keeper.EmitUpgradeChainEvent(ctx, plan.Height) + } } } diff --git a/modules/core/02-client/abci_test.go b/modules/core/02-client/abci_test.go index 27f8f7f4b12..c5dbf2c8a55 100644 --- a/modules/core/02-client/abci_test.go +++ b/modules/core/02-client/abci_test.go @@ -1,19 +1,19 @@ package client_test import ( + "strings" "testing" + sdk "github.com/cosmos/cosmos-sdk/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - client "github.com/cosmos/ibc-go/v4/modules/core/02-client" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - localhosttypes "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + client "github.com/cosmos/ibc-go/v7/modules/core/02-client" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type ClientTestSuite struct { @@ -30,13 +30,6 @@ func (suite *ClientTestSuite) SetupTest() { suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) - - // set localhost client - revision := types.ParseChainID(suite.chainA.GetContext().ChainID()) - localHostClient := localhosttypes.NewClientState( - suite.chainA.GetContext().ChainID(), types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())), - ) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), exported.Localhost, localHostClient) } func TestClientTestSuite(t *testing.T) { @@ -44,11 +37,6 @@ func TestClientTestSuite(t *testing.T) { } func (suite *ClientTestSuite) TestBeginBlocker() { - prevHeight := types.GetSelfHeight(suite.chainA.GetContext()) - - localHostClient := suite.chainA.GetClientState(exported.Localhost) - suite.Require().Equal(prevHeight, localHostClient.GetLatestHeight()) - for i := 0; i < 10; i++ { // increment height suite.coordinator.CommitBlock(suite.chainA, suite.chainB) @@ -56,10 +44,6 @@ func (suite *ClientTestSuite) TestBeginBlocker() { suite.Require().NotPanics(func() { client.BeginBlocker(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper) }, "BeginBlocker shouldn't panic") - - localHostClient = suite.chainA.GetClientState(exported.Localhost) - suite.Require().Equal(prevHeight.Increment(), localHostClient.GetLatestHeight()) - prevHeight = localHostClient.GetLatestHeight().(types.Height) } } @@ -88,7 +72,59 @@ func (suite *ClientTestSuite) TestBeginBlockerConsensusState() { // plan Height is at ctx.BlockHeight+1 consState, found := suite.chainA.GetSimApp().UpgradeKeeper.GetUpgradedConsensusState(newCtx, plan.Height) suite.Require().True(found) - bz, err = types.MarshalConsensusState(suite.chainA.App.AppCodec(), &ibctmtypes.ConsensusState{Timestamp: newCtx.BlockTime(), NextValidatorsHash: nextValsHash}) + bz, err = types.MarshalConsensusState(suite.chainA.App.AppCodec(), &ibctm.ConsensusState{Timestamp: newCtx.BlockTime(), NextValidatorsHash: nextValsHash}) suite.Require().NoError(err) suite.Require().Equal(bz, consState) } + +func (suite *ClientTestSuite) TestBeginBlockerUpgradeEvents() { + plan := &upgradetypes.Plan{ + Name: "test", + Height: suite.chainA.GetContext().BlockHeight() + 1, + } + // set upgrade plan in the upgrade store + store := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetKey(upgradetypes.StoreKey)) + bz := suite.chainA.App.AppCodec().MustMarshal(plan) + store.Set(upgradetypes.PlanKey(), bz) + + nextValsHash := []byte("nextValsHash") + newCtx := suite.chainA.GetContext().WithBlockHeader(tmproto.Header{ + Height: suite.chainA.GetContext().BlockHeight(), + NextValidatorsHash: nextValsHash, + }) + + err := suite.chainA.GetSimApp().UpgradeKeeper.SetUpgradedClient(newCtx, plan.Height, []byte("client state")) + suite.Require().NoError(err) + + cacheCtx, writeCache := suite.chainA.GetContext().CacheContext() + + client.BeginBlocker(cacheCtx, suite.chainA.App.GetIBCKeeper().ClientKeeper) + writeCache() + + suite.requireContainsEvent(cacheCtx.EventManager().Events(), types.EventTypeUpgradeChain, true) +} + +func (suite *ClientTestSuite) TestBeginBlockerUpgradeEventsAbsence() { + cacheCtx, writeCache := suite.chainA.GetContext().CacheContext() + client.BeginBlocker(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper) + writeCache() + suite.requireContainsEvent(cacheCtx.EventManager().Events(), types.EventTypeUpgradeChain, false) +} + +// requireContainsEvent verifies if an event of a specific type was emitted. +func (suite *ClientTestSuite) requireContainsEvent(events sdk.Events, eventType string, shouldContain bool) { + found := false + var eventTypes []string + for _, e := range events { + eventTypes = append(eventTypes, e.Type) + if e.Type == eventType { + found = true + break + } + } + if shouldContain { + suite.Require().True(found, "event type %s was not found in %s", eventType, strings.Join(eventTypes, ",")) + } else { + suite.Require().False(found, "event type %s was found in %s", eventType, strings.Join(eventTypes, ",")) + } +} diff --git a/modules/core/02-client/client/cli/cli.go b/modules/core/02-client/client/cli/cli.go index 74bb514ae1d..f1017e2df0f 100644 --- a/modules/core/02-client/client/cli/cli.go +++ b/modules/core/02-client/client/cli/cli.go @@ -4,7 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) // GetQueryCmd returns the query commands for IBC clients @@ -26,7 +26,7 @@ func GetQueryCmd() *cobra.Command { GetCmdQueryConsensusState(), GetCmdQueryHeader(), GetCmdSelfConsensusState(), - GetCmdParams(), + GetCmdClientParams(), ) return queryCmd @@ -45,7 +45,7 @@ func NewTxCmd() *cobra.Command { txCmd.AddCommand( NewCreateClientCmd(), NewUpdateClientCmd(), - NewSubmitMisbehaviourCmd(), + NewSubmitMisbehaviourCmd(), // Deprecated NewUpgradeClientCmd(), ) diff --git a/modules/core/02-client/client/cli/query.go b/modules/core/02-client/client/cli/query.go index 66e114902fe..337b142419c 100644 --- a/modules/core/02-client/client/cli/query.go +++ b/modules/core/02-client/client/cli/query.go @@ -9,9 +9,9 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/client/utils" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/client/utils" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) const ( @@ -25,7 +25,7 @@ func GetCmdQueryClientStates() *cobra.Command { Use: "states", Short: "Query all available light clients", Long: "Query all available light clients", - Example: fmt.Sprintf("%s query %s %s states", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s states", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -64,7 +64,7 @@ func GetCmdQueryClientState() *cobra.Command { Use: "state [client-id]", Short: "Query a client state", Long: "Query stored client state", - Example: fmt.Sprintf("%s query %s %s state [client-id]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s state [client-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -95,7 +95,7 @@ func GetCmdQueryClientStatus() *cobra.Command { Use: "status [client-id]", Short: "Query client status", Long: "Query client activity status. Any client without an 'Active' status is considered inactive", - Example: fmt.Sprintf("%s query %s %s status [client-id]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s status [client-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -119,6 +119,8 @@ func GetCmdQueryClientStatus() *cobra.Command { }, } + flags.AddQueryFlagsToCmd(cmd) + return cmd } @@ -129,7 +131,7 @@ func GetCmdQueryConsensusStates() *cobra.Command { Use: "consensus-states [client-id]", Short: "Query all the consensus states of a client.", Long: "Query all the consensus states from a given client state.", - Example: fmt.Sprintf("%s query %s %s consensus-states [client-id]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s consensus-states [client-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -171,7 +173,7 @@ func GetCmdQueryConsensusStateHeights() *cobra.Command { Use: "consensus-state-heights [client-id]", Short: "Query the heights of all consensus states of a client.", Long: "Query the heights of all consensus states associated with the provided client ID.", - Example: fmt.Sprintf("%s query %s %s consensus-state-heights [client-id]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s consensus-state-heights [client-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -215,7 +217,7 @@ func GetCmdQueryConsensusState() *cobra.Command { Short: "Query the consensus state of a client at a given height", Long: `Query the consensus state for a particular light client at a given height. If the '--latest' flag is included, the query returns the latest consensus state, overriding the height argument.`, - Example: fmt.Sprintf("%s query %s %s consensus-state [client-id] [height]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s consensus-state [client-id] [height]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.RangeArgs(1, 2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -261,7 +263,7 @@ func GetCmdQueryHeader() *cobra.Command { Use: "header", Short: "Query the latest header of the running chain", Long: "Query the latest Tendermint header of the running chain", - Example: fmt.Sprintf("%s query %s %s header", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s header", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -288,7 +290,7 @@ func GetCmdSelfConsensusState() *cobra.Command { Use: "self-consensus-state", Short: "Query the self consensus state for this chain", Long: "Query the self consensus state for this chain. This result may be used for verifying IBC clients representing this chain which are hosted on counterparty chains.", - Example: fmt.Sprintf("%s query %s %s self-consensus-state", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s self-consensus-state", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -309,14 +311,14 @@ func GetCmdSelfConsensusState() *cobra.Command { return cmd } -// GetCmdParams returns the command handler for ibc client parameter querying. -func GetCmdParams() *cobra.Command { +// GetCmdClientParams returns the command handler for ibc client parameter querying. +func GetCmdClientParams() *cobra.Command { cmd := &cobra.Command{ Use: "params", Short: "Query the current ibc client parameters", Long: "Query the current ibc client parameters", Args: cobra.NoArgs, - Example: fmt.Sprintf("%s query %s %s params", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s params", version.AppName, ibcexported.ModuleName, types.SubModuleName), RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { diff --git a/modules/core/02-client/client/cli/tx.go b/modules/core/02-client/client/cli/tx.go index fdf9b8e5b89..14401a659fc 100644 --- a/modules/core/02-client/client/cli/tx.go +++ b/modules/core/02-client/client/cli/tx.go @@ -2,7 +2,7 @@ package cli import ( "fmt" - "io/ioutil" + "os" "strconv" "github.com/cosmos/cosmos-sdk/client" @@ -12,12 +12,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // NewCreateClientCmd defines the command to create a new IBC light client. @@ -43,7 +43,7 @@ func NewCreateClientCmd() *cobra.Command { if err := cdc.UnmarshalInterfaceJSON([]byte(clientContentOrFileName), &clientState); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(clientContentOrFileName) + contents, err := os.ReadFile(clientContentOrFileName) if err != nil { return fmt.Errorf("neither JSON input nor path to .json file for client state were provided: %w", err) } @@ -59,7 +59,7 @@ func NewCreateClientCmd() *cobra.Command { if err := cdc.UnmarshalInterfaceJSON([]byte(consensusContentOrFileName), &consensusState); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(consensusContentOrFileName) + contents, err := os.ReadFile(consensusContentOrFileName) if err != nil { return fmt.Errorf("neither JSON input nor path to .json file for consensus state were provided: %w", err) } @@ -79,17 +79,16 @@ func NewCreateClientCmd() *cobra.Command { } flags.AddTxFlagsToCmd(cmd) - return cmd } // NewUpdateClientCmd defines the command to update an IBC client. func NewUpdateClientCmd() *cobra.Command { - return &cobra.Command{ - Use: "update [client-id] [path/to/header.json]", - Short: "update existing client with a header", - Long: "update existing client with a header", - Example: fmt.Sprintf("%s tx ibc %s update [client-id] [path/to/header.json] --from node0 --home ../node0/cli --chain-id $CID", version.AppName, types.SubModuleName), + cmd := &cobra.Command{ + Use: "update [client-id] [path/to/client_msg.json]", + Short: "update existing client with a client message", + Long: "update existing client with a client message, for example a header, misbehaviour or batch update", + Example: fmt.Sprintf("%s tx ibc %s update [client-id] [path/to/client_msg.json] --from node0 --home ../node0/cli --chain-id $CID", version.AppName, types.SubModuleName), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) @@ -100,22 +99,22 @@ func NewUpdateClientCmd() *cobra.Command { cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) - var header exported.Header - headerContentOrFileName := args[1] - if err := cdc.UnmarshalInterfaceJSON([]byte(headerContentOrFileName), &header); err != nil { + var clientMsg exported.ClientMessage + clientMsgContentOrFileName := args[1] + if err := cdc.UnmarshalInterfaceJSON([]byte(clientMsgContentOrFileName), &clientMsg); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(headerContentOrFileName) + contents, err := os.ReadFile(clientMsgContentOrFileName) if err != nil { return fmt.Errorf("neither JSON input nor path to .json file for header were provided: %w", err) } - if err := cdc.UnmarshalInterfaceJSON(contents, &header); err != nil { + if err := cdc.UnmarshalInterfaceJSON(contents, &clientMsg); err != nil { return fmt.Errorf("error unmarshalling header file: %w", err) } } - msg, err := types.NewMsgUpdateClient(clientID, header, clientCtx.GetFromAddress().String()) + msg, err := types.NewMsgUpdateClient(clientID, clientMsg, clientCtx.GetFromAddress().String()) if err != nil { return err } @@ -123,17 +122,22 @@ func NewUpdateClientCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, } + + flags.AddTxFlagsToCmd(cmd) + return cmd } // NewSubmitMisbehaviourCmd defines the command to submit a misbehaviour to prevent // future updates. +// Deprecated: NewSubmitMisbehaviourCmd is deprecated and will be removed in a future release. +// Please use NewUpdateClientCmd instead. func NewSubmitMisbehaviourCmd() *cobra.Command { - return &cobra.Command{ - Use: "misbehaviour [path/to/misbehaviour.json]", + cmd := &cobra.Command{ + Use: "misbehaviour [clientID] [path/to/misbehaviour.json]", Short: "submit a client misbehaviour", Long: "submit a client misbehaviour to prevent future updates", - Example: fmt.Sprintf("%s tx ibc %s misbehaviour [path/to/misbehaviour.json] --from node0 --home ../node0/cli --chain-id $CID", version.AppName, types.SubModuleName), - Args: cobra.ExactArgs(1), + Example: fmt.Sprintf("%s tx ibc %s misbehaviour [clientID] [path/to/misbehaviour.json] --from node0 --home ../node0/cli --chain-id $CID", version.AppName, types.SubModuleName), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) if err != nil { @@ -141,12 +145,13 @@ func NewSubmitMisbehaviourCmd() *cobra.Command { } cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) - var misbehaviour exported.Misbehaviour - misbehaviourContentOrFileName := args[0] + var misbehaviour exported.ClientMessage + clientID := args[0] + misbehaviourContentOrFileName := args[1] if err := cdc.UnmarshalInterfaceJSON([]byte(misbehaviourContentOrFileName), &misbehaviour); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(misbehaviourContentOrFileName) + contents, err := os.ReadFile(misbehaviourContentOrFileName) if err != nil { return fmt.Errorf("neither JSON input nor path to .json file for misbehaviour were provided: %w", err) } @@ -156,7 +161,7 @@ func NewSubmitMisbehaviourCmd() *cobra.Command { } } - msg, err := types.NewMsgSubmitMisbehaviour(misbehaviour.GetClientID(), misbehaviour, clientCtx.GetFromAddress().String()) + msg, err := types.NewMsgSubmitMisbehaviour(clientID, misbehaviour, clientCtx.GetFromAddress().String()) if err != nil { return err } @@ -164,6 +169,9 @@ func NewSubmitMisbehaviourCmd() *cobra.Command { return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) }, } + + flags.AddTxFlagsToCmd(cmd) + return cmd } // NewUpgradeClientCmd defines the command to upgrade an IBC light client. @@ -190,7 +198,7 @@ func NewUpgradeClientCmd() *cobra.Command { if err := cdc.UnmarshalInterfaceJSON([]byte(clientContentOrFileName), &clientState); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(clientContentOrFileName) + contents, err := os.ReadFile(clientContentOrFileName) if err != nil { return fmt.Errorf("neither JSON input nor path to .json file for client state were provided: %w", err) } @@ -206,7 +214,7 @@ func NewUpgradeClientCmd() *cobra.Command { if err := cdc.UnmarshalInterfaceJSON([]byte(consensusContentOrFileName), &consensusState); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(consensusContentOrFileName) + contents, err := os.ReadFile(consensusContentOrFileName) if err != nil { return fmt.Errorf("neither JSON input nor path to .json file for consensus state were provided: %w", err) } @@ -229,7 +237,6 @@ func NewUpgradeClientCmd() *cobra.Command { } flags.AddTxFlagsToCmd(cmd) - return cmd } @@ -248,12 +255,12 @@ func NewCmdSubmitUpdateClientProposal() *cobra.Command { return err } - title, err := cmd.Flags().GetString(govcli.FlagTitle) + title, err := cmd.Flags().GetString(govcli.FlagTitle) //nolint:staticcheck // need this till full govv1 conversion. if err != nil { return err } - description, err := cmd.Flags().GetString(govcli.FlagDescription) + description, err := cmd.Flags().GetString(govcli.FlagDescription) //nolint:staticcheck // need this till full govv1 conversion. if err != nil { return err } @@ -287,8 +294,8 @@ func NewCmdSubmitUpdateClientProposal() *cobra.Command { }, } - cmd.Flags().String(govcli.FlagTitle, "", "title of proposal") - cmd.Flags().String(govcli.FlagDescription, "", "description of proposal") + cmd.Flags().String(govcli.FlagTitle, "", "title of proposal") //nolint:staticcheck // need this till full govv1 conversion. + cmd.Flags().String(govcli.FlagDescription, "", "description of proposal") //nolint:staticcheck // need this till full govv1 conversion. cmd.Flags().String(govcli.FlagDeposit, "", "deposit of proposal") return cmd @@ -319,12 +326,12 @@ func NewCmdSubmitUpgradeProposal() *cobra.Command { } cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) - title, err := cmd.Flags().GetString(govcli.FlagTitle) + title, err := cmd.Flags().GetString(govcli.FlagTitle) //nolint:staticcheck // need this till full govv1 conversion. if err != nil { return err } - description, err := cmd.Flags().GetString(govcli.FlagDescription) + description, err := cmd.Flags().GetString(govcli.FlagDescription) //nolint:staticcheck // need this till full govv1 conversion. if err != nil { return err } @@ -347,7 +354,7 @@ func NewCmdSubmitUpgradeProposal() *cobra.Command { if err := cdc.UnmarshalInterfaceJSON([]byte(clientContentOrFileName), &clientState); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(clientContentOrFileName) + contents, err := os.ReadFile(clientContentOrFileName) if err != nil { return fmt.Errorf("neither JSON input nor path to .json file for client state were provided: %w", err) } @@ -386,8 +393,8 @@ func NewCmdSubmitUpgradeProposal() *cobra.Command { }, } - cmd.Flags().String(govcli.FlagTitle, "", "title of proposal") - cmd.Flags().String(govcli.FlagDescription, "", "description of proposal") + cmd.Flags().String(govcli.FlagTitle, "", "title of proposal") //nolint:staticcheck // need this till full govv1 conversion. + cmd.Flags().String(govcli.FlagDescription, "", "description of proposal") //nolint:staticcheck // need this till full govv1 conversion. cmd.Flags().String(govcli.FlagDeposit, "", "deposit of proposal") return cmd diff --git a/modules/core/02-client/client/proposal_handler.go b/modules/core/02-client/client/proposal_handler.go index 2c5aa8911d1..9a540f4da3b 100644 --- a/modules/core/02-client/client/proposal_handler.go +++ b/modules/core/02-client/client/proposal_handler.go @@ -1,26 +1,12 @@ package client import ( - "net/http" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/types/rest" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" - govrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/client/cli" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/client/cli" ) var ( - UpdateClientProposalHandler = govclient.NewProposalHandler(cli.NewCmdSubmitUpdateClientProposal, emptyRestHandler) - UpgradeProposalHandler = govclient.NewProposalHandler(cli.NewCmdSubmitUpgradeProposal, emptyRestHandler) + UpdateClientProposalHandler = govclient.NewProposalHandler(cli.NewCmdSubmitUpdateClientProposal) + UpgradeProposalHandler = govclient.NewProposalHandler(cli.NewCmdSubmitUpgradeProposal) ) - -func emptyRestHandler(client.Context) govrest.ProposalRESTHandler { - return govrest.ProposalRESTHandler{ - SubRoute: "unsupported-ibc-client", - Handler: func(w http.ResponseWriter, r *http.Request) { - rest.WriteErrorResponse(w, http.StatusBadRequest, "Legacy REST Routes are not supported for IBC proposals") - }, - } -} diff --git a/modules/core/02-client/client/utils/utils.go b/modules/core/02-client/client/utils/utils.go index d4361098085..9dd2675087a 100644 --- a/modules/core/02-client/client/utils/utils.go +++ b/modules/core/02-client/client/utils/utils.go @@ -3,17 +3,17 @@ package utils import ( "context" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/client" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/client" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ) // QueryClientState returns a client state. If prove is true, it performs an ABCI store query @@ -46,7 +46,7 @@ func QueryClientStateABCI( // check if client exists if len(value) == 0 { - return nil, sdkerrors.Wrap(types.ErrClientNotFound, clientID) + return nil, errorsmod.Wrap(types.ErrClientNotFound, clientID) } cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) @@ -99,7 +99,7 @@ func QueryConsensusStateABCI( // check if consensus state exists if len(value) == 0 { - return nil, sdkerrors.Wrap(types.ErrConsensusStateNotFound, clientID) + return nil, errorsmod.Wrap(types.ErrConsensusStateNotFound, clientID) } cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) @@ -119,15 +119,15 @@ func QueryConsensusStateABCI( // QueryTendermintHeader takes a client context and returns the appropriate // tendermint header -func QueryTendermintHeader(clientCtx client.Context) (ibctmtypes.Header, int64, error) { +func QueryTendermintHeader(clientCtx client.Context) (ibctm.Header, int64, error) { node, err := clientCtx.GetNode() if err != nil { - return ibctmtypes.Header{}, 0, err + return ibctm.Header{}, 0, err } info, err := node.ABCIInfo(context.Background()) if err != nil { - return ibctmtypes.Header{}, 0, err + return ibctm.Header{}, 0, err } var height int64 @@ -139,7 +139,7 @@ func QueryTendermintHeader(clientCtx client.Context) (ibctmtypes.Header, int64, commit, err := node.Commit(context.Background(), &height) if err != nil { - return ibctmtypes.Header{}, 0, err + return ibctm.Header{}, 0, err } page := 1 @@ -147,16 +147,16 @@ func QueryTendermintHeader(clientCtx client.Context) (ibctmtypes.Header, int64, validators, err := node.Validators(context.Background(), &height, &page, &count) if err != nil { - return ibctmtypes.Header{}, 0, err + return ibctm.Header{}, 0, err } protoCommit := commit.SignedHeader.ToProto() protoValset, err := tmtypes.NewValidatorSet(validators.Validators).ToProto() if err != nil { - return ibctmtypes.Header{}, 0, err + return ibctm.Header{}, 0, err } - header := ibctmtypes.Header{ + header := ibctm.Header{ SignedHeader: protoCommit, ValidatorSet: protoValset, } @@ -166,15 +166,15 @@ func QueryTendermintHeader(clientCtx client.Context) (ibctmtypes.Header, int64, // QuerySelfConsensusState takes a client context and returns the appropriate // tendermint consensus state -func QuerySelfConsensusState(clientCtx client.Context) (*ibctmtypes.ConsensusState, int64, error) { +func QuerySelfConsensusState(clientCtx client.Context) (*ibctm.ConsensusState, int64, error) { node, err := clientCtx.GetNode() if err != nil { - return &ibctmtypes.ConsensusState{}, 0, err + return &ibctm.ConsensusState{}, 0, err } info, err := node.ABCIInfo(context.Background()) if err != nil { - return &ibctmtypes.ConsensusState{}, 0, err + return &ibctm.ConsensusState{}, 0, err } var height int64 @@ -186,7 +186,7 @@ func QuerySelfConsensusState(clientCtx client.Context) (*ibctmtypes.ConsensusSta commit, err := node.Commit(context.Background(), &height) if err != nil { - return &ibctmtypes.ConsensusState{}, 0, err + return &ibctm.ConsensusState{}, 0, err } page := 1 @@ -195,10 +195,10 @@ func QuerySelfConsensusState(clientCtx client.Context) (*ibctmtypes.ConsensusSta nextHeight := height + 1 nextVals, err := node.Validators(context.Background(), &nextHeight, &page, &count) if err != nil { - return &ibctmtypes.ConsensusState{}, 0, err + return &ibctm.ConsensusState{}, 0, err } - state := &ibctmtypes.ConsensusState{ + state := &ibctm.ConsensusState{ Timestamp: commit.Time, Root: commitmenttypes.NewMerkleRoot(commit.AppHash), NextValidatorsHash: tmtypes.NewValidatorSet(nextVals.Validators).Hash(), diff --git a/modules/core/02-client/doc.go b/modules/core/02-client/doc.go index abb7f35fff3..34fcb5d432d 100644 --- a/modules/core/02-client/doc.go +++ b/modules/core/02-client/doc.go @@ -1,10 +1,7 @@ /* Package client implements the ICS 02 - Client Semantics specification -https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics. This -concrete implementations defines types and method to store and update light +(https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics). This +concrete implementation defines types and methods to store and update light clients which tracks on other chain's state. - -The main type is `Client`, which provides `commitment.Root` to verify state proofs and `ConsensusState` to -verify header proofs. */ package client diff --git a/modules/core/02-client/genesis.go b/modules/core/02-client/genesis.go index 8d4654d6438..aae41d9ae5a 100644 --- a/modules/core/02-client/genesis.go +++ b/modules/core/02-client/genesis.go @@ -5,9 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/keeper" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // InitGenesis initializes the ibc client submodule's state from a provided genesis @@ -46,14 +46,9 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { } k.SetNextClientSequence(ctx, gs.NextClientSequence) - - // NOTE: localhost creation is specifically disallowed for the time being. - // Issue: https://github.com/cosmos/cosmos-sdk/issues/7871 } // ExportGenesis returns the ibc client submodule's exported genesis. -// NOTE: CreateLocalhost should always be false on export since a -// created localhost will be included in the exported clients. func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { genClients := k.GetAllGenesisClients(ctx) clientsMetadata, err := k.GetAllClientMetadata(ctx, genClients) @@ -61,10 +56,11 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { panic(err) } return types.GenesisState{ - Clients: genClients, - ClientsMetadata: clientsMetadata, - ClientsConsensus: k.GetAllConsensusStates(ctx), - Params: k.GetParams(ctx), + Clients: genClients, + ClientsMetadata: clientsMetadata, + ClientsConsensus: k.GetAllConsensusStates(ctx), + Params: k.GetParams(ctx), + // Warning: CreateLocalhost is deprecated CreateLocalhost: false, NextClientSequence: k.GetNextClientSequence(ctx), } diff --git a/modules/core/02-client/keeper/client.go b/modules/core/02-client/keeper/client.go index 4b770dafe19..8cb5a02b2d2 100644 --- a/modules/core/02-client/keeper/client.go +++ b/modules/core/02-client/keeper/client.go @@ -1,145 +1,104 @@ package keeper import ( - "encoding/hex" - - "github.com/armon/go-metrics" + errorsmod "cosmossdk.io/errors" + metrics "github.com/armon/go-metrics" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) -// CreateClient creates a new client state and populates it with a given consensus -// state as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics#create +// CreateClient generates a new client identifier and isolated prefix store for the provided client state. +// The client state is responsible for setting any client-specific data in the store via the Initialize method. +// This includes the client state, initial consensus state and any associated metadata. func (k Keeper) CreateClient( ctx sdk.Context, clientState exported.ClientState, consensusState exported.ConsensusState, ) (string, error) { params := k.GetParams(ctx) if !params.IsAllowedClient(clientState.ClientType()) { - return "", sdkerrors.Wrapf( + return "", errorsmod.Wrapf( types.ErrInvalidClientType, "client state type %s is not registered in the allowlist", clientState.ClientType(), ) } clientID := k.GenerateClientIdentifier(ctx, clientState.ClientType()) + clientStore := k.ClientStore(ctx, clientID) - k.SetClientState(ctx, clientID, clientState) - k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String()) - - // verifies initial consensus state against client state and initializes client store with any client-specific metadata - // e.g. set ProcessedTime in Tendermint clients - if err := clientState.Initialize(ctx, k.cdc, k.ClientStore(ctx, clientID), consensusState); err != nil { + if err := clientState.Initialize(ctx, k.cdc, clientStore, consensusState); err != nil { return "", err } - // check if consensus state is nil in case the created client is Localhost - if consensusState != nil { - k.SetClientConsensusState(ctx, clientID, clientState.GetLatestHeight(), consensusState) - } - k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String()) - defer func() { - telemetry.IncrCounterWithLabels( - []string{"ibc", "client", "create"}, - 1, - []metrics.Label{telemetry.NewLabel(types.LabelClientType, clientState.ClientType())}, - ) - }() + defer telemetry.IncrCounterWithLabels( + []string{"ibc", "client", "create"}, + 1, + []metrics.Label{telemetry.NewLabel(types.LabelClientType, clientState.ClientType())}, + ) - EmitCreateClientEvent(ctx, clientID, clientState) + emitCreateClientEvent(ctx, clientID, clientState) return clientID, nil } // UpdateClient updates the consensus state and the state root from a provided header. -func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, clientMsg exported.ClientMessage) error { clientState, found := k.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID) + return errorsmod.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID) } clientStore := k.ClientStore(ctx, clientID) if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(types.ErrClientNotActive, "cannot update client (%s) with status %s", clientID, status) + return errorsmod.Wrapf(types.ErrClientNotActive, "cannot update client (%s) with status %s", clientID, status) } - // Any writes made in CheckHeaderAndUpdateState are persisted on both valid updates and misbehaviour updates. - // Light client implementations are responsible for writing the correct metadata (if any) in either case. - newClientState, newConsensusState, err := clientState.CheckHeaderAndUpdateState(ctx, k.cdc, clientStore, header) - if err != nil { - return sdkerrors.Wrapf(err, "cannot update client with ID %s", clientID) + if err := clientState.VerifyClientMessage(ctx, k.cdc, clientStore, clientMsg); err != nil { + return err } - // emit the full header in events - var ( - headerStr string - consensusHeight exported.Height - ) - if header != nil { - // Marshal the Header as an Any and encode the resulting bytes to hex. - // This prevents the event value from containing invalid UTF-8 characters - // which may cause data to be lost when JSON encoding/decoding. - headerStr = hex.EncodeToString(types.MustMarshalHeader(k.cdc, header)) - // set default consensus height with header height - consensusHeight = header.GetHeight() + foundMisbehaviour := clientState.CheckForMisbehaviour(ctx, k.cdc, clientStore, clientMsg) + if foundMisbehaviour { + clientState.UpdateStateOnMisbehaviour(ctx, k.cdc, clientStore, clientMsg) - } + k.Logger(ctx).Info("client frozen due to misbehaviour", "client-id", clientID) - // set new client state regardless of if update is valid update or misbehaviour - k.SetClientState(ctx, clientID, newClientState) - // If client state is not frozen after clientState CheckHeaderAndUpdateState, - // then update was valid. Write the update state changes, and set new consensus state. - // Else the update was proof of misbehaviour and we must emit appropriate misbehaviour events. - if status := newClientState.Status(ctx, clientStore, k.cdc); status != exported.Frozen { - // if update is not misbehaviour then update the consensus state - // we don't set consensus state for localhost client - if header != nil && clientID != exported.Localhost { - k.SetClientConsensusState(ctx, clientID, header.GetHeight(), newConsensusState) - } else { - consensusHeight = types.GetSelfHeight(ctx) - } - - k.Logger(ctx).Info("client state updated", "client-id", clientID, "height", consensusHeight.String()) - - defer func() { - telemetry.IncrCounterWithLabels( - []string{"ibc", "client", "update"}, - 1, - []metrics.Label{ - telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), - telemetry.NewLabel(types.LabelClientID, clientID), - telemetry.NewLabel(types.LabelUpdateType, "msg"), - }, - ) - }() - - // emitting events in the keeper emits for both begin block and handler client updates - EmitUpdateClientEvent(ctx, clientID, newClientState, consensusHeight, headerStr) - } else { + defer telemetry.IncrCounterWithLabels( + []string{"ibc", "client", "misbehaviour"}, + 1, + []metrics.Label{ + telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), + telemetry.NewLabel(types.LabelClientID, clientID), + telemetry.NewLabel(types.LabelMsgType, "update"), + }, + ) - k.Logger(ctx).Info("client frozen due to misbehaviour", "client-id", clientID) + emitSubmitMisbehaviourEvent(ctx, clientID, clientState) - defer func() { - telemetry.IncrCounterWithLabels( - []string{"ibc", "client", "misbehaviour"}, - 1, - []metrics.Label{ - telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), - telemetry.NewLabel(types.LabelClientID, clientID), - telemetry.NewLabel(types.LabelMsgType, "update"), - }, - ) - }() - - EmitSubmitMisbehaviourEventOnUpdate(ctx, clientID, newClientState, consensusHeight, headerStr) + return nil } + consensusHeights := clientState.UpdateState(ctx, k.cdc, clientStore, clientMsg) + + k.Logger(ctx).Info("client state updated", "client-id", clientID, "heights", consensusHeights) + + defer telemetry.IncrCounterWithLabels( + []string{"ibc", "client", "update"}, + 1, + []metrics.Label{ + telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), + telemetry.NewLabel(types.LabelClientID, clientID), + telemetry.NewLabel(types.LabelUpdateType, "msg"), + }, + ) + + // emitting events in the keeper emits for both begin block and handler client updates + emitUpdateClientEvent(ctx, clientID, clientState.ClientType(), consensusHeights, k.cdc, clientMsg) + return nil } @@ -150,81 +109,33 @@ func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient e ) error { clientState, found := k.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID) + return errorsmod.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID) } clientStore := k.ClientStore(ctx, clientID) if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(types.ErrClientNotActive, "cannot upgrade client (%s) with status %s", clientID, status) - } - - updatedClientState, updatedConsState, err := clientState.VerifyUpgradeAndUpdateState(ctx, k.cdc, clientStore, - upgradedClient, upgradedConsState, proofUpgradeClient, proofUpgradeConsState) - if err != nil { - return sdkerrors.Wrapf(err, "cannot upgrade client with ID %s", clientID) - } - - k.SetClientState(ctx, clientID, updatedClientState) - k.SetClientConsensusState(ctx, clientID, updatedClientState.GetLatestHeight(), updatedConsState) - - k.Logger(ctx).Info("client state upgraded", "client-id", clientID, "height", updatedClientState.GetLatestHeight().String()) - - defer func() { - telemetry.IncrCounterWithLabels( - []string{"ibc", "client", "upgrade"}, - 1, - []metrics.Label{ - telemetry.NewLabel(types.LabelClientType, updatedClientState.ClientType()), - telemetry.NewLabel(types.LabelClientID, clientID), - }, - ) - }() - - // emitting events in the keeper emits for client upgrades - EmitUpgradeClientEvent(ctx, clientID, updatedClientState) - - return nil -} - -// CheckMisbehaviourAndUpdateState checks for client misbehaviour and freezes the -// client if so. -func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, misbehaviour exported.Misbehaviour) error { - clientState, found := k.GetClientState(ctx, misbehaviour.GetClientID()) - if !found { - return sdkerrors.Wrapf(types.ErrClientNotFound, "cannot check misbehaviour for client with ID %s", misbehaviour.GetClientID()) - } - - clientStore := k.ClientStore(ctx, misbehaviour.GetClientID()) - - if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(types.ErrClientNotActive, "cannot process misbehaviour for client (%s) with status %s", misbehaviour.GetClientID(), status) - } - - if err := misbehaviour.ValidateBasic(); err != nil { - return err + return errorsmod.Wrapf(types.ErrClientNotActive, "cannot upgrade client (%s) with status %s", clientID, status) } - clientState, err := clientState.CheckMisbehaviourAndUpdateState(ctx, k.cdc, clientStore, misbehaviour) - if err != nil { - return err + if err := clientState.VerifyUpgradeAndUpdateState(ctx, k.cdc, clientStore, + upgradedClient, upgradedConsState, proofUpgradeClient, proofUpgradeConsState, + ); err != nil { + return errorsmod.Wrapf(err, "cannot upgrade client with ID %s", clientID) } - k.SetClientState(ctx, misbehaviour.GetClientID(), clientState) - k.Logger(ctx).Info("client frozen due to misbehaviour", "client-id", misbehaviour.GetClientID()) + k.Logger(ctx).Info("client state upgraded", "client-id", clientID, "height", upgradedClient.GetLatestHeight().String()) - defer func() { - telemetry.IncrCounterWithLabels( - []string{"ibc", "client", "misbehaviour"}, - 1, - []metrics.Label{ - telemetry.NewLabel(types.LabelClientType, misbehaviour.ClientType()), - telemetry.NewLabel(types.LabelClientID, misbehaviour.GetClientID()), - }, - ) - }() + defer telemetry.IncrCounterWithLabels( + []string{"ibc", "client", "upgrade"}, + 1, + []metrics.Label{ + telemetry.NewLabel(types.LabelClientType, upgradedClient.ClientType()), + telemetry.NewLabel(types.LabelClientID, clientID), + }, + ) - EmitSubmitMisbehaviourEvent(ctx, misbehaviour.GetClientID(), clientState) + emitUpgradeClientEvent(ctx, clientID, upgradedClient) return nil } diff --git a/modules/core/02-client/keeper/client_test.go b/modules/core/02-client/keeper/client_test.go index d3492e9f25e..94b5fed855a 100644 --- a/modules/core/02-client/keeper/client_test.go +++ b/modules/core/02-client/keeper/client_test.go @@ -6,16 +6,14 @@ import ( "time" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - tmtypes "github.com/tendermint/tendermint/types" - - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - localhosttypes "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibctestingmock "github.com/cosmos/ibc-go/v4/testing/mock" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestCreateClient() { @@ -24,8 +22,8 @@ func (suite *KeeperTestSuite) TestCreateClient() { clientState exported.ClientState expPass bool }{ - {"success", ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), true}, - {"client type not supported", localhosttypes.NewClientState(testChainID, clienttypes.NewHeight(0, 1)), false}, + {"success", ibctm.NewClientState(testChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), true}, + {"client type not supported", solomachine.NewClientState(0, &solomachine.ConsensusState{PublicKey: suite.solomachine.ConsensusState().PublicKey, Diversifier: suite.solomachine.Diversifier, Timestamp: suite.solomachine.Time}), false}, } for i, tc := range cases { @@ -34,9 +32,11 @@ func (suite *KeeperTestSuite) TestCreateClient() { if tc.expPass { suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.msg) suite.Require().NotNil(clientID, "valid test case %d failed: %s", i, tc.msg) + suite.Require().True(suite.keeper.ClientStore(suite.ctx, clientID).Has(host.ClientStateKey())) } else { suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.msg) suite.Require().Equal("", clientID, "invalid test case %d passed: %s", i, tc.msg) + suite.Require().False(suite.keeper.ClientStore(suite.ctx, clientID).Has(host.ClientStateKey())) } } } @@ -44,20 +44,20 @@ func (suite *KeeperTestSuite) TestCreateClient() { func (suite *KeeperTestSuite) TestUpdateClientTendermint() { var ( path *ibctesting.Path - updateHeader *ibctmtypes.Header + updateHeader *ibctm.Header ) // Must create header creation functions since suite.header gets recreated on each test case - createFutureUpdateFn := func(trustedHeight clienttypes.Height) *ibctmtypes.Header { + createFutureUpdateFn := func(trustedHeight clienttypes.Height) *ibctm.Header { header, err := suite.chainA.ConstructUpdateTMClientHeaderWithTrustedHeight(path.EndpointB.Chain, path.EndpointA.ClientID, trustedHeight) suite.Require().NoError(err) return header } - createPastUpdateFn := func(fillHeight, trustedHeight clienttypes.Height) *ibctmtypes.Header { + createPastUpdateFn := func(fillHeight, trustedHeight clienttypes.Height) *ibctm.Header { consState, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, trustedHeight) suite.Require().True(found) - return suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(fillHeight.RevisionHeight), trustedHeight, consState.(*ibctmtypes.ConsensusState).Timestamp.Add(time.Second*5), + return suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(fillHeight.RevisionHeight), trustedHeight, consState.(*ibctm.ConsensusState).Timestamp.Add(time.Second*5), suite.chainB.Vals, suite.chainB.Vals, suite.chainB.Vals, suite.chainB.Signers) } @@ -68,26 +68,28 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { expFreeze bool }{ {"valid update", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) - trustHeight := clientState.GetLatestHeight().(types.Height) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) + trustHeight := clientState.GetLatestHeight().(clienttypes.Height) // store intermediate consensus state to check that trustedHeight does not need to be highest consensus state before header height - path.EndpointA.UpdateClient() + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) updateHeader = createFutureUpdateFn(trustHeight) }, true, false}, {"valid past update", func() { clientState := path.EndpointA.GetClientState() - trustedHeight := clientState.GetLatestHeight().(types.Height) + trustedHeight := clientState.GetLatestHeight().(clienttypes.Height) currHeight := suite.chainB.CurrentHeader.Height - fillHeight := types.NewHeight(clientState.GetLatestHeight().GetRevisionNumber(), uint64(currHeight)) + fillHeight := clienttypes.NewHeight(clientState.GetLatestHeight().GetRevisionNumber(), uint64(currHeight)) // commit a couple blocks to allow client to fill in gaps suite.coordinator.CommitBlock(suite.chainB) // this height is not filled in yet suite.coordinator.CommitBlock(suite.chainB) // this height is filled in by the update below - path.EndpointA.UpdateClient() + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) // ensure fill height not set _, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, fillHeight) @@ -100,24 +102,24 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { {"valid duplicate update", func() { clientID := path.EndpointA.ClientID - height1 := types.NewHeight(0, 1) + height1 := clienttypes.NewHeight(1, 1) // store previous consensus state - prevConsState := &ibctmtypes.ConsensusState{ + prevConsState := &ibctm.ConsensusState{ Timestamp: suite.past, NextValidatorsHash: suite.chainB.Vals.Hash(), } suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), clientID, height1, prevConsState) - height5 := types.NewHeight(0, 5) + height5 := clienttypes.NewHeight(1, 5) // store next consensus state to check that trustedHeight does not need to be hightest consensus state before header height - nextConsState := &ibctmtypes.ConsensusState{ + nextConsState := &ibctm.ConsensusState{ Timestamp: suite.past.Add(time.Minute), NextValidatorsHash: suite.chainB.Vals.Hash(), } suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), clientID, height5, nextConsState) - height3 := types.NewHeight(0, 3) + height3 := clienttypes.NewHeight(1, 3) // updateHeader will fill in consensus state between prevConsState and suite.consState // clientState should not be updated updateHeader = createPastUpdateFn(height3, height1) @@ -127,23 +129,23 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { {"misbehaviour detection: conflicting header", func() { clientID := path.EndpointA.ClientID - height1 := types.NewHeight(0, 1) + height1 := clienttypes.NewHeight(1, 1) // store previous consensus state - prevConsState := &ibctmtypes.ConsensusState{ + prevConsState := &ibctm.ConsensusState{ Timestamp: suite.past, NextValidatorsHash: suite.chainB.Vals.Hash(), } suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), clientID, height1, prevConsState) - height5 := types.NewHeight(0, 5) + height5 := clienttypes.NewHeight(1, 5) // store next consensus state to check that trustedHeight does not need to be hightest consensus state before header height - nextConsState := &ibctmtypes.ConsensusState{ + nextConsState := &ibctm.ConsensusState{ Timestamp: suite.past.Add(time.Minute), NextValidatorsHash: suite.chainB.Vals.Hash(), } suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), clientID, height5, nextConsState) - height3 := types.NewHeight(0, 3) + height3 := clienttypes.NewHeight(1, 3) // updateHeader will fill in consensus state between prevConsState and suite.consState // clientState should not be updated updateHeader = createPastUpdateFn(height3, height1) @@ -153,21 +155,21 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), clientID, updateHeader.GetHeight(), conflictConsState) }, true, true}, {"misbehaviour detection: monotonic time violation", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientID := path.EndpointA.ClientID - trustedHeight := clientState.GetLatestHeight().(types.Height) + trustedHeight := clientState.GetLatestHeight().(clienttypes.Height) // store intermediate consensus state at a time greater than updateHeader time // this will break time monotonicity - incrementedClientHeight := clientState.GetLatestHeight().Increment().(types.Height) - intermediateConsState := &ibctmtypes.ConsensusState{ + incrementedClientHeight := clientState.GetLatestHeight().Increment().(clienttypes.Height) + intermediateConsState := &ibctm.ConsensusState{ Timestamp: suite.coordinator.CurrentTime.Add(2 * time.Hour), NextValidatorsHash: suite.chainB.Vals.Hash(), } suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), clientID, incrementedClientHeight, intermediateConsState) // set iteration key clientStore := suite.keeper.ClientStore(suite.ctx, clientID) - ibctmtypes.SetIterationKey(clientStore, incrementedClientHeight) + ibctm.SetIterationKey(clientStore, incrementedClientHeight) clientState.LatestHeight = incrementedClientHeight suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), clientID, clientState) @@ -175,28 +177,28 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { updateHeader = createFutureUpdateFn(trustedHeight) }, true, true}, {"client state not found", func() { - updateHeader = createFutureUpdateFn(path.EndpointA.GetClientState().GetLatestHeight().(types.Height)) + updateHeader = createFutureUpdateFn(path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height)) path.EndpointA.ClientID = ibctesting.InvalidID }, false, false}, {"consensus state not found", func() { clientState := path.EndpointA.GetClientState() - tmClient, ok := clientState.(*ibctmtypes.ClientState) + tmClient, ok := clientState.(*ibctm.ClientState) suite.Require().True(ok) - tmClient.LatestHeight = tmClient.LatestHeight.Increment().(types.Height) + tmClient.LatestHeight = tmClient.LatestHeight.Increment().(clienttypes.Height) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID, clientState) - updateHeader = createFutureUpdateFn(clientState.GetLatestHeight().(types.Height)) + updateHeader = createFutureUpdateFn(clientState.GetLatestHeight().(clienttypes.Height)) }, false, false}, {"client is not active", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) - clientState.FrozenHeight = types.NewHeight(0, 1) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) + clientState.FrozenHeight = clienttypes.NewHeight(1, 1) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID, clientState) - updateHeader = createFutureUpdateFn(clientState.GetLatestHeight().(types.Height)) + updateHeader = createFutureUpdateFn(clientState.GetLatestHeight().(clienttypes.Height)) }, false, false}, {"invalid header", func() { - updateHeader = createFutureUpdateFn(path.EndpointA.GetClientState().GetLatestHeight().(types.Height)) - updateHeader.TrustedHeight = updateHeader.TrustedHeight.Increment().(types.Height) + updateHeader = createFutureUpdateFn(path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height)) + updateHeader.TrustedHeight = updateHeader.TrustedHeight.Increment().(clienttypes.Height) }, false, false}, } @@ -222,9 +224,9 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { newClientState := path.EndpointA.GetClientState() if tc.expFreeze { - suite.Require().True(!newClientState.(*ibctmtypes.ClientState).FrozenHeight.IsZero(), "client did not freeze after conflicting header was submitted to UpdateClient") + suite.Require().True(!newClientState.(*ibctm.ClientState).FrozenHeight.IsZero(), "client did not freeze after conflicting header was submitted to UpdateClient") } else { - expConsensusState := &ibctmtypes.ConsensusState{ + expConsensusState := &ibctm.ConsensusState{ Timestamp: updateHeader.GetTime(), Root: commitmenttypes.NewMerkleRoot(updateHeader.Header.GetAppHash()), NextValidatorsHash: updateHeader.Header.NextValidatorsHash, @@ -252,19 +254,6 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { } } -func (suite *KeeperTestSuite) TestUpdateClientLocalhost() { - revision := types.ParseChainID(suite.chainA.ChainID) - var localhostClient exported.ClientState = localhosttypes.NewClientState(suite.chainA.ChainID, types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight()))) - - ctx := suite.chainA.GetContext().WithBlockHeight(suite.chainA.GetContext().BlockHeight() + 1) - err := suite.chainA.App.GetIBCKeeper().ClientKeeper.UpdateClient(ctx, exported.Localhost, nil) - suite.Require().NoError(err) - - clientState, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(ctx, exported.Localhost) - suite.Require().True(found) - suite.Require().Equal(localhostClient.GetLatestHeight().(types.Height).Increment(), clientState.GetLatestHeight()) -} - func (suite *KeeperTestSuite) TestUpgradeClient() { var ( path *ibctesting.Path @@ -273,7 +262,6 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { lastHeight exported.Height proofUpgradedClient, proofUpgradedConsState []byte upgradedClientBz, upgradedConsStateBz []byte - err error ) testCases := []struct { @@ -285,16 +273,17 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { name: "successful upgrade", setup: func() { // last Height is at next block - lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(1, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + err := suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.Require().NoError(err) + err = suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.Require().NoError(err) // commit upgrade store changes and update clients - suite.coordinator.CommitBlock(suite.chainB) - err := path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() suite.Require().NoError(err) cs, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID) @@ -309,16 +298,18 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { name: "client state not found", setup: func() { // last Height is at next block - lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(1, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + err := suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.Require().NoError(err) + err = suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.Require().NoError(err) // commit upgrade store changes and update clients suite.coordinator.CommitBlock(suite.chainB) - err := path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() suite.Require().NoError(err) cs, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID) @@ -337,16 +328,18 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { // client is frozen // last Height is at next block - lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(1, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + err := suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.Require().NoError(err) + err = suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.Require().NoError(err) // commit upgrade store changes and update clients suite.coordinator.CommitBlock(suite.chainB) - err := path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() suite.Require().NoError(err) cs, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID) @@ -356,9 +349,9 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) // set frozen client in store - tmClient, ok := cs.(*ibctmtypes.ClientState) + tmClient, ok := cs.(*ibctm.ClientState) suite.Require().True(ok) - tmClient.FrozenHeight = types.NewHeight(0, 1) + tmClient.FrozenHeight = clienttypes.NewHeight(1, 1) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID, tmClient) }, expPass: false, @@ -367,17 +360,21 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { name: "tendermint client VerifyUpgrade fails", setup: func() { // last Height is at next block - lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(1, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + err := suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.Require().NoError(err) + err = suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.Require().NoError(err) // change upgradedClient client-specified parameters - upgradedClient = ibctmtypes.NewClientState("wrongchainID", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, true, true) + tmClient := upgradedClient.(*ibctm.ClientState) + tmClient.ChainId = "wrongchainID" + upgradedClient = tmClient suite.coordinator.CommitBlock(suite.chainB) - err := path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() suite.Require().NoError(err) cs, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID) @@ -394,22 +391,26 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { tc := tc path = ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(path) - upgradedClient = ibctmtypes.NewClientState("newChainId-1", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) + revisionNumber := clienttypes.ParseChainID(clientState.ChainId) + + newChainID, err := clienttypes.SetRevisionNumber(clientState.ChainId, revisionNumber+1) + suite.Require().NoError(err) + + upgradedClient = ibctm.NewClientState(newChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, clienttypes.NewHeight(revisionNumber+1, clientState.GetLatestHeight().GetRevisionHeight()+1), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) upgradedClient = upgradedClient.ZeroCustomFields() - upgradedClientBz, err = types.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) + upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) suite.Require().NoError(err) - upgradedConsState = &ibctmtypes.ConsensusState{ + upgradedConsState = &ibctm.ConsensusState{ NextValidatorsHash: []byte("nextValsHash"), } - upgradedConsStateBz, err = types.MarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState) + upgradedConsStateBz, err = clienttypes.MarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState) suite.Require().NoError(err) tc.setup() - // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient - upgradedClient = upgradedClient.ZeroCustomFields() - err = suite.chainA.App.GetIBCKeeper().ClientKeeper.UpgradeClient(suite.chainA.GetContext(), path.EndpointA.ClientID, upgradedClient, upgradedConsState, proofUpgradedClient, proofUpgradedConsState) if tc.expPass { @@ -420,256 +421,10 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { } } -func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { - var ( - clientID string - err error - ) - - altPrivVal := ibctestingmock.NewPV() - altPubKey, err := altPrivVal.GetPubKey() - suite.Require().NoError(err) - altVal := tmtypes.NewValidator(altPubKey, 4) - - // Set valSet here with suite.valSet so it doesn't get reset on each testcase - valSet := suite.valSet - valsHash := valSet.Hash() - - // Create bothValSet with both suite validator and altVal - bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) - bothValsHash := bothValSet.Hash() - // Create alternative validator set with only altVal - altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) - - // Create signer array and ensure it is in same order as bothValSet - _, suiteVal := suite.valSet.GetByIndex(0) - bothSigners := make(map[string]tmtypes.PrivValidator, 2) - bothSigners[suiteVal.Address.String()] = suite.privVal - bothSigners[altVal.Address.String()] = altPrivVal - - altSigners := make(map[string]tmtypes.PrivValidator, 1) - altSigners[altVal.Address.String()] = altPrivVal - - // Create valid Misbehaviour by making a duplicate header that signs over different block time - altTime := suite.ctx.BlockTime().Add(time.Minute) - - heightPlus3 := types.NewHeight(0, height+3) - heightPlus5 := types.NewHeight(0, height+5) - - testCases := []struct { - name string - misbehaviour *ibctmtypes.Misbehaviour - malleate func() error - expPass bool - }{ - { - "trusting period misbehavior should pass", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight+1), testClientHeight, altTime, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight+1), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: clientID, - }, - func() error { - suite.consensusState.NextValidatorsHash = bothValsHash - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - - return err - }, - true, - }, - { - "time misbehavior should pass", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight+5), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight+1), testClientHeight, altTime, bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: clientID, - }, - func() error { - suite.consensusState.NextValidatorsHash = bothValsHash - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - - return err - }, - true, - }, - { - "misbehavior at later height should pass", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight+1), testClientHeight, altTime, bothValSet, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight+1), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, valSet, bothSigners), - ClientId: clientID, - }, - func() error { - suite.consensusState.NextValidatorsHash = valsHash - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - - // store intermediate consensus state to check that trustedHeight does not need to be highest consensus state before header height - intermediateConsState := &ibctmtypes.ConsensusState{ - Timestamp: suite.now.Add(time.Minute), - NextValidatorsHash: suite.chainB.Vals.Hash(), - } - suite.keeper.SetClientConsensusState(suite.ctx, clientID, heightPlus3, intermediateConsState) - - clientState.LatestHeight = heightPlus3 - suite.keeper.SetClientState(suite.ctx, clientID, clientState) - - return err - }, - true, - }, - { - "misbehavior at later height with different trusted heights should pass", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight+1), testClientHeight, altTime, bothValSet, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight+1), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: clientID, - }, - func() error { - suite.consensusState.NextValidatorsHash = valsHash - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - - // store trusted consensus state for Header2 - intermediateConsState := &ibctmtypes.ConsensusState{ - Timestamp: suite.now.Add(time.Minute), - NextValidatorsHash: bothValsHash, - } - suite.keeper.SetClientConsensusState(suite.ctx, clientID, heightPlus3, intermediateConsState) - - clientState.LatestHeight = heightPlus3 - suite.keeper.SetClientState(suite.ctx, clientID, clientState) - - return err - }, - true, - }, - { - "misbehavior ValidateBasic fails: misbehaviour height is at same height as trusted height", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: clientID, - }, - func() error { - suite.consensusState.NextValidatorsHash = bothValsHash - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - - return err - }, - false, - }, - { - "trusted ConsensusState1 not found", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight+1), heightPlus3, altTime, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight+1), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, valSet, bothSigners), - ClientId: clientID, - }, - func() error { - suite.consensusState.NextValidatorsHash = valsHash - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - // intermediate consensus state at height + 3 is not created - return err - }, - false, - }, - { - "trusted ConsensusState2 not found", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight+1), testClientHeight, altTime, bothValSet, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight+1), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: clientID, - }, - func() error { - suite.consensusState.NextValidatorsHash = valsHash - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - // intermediate consensus state at height + 3 is not created - return err - }, - false, - }, - { - "client state not found", - &ibctmtypes.Misbehaviour{}, - func() error { return nil }, - false, - }, - { - "client already is not active - client is frozen", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight+1), testClientHeight, altTime, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight+1), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: clientID, - }, - func() error { - suite.consensusState.NextValidatorsHash = bothValsHash - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - - clientState.FrozenHeight = types.NewHeight(0, 1) - suite.keeper.SetClientState(suite.ctx, clientID, clientState) - - return err - }, - false, - }, - { - "misbehaviour check failed", - &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight+1), testClientHeight, altTime, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight+1), testClientHeight, suite.ctx.BlockTime(), altValSet, altValSet, bothValSet, altSigners), - ClientId: clientID, - }, - func() error { - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - if err != nil { - return err - } - clientID, err = suite.keeper.CreateClient(suite.ctx, clientState, suite.consensusState) - - return err - }, - false, - }, - } - - for i, tc := range testCases { - tc := tc - i := i - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - clientID = testClientID // must be explicitly changed - - err := tc.malleate() - suite.Require().NoError(err) - - tc.misbehaviour.ClientId = clientID - - err = suite.keeper.CheckMisbehaviourAndUpdateState(suite.ctx, tc.misbehaviour) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - - clientState, found := suite.keeper.GetClientState(suite.ctx, clientID) - suite.Require().True(found, "valid test case %d failed: %s", i, tc.name) - suite.Require().True(!clientState.(*ibctmtypes.ClientState).FrozenHeight.IsZero(), "valid test case %d failed: %s", i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - } - }) - } -} - func (suite *KeeperTestSuite) TestUpdateClientEventEmission() { path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(path) + header, err := suite.chainA.ConstructUpdateTMClientHeader(suite.chainB, path.EndpointA.ClientID) suite.Require().NoError(err) @@ -677,6 +432,7 @@ func (suite *KeeperTestSuite) TestUpdateClientEventEmission() { path.EndpointA.ClientID, header, suite.chainA.SenderAccount.GetAddress().String(), ) + suite.Require().NoError(err) result, err := suite.chainA.SendMsgs(msg) suite.Require().NoError(err) @@ -687,13 +443,13 @@ func (suite *KeeperTestSuite) TestUpdateClientEventEmission() { // use a boolean to ensure the update event contains the header contains := false for _, attr := range updateEvent.Attributes { - if string(attr.Key) == clienttypes.AttributeKeyHeader { + if attr.Key == clienttypes.AttributeKeyHeader { contains = true - bz, err := hex.DecodeString(string(attr.Value)) + bz, err := hex.DecodeString(attr.Value) suite.Require().NoError(err) - emittedHeader, err := types.UnmarshalHeader(suite.chainA.App.AppCodec(), bz) + emittedHeader, err := clienttypes.UnmarshalClientMessage(suite.chainA.App.AppCodec(), bz) suite.Require().NoError(err) suite.Require().Equal(header, emittedHeader) } diff --git a/modules/core/02-client/keeper/encoding.go b/modules/core/02-client/keeper/encoding.go index 6c036455ce3..0b9e2a307b3 100644 --- a/modules/core/02-client/keeper/encoding.go +++ b/modules/core/02-client/keeper/encoding.go @@ -1,8 +1,8 @@ package keeper import ( - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // UnmarshalClientState attempts to decode and return an ClientState object from diff --git a/modules/core/02-client/keeper/events.go b/modules/core/02-client/keeper/events.go index 0702651a611..9b0bb6841ba 100644 --- a/modules/core/02-client/keeper/events.go +++ b/modules/core/02-client/keeper/events.go @@ -1,16 +1,21 @@ package keeper import ( + "encoding/hex" "fmt" + "strconv" + "strings" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) -// EmitCreateClientEvent emits a create client event -func EmitCreateClientEvent(ctx sdk.Context, clientID string, clientState exported.ClientState) { +// emitCreateClientEvent emits a create client event +func emitCreateClientEvent(ctx sdk.Context, clientID string, clientState exported.ClientState) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeCreateClient, @@ -25,15 +30,33 @@ func EmitCreateClientEvent(ctx sdk.Context, clientID string, clientState exporte }) } -// EmitUpdateClientEvent emits an update client event -func EmitUpdateClientEvent(ctx sdk.Context, clientID string, clientState exported.ClientState, consensusHeight exported.Height, headerStr string) { +// emitUpdateClientEvent emits an update client event +func emitUpdateClientEvent(ctx sdk.Context, clientID string, clientType string, consensusHeights []exported.Height, cdc codec.BinaryCodec, clientMsg exported.ClientMessage) { + // Marshal the ClientMessage as an Any and encode the resulting bytes to hex. + // This prevents the event value from containing invalid UTF-8 characters + // which may cause data to be lost when JSON encoding/decoding. + clientMsgStr := hex.EncodeToString(types.MustMarshalClientMessage(cdc, clientMsg)) + + var consensusHeightAttr string + if len(consensusHeights) != 0 { + consensusHeightAttr = consensusHeights[0].String() + } + + consensusHeightsAttr := make([]string, len(consensusHeights)) + for i, height := range consensusHeights { + consensusHeightsAttr[i] = height.String() + } + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeUpdateClient, sdk.NewAttribute(types.AttributeKeyClientID, clientID), - sdk.NewAttribute(types.AttributeKeyClientType, clientState.ClientType()), - sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeight.String()), - sdk.NewAttribute(types.AttributeKeyHeader, headerStr), + sdk.NewAttribute(types.AttributeKeyClientType, clientType), + // Deprecated: AttributeKeyConsensusHeight is deprecated and will be removed in a future release. + // Please use AttributeKeyConsensusHeights instead. + sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeightAttr), + sdk.NewAttribute(types.AttributeKeyConsensusHeights, strings.Join(consensusHeightsAttr, ",")), + sdk.NewAttribute(types.AttributeKeyHeader, clientMsgStr), ), sdk.NewEvent( sdk.EventTypeMessage, @@ -42,8 +65,8 @@ func EmitUpdateClientEvent(ctx sdk.Context, clientID string, clientState exporte }) } -// EmitUpdateClientEvent emits an upgrade client event -func EmitUpgradeClientEvent(ctx sdk.Context, clientID string, clientState exported.ClientState) { +// emitUpgradeClientEvent emits an upgrade client event +func emitUpgradeClientEvent(ctx sdk.Context, clientID string, clientState exported.ClientState) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeUpgradeClient, @@ -58,49 +81,62 @@ func EmitUpgradeClientEvent(ctx sdk.Context, clientID string, clientState export }) } -// EmitUpdateClientProposalEvent emits an update client proposal event -func EmitUpdateClientProposalEvent(ctx sdk.Context, clientID string, clientState exported.ClientState) { - ctx.EventManager().EmitEvent( +// emitUpdateClientProposalEvent emits an update client proposal event +func emitUpdateClientProposalEvent(ctx sdk.Context, clientID, clientType string) { + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeUpdateClientProposal, sdk.NewAttribute(types.AttributeKeySubjectClientID, clientID), - sdk.NewAttribute(types.AttributeKeyClientType, clientState.ClientType()), - sdk.NewAttribute(types.AttributeKeyConsensusHeight, clientState.GetLatestHeight().String()), + sdk.NewAttribute(types.AttributeKeyClientType, clientType), ), - ) + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) } -// EmitUpgradeClientProposalEvent emits an upgrade client proposal event -func EmitUpgradeClientProposalEvent(ctx sdk.Context, title string, height int64) { - ctx.EventManager().EmitEvent( +// emitUpgradeClientProposalEvent emits an upgrade client proposal event +func emitUpgradeClientProposalEvent(ctx sdk.Context, title string, height int64) { + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeUpgradeClientProposal, sdk.NewAttribute(types.AttributeKeyUpgradePlanTitle, title), sdk.NewAttribute(types.AttributeKeyUpgradePlanHeight, fmt.Sprintf("%d", height)), ), - ) + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) } -// EmitSubmitMisbehaviourEvent emits a client misbehaviour event -func EmitSubmitMisbehaviourEvent(ctx sdk.Context, clientID string, clientState exported.ClientState) { - ctx.EventManager().EmitEvent( +// emitSubmitMisbehaviourEvent emits a client misbehaviour event +func emitSubmitMisbehaviourEvent(ctx sdk.Context, clientID string, clientState exported.ClientState) { + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeSubmitMisbehaviour, sdk.NewAttribute(types.AttributeKeyClientID, clientID), sdk.NewAttribute(types.AttributeKeyClientType, clientState.ClientType()), ), - ) + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) } -// EmitSubmitMisbehaviourEventOnUpdate emits a client misbehaviour event on a client update event -func EmitSubmitMisbehaviourEventOnUpdate(ctx sdk.Context, clientID string, clientState exported.ClientState, consensusHeight exported.Height, headerStr string) { - ctx.EventManager().EmitEvent( +// EmitUpgradeChainEvent emits an upgrade chain event. +func EmitUpgradeChainEvent(ctx sdk.Context, height int64) { + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( - types.EventTypeSubmitMisbehaviour, - sdk.NewAttribute(types.AttributeKeyClientID, clientID), - sdk.NewAttribute(types.AttributeKeyClientType, clientState.ClientType()), - sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeight.String()), - sdk.NewAttribute(types.AttributeKeyHeader, headerStr), + types.EventTypeUpgradeChain, + sdk.NewAttribute(types.AttributeKeyUpgradePlanHeight, strconv.FormatInt(height, 10)), + sdk.NewAttribute(types.AttributeKeyUpgradeStore, upgradetypes.StoreKey), // which store to query proof of consensus state from + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), ), - ) + }) } diff --git a/modules/core/02-client/keeper/grpc_query.go b/modules/core/02-client/keeper/grpc_query.go index 3fc7b6e7cde..5f575303c02 100644 --- a/modules/core/02-client/keeper/grpc_query.go +++ b/modules/core/02-client/keeper/grpc_query.go @@ -7,16 +7,16 @@ import ( "sort" "strings" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var _ types.QueryServer = Keeper{} @@ -36,18 +36,18 @@ func (q Keeper) ClientState(c context.Context, req *types.QueryClientStateReques if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrap(types.ErrClientNotFound, req.ClientId).Error(), + errorsmod.Wrap(types.ErrClientNotFound, req.ClientId).Error(), ) } - any, err := types.PackClientState(clientState) + protoAny, err := types.PackClientState(clientState) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } proofHeight := types.GetSelfHeight(ctx) return &types.QueryClientStateResponse{ - ClientState: any, + ClientState: protoAny, ProofHeight: proofHeight, }, nil } @@ -63,25 +63,26 @@ func (q Keeper) ClientStates(c context.Context, req *types.QueryClientStatesRequ clientStates := types.IdentifiedClientStates{} store := prefix.NewStore(ctx.KVStore(q.storeKey), host.KeyClientStorePrefix) - pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { + pageRes, err := query.FilteredPaginate(store, req.Pagination, func(key, value []byte, accumulate bool) (bool, error) { + // filter any metadata stored under client state key keySplit := strings.Split(string(key), "/") if keySplit[len(keySplit)-1] != "clientState" { - return nil + return false, nil } clientState, err := q.UnmarshalClientState(value) if err != nil { - return err + return false, err } clientID := keySplit[1] if err := host.ClientIdentifierValidator(clientID); err != nil { - return err + return false, err } identifiedClient := types.NewIdentifiedClientState(clientID, clientState) clientStates = append(clientStates, identifiedClient) - return nil + return true, nil }) if err != nil { return nil, err @@ -126,18 +127,18 @@ func (q Keeper) ConsensusState(c context.Context, req *types.QueryConsensusState if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(types.ErrConsensusStateNotFound, "client-id: %s, height: %s", req.ClientId, height).Error(), + errorsmod.Wrapf(types.ErrConsensusStateNotFound, "client-id: %s, height: %s", req.ClientId, height).Error(), ) } - any, err := types.PackConsensusState(consensusState) + protoAny, err := types.PackConsensusState(consensusState) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } proofHeight := types.GetSelfHeight(ctx) return &types.QueryConsensusStateResponse{ - ConsensusState: any, + ConsensusState: protoAny, ProofHeight: proofHeight, }, nil } @@ -215,7 +216,6 @@ func (q Keeper) ConsensusStateHeights(c context.Context, req *types.QueryConsens consensusStateHeights = append(consensusStateHeights, height) return true, nil }) - if err != nil { return nil, err } @@ -241,7 +241,7 @@ func (q Keeper) ClientStatus(c context.Context, req *types.QueryClientStatusRequ if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrap(types.ErrClientNotFound, req.ClientId).Error(), + errorsmod.Wrap(types.ErrClientNotFound, req.ClientId).Error(), ) } @@ -290,13 +290,13 @@ func (q Keeper) UpgradedClientState(c context.Context, req *types.QueryUpgradedC ) } - any, err := types.PackClientState(clientState) + protoAny, err := types.PackClientState(clientState) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } return &types.QueryUpgradedClientStateResponse{ - UpgradedClientState: any, + UpgradedClientState: protoAny, }, nil } @@ -320,12 +320,12 @@ func (q Keeper) UpgradedConsensusState(c context.Context, req *types.QueryUpgrad ) } - any, err := types.PackConsensusState(consensusState) + protoAny, err := types.PackConsensusState(consensusState) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } return &types.QueryUpgradedConsensusStateResponse{ - UpgradedConsensusState: any, + UpgradedConsensusState: protoAny, }, nil } diff --git a/modules/core/02-client/keeper/grpc_query_test.go b/modules/core/02-client/keeper/grpc_query_test.go index 1fb29d06964..50683e98723 100644 --- a/modules/core/02-client/keeper/grpc_query_test.go +++ b/modules/core/02-client/keeper/grpc_query_test.go @@ -9,10 +9,10 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/metadata" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/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/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestQueryClientState() { @@ -142,7 +142,7 @@ func (suite *KeeperTestSuite) TestQueryClientStates() { idcs := types.NewIdentifiedClientState(path1.EndpointA.ClientID, clientStateA1) idcs2 := types.NewIdentifiedClientState(path2.EndpointA.ClientID, clientStateA2) - // order is sorted by client id, localhost is last + // order is sorted by client id expClientStates = types.IdentifiedClientStates{idcs, idcs2}.Sort() req = &types.QueryClientStatesRequest{ Pagination: &query.PageRequest{ @@ -158,22 +158,16 @@ func (suite *KeeperTestSuite) TestQueryClientStates() { for _, tc := range testCases { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset - expClientStates = nil - tc.malleate() - // always add localhost which is created by default in init genesis - localhostClientState := suite.chainA.GetClientState(exported.Localhost) - identifiedLocalhost := types.NewIdentifiedClientState(exported.Localhost, localhostClientState) - expClientStates = append(expClientStates, identifiedLocalhost) ctx := sdk.WrapSDKContext(suite.chainA.GetContext()) res, err := suite.chainA.QueryServer.ClientStates(ctx, req) - if tc.expPass { suite.Require().NoError(err) suite.Require().NotNil(res) suite.Require().Equal(expClientStates.Sort(), res.ClientStates) + suite.Require().Equal(len(expClientStates), int(res.Pagination.Total)) } else { suite.Require().Error(err) } @@ -259,7 +253,8 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() { suite.Require().NoError(err) // update client to new height - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) req = &types.QueryConsensusStateRequest{ ClientId: path.EndpointA.ClientID, @@ -386,7 +381,6 @@ func (suite *KeeperTestSuite) TestQueryConsensusStates() { for i := range expConsensusStates { suite.Require().NotNil(res.ConsensusStates[i]) suite.Require().Equal(expConsensusStates[i], res.ConsensusStates[i]) - // ensure UnpackInterfaces is defined cachedValue := res.ConsensusStates[i].ConsensusState.GetCachedValue() suite.Require().NotNil(cachedValue) @@ -534,7 +528,7 @@ func (suite *KeeperTestSuite) TestQueryClientStatus() { func() { path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(path) - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) // increment latest height so no consensus state is stored clientState.LatestHeight = clientState.LatestHeight.Increment().(types.Height) @@ -551,7 +545,7 @@ func (suite *KeeperTestSuite) TestQueryClientStatus() { func() { path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(path) - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = types.NewHeight(0, 1) path.EndpointA.SetClientState(clientState) @@ -646,7 +640,7 @@ func (suite *KeeperTestSuite) TestQueryUpgradedConsensusStates() { } } -func (suite *KeeperTestSuite) TestQueryParams() { +func (suite *KeeperTestSuite) TestQueryClientParams() { ctx := sdk.WrapSDKContext(suite.chainA.GetContext()) expParams := types.DefaultParams() res, _ := suite.chainA.QueryServer.ClientParams(ctx, &types.QueryClientParamsRequest{}) diff --git a/modules/core/02-client/keeper/keeper.go b/modules/core/02-client/keeper/keeper.go index fbb911f8997..aa0eea8c194 100644 --- a/modules/core/02-client/keeper/keeper.go +++ b/modules/core/02-client/keeper/keeper.go @@ -5,26 +5,28 @@ import ( "reflect" "strings" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/light" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ) // Keeper represents a type that grants read and write permissions to any client // state information type Keeper struct { - storeKey sdk.StoreKey + storeKey storetypes.StoreKey cdc codec.BinaryCodec paramSpace paramtypes.Subspace stakingKeeper types.StakingKeeper @@ -32,7 +34,7 @@ type Keeper struct { } // NewKeeper creates a new NewKeeper instance -func NewKeeper(cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Subspace, sk types.StakingKeeper, uk types.UpgradeKeeper) Keeper { +func NewKeeper(cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, sk types.StakingKeeper, uk types.UpgradeKeeper) Keeper { // set KeyTable if it has not already been set if !paramSpace.HasKeyTable() { paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) @@ -49,7 +51,7 @@ func NewKeeper(cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Su // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+host.ModuleName+"/"+types.SubModuleName) + return ctx.Logger().With("module", "x/"+exported.ModuleName+"/"+types.SubModuleName) } // GenerateClientIdentifier returns the next client identifier. @@ -66,7 +68,7 @@ func (k Keeper) GenerateClientIdentifier(ctx sdk.Context, clientType string) str func (k Keeper) GetClientState(ctx sdk.Context, clientID string) (exported.ClientState, bool) { store := k.ClientStore(ctx, clientID) bz := store.Get(host.ClientStateKey()) - if bz == nil { + if len(bz) == 0 { return nil, false } @@ -84,7 +86,7 @@ func (k Keeper) SetClientState(ctx sdk.Context, clientID string, clientState exp func (k Keeper) GetClientConsensusState(ctx sdk.Context, clientID string, height exported.Height) (exported.ConsensusState, bool) { store := k.ClientStore(ctx, clientID) bz := store.Get(host.ConsensusStateKey(height)) - if bz == nil { + if len(bz) == 0 { return nil, false } @@ -103,7 +105,7 @@ func (k Keeper) SetClientConsensusState(ctx sdk.Context, clientID string, height func (k Keeper) GetNextClientSequence(ctx sdk.Context) uint64 { store := ctx.KVStore(k.storeKey) bz := store.Get([]byte(types.KeyNextClientSequence)) - if bz == nil { + if len(bz) == 0 { panic("next client sequence is nil") } @@ -124,7 +126,7 @@ func (k Keeper) IterateConsensusStates(ctx sdk.Context, cb func(clientID string, store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, host.KeyClientStorePrefix) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { keySplit := strings.Split(string(iterator.Key()), "/") // consensus key is in the format "clients//consensusStates/" @@ -146,7 +148,7 @@ func (k Keeper) IterateConsensusStates(ctx sdk.Context, cb func(clientID string, // GetAllGenesisClients returns all the clients in state with their client ids returned as IdentifiedClientState func (k Keeper) GetAllGenesisClients(ctx sdk.Context) types.IdentifiedClientStates { var genClients types.IdentifiedClientStates - k.IterateClients(ctx, func(clientID string, cs exported.ClientState) bool { + k.IterateClientStates(ctx, nil, func(clientID string, cs exported.ClientState) bool { genClients = append(genClients, types.NewIdentifiedClientState(clientID, cs)) return false }) @@ -172,7 +174,7 @@ func (k Keeper) GetAllClientMetadata(ctx sdk.Context, genClients []types.Identif for i, metadata := range gms { cmd, ok := metadata.(types.GenesisMetadata) if !ok { - return nil, sdkerrors.Wrapf(types.ErrInvalidClientMetadata, "expected metadata type: %T, got: %T", + return nil, errorsmod.Wrapf(types.ErrInvalidClientMetadata, "expected metadata type: %T, got: %T", types.GenesisMetadata{}, cmd) } clientMetadata[i] = cmd @@ -244,19 +246,19 @@ func (k Keeper) GetLatestClientConsensusState(ctx sdk.Context, clientID string) func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height exported.Height) (exported.ConsensusState, error) { selfHeight, ok := height.(types.Height) if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", types.Height{}, height) + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "expected %T, got %T", types.Height{}, height) } // check that height revision matches chainID revision revision := types.ParseChainID(ctx.ChainID()) if revision != height.GetRevisionNumber() { - return nil, sdkerrors.Wrapf(types.ErrInvalidHeight, "chainID revision number does not match height revision number: expected %d, got %d", revision, height.GetRevisionNumber()) + return nil, errorsmod.Wrapf(types.ErrInvalidHeight, "chainID revision number does not match height revision number: expected %d, got %d", revision, height.GetRevisionNumber()) } histInfo, found := k.stakingKeeper.GetHistoricalInfo(ctx, int64(selfHeight.RevisionHeight)) if !found { - return nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "no historical info found at height %d", selfHeight.RevisionHeight) + return nil, errorsmod.Wrapf(ibcerrors.ErrNotFound, "no historical info found at height %d", selfHeight.RevisionHeight) } - consensusState := &ibctmtypes.ConsensusState{ + consensusState := &ibctm.ConsensusState{ Timestamp: histInfo.Header.Time, Root: commitmenttypes.NewMerkleRoot(histInfo.Header.GetAppHash()), NextValidatorsHash: histInfo.Header.NextValidatorsHash, @@ -268,10 +270,10 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height exported.Height) ( // This function is only used to validate the client state the counterparty stores for this chain // Client must be in same revision as the executing chain func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error { - tmClient, ok := clientState.(*ibctmtypes.ClientState) + tmClient, ok := clientState.(*ibctm.ClientState) if !ok { - return sdkerrors.Wrapf(types.ErrInvalidClient, "client must be a Tendermint client, expected: %T, got: %T", - &ibctmtypes.ClientState{}, tmClient) + return errorsmod.Wrapf(types.ErrInvalidClient, "client must be a Tendermint client, expected: %T, got: %T", + &ibctm.ClientState{}, tmClient) } if !tmClient.FrozenHeight.IsZero() { @@ -279,7 +281,7 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS } if ctx.ChainID() != tmClient.ChainId { - return sdkerrors.Wrapf(types.ErrInvalidClient, "invalid chain-id. expected: %s, got: %s", + return errorsmod.Wrapf(types.ErrInvalidClient, "invalid chain-id. expected: %s, got: %s", ctx.ChainID(), tmClient.ChainId) } @@ -287,34 +289,34 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS // client must be in the same revision as executing chain if tmClient.LatestHeight.RevisionNumber != revision { - return sdkerrors.Wrapf(types.ErrInvalidClient, "client is not in the same revision as the chain. expected revision: %d, got: %d", + return errorsmod.Wrapf(types.ErrInvalidClient, "client is not in the same revision as the chain. expected revision: %d, got: %d", tmClient.LatestHeight.RevisionNumber, revision) } selfHeight := types.NewHeight(revision, uint64(ctx.BlockHeight())) if tmClient.LatestHeight.GTE(selfHeight) { - return sdkerrors.Wrapf(types.ErrInvalidClient, "client has LatestHeight %d greater than or equal to chain height %d", + return errorsmod.Wrapf(types.ErrInvalidClient, "client has LatestHeight %d greater than or equal to chain height %d", tmClient.LatestHeight, selfHeight) } expectedProofSpecs := commitmenttypes.GetSDKSpecs() if !reflect.DeepEqual(expectedProofSpecs, tmClient.ProofSpecs) { - return sdkerrors.Wrapf(types.ErrInvalidClient, "client has invalid proof specs. expected: %v got: %v", + return errorsmod.Wrapf(types.ErrInvalidClient, "client has invalid proof specs. expected: %v got: %v", expectedProofSpecs, tmClient.ProofSpecs) } if err := light.ValidateTrustLevel(tmClient.TrustLevel.ToTendermint()); err != nil { - return sdkerrors.Wrapf(types.ErrInvalidClient, "trust-level invalid: %v", err) + return errorsmod.Wrapf(types.ErrInvalidClient, "trust-level invalid: %v", err) } expectedUbdPeriod := k.stakingKeeper.UnbondingTime(ctx) if expectedUbdPeriod != tmClient.UnbondingPeriod { - return sdkerrors.Wrapf(types.ErrInvalidClient, "invalid unbonding period. expected: %s, got: %s", + return errorsmod.Wrapf(types.ErrInvalidClient, "invalid unbonding period. expected: %s, got: %s", expectedUbdPeriod, tmClient.UnbondingPeriod) } if tmClient.UnbondingPeriod < tmClient.TrustingPeriod { - return sdkerrors.Wrapf(types.ErrInvalidClient, "unbonding period must be greater than trusting period. unbonding period (%d) < trusting period (%d)", + return errorsmod.Wrapf(types.ErrInvalidClient, "unbonding period must be greater than trusting period. unbonding period (%d) < trusting period (%d)", tmClient.UnbondingPeriod, tmClient.TrustingPeriod) } @@ -322,7 +324,7 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS // For now, SDK IBC implementation assumes that upgrade path (if defined) is defined by SDK upgrade module expectedUpgradePath := []string{upgradetypes.StoreKey, upgradetypes.KeyUpgradedIBCState} if !reflect.DeepEqual(expectedUpgradePath, tmClient.UpgradePath) { - return sdkerrors.Wrapf(types.ErrInvalidClient, "upgrade path must be the upgrade path defined by upgrade module. expected %v, got %v", + return errorsmod.Wrapf(types.ErrInvalidClient, "upgrade path must be the upgrade path defined by upgrade module. expected %v, got %v", expectedUpgradePath, tmClient.UpgradePath) } } @@ -349,35 +351,38 @@ func (k Keeper) SetUpgradedConsensusState(ctx sdk.Context, planHeight int64, bz return k.upgradeKeeper.SetUpgradedConsensusState(ctx, planHeight, bz) } -// IterateClients provides an iterator over all stored light client State +// IterateClientStates provides an iterator over all stored light client State // objects. For each State object, cb will be called. If the cb returns true, // the iterator will close and stop. -func (k Keeper) IterateClients(ctx sdk.Context, cb func(clientID string, cs exported.ClientState) bool) { +func (k Keeper) IterateClientStates(ctx sdk.Context, prefix []byte, cb func(clientID string, cs exported.ClientState) bool) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, host.KeyClientStorePrefix) + iterator := sdk.KVStorePrefixIterator(store, host.PrefixedClientStoreKey(prefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { - keySplit := strings.Split(string(iterator.Key()), "/") - if keySplit[len(keySplit)-1] != host.KeyClientState { + path := string(iterator.Key()) + if !strings.Contains(path, host.KeyClientState) { + // skip non client state keys continue } + + clientID := host.MustParseClientStatePath(path) clientState := k.MustUnmarshalClientState(iterator.Value()) - // key is ibc/{clientid}/clientState - // Thus, keySplit[1] is clientID - if cb(keySplit[1], clientState) { + if cb(clientID, clientState) { break } } } // GetAllClients returns all stored light client State objects. -func (k Keeper) GetAllClients(ctx sdk.Context) (states []exported.ClientState) { - k.IterateClients(ctx, func(_ string, state exported.ClientState) bool { +func (k Keeper) GetAllClients(ctx sdk.Context) []exported.ClientState { + var states []exported.ClientState + k.IterateClientStates(ctx, nil, func(_ string, state exported.ClientState) bool { states = append(states, state) return false }) + return states } diff --git a/modules/core/02-client/keeper/keeper_test.go b/modules/core/02-client/keeper/keeper_test.go index 11acea3df7d..8e5cac289d4 100644 --- a/modules/core/02-client/keeper/keeper_test.go +++ b/modules/core/02-client/keeper/keeper_test.go @@ -15,15 +15,15 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/keeper" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - localhosttypes "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibctestingmock "github.com/cosmos/ibc-go/v4/testing/mock" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctestingmock "github.com/cosmos/ibc-go/v7/testing/mock" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) const ( @@ -44,7 +44,6 @@ const ( var ( testClientHeight = types.NewHeight(0, 5) testClientHeightRevision1 = types.NewHeight(1, 5) - newClientHeight = types.NewHeight(1, 1) ) type KeeperTestSuite struct { @@ -58,13 +57,14 @@ type KeeperTestSuite struct { cdc codec.Codec ctx sdk.Context keeper *keeper.Keeper - consensusState *ibctmtypes.ConsensusState - header *ibctmtypes.Header + consensusState *ibctm.ConsensusState + header *ibctm.Header valSet *tmtypes.ValidatorSet valSetHash tmbytes.HexBytes privVal tmtypes.PrivValidator now time.Time past time.Time + solomachine *ibctesting.Solomachine signers map[string]tmtypes.PrivValidator @@ -102,7 +102,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.signers[validator.Address.String()] = suite.privVal suite.header = suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeightMinus1, now2, suite.valSet, suite.valSet, suite.valSet, suite.signers) - suite.consensusState = ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("hash")), suite.valSetHash) + suite.consensusState = ibctm.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("hash")), suite.valSetHash) var validators stakingtypes.Validators for i := 1; i < 11; i++ { @@ -122,12 +122,7 @@ func (suite *KeeperTestSuite) SetupTest() { app.StakingKeeper.SetHistoricalInfo(suite.ctx, int64(i), &hi) } - // add localhost client - revision := types.ParseChainID(suite.chainA.ChainID) - localHostClient := localhosttypes.NewClientState( - suite.chainA.ChainID, types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())), - ) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), exported.Localhost, localHostClient) + suite.solomachine = ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinesingle", "testing", 1) // TODO: deprecate queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, app.InterfaceRegistry()) @@ -140,7 +135,7 @@ func TestKeeperTestSuite(t *testing.T) { } func (suite *KeeperTestSuite) TestSetClientState() { - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + clientState := ibctm.NewClientState(testChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) retrievedState, found := suite.keeper.GetClientState(suite.ctx, testClientID) @@ -154,13 +149,14 @@ func (suite *KeeperTestSuite) TestSetClientConsensusState() { retrievedConsState, found := suite.keeper.GetClientConsensusState(suite.ctx, testClientID, testClientHeight) suite.Require().True(found, "GetConsensusState failed") - tmConsState, ok := retrievedConsState.(*ibctmtypes.ConsensusState) + tmConsState, ok := retrievedConsState.(*ibctm.ConsensusState) suite.Require().True(ok) suite.Require().Equal(suite.consensusState, tmConsState, "ConsensusState not stored correctly") } func (suite *KeeperTestSuite) TestValidateSelfClient() { - testClientHeight := types.NewHeight(0, uint64(suite.chainA.GetContext().BlockHeight()-1)) + testClientHeight := types.GetSelfHeight(suite.chainA.GetContext()) + testClientHeight.RevisionHeight-- testCases := []struct { name string @@ -169,62 +165,61 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { }{ { "success", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), true, }, { "success with nil UpgradePath", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), nil, false, false), + ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), nil), true, }, - { - "invalid client type", - localhosttypes.NewClientState(suite.chainA.ChainID, testClientHeight), - false, - }, { "frozen client", - &ibctmtypes.ClientState{suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false}, + &ibctm.ClientState{ChainId: suite.chainA.ChainID, TrustLevel: ibctm.DefaultTrustLevel, TrustingPeriod: trustingPeriod, UnbondingPeriod: ubdPeriod, MaxClockDrift: maxClockDrift, FrozenHeight: testClientHeight, LatestHeight: testClientHeight, ProofSpecs: commitmenttypes.GetSDKSpecs(), UpgradePath: ibctesting.UpgradePath}, false, }, { "incorrect chainID", - ibctmtypes.NewClientState("gaiatestnet", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ibctm.NewClientState("gaiatestnet", ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), false, }, { "invalid client height", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.NewHeight(0, uint64(suite.chainA.GetContext().BlockHeight())), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.GetSelfHeight(suite.chainA.GetContext()).Increment().(types.Height), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), + false, + }, + { + "invalid client type", + solomachine.NewClientState(0, &solomachine.ConsensusState{PublicKey: suite.solomachine.ConsensusState().PublicKey, Diversifier: suite.solomachine.Diversifier, Timestamp: suite.solomachine.Time}), false, }, { "invalid client revision", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightRevision1, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightRevision1, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), false, }, { "invalid proof specs", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, nil, ibctesting.UpgradePath, false, false), + ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, nil, ibctesting.UpgradePath), false, }, { "invalid trust level", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.Fraction{0, 1}, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - false, + ibctm.NewClientState(suite.chainA.ChainID, ibctm.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), false, }, { "invalid unbonding period", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+10, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod+10, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), false, }, { "invalid trusting period", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ubdPeriod+10, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ubdPeriod+10, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), false, }, { "invalid upgrade path", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), []string{"bad", "upgrade", "path"}, false, false), + ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), []string{"bad", "upgrade", "path"}), false, }, } @@ -239,14 +234,14 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { } } -func (suite KeeperTestSuite) TestGetAllGenesisClients() { +func (suite KeeperTestSuite) TestGetAllGenesisClients() { //nolint:govet // this is a test, we are okay with copying locks clientIDs := []string{ testClientID2, testClientID3, testClientID, } expClients := []exported.ClientState{ - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ibctm.NewClientState(testChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), + ibctm.NewClientState(testChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), + ibctm.NewClientState(testChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), } expGenClients := make(types.IdentifiedClientStates, len(expClients)) @@ -256,38 +251,32 @@ func (suite KeeperTestSuite) TestGetAllGenesisClients() { expGenClients[i] = types.NewIdentifiedClientState(clientIDs[i], expClients[i]) } - // add localhost client - localHostClient, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), exported.Localhost) - suite.Require().True(found) - expGenClients = append(expGenClients, types.NewIdentifiedClientState(exported.Localhost, localHostClient)) - genClients := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetAllGenesisClients(suite.chainA.GetContext()) suite.Require().Equal(expGenClients.Sort(), genClients) } -func (suite KeeperTestSuite) TestGetAllGenesisMetadata() { +func (suite KeeperTestSuite) TestGetAllGenesisMetadata() { //nolint:govet // this is a test, we are okay with copying locks expectedGenMetadata := []types.IdentifiedGenesisMetadata{ types.NewIdentifiedGenesisMetadata( "07-tendermint-1", []types.GenesisMetadata{ - types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(0, 1)), []byte("foo")), - types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(0, 2)), []byte("bar")), - types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(0, 3)), []byte("baz")), + types.NewGenesisMetadata(ibctm.ProcessedTimeKey(types.NewHeight(0, 1)), []byte("foo")), + types.NewGenesisMetadata(ibctm.ProcessedTimeKey(types.NewHeight(0, 2)), []byte("bar")), + types.NewGenesisMetadata(ibctm.ProcessedTimeKey(types.NewHeight(0, 3)), []byte("baz")), }, ), types.NewIdentifiedGenesisMetadata( "clientB", []types.GenesisMetadata{ - types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(1, 100)), []byte("val1")), - types.NewGenesisMetadata(ibctmtypes.ProcessedTimeKey(types.NewHeight(2, 300)), []byte("val2")), + types.NewGenesisMetadata(ibctm.ProcessedTimeKey(types.NewHeight(1, 100)), []byte("val1")), + types.NewGenesisMetadata(ibctm.ProcessedTimeKey(types.NewHeight(2, 300)), []byte("val2")), }, ), } genClients := []types.IdentifiedClientState{ - types.NewIdentifiedClientState("07-tendermint-1", &ibctmtypes.ClientState{}), types.NewIdentifiedClientState("clientB", &ibctmtypes.ClientState{}), - types.NewIdentifiedClientState("clientC", &ibctmtypes.ClientState{}), types.NewIdentifiedClientState("clientD", &localhosttypes.ClientState{}), + types.NewIdentifiedClientState("07-tendermint-1", &ibctm.ClientState{}), types.NewIdentifiedClientState("clientB", &ibctm.ClientState{}), } suite.chainA.App.GetIBCKeeper().ClientKeeper.SetAllClientMetadata(suite.chainA.GetContext(), expectedGenMetadata) @@ -297,7 +286,7 @@ func (suite KeeperTestSuite) TestGetAllGenesisMetadata() { suite.Require().Equal(expectedGenMetadata, actualGenMetadata, "retrieved metadata is unexpected") } -func (suite KeeperTestSuite) TestGetConsensusState() { +func (suite KeeperTestSuite) TestGetConsensusState() { //nolint:govet // this is a test, we are okay with copying locks suite.ctx = suite.ctx.WithBlockHeight(10) cases := []struct { name string @@ -323,14 +312,14 @@ func (suite KeeperTestSuite) TestGetConsensusState() { } } -func (suite KeeperTestSuite) TestConsensusStateHelpers() { +func (suite KeeperTestSuite) TestConsensusStateHelpers() { //nolint:govet // this is a test, we are okay with copying locks // initial setup - clientState := ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + clientState := ibctm.NewClientState(testChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) suite.keeper.SetClientState(suite.ctx, testClientID, clientState) suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) - nextState := ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("next")), suite.valSetHash) + nextState := ibctm.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("next")), suite.valSetHash) testClientHeightPlus5 := types.NewHeight(0, height+5) @@ -349,7 +338,7 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() { // 2 clients in total are created on chainA. The first client is updated so it contains an initial consensus state // and a consensus state at the update height. -func (suite KeeperTestSuite) TestGetAllConsensusStates() { +func (suite KeeperTestSuite) TestGetAllConsensusStates() { //nolint:govet // this is a test, we are okay with copying locks path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(path) @@ -397,3 +386,67 @@ func (suite KeeperTestSuite) TestGetAllConsensusStates() { consStates := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetAllConsensusStates(suite.chainA.GetContext()) suite.Require().Equal(expConsensusStates, consStates, "%s \n\n%s", expConsensusStates, consStates) } + +func (suite KeeperTestSuite) TestIterateClientStates() { //nolint:govet // this is a test, we are okay with copying locks + paths := []*ibctesting.Path{ + ibctesting.NewPath(suite.chainA, suite.chainB), + ibctesting.NewPath(suite.chainA, suite.chainB), + ibctesting.NewPath(suite.chainA, suite.chainB), + } + + solomachines := []*ibctesting.Solomachine{ + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1), + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4), + } + + var ( + expTMClientIDs = make([]string, len(paths)) + expSMClientIDs = make([]string, len(solomachines)) + ) + + // create tendermint clients + for i, path := range paths { + suite.coordinator.SetupClients(path) + expTMClientIDs[i] = path.EndpointA.ClientID + } + + // create solomachine clients + for i, sm := range solomachines { + expSMClientIDs[i] = sm.CreateClient(suite.chainA) + } + + testCases := []struct { + name string + prefix []byte + expClientIDs []string + }{ + { + "all clientIDs", + nil, + append(expSMClientIDs, expTMClientIDs...), + }, + { + "tendermint clientIDs", + []byte(exported.Tendermint), + expTMClientIDs, + }, + { + "solo machine clientIDs", + []byte(exported.Solomachine), + expSMClientIDs, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + var clientIDs []string + suite.chainA.GetSimApp().IBCKeeper.ClientKeeper.IterateClientStates(suite.chainA.GetContext(), tc.prefix, func(clientID string, _ exported.ClientState) bool { + clientIDs = append(clientIDs, clientID) + return false + }) + + suite.Require().Equal(tc.expClientIDs, clientIDs) + }) + } +} diff --git a/modules/core/02-client/keeper/migrations.go b/modules/core/02-client/keeper/migrations.go index c0ad7210341..ad3587ae901 100644 --- a/modules/core/02-client/keeper/migrations.go +++ b/modules/core/02-client/keeper/migrations.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - v100 "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100" + v7 "github.com/cosmos/ibc-go/v7/modules/core/02-client/migrations/v7" ) // Migrator is a struct for handling in-place store migrations. @@ -16,12 +16,12 @@ func NewMigrator(keeper Keeper) Migrator { return Migrator{keeper: keeper} } -// Migrate1to2 migrates from version 1 to 2. +// Migrate2to3 migrates from version 2 to 3. // This migration -// - migrates solo machine client states from v1 to v2 protobuf definition +// - migrates solo machine client states from v2 to v3 protobuf definition // - prunes solo machine consensus states -// - prunes expired tendermint consensus states -// - adds iteration and processed height keys for unexpired tendermint consensus states -func (m Migrator) Migrate1to2(ctx sdk.Context) error { - return v100.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) +// - removes the localhost client +// - asserts that existing tendermint clients are properly registered on the chain codec +func (m Migrator) Migrate2to3(ctx sdk.Context) error { + return v7.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc, m.keeper) } diff --git a/modules/core/02-client/keeper/params.go b/modules/core/02-client/keeper/params.go index d2ba2000792..5ed3181472f 100644 --- a/modules/core/02-client/keeper/params.go +++ b/modules/core/02-client/keeper/params.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) // GetAllowedClients retrieves the allowed clients from the paramstore diff --git a/modules/core/02-client/keeper/params_test.go b/modules/core/02-client/keeper/params_test.go index fe136a6346b..49484ad4c85 100644 --- a/modules/core/02-client/keeper/params_test.go +++ b/modules/core/02-client/keeper/params_test.go @@ -1,7 +1,7 @@ package keeper_test import ( - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) func (suite *KeeperTestSuite) TestParams() { @@ -12,6 +12,6 @@ func (suite *KeeperTestSuite) TestParams() { expParams.AllowedClients = []string{} suite.chainA.App.GetIBCKeeper().ClientKeeper.SetParams(suite.chainA.GetContext(), expParams) - params = suite.chainA.App.GetIBCKeeper().ClientKeeper.GetParams(suite.chainA.GetContext()) + _ = suite.chainA.App.GetIBCKeeper().ClientKeeper.GetParams(suite.chainA.GetContext()) suite.Require().Empty(expParams.AllowedClients) } diff --git a/modules/core/02-client/keeper/proposal.go b/modules/core/02-client/keeper/proposal.go index 4b182e5e7c3..a56d9b6ca72 100644 --- a/modules/core/02-client/keeper/proposal.go +++ b/modules/core/02-client/keeper/proposal.go @@ -1,68 +1,61 @@ package keeper import ( - "github.com/armon/go-metrics" + errorsmod "cosmossdk.io/errors" + metrics "github.com/armon/go-metrics" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // ClientUpdateProposal will retrieve the subject and substitute client. // A callback will occur to the subject client state with the client // prefixed store being provided for both the subject and the substitute client. -// The localhost client is not allowed to be modified with a proposal. The IBC -// client implementations are responsible for validating the parameters of the +// The IBC client implementations are responsible for validating the parameters of the // subtitute (enusring they match the subject's parameters) as well as copying // the necessary consensus states from the subtitute to the subject client // store. The substitute must be Active and the subject must not be Active. func (k Keeper) ClientUpdateProposal(ctx sdk.Context, p *types.ClientUpdateProposal) error { - if p.SubjectClientId == exported.Localhost || p.SubstituteClientId == exported.Localhost { - return sdkerrors.Wrap(types.ErrInvalidUpdateClientProposal, "cannot update localhost client with proposal") - } - subjectClientState, found := k.GetClientState(ctx, p.SubjectClientId) if !found { - return sdkerrors.Wrapf(types.ErrClientNotFound, "subject client with ID %s", p.SubjectClientId) + return errorsmod.Wrapf(types.ErrClientNotFound, "subject client with ID %s", p.SubjectClientId) } subjectClientStore := k.ClientStore(ctx, p.SubjectClientId) if status := subjectClientState.Status(ctx, subjectClientStore, k.cdc); status == exported.Active { - return sdkerrors.Wrap(types.ErrInvalidUpdateClientProposal, "cannot update Active subject client") + return errorsmod.Wrap(types.ErrInvalidUpdateClientProposal, "cannot update Active subject client") } substituteClientState, found := k.GetClientState(ctx, p.SubstituteClientId) if !found { - return sdkerrors.Wrapf(types.ErrClientNotFound, "substitute client with ID %s", p.SubstituteClientId) + return errorsmod.Wrapf(types.ErrClientNotFound, "substitute client with ID %s", p.SubstituteClientId) } if subjectClientState.GetLatestHeight().GTE(substituteClientState.GetLatestHeight()) { - return sdkerrors.Wrapf(types.ErrInvalidHeight, "subject client state latest height is greater or equal to substitute client state latest height (%s >= %s)", subjectClientState.GetLatestHeight(), substituteClientState.GetLatestHeight()) + return errorsmod.Wrapf(types.ErrInvalidHeight, "subject client state latest height is greater or equal to substitute client state latest height (%s >= %s)", subjectClientState.GetLatestHeight(), substituteClientState.GetLatestHeight()) } substituteClientStore := k.ClientStore(ctx, p.SubstituteClientId) if status := substituteClientState.Status(ctx, substituteClientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(types.ErrClientNotActive, "substitute client is not Active, status is %s", status) + return errorsmod.Wrapf(types.ErrClientNotActive, "substitute client is not Active, status is %s", status) } - clientState, err := subjectClientState.CheckSubstituteAndUpdateState(ctx, k.cdc, subjectClientStore, substituteClientStore, substituteClientState) - if err != nil { + if err := subjectClientState.CheckSubstituteAndUpdateState(ctx, k.cdc, subjectClientStore, substituteClientStore, substituteClientState); err != nil { return err } - k.SetClientState(ctx, p.SubjectClientId, clientState) - k.Logger(ctx).Info("client updated after governance proposal passed", "client-id", p.SubjectClientId, "height", clientState.GetLatestHeight().String()) + k.Logger(ctx).Info("client updated after governance proposal passed", "client-id", p.SubjectClientId) defer func() { telemetry.IncrCounterWithLabels( []string{"ibc", "client", "update"}, 1, []metrics.Label{ - telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), + telemetry.NewLabel(types.LabelClientType, substituteClientState.ClientType()), telemetry.NewLabel(types.LabelClientID, p.SubjectClientId), telemetry.NewLabel(types.LabelUpdateType, "proposal"), }, @@ -70,7 +63,7 @@ func (k Keeper) ClientUpdateProposal(ctx sdk.Context, p *types.ClientUpdatePropo }() // emitting events in the keeper for proposal updates to clients - EmitUpdateClientProposalEvent(ctx, p.SubjectClientId, clientState) + emitUpdateClientProposalEvent(ctx, p.SubjectClientId, substituteClientState.ClientType()) return nil } @@ -82,14 +75,14 @@ func (k Keeper) ClientUpdateProposal(ctx sdk.Context, p *types.ClientUpdatePropo func (k Keeper) HandleUpgradeProposal(ctx sdk.Context, p *types.UpgradeProposal) error { clientState, err := types.UnpackClientState(p.UpgradedClientState) if err != nil { - return sdkerrors.Wrap(err, "could not unpack UpgradedClientState") + return errorsmod.Wrap(err, "could not unpack UpgradedClientState") } // zero out any custom fields before setting cs := clientState.ZeroCustomFields() bz, err := types.MarshalClientState(k.cdc, cs) if err != nil { - return sdkerrors.Wrap(err, "could not marshal UpgradedClientState") + return errorsmod.Wrap(err, "could not marshal UpgradedClientState") } if err := k.upgradeKeeper.ScheduleUpgrade(ctx, p.Plan); err != nil { @@ -103,7 +96,7 @@ func (k Keeper) HandleUpgradeProposal(ctx sdk.Context, p *types.UpgradeProposal) } // emitting an event for handling client upgrade proposal - EmitUpgradeClientProposalEvent(ctx, p.Title, p.Plan.Height) + emitUpgradeClientProposalEvent(ctx, p.Title, p.Plan.Height) return nil } diff --git a/modules/core/02-client/keeper/proposal_test.go b/modules/core/02-client/keeper/proposal_test.go index 5a635d99ecc..651e3db61b5 100644 --- a/modules/core/02-client/keeper/proposal_test.go +++ b/modules/core/02-client/keeper/proposal_test.go @@ -1,13 +1,13 @@ package keeper_test import ( - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/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/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestClientUpdateProposal() { @@ -15,7 +15,6 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { subject, substitute string subjectClientState, substituteClientState exported.ClientState content govtypes.Content - err error ) testCases := []struct { @@ -30,7 +29,7 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { }, { "subject and substitute use different revision numbers", func() { - tmClientState, ok := substituteClientState.(*ibctmtypes.ClientState) + tmClientState, ok := substituteClientState.(*ibctm.ClientState) suite.Require().True(ok) consState, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientConsensusState(suite.chainA.GetContext(), substitute, tmClientState.LatestHeight) suite.Require().True(found) @@ -40,23 +39,13 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), substitute, tmClientState.LatestHeight, consState) clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), substitute) - ibctmtypes.SetProcessedTime(clientStore, tmClientState.LatestHeight, 100) - ibctmtypes.SetProcessedHeight(clientStore, tmClientState.LatestHeight, types.NewHeight(0, 1)) + ibctm.SetProcessedTime(clientStore, tmClientState.LatestHeight, 100) + ibctm.SetProcessedHeight(clientStore, tmClientState.LatestHeight, types.NewHeight(0, 1)) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitute, tmClientState) content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute) }, true, }, - { - "cannot use localhost as subject", func() { - content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, exported.Localhost, substitute) - }, false, - }, - { - "cannot use localhost as substitute", func() { - content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, exported.Localhost) - }, false, - }, { "cannot use solomachine as substitute for tendermint client", func() { solomachine := ibctesting.NewSolomachine(suite.T(), suite.cdc, "solo machine", "", 1) @@ -78,7 +67,7 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { }, { "subject and substitute have equal latest height", func() { - tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState) + tmClientState, ok := subjectClientState.(*ibctm.ClientState) suite.Require().True(ok) tmClientState.LatestHeight = substituteClientState.GetLatestHeight().(types.Height) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState) @@ -88,7 +77,7 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { }, { "update fails, client is not frozen or expired", func() { - tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState) + tmClientState, ok := subjectClientState.(*ibctm.ClientState) suite.Require().True(ok) tmClientState.FrozenHeight = types.ZeroHeight() suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState) @@ -98,7 +87,7 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { }, { "substitute is frozen", func() { - tmClientState, ok := substituteClientState.(*ibctmtypes.ClientState) + tmClientState, ok := substituteClientState.(*ibctm.ClientState) suite.Require().True(ok) tmClientState.FrozenHeight = types.NewHeight(0, 1) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitute, tmClientState) @@ -124,18 +113,20 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { substitute = substitutePath.EndpointA.ClientID // update substitute twice - substitutePath.EndpointA.UpdateClient() - substitutePath.EndpointA.UpdateClient() + err := substitutePath.EndpointA.UpdateClient() + suite.Require().NoError(err) + err = substitutePath.EndpointA.UpdateClient() + suite.Require().NoError(err) substituteClientState = suite.chainA.GetClientState(substitute) - tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState) + tmClientState, ok := subjectClientState.(*ibctm.ClientState) suite.Require().True(ok) tmClientState.AllowUpdateAfterMisbehaviour = true tmClientState.AllowUpdateAfterExpiry = true tmClientState.FrozenHeight = tmClientState.LatestHeight suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState) - tmClientState, ok = substituteClientState.(*ibctmtypes.ClientState) + tmClientState, ok = substituteClientState.(*ibctm.ClientState) suite.Require().True(ok) tmClientState.AllowUpdateAfterMisbehaviour = true tmClientState.AllowUpdateAfterExpiry = true @@ -158,7 +149,7 @@ func (suite *KeeperTestSuite) TestClientUpdateProposal() { func (suite *KeeperTestSuite) TestHandleUpgradeProposal() { var ( - upgradedClientState *ibctmtypes.ClientState + upgradedClientState *ibctm.ClientState oldPlan, plan upgradetypes.Plan content govtypes.Content err error @@ -188,13 +179,13 @@ func (suite *KeeperTestSuite) TestHandleUpgradeProposal() { }, { "cannot unpack client state", func() { - any, err := types.PackConsensusState(&ibctmtypes.ConsensusState{}) + protoAny, err := types.PackConsensusState(&ibctm.ConsensusState{}) suite.Require().NoError(err) content = &types.UpgradeProposal{ Title: ibctesting.Title, Description: ibctesting.Description, Plan: plan, - UpgradedClientState: any, + UpgradedClientState: protoAny, } }, false, }, @@ -209,7 +200,7 @@ func (suite *KeeperTestSuite) TestHandleUpgradeProposal() { path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(path) - upgradedClientState = suite.chainA.GetClientState(path.EndpointA.ClientID).ZeroCustomFields().(*ibctmtypes.ClientState) + upgradedClientState = suite.chainA.GetClientState(path.EndpointA.ClientID).ZeroCustomFields().(*ibctm.ClientState) // use height 1000 to distinguish from old plan plan = upgradetypes.Plan{ @@ -228,7 +219,8 @@ func (suite *KeeperTestSuite) TestHandleUpgradeProposal() { bz, err := types.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClientState) suite.Require().NoError(err) - suite.chainA.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainA.GetContext(), oldPlan.Height, bz) + + suite.chainA.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainA.GetContext(), oldPlan.Height, bz) //nolint:errcheck } upgradeProp, ok := content.(*types.UpgradeProposal) diff --git a/modules/core/02-client/legacy/v100/genesis.go b/modules/core/02-client/legacy/v100/genesis.go deleted file mode 100644 index 156a067f386..00000000000 --- a/modules/core/02-client/legacy/v100/genesis.go +++ /dev/null @@ -1,151 +0,0 @@ -package v100 - -import ( - "bytes" - "time" - - "github.com/cosmos/cosmos-sdk/codec" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" -) - -// MigrateGenesis accepts exported v1.0.0 IBC client genesis file and migrates it to: -// -// - Update solo machine client state protobuf definition (v1 to v2) -// - Remove all solo machine consensus states -// - Remove all expired tendermint consensus states -// - Adds ProcessedHeight and Iteration keys for unexpired tendermint consensus states -func MigrateGenesis(cdc codec.BinaryCodec, clientGenState *types.GenesisState, genesisBlockTime time.Time, selfHeight exported.Height) (*types.GenesisState, error) { - // To prune the consensus states, we will create new clientsConsensus - // and clientsMetadata. These slices will be filled up with consensus states - // which should not be pruned. No solo machine consensus states should be added - // and only unexpired consensus states for tendermint clients will be added. - // The metadata keys for unexpired consensus states will be added to clientsMetadata - var ( - clientsConsensus []types.ClientConsensusStates - clientsMetadata []types.IdentifiedGenesisMetadata - ) - - for i, client := range clientGenState.Clients { - clientType, _, err := types.ParseClientIdentifier(client.ClientId) - if err != nil { - return nil, err - } - - // update solo machine client state defintions - if clientType == exported.Solomachine { - clientState := &ClientState{} - if err := cdc.Unmarshal(client.ClientState.Value, clientState); err != nil { - return nil, sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") - } - - updatedClientState := migrateSolomachine(clientState) - - any, err := types.PackClientState(updatedClientState) - if err != nil { - return nil, err - } - - clientGenState.Clients[i] = types.IdentifiedClientState{ - ClientId: client.ClientId, - ClientState: any, - } - } - - // iterate consensus states by client - for _, clientConsensusStates := range clientGenState.ClientsConsensus { - // look for consensus states for the current client - if clientConsensusStates.ClientId == client.ClientId { - switch clientType { - case exported.Solomachine: - // remove all consensus states for the solo machine - // do not add to new clientsConsensus - - case exported.Tendermint: - // only add non expired consensus states to new clientsConsensus - tmClientState, ok := client.ClientState.GetCachedValue().(*ibctmtypes.ClientState) - if !ok { - return nil, types.ErrInvalidClient - } - - // collect unexpired consensus states - var unexpiredConsensusStates []types.ConsensusStateWithHeight - for _, consState := range clientConsensusStates.ConsensusStates { - tmConsState := consState.ConsensusState.GetCachedValue().(*ibctmtypes.ConsensusState) - if !tmClientState.IsExpired(tmConsState.Timestamp, genesisBlockTime) { - unexpiredConsensusStates = append(unexpiredConsensusStates, consState) - } - } - - // if we found at least one unexpired consensus state, create a clientConsensusState - // and add it to clientsConsensus - if len(unexpiredConsensusStates) != 0 { - clientsConsensus = append(clientsConsensus, types.ClientConsensusStates{ - ClientId: client.ClientId, - ConsensusStates: unexpiredConsensusStates, - }) - } - - // collect metadata for unexpired consensus states - var clientMetadata []types.GenesisMetadata - - // remove all expired tendermint consensus state metadata by adding only - // unexpired consensus state metadata - for _, consState := range unexpiredConsensusStates { - for _, identifiedGenMetadata := range clientGenState.ClientsMetadata { - // look for metadata for current client - if identifiedGenMetadata.ClientId == client.ClientId { - - // obtain height for consensus state being pruned - height := consState.Height - - // iterate through metadata and find metadata for current unexpired height - // only unexpired consensus state metadata should be added - for _, metadata := range identifiedGenMetadata.ClientMetadata { - // the previous version of IBC only contained the processed time metadata - // if we find the processed time metadata for an unexpired height, add the - // iteration key and processed height keys. - if bytes.Equal(metadata.Key, ibctmtypes.ProcessedTimeKey(height)) { - clientMetadata = append(clientMetadata, - // set the processed height using the current self height - // this is safe, it may cause delays in packet processing if there - // is a non zero connection delay time - types.GenesisMetadata{ - Key: ibctmtypes.ProcessedHeightKey(height), - Value: []byte(selfHeight.String()), - }, - metadata, // processed time - types.GenesisMetadata{ - Key: ibctmtypes.IterationKey(height), - Value: host.ConsensusStateKey(height), - }) - } - } - - } - } - } - - // if we have metadata for unexipred consensus states, add it to consensusMetadata - if len(clientMetadata) != 0 { - clientsMetadata = append(clientsMetadata, types.IdentifiedGenesisMetadata{ - ClientId: client.ClientId, - ClientMetadata: clientMetadata, - }) - } - - default: - break - } - } - } - } - - clientGenState.ClientsConsensus = clientsConsensus - clientGenState.ClientsMetadata = clientsMetadata - return clientGenState, nil -} diff --git a/modules/core/02-client/legacy/v100/genesis_test.go b/modules/core/02-client/legacy/v100/genesis_test.go deleted file mode 100644 index 04f6b33f053..00000000000 --- a/modules/core/02-client/legacy/v100/genesis_test.go +++ /dev/null @@ -1,308 +0,0 @@ -package v100_test - -import ( - "bytes" - "encoding/json" - "time" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client" - v100 "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - "github.com/cosmos/ibc-go/v4/testing/simapp" -) - -func (suite *LegacyTestSuite) TestMigrateGenesisSolomachine() { - path := ibctesting.NewPath(suite.chainA, suite.chainB) - encodingConfig := simapp.MakeTestEncodingConfig() - clientCtx := client.Context{}. - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithJSONCodec(encodingConfig.Marshaler) - - // create multiple legacy solo machine clients - solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1) - solomachineMulti := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4) - - // create tendermint clients - suite.coordinator.SetupClients(path) - err := path.EndpointA.UpdateClient() - suite.Require().NoError(err) - clientGenState := ibcclient.ExportGenesis(path.EndpointA.Chain.GetContext(), path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper) - - // manually generate old proto buf definitions and set in genesis - // NOTE: we cannot use 'ExportGenesis' for the solo machines since we are - // using client states and consensus states which do not implement the exported.ClientState - // and exported.ConsensusState interface - var clients []types.IdentifiedClientState - for _, sm := range []*ibctesting.Solomachine{solomachine, solomachineMulti} { - clientState := sm.ClientState() - - var seq uint64 - if clientState.IsFrozen { - seq = 1 - } - - // generate old client state proto defintion - legacyClientState := &v100.ClientState{ - Sequence: clientState.Sequence, - FrozenSequence: seq, - ConsensusState: &v100.ConsensusState{ - PublicKey: clientState.ConsensusState.PublicKey, - Diversifier: clientState.ConsensusState.Diversifier, - Timestamp: clientState.ConsensusState.Timestamp, - }, - AllowUpdateAfterProposal: clientState.AllowUpdateAfterProposal, - } - - // set client state - any, err := codectypes.NewAnyWithValue(legacyClientState) - suite.Require().NoError(err) - suite.Require().NotNil(any) - client := types.IdentifiedClientState{ - ClientId: sm.ClientID, - ClientState: any, - } - clients = append(clients, client) - - // set in store for ease of determining expected genesis - clientStore := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(path.EndpointA.Chain.GetContext(), sm.ClientID) - bz, err := path.EndpointA.Chain.App.AppCodec().MarshalInterface(legacyClientState) - suite.Require().NoError(err) - clientStore.Set(host.ClientStateKey(), bz) - - // set some consensus states - height1 := types.NewHeight(0, 1) - height2 := types.NewHeight(1, 2) - height3 := types.NewHeight(0, 123) - - any, err = codectypes.NewAnyWithValue(legacyClientState.ConsensusState) - suite.Require().NoError(err) - suite.Require().NotNil(any) - consensusState1 := types.ConsensusStateWithHeight{ - Height: height1, - ConsensusState: any, - } - consensusState2 := types.ConsensusStateWithHeight{ - Height: height2, - ConsensusState: any, - } - consensusState3 := types.ConsensusStateWithHeight{ - Height: height3, - ConsensusState: any, - } - - clientConsensusState := types.ClientConsensusStates{ - ClientId: sm.ClientID, - ConsensusStates: []types.ConsensusStateWithHeight{consensusState1, consensusState2, consensusState3}, - } - - clientGenState.ClientsConsensus = append(clientGenState.ClientsConsensus, clientConsensusState) - - // set in store for ease of determining expected genesis - bz, err = path.EndpointA.Chain.App.AppCodec().MarshalInterface(legacyClientState.ConsensusState) - suite.Require().NoError(err) - clientStore.Set(host.ConsensusStateKey(height1), bz) - clientStore.Set(host.ConsensusStateKey(height2), bz) - clientStore.Set(host.ConsensusStateKey(height3), bz) - } - // solo machine clients must come before tendermint in expected - clientGenState.Clients = append(clients, clientGenState.Clients...) - - // migrate store get expected genesis - // store migration and genesis migration should produce identical results - err = v100.MigrateStore(path.EndpointA.Chain.GetContext(), path.EndpointA.Chain.GetSimApp().GetKey(host.StoreKey), path.EndpointA.Chain.App.AppCodec()) - suite.Require().NoError(err) - expectedClientGenState := ibcclient.ExportGenesis(path.EndpointA.Chain.GetContext(), path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper) - - // NOTE: genesis time isn't updated since we aren't testing for tendermint consensus state pruning - migrated, err := v100.MigrateGenesis(codec.NewProtoCodec(clientCtx.InterfaceRegistry), &clientGenState, suite.coordinator.CurrentTime, types.GetSelfHeight(suite.chainA.GetContext())) - suite.Require().NoError(err) - - // 'ExportGenesis' order metadata keys by processedheight, processedtime for all heights, then it appends all iteration keys - // In order to match the genesis migration with export genesis (from store migrations) we must reorder the iteration keys to be last - // This isn't ideal, but it is better than modifying the genesis migration from a previous version to match the export genesis of a new version - // which provides no benefit except nicer testing - for i, clientMetadata := range migrated.ClientsMetadata { - var updatedMetadata []types.GenesisMetadata - var iterationKeys []types.GenesisMetadata - for _, metadata := range clientMetadata.ClientMetadata { - if bytes.HasPrefix(metadata.Key, []byte(ibctmtypes.KeyIterateConsensusStatePrefix)) { - iterationKeys = append(iterationKeys, metadata) - } else { - updatedMetadata = append(updatedMetadata, metadata) - } - } - updatedMetadata = append(updatedMetadata, iterationKeys...) - migrated.ClientsMetadata[i] = types.IdentifiedGenesisMetadata{ - ClientId: clientMetadata.ClientId, - ClientMetadata: updatedMetadata, - } - } - - bz, err := clientCtx.JSONCodec.MarshalJSON(&expectedClientGenState) - suite.Require().NoError(err) - - // Indent the JSON bz correctly. - var jsonObj map[string]interface{} - err = json.Unmarshal(bz, &jsonObj) - suite.Require().NoError(err) - expectedIndentedBz, err := json.MarshalIndent(jsonObj, "", "\t") - suite.Require().NoError(err) - - bz, err = clientCtx.JSONCodec.MarshalJSON(migrated) - suite.Require().NoError(err) - - // Indent the JSON bz correctly. - err = json.Unmarshal(bz, &jsonObj) - suite.Require().NoError(err) - indentedBz, err := json.MarshalIndent(jsonObj, "", "\t") - suite.Require().NoError(err) - - suite.Require().Equal(string(expectedIndentedBz), string(indentedBz)) -} - -func (suite *LegacyTestSuite) TestMigrateGenesisTendermint() { - // create two paths and setup clients - path1 := ibctesting.NewPath(suite.chainA, suite.chainB) - path2 := ibctesting.NewPath(suite.chainA, suite.chainB) - encodingConfig := simapp.MakeTestEncodingConfig() - clientCtx := client.Context{}. - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithJSONCodec(encodingConfig.Marshaler) - - suite.coordinator.SetupClients(path1) - suite.coordinator.SetupClients(path2) - - // collect all heights expected to be pruned - var path1PruneHeights, path2PruneHeights []exported.Height - path1PruneHeights = append(path1PruneHeights, path1.EndpointA.GetClientState().GetLatestHeight()) - path2PruneHeights = append(path2PruneHeights, path2.EndpointA.GetClientState().GetLatestHeight()) - - // these heights will be expired and also pruned - for i := 0; i < 3; i++ { - path1.EndpointA.UpdateClient() - path1PruneHeights = append(path1PruneHeights, path1.EndpointA.GetClientState().GetLatestHeight()) - } - for i := 0; i < 3; i++ { - path2.EndpointA.UpdateClient() - path2PruneHeights = append(path2PruneHeights, path2.EndpointA.GetClientState().GetLatestHeight()) - } - - // Increment the time by a week - suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) - - // create the consensus state that can be used as trusted height for next update - path1.EndpointA.UpdateClient() - path1.EndpointA.UpdateClient() - path2.EndpointA.UpdateClient() - path2.EndpointA.UpdateClient() - - clientGenState := ibcclient.ExportGenesis(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper) - suite.Require().NotNil(clientGenState.Clients) - suite.Require().NotNil(clientGenState.ClientsConsensus) - suite.Require().NotNil(clientGenState.ClientsMetadata) - - // Increment the time by another week, then update the client. - // This will cause the consensus states created before the first time increment - // to be expired - suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) - - // migrate store get expected genesis - // store migration and genesis migration should produce identical results - err := v100.MigrateStore(path1.EndpointA.Chain.GetContext(), path1.EndpointA.Chain.GetSimApp().GetKey(host.StoreKey), path1.EndpointA.Chain.App.AppCodec()) - suite.Require().NoError(err) - expectedClientGenState := ibcclient.ExportGenesis(path1.EndpointA.Chain.GetContext(), path1.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper) - - migrated, err := v100.MigrateGenesis(codec.NewProtoCodec(clientCtx.InterfaceRegistry), &clientGenState, suite.coordinator.CurrentTime, types.GetSelfHeight(suite.chainA.GetContext())) - suite.Require().NoError(err) - - // 'ExportGenesis' order metadata keys by processedheight, processedtime for all heights, then it appends all iteration keys - // In order to match the genesis migration with export genesis we must reorder the iteration keys to be last - // This isn't ideal, but it is better than modifying the genesis migration from a previous version to match the export genesis of a new version - // which provides no benefit except nicer testing - for i, clientMetadata := range migrated.ClientsMetadata { - var updatedMetadata []types.GenesisMetadata - var iterationKeys []types.GenesisMetadata - for _, metadata := range clientMetadata.ClientMetadata { - if bytes.HasPrefix(metadata.Key, []byte(ibctmtypes.KeyIterateConsensusStatePrefix)) { - iterationKeys = append(iterationKeys, metadata) - } else { - updatedMetadata = append(updatedMetadata, metadata) - } - } - updatedMetadata = append(updatedMetadata, iterationKeys...) - migrated.ClientsMetadata[i] = types.IdentifiedGenesisMetadata{ - ClientId: clientMetadata.ClientId, - ClientMetadata: updatedMetadata, - } - } - - // check path 1 client pruning - for _, height := range path1PruneHeights { - for _, client := range migrated.ClientsConsensus { - if client.ClientId == path1.EndpointA.ClientID { - for _, consensusState := range client.ConsensusStates { - suite.Require().NotEqual(height, consensusState.Height) - } - } - } - for _, client := range migrated.ClientsMetadata { - if client.ClientId == path1.EndpointA.ClientID { - for _, metadata := range client.ClientMetadata { - suite.Require().NotEqual(ibctmtypes.ProcessedTimeKey(height), metadata.Key) - suite.Require().NotEqual(ibctmtypes.ProcessedHeightKey(height), metadata.Key) - suite.Require().NotEqual(ibctmtypes.IterationKey(height), metadata.Key) - } - } - } - } - - // check path 2 client pruning - for _, height := range path2PruneHeights { - for _, client := range migrated.ClientsConsensus { - if client.ClientId == path2.EndpointA.ClientID { - for _, consensusState := range client.ConsensusStates { - suite.Require().NotEqual(height, consensusState.Height) - } - } - } - for _, client := range migrated.ClientsMetadata { - if client.ClientId == path2.EndpointA.ClientID { - for _, metadata := range client.ClientMetadata { - suite.Require().NotEqual(ibctmtypes.ProcessedTimeKey(height), metadata.Key) - suite.Require().NotEqual(ibctmtypes.ProcessedHeightKey(height), metadata.Key) - suite.Require().NotEqual(ibctmtypes.IterationKey(height), metadata.Key) - } - } - } - } - bz, err := clientCtx.JSONCodec.MarshalJSON(&expectedClientGenState) - suite.Require().NoError(err) - - // Indent the JSON bz correctly. - var jsonObj map[string]interface{} - err = json.Unmarshal(bz, &jsonObj) - suite.Require().NoError(err) - expectedIndentedBz, err := json.MarshalIndent(jsonObj, "", "\t") - suite.Require().NoError(err) - - bz, err = clientCtx.JSONCodec.MarshalJSON(migrated) - suite.Require().NoError(err) - - // Indent the JSON bz correctly. - err = json.Unmarshal(bz, &jsonObj) - suite.Require().NoError(err) - indentedBz, err := json.MarshalIndent(jsonObj, "", "\t") - suite.Require().NoError(err) - - suite.Require().Equal(string(expectedIndentedBz), string(indentedBz)) -} diff --git a/modules/core/02-client/legacy/v100/solomachine.pb.go b/modules/core/02-client/legacy/v100/solomachine.pb.go deleted file mode 100644 index 3ed69fb1b21..00000000000 --- a/modules/core/02-client/legacy/v100/solomachine.pb.go +++ /dev/null @@ -1,4121 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: ibc/lightclients/solomachine/v1/solomachine.proto - -package v100 - -import ( - fmt "fmt" - types "github.com/cosmos/cosmos-sdk/codec/types" - types1 "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - types2 "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// DataType defines the type of solo machine proof being created. This is done -// to preserve uniqueness of different data sign byte encodings. -type DataType int32 - -const ( - // Default State - UNSPECIFIED DataType = 0 - // Data type for client state verification - CLIENT DataType = 1 - // Data type for consensus state verification - CONSENSUS DataType = 2 - // Data type for connection state verification - CONNECTION DataType = 3 - // Data type for channel state verification - CHANNEL DataType = 4 - // Data type for packet commitment verification - PACKETCOMMITMENT DataType = 5 - // Data type for packet acknowledgement verification - PACKETACKNOWLEDGEMENT DataType = 6 - // Data type for packet receipt absence verification - PACKETRECEIPTABSENCE DataType = 7 - // Data type for next sequence recv verification - NEXTSEQUENCERECV DataType = 8 - // Data type for header verification - HEADER DataType = 9 -) - -var DataType_name = map[int32]string{ - 0: "DATA_TYPE_UNINITIALIZED_UNSPECIFIED", - 1: "DATA_TYPE_CLIENT_STATE", - 2: "DATA_TYPE_CONSENSUS_STATE", - 3: "DATA_TYPE_CONNECTION_STATE", - 4: "DATA_TYPE_CHANNEL_STATE", - 5: "DATA_TYPE_PACKET_COMMITMENT", - 6: "DATA_TYPE_PACKET_ACKNOWLEDGEMENT", - 7: "DATA_TYPE_PACKET_RECEIPT_ABSENCE", - 8: "DATA_TYPE_NEXT_SEQUENCE_RECV", - 9: "DATA_TYPE_HEADER", -} - -var DataType_value = map[string]int32{ - "DATA_TYPE_UNINITIALIZED_UNSPECIFIED": 0, - "DATA_TYPE_CLIENT_STATE": 1, - "DATA_TYPE_CONSENSUS_STATE": 2, - "DATA_TYPE_CONNECTION_STATE": 3, - "DATA_TYPE_CHANNEL_STATE": 4, - "DATA_TYPE_PACKET_COMMITMENT": 5, - "DATA_TYPE_PACKET_ACKNOWLEDGEMENT": 6, - "DATA_TYPE_PACKET_RECEIPT_ABSENCE": 7, - "DATA_TYPE_NEXT_SEQUENCE_RECV": 8, - "DATA_TYPE_HEADER": 9, -} - -func (x DataType) String() string { - return proto.EnumName(DataType_name, int32(x)) -} - -func (DataType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{0} -} - -// ClientState defines a solo machine client that tracks the current consensus -// state and if the client is frozen. -type ClientState struct { - // latest sequence of the client state - Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` - // frozen sequence of the solo machine - FrozenSequence uint64 `protobuf:"varint,2,opt,name=frozen_sequence,json=frozenSequence,proto3" json:"frozen_sequence,omitempty" yaml:"frozen_sequence"` - ConsensusState *ConsensusState `protobuf:"bytes,3,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty" yaml:"consensus_state"` - // when set to true, will allow governance to update a solo machine client. - // The client will be unfrozen if it is frozen. - AllowUpdateAfterProposal bool `protobuf:"varint,4,opt,name=allow_update_after_proposal,json=allowUpdateAfterProposal,proto3" json:"allow_update_after_proposal,omitempty" yaml:"allow_update_after_proposal"` -} - -func (m *ClientState) Reset() { *m = ClientState{} } -func (m *ClientState) String() string { return proto.CompactTextString(m) } -func (*ClientState) ProtoMessage() {} -func (*ClientState) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{0} -} -func (m *ClientState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ClientState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ClientState.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 *ClientState) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClientState.Merge(m, src) -} -func (m *ClientState) XXX_Size() int { - return m.Size() -} -func (m *ClientState) XXX_DiscardUnknown() { - xxx_messageInfo_ClientState.DiscardUnknown(m) -} - -var xxx_messageInfo_ClientState proto.InternalMessageInfo - -// ConsensusState defines a solo machine consensus state. The sequence of a -// consensus state is contained in the "height" key used in storing the -// consensus state. -type ConsensusState struct { - // public key of the solo machine - PublicKey *types.Any `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty" yaml:"public_key"` - // diversifier allows the same public key to be re-used across different solo - // machine clients (potentially on different chains) without being considered - // misbehaviour. - Diversifier string `protobuf:"bytes,2,opt,name=diversifier,proto3" json:"diversifier,omitempty"` - Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` -} - -func (m *ConsensusState) Reset() { *m = ConsensusState{} } -func (m *ConsensusState) String() string { return proto.CompactTextString(m) } -func (*ConsensusState) ProtoMessage() {} -func (*ConsensusState) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{1} -} -func (m *ConsensusState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ConsensusState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ConsensusState.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 *ConsensusState) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConsensusState.Merge(m, src) -} -func (m *ConsensusState) XXX_Size() int { - return m.Size() -} -func (m *ConsensusState) XXX_DiscardUnknown() { - xxx_messageInfo_ConsensusState.DiscardUnknown(m) -} - -var xxx_messageInfo_ConsensusState proto.InternalMessageInfo - -// Header defines a solo machine consensus header -type Header struct { - // sequence to update solo machine public key at - Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"` - NewPublicKey *types.Any `protobuf:"bytes,4,opt,name=new_public_key,json=newPublicKey,proto3" json:"new_public_key,omitempty" yaml:"new_public_key"` - NewDiversifier string `protobuf:"bytes,5,opt,name=new_diversifier,json=newDiversifier,proto3" json:"new_diversifier,omitempty" yaml:"new_diversifier"` -} - -func (m *Header) Reset() { *m = Header{} } -func (m *Header) String() string { return proto.CompactTextString(m) } -func (*Header) ProtoMessage() {} -func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{2} -} -func (m *Header) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Header.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 *Header) XXX_Merge(src proto.Message) { - xxx_messageInfo_Header.Merge(m, src) -} -func (m *Header) XXX_Size() int { - return m.Size() -} -func (m *Header) XXX_DiscardUnknown() { - xxx_messageInfo_Header.DiscardUnknown(m) -} - -var xxx_messageInfo_Header proto.InternalMessageInfo - -// Misbehaviour defines misbehaviour for a solo machine which consists -// of a sequence and two signatures over different messages at that sequence. -type Misbehaviour struct { - ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` - Sequence uint64 `protobuf:"varint,2,opt,name=sequence,proto3" json:"sequence,omitempty"` - SignatureOne *SignatureAndData `protobuf:"bytes,3,opt,name=signature_one,json=signatureOne,proto3" json:"signature_one,omitempty" yaml:"signature_one"` - SignatureTwo *SignatureAndData `protobuf:"bytes,4,opt,name=signature_two,json=signatureTwo,proto3" json:"signature_two,omitempty" yaml:"signature_two"` -} - -func (m *Misbehaviour) Reset() { *m = Misbehaviour{} } -func (m *Misbehaviour) String() string { return proto.CompactTextString(m) } -func (*Misbehaviour) ProtoMessage() {} -func (*Misbehaviour) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{3} -} -func (m *Misbehaviour) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Misbehaviour) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Misbehaviour.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 *Misbehaviour) XXX_Merge(src proto.Message) { - xxx_messageInfo_Misbehaviour.Merge(m, src) -} -func (m *Misbehaviour) XXX_Size() int { - return m.Size() -} -func (m *Misbehaviour) XXX_DiscardUnknown() { - xxx_messageInfo_Misbehaviour.DiscardUnknown(m) -} - -var xxx_messageInfo_Misbehaviour proto.InternalMessageInfo - -// SignatureAndData contains a signature and the data signed over to create that -// signature. -type SignatureAndData struct { - Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` - DataType DataType `protobuf:"varint,2,opt,name=data_type,json=dataType,proto3,enum=ibc.lightclients.solomachine.v1.DataType" json:"data_type,omitempty" yaml:"data_type"` - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` - Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` -} - -func (m *SignatureAndData) Reset() { *m = SignatureAndData{} } -func (m *SignatureAndData) String() string { return proto.CompactTextString(m) } -func (*SignatureAndData) ProtoMessage() {} -func (*SignatureAndData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{4} -} -func (m *SignatureAndData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SignatureAndData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SignatureAndData.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 *SignatureAndData) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignatureAndData.Merge(m, src) -} -func (m *SignatureAndData) XXX_Size() int { - return m.Size() -} -func (m *SignatureAndData) XXX_DiscardUnknown() { - xxx_messageInfo_SignatureAndData.DiscardUnknown(m) -} - -var xxx_messageInfo_SignatureAndData proto.InternalMessageInfo - -// TimestampedSignatureData contains the signature data and the timestamp of the -// signature. -type TimestampedSignatureData struct { - SignatureData []byte `protobuf:"bytes,1,opt,name=signature_data,json=signatureData,proto3" json:"signature_data,omitempty" yaml:"signature_data"` - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` -} - -func (m *TimestampedSignatureData) Reset() { *m = TimestampedSignatureData{} } -func (m *TimestampedSignatureData) String() string { return proto.CompactTextString(m) } -func (*TimestampedSignatureData) ProtoMessage() {} -func (*TimestampedSignatureData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{5} -} -func (m *TimestampedSignatureData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *TimestampedSignatureData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_TimestampedSignatureData.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 *TimestampedSignatureData) XXX_Merge(src proto.Message) { - xxx_messageInfo_TimestampedSignatureData.Merge(m, src) -} -func (m *TimestampedSignatureData) XXX_Size() int { - return m.Size() -} -func (m *TimestampedSignatureData) XXX_DiscardUnknown() { - xxx_messageInfo_TimestampedSignatureData.DiscardUnknown(m) -} - -var xxx_messageInfo_TimestampedSignatureData proto.InternalMessageInfo - -// SignBytes defines the signed bytes used for signature verification. -type SignBytes struct { - Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Diversifier string `protobuf:"bytes,3,opt,name=diversifier,proto3" json:"diversifier,omitempty"` - // type of the data used - DataType DataType `protobuf:"varint,4,opt,name=data_type,json=dataType,proto3,enum=ibc.lightclients.solomachine.v1.DataType" json:"data_type,omitempty" yaml:"data_type"` - // marshaled data - Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` -} - -func (m *SignBytes) Reset() { *m = SignBytes{} } -func (m *SignBytes) String() string { return proto.CompactTextString(m) } -func (*SignBytes) ProtoMessage() {} -func (*SignBytes) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{6} -} -func (m *SignBytes) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SignBytes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_SignBytes.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 *SignBytes) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignBytes.Merge(m, src) -} -func (m *SignBytes) XXX_Size() int { - return m.Size() -} -func (m *SignBytes) XXX_DiscardUnknown() { - xxx_messageInfo_SignBytes.DiscardUnknown(m) -} - -var xxx_messageInfo_SignBytes proto.InternalMessageInfo - -// HeaderData returns the SignBytes data for update verification. -type HeaderData struct { - // header public key - NewPubKey *types.Any `protobuf:"bytes,1,opt,name=new_pub_key,json=newPubKey,proto3" json:"new_pub_key,omitempty" yaml:"new_pub_key"` - // header diversifier - NewDiversifier string `protobuf:"bytes,2,opt,name=new_diversifier,json=newDiversifier,proto3" json:"new_diversifier,omitempty" yaml:"new_diversifier"` -} - -func (m *HeaderData) Reset() { *m = HeaderData{} } -func (m *HeaderData) String() string { return proto.CompactTextString(m) } -func (*HeaderData) ProtoMessage() {} -func (*HeaderData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{7} -} -func (m *HeaderData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *HeaderData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_HeaderData.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 *HeaderData) XXX_Merge(src proto.Message) { - xxx_messageInfo_HeaderData.Merge(m, src) -} -func (m *HeaderData) XXX_Size() int { - return m.Size() -} -func (m *HeaderData) XXX_DiscardUnknown() { - xxx_messageInfo_HeaderData.DiscardUnknown(m) -} - -var xxx_messageInfo_HeaderData proto.InternalMessageInfo - -// ClientStateData returns the SignBytes data for client state verification. -type ClientStateData struct { - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - ClientState *types.Any `protobuf:"bytes,2,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` -} - -func (m *ClientStateData) Reset() { *m = ClientStateData{} } -func (m *ClientStateData) String() string { return proto.CompactTextString(m) } -func (*ClientStateData) ProtoMessage() {} -func (*ClientStateData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{8} -} -func (m *ClientStateData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ClientStateData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ClientStateData.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 *ClientStateData) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClientStateData.Merge(m, src) -} -func (m *ClientStateData) XXX_Size() int { - return m.Size() -} -func (m *ClientStateData) XXX_DiscardUnknown() { - xxx_messageInfo_ClientStateData.DiscardUnknown(m) -} - -var xxx_messageInfo_ClientStateData proto.InternalMessageInfo - -// ConsensusStateData returns the SignBytes data for consensus state -// verification. -type ConsensusStateData struct { - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - ConsensusState *types.Any `protobuf:"bytes,2,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty" yaml:"consensus_state"` -} - -func (m *ConsensusStateData) Reset() { *m = ConsensusStateData{} } -func (m *ConsensusStateData) String() string { return proto.CompactTextString(m) } -func (*ConsensusStateData) ProtoMessage() {} -func (*ConsensusStateData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{9} -} -func (m *ConsensusStateData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ConsensusStateData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ConsensusStateData.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 *ConsensusStateData) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConsensusStateData.Merge(m, src) -} -func (m *ConsensusStateData) XXX_Size() int { - return m.Size() -} -func (m *ConsensusStateData) XXX_DiscardUnknown() { - xxx_messageInfo_ConsensusStateData.DiscardUnknown(m) -} - -var xxx_messageInfo_ConsensusStateData proto.InternalMessageInfo - -// ConnectionStateData returns the SignBytes data for connection state -// verification. -type ConnectionStateData struct { - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - Connection *types1.ConnectionEnd `protobuf:"bytes,2,opt,name=connection,proto3" json:"connection,omitempty"` -} - -func (m *ConnectionStateData) Reset() { *m = ConnectionStateData{} } -func (m *ConnectionStateData) String() string { return proto.CompactTextString(m) } -func (*ConnectionStateData) ProtoMessage() {} -func (*ConnectionStateData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{10} -} -func (m *ConnectionStateData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ConnectionStateData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ConnectionStateData.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 *ConnectionStateData) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConnectionStateData.Merge(m, src) -} -func (m *ConnectionStateData) XXX_Size() int { - return m.Size() -} -func (m *ConnectionStateData) XXX_DiscardUnknown() { - xxx_messageInfo_ConnectionStateData.DiscardUnknown(m) -} - -var xxx_messageInfo_ConnectionStateData proto.InternalMessageInfo - -// ChannelStateData returns the SignBytes data for channel state -// verification. -type ChannelStateData struct { - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - Channel *types2.Channel `protobuf:"bytes,2,opt,name=channel,proto3" json:"channel,omitempty"` -} - -func (m *ChannelStateData) Reset() { *m = ChannelStateData{} } -func (m *ChannelStateData) String() string { return proto.CompactTextString(m) } -func (*ChannelStateData) ProtoMessage() {} -func (*ChannelStateData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{11} -} -func (m *ChannelStateData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ChannelStateData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ChannelStateData.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 *ChannelStateData) XXX_Merge(src proto.Message) { - xxx_messageInfo_ChannelStateData.Merge(m, src) -} -func (m *ChannelStateData) XXX_Size() int { - return m.Size() -} -func (m *ChannelStateData) XXX_DiscardUnknown() { - xxx_messageInfo_ChannelStateData.DiscardUnknown(m) -} - -var xxx_messageInfo_ChannelStateData proto.InternalMessageInfo - -// PacketCommitmentData returns the SignBytes data for packet commitment -// verification. -type PacketCommitmentData struct { - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - Commitment []byte `protobuf:"bytes,2,opt,name=commitment,proto3" json:"commitment,omitempty"` -} - -func (m *PacketCommitmentData) Reset() { *m = PacketCommitmentData{} } -func (m *PacketCommitmentData) String() string { return proto.CompactTextString(m) } -func (*PacketCommitmentData) ProtoMessage() {} -func (*PacketCommitmentData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{12} -} -func (m *PacketCommitmentData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PacketCommitmentData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PacketCommitmentData.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 *PacketCommitmentData) XXX_Merge(src proto.Message) { - xxx_messageInfo_PacketCommitmentData.Merge(m, src) -} -func (m *PacketCommitmentData) XXX_Size() int { - return m.Size() -} -func (m *PacketCommitmentData) XXX_DiscardUnknown() { - xxx_messageInfo_PacketCommitmentData.DiscardUnknown(m) -} - -var xxx_messageInfo_PacketCommitmentData proto.InternalMessageInfo - -func (m *PacketCommitmentData) GetPath() []byte { - if m != nil { - return m.Path - } - return nil -} - -func (m *PacketCommitmentData) GetCommitment() []byte { - if m != nil { - return m.Commitment - } - return nil -} - -// PacketAcknowledgementData returns the SignBytes data for acknowledgement -// verification. -type PacketAcknowledgementData struct { - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - Acknowledgement []byte `protobuf:"bytes,2,opt,name=acknowledgement,proto3" json:"acknowledgement,omitempty"` -} - -func (m *PacketAcknowledgementData) Reset() { *m = PacketAcknowledgementData{} } -func (m *PacketAcknowledgementData) String() string { return proto.CompactTextString(m) } -func (*PacketAcknowledgementData) ProtoMessage() {} -func (*PacketAcknowledgementData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{13} -} -func (m *PacketAcknowledgementData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PacketAcknowledgementData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PacketAcknowledgementData.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 *PacketAcknowledgementData) XXX_Merge(src proto.Message) { - xxx_messageInfo_PacketAcknowledgementData.Merge(m, src) -} -func (m *PacketAcknowledgementData) XXX_Size() int { - return m.Size() -} -func (m *PacketAcknowledgementData) XXX_DiscardUnknown() { - xxx_messageInfo_PacketAcknowledgementData.DiscardUnknown(m) -} - -var xxx_messageInfo_PacketAcknowledgementData proto.InternalMessageInfo - -func (m *PacketAcknowledgementData) GetPath() []byte { - if m != nil { - return m.Path - } - return nil -} - -func (m *PacketAcknowledgementData) GetAcknowledgement() []byte { - if m != nil { - return m.Acknowledgement - } - return nil -} - -// PacketReceiptAbsenceData returns the SignBytes data for -// packet receipt absence verification. -type PacketReceiptAbsenceData struct { - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} - -func (m *PacketReceiptAbsenceData) Reset() { *m = PacketReceiptAbsenceData{} } -func (m *PacketReceiptAbsenceData) String() string { return proto.CompactTextString(m) } -func (*PacketReceiptAbsenceData) ProtoMessage() {} -func (*PacketReceiptAbsenceData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{14} -} -func (m *PacketReceiptAbsenceData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PacketReceiptAbsenceData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PacketReceiptAbsenceData.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 *PacketReceiptAbsenceData) XXX_Merge(src proto.Message) { - xxx_messageInfo_PacketReceiptAbsenceData.Merge(m, src) -} -func (m *PacketReceiptAbsenceData) XXX_Size() int { - return m.Size() -} -func (m *PacketReceiptAbsenceData) XXX_DiscardUnknown() { - xxx_messageInfo_PacketReceiptAbsenceData.DiscardUnknown(m) -} - -var xxx_messageInfo_PacketReceiptAbsenceData proto.InternalMessageInfo - -func (m *PacketReceiptAbsenceData) GetPath() []byte { - if m != nil { - return m.Path - } - return nil -} - -// NextSequenceRecvData returns the SignBytes data for verification of the next -// sequence to be received. -type NextSequenceRecvData struct { - Path []byte `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - NextSeqRecv uint64 `protobuf:"varint,2,opt,name=next_seq_recv,json=nextSeqRecv,proto3" json:"next_seq_recv,omitempty" yaml:"next_seq_recv"` -} - -func (m *NextSequenceRecvData) Reset() { *m = NextSequenceRecvData{} } -func (m *NextSequenceRecvData) String() string { return proto.CompactTextString(m) } -func (*NextSequenceRecvData) ProtoMessage() {} -func (*NextSequenceRecvData) Descriptor() ([]byte, []int) { - return fileDescriptor_6cc2ee18f7f86d4e, []int{15} -} -func (m *NextSequenceRecvData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *NextSequenceRecvData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_NextSequenceRecvData.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 *NextSequenceRecvData) XXX_Merge(src proto.Message) { - xxx_messageInfo_NextSequenceRecvData.Merge(m, src) -} -func (m *NextSequenceRecvData) XXX_Size() int { - return m.Size() -} -func (m *NextSequenceRecvData) XXX_DiscardUnknown() { - xxx_messageInfo_NextSequenceRecvData.DiscardUnknown(m) -} - -var xxx_messageInfo_NextSequenceRecvData proto.InternalMessageInfo - -func (m *NextSequenceRecvData) GetPath() []byte { - if m != nil { - return m.Path - } - return nil -} - -func (m *NextSequenceRecvData) GetNextSeqRecv() uint64 { - if m != nil { - return m.NextSeqRecv - } - return 0 -} - -func init() { - proto.RegisterEnum("ibc.lightclients.solomachine.v1.DataType", DataType_name, DataType_value) - proto.RegisterType((*ClientState)(nil), "ibc.lightclients.solomachine.v1.ClientState") - proto.RegisterType((*ConsensusState)(nil), "ibc.lightclients.solomachine.v1.ConsensusState") - proto.RegisterType((*Header)(nil), "ibc.lightclients.solomachine.v1.Header") - proto.RegisterType((*Misbehaviour)(nil), "ibc.lightclients.solomachine.v1.Misbehaviour") - proto.RegisterType((*SignatureAndData)(nil), "ibc.lightclients.solomachine.v1.SignatureAndData") - proto.RegisterType((*TimestampedSignatureData)(nil), "ibc.lightclients.solomachine.v1.TimestampedSignatureData") - proto.RegisterType((*SignBytes)(nil), "ibc.lightclients.solomachine.v1.SignBytes") - proto.RegisterType((*HeaderData)(nil), "ibc.lightclients.solomachine.v1.HeaderData") - proto.RegisterType((*ClientStateData)(nil), "ibc.lightclients.solomachine.v1.ClientStateData") - proto.RegisterType((*ConsensusStateData)(nil), "ibc.lightclients.solomachine.v1.ConsensusStateData") - proto.RegisterType((*ConnectionStateData)(nil), "ibc.lightclients.solomachine.v1.ConnectionStateData") - proto.RegisterType((*ChannelStateData)(nil), "ibc.lightclients.solomachine.v1.ChannelStateData") - proto.RegisterType((*PacketCommitmentData)(nil), "ibc.lightclients.solomachine.v1.PacketCommitmentData") - proto.RegisterType((*PacketAcknowledgementData)(nil), "ibc.lightclients.solomachine.v1.PacketAcknowledgementData") - proto.RegisterType((*PacketReceiptAbsenceData)(nil), "ibc.lightclients.solomachine.v1.PacketReceiptAbsenceData") - proto.RegisterType((*NextSequenceRecvData)(nil), "ibc.lightclients.solomachine.v1.NextSequenceRecvData") -} - -func init() { - proto.RegisterFile("ibc/lightclients/solomachine/v1/solomachine.proto", fileDescriptor_6cc2ee18f7f86d4e) -} - -var fileDescriptor_6cc2ee18f7f86d4e = []byte{ - // 1369 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x5f, 0x6f, 0xdb, 0x54, - 0x14, 0xaf, 0xb3, 0xac, 0x6b, 0x4e, 0xba, 0x36, 0x78, 0xd9, 0x96, 0x7a, 0x53, 0x62, 0x8c, 0x18, - 0x05, 0xb1, 0x78, 0x2d, 0x30, 0xa1, 0x09, 0x0d, 0x1c, 0xc7, 0xb0, 0x6c, 0xad, 0x1b, 0x1c, 0x17, - 0xb6, 0x09, 0xc9, 0x72, 0x9c, 0xdb, 0xd4, 0x5a, 0xe2, 0x1b, 0x62, 0x27, 0x5d, 0x90, 0x90, 0x10, - 0x4f, 0x23, 0xe2, 0x81, 0x2f, 0x10, 0x09, 0x81, 0xf8, 0x2a, 0xc0, 0xe3, 0x78, 0xe3, 0x29, 0xa0, - 0xed, 0x1b, 0xe4, 0x13, 0x20, 0xfb, 0xde, 0xc4, 0x76, 0xba, 0xa6, 0xe2, 0xdf, 0xdb, 0xbd, 0xe7, - 0xfc, 0xce, 0xef, 0x9c, 0x7b, 0xce, 0xf1, 0xb9, 0xd7, 0xb0, 0x65, 0xd7, 0x2d, 0xb1, 0x65, 0x37, - 0x0f, 0x3d, 0xab, 0x65, 0x23, 0xc7, 0x73, 0x45, 0x17, 0xb7, 0x70, 0xdb, 0xb4, 0x0e, 0x6d, 0x07, - 0x89, 0xfd, 0xad, 0xe8, 0xb6, 0xd8, 0xe9, 0x62, 0x0f, 0xb3, 0x05, 0xbb, 0x6e, 0x15, 0xa3, 0x26, - 0xc5, 0x28, 0xa6, 0xbf, 0xc5, 0xbd, 0xe6, 0x73, 0x5a, 0xb8, 0x8b, 0x44, 0x0b, 0x3b, 0x0e, 0xb2, - 0x3c, 0x1b, 0x3b, 0x3e, 0x55, 0xb8, 0x23, 0x4c, 0xdc, 0xcb, 0x21, 0xf0, 0xd0, 0x74, 0x1c, 0xd4, - 0x0a, 0x50, 0x64, 0x49, 0x21, 0xd9, 0x26, 0x6e, 0xe2, 0x60, 0x29, 0xfa, 0x2b, 0x2a, 0xdd, 0x68, - 0x62, 0xdc, 0x6c, 0x21, 0x31, 0xd8, 0xd5, 0x7b, 0x07, 0xa2, 0xe9, 0x0c, 0x88, 0x4a, 0xf8, 0x2d, - 0x01, 0x69, 0x39, 0x88, 0xab, 0xe6, 0x99, 0x1e, 0x62, 0x39, 0x58, 0x71, 0xd1, 0xe7, 0x3d, 0xe4, - 0x58, 0x28, 0xc7, 0xf0, 0xcc, 0x66, 0x52, 0x9b, 0xed, 0x59, 0x19, 0xd6, 0x0f, 0xba, 0xf8, 0x0b, - 0xe4, 0x18, 0x33, 0x48, 0xc2, 0x87, 0x94, 0xb8, 0xc9, 0xb8, 0x70, 0x69, 0x60, 0xb6, 0x5b, 0xb7, - 0x84, 0x39, 0x80, 0xa0, 0xad, 0x11, 0x49, 0x6d, 0x4a, 0xe2, 0xc1, 0xba, 0x85, 0x1d, 0x17, 0x39, - 0x6e, 0xcf, 0x35, 0x5c, 0xdf, 0x67, 0xee, 0x0c, 0xcf, 0x6c, 0xa6, 0xb7, 0xc5, 0xe2, 0x29, 0x89, - 0x2a, 0xca, 0x53, 0xbb, 0x20, 0xd4, 0xa8, 0xd7, 0x39, 0x46, 0x41, 0x5b, 0xb3, 0x62, 0x58, 0x16, - 0xc1, 0x15, 0xb3, 0xd5, 0xc2, 0x47, 0x46, 0xaf, 0xd3, 0x30, 0x3d, 0x64, 0x98, 0x07, 0x1e, 0xea, - 0x1a, 0x9d, 0x2e, 0xee, 0x60, 0xd7, 0x6c, 0xe5, 0x92, 0x3c, 0xb3, 0xb9, 0x52, 0xba, 0x36, 0x19, - 0x17, 0x04, 0x42, 0xb8, 0x00, 0x2c, 0x68, 0xb9, 0x40, 0xbb, 0x1f, 0x28, 0x25, 0x5f, 0x57, 0xa5, - 0xaa, 0x5b, 0xc9, 0x27, 0xdf, 0x17, 0x96, 0x84, 0x1f, 0x18, 0x58, 0x8b, 0xc7, 0xca, 0xde, 0x05, - 0xe8, 0xf4, 0xea, 0x2d, 0xdb, 0x32, 0x1e, 0xa1, 0x41, 0x90, 0xd8, 0xf4, 0x76, 0xb6, 0x48, 0xca, - 0x52, 0x9c, 0x96, 0xa5, 0x28, 0x39, 0x83, 0xd2, 0xc5, 0xc9, 0xb8, 0xf0, 0x12, 0x09, 0x22, 0xb4, - 0x10, 0xb4, 0x14, 0xd9, 0xdc, 0x43, 0x03, 0x96, 0x87, 0x74, 0xc3, 0xee, 0xa3, 0xae, 0x6b, 0x1f, - 0xd8, 0xa8, 0x1b, 0x94, 0x20, 0xa5, 0x45, 0x45, 0xec, 0x55, 0x48, 0x79, 0x76, 0x1b, 0xb9, 0x9e, - 0xd9, 0xee, 0x04, 0xd9, 0x4d, 0x6a, 0xa1, 0x80, 0x06, 0xf9, 0x75, 0x02, 0x96, 0xef, 0x20, 0xb3, - 0x81, 0xba, 0x0b, 0x6b, 0x1e, 0xa3, 0x4a, 0xcc, 0x51, 0xf9, 0x5a, 0xd7, 0x6e, 0x3a, 0xa6, 0xd7, - 0xeb, 0x92, 0x32, 0xae, 0x6a, 0xa1, 0x80, 0xdd, 0x87, 0x35, 0x07, 0x1d, 0x19, 0x91, 0x83, 0x27, - 0x17, 0x1c, 0x7c, 0x63, 0x32, 0x2e, 0x5c, 0x24, 0x07, 0x8f, 0x5b, 0x09, 0xda, 0xaa, 0x83, 0x8e, - 0xaa, 0xb3, 0xf3, 0xcb, 0xb0, 0xee, 0x03, 0xa2, 0x39, 0x38, 0xeb, 0xe7, 0x20, 0xda, 0x10, 0x73, - 0x00, 0x41, 0xf3, 0x23, 0x29, 0x87, 0x02, 0x9a, 0x84, 0x5f, 0x12, 0xb0, 0xba, 0x6b, 0xbb, 0x75, - 0x74, 0x68, 0xf6, 0x6d, 0xdc, 0xeb, 0xb2, 0x5b, 0x90, 0x22, 0xcd, 0x67, 0xd8, 0x8d, 0x20, 0x17, - 0xa9, 0x52, 0x76, 0x32, 0x2e, 0x64, 0x68, 0x9b, 0x4d, 0x55, 0x82, 0xb6, 0x42, 0xd6, 0x95, 0x46, - 0x2c, 0x7b, 0x89, 0xb9, 0xec, 0x75, 0xe0, 0xfc, 0x2c, 0x1d, 0x06, 0x76, 0xa6, 0xad, 0xbe, 0x75, - 0x6a, 0xab, 0xd7, 0xa6, 0x56, 0x92, 0xd3, 0x28, 0x9b, 0x9e, 0x59, 0xca, 0x4d, 0xc6, 0x85, 0x2c, - 0x89, 0x22, 0xc6, 0x28, 0x68, 0xab, 0xb3, 0xfd, 0x9e, 0x33, 0xe7, 0xd1, 0x3b, 0xc2, 0x34, 0xe5, - 0xff, 0x95, 0x47, 0xef, 0x08, 0x47, 0x3d, 0xea, 0x47, 0x98, 0x66, 0xf2, 0x67, 0x06, 0x32, 0xf3, - 0x14, 0xf1, 0xf6, 0x60, 0xe6, 0xdb, 0xe3, 0x33, 0x48, 0x35, 0x4c, 0xcf, 0x34, 0xbc, 0x41, 0x87, - 0x64, 0x6e, 0x6d, 0xfb, 0xf5, 0x53, 0xc3, 0xf4, 0x79, 0xf5, 0x41, 0x07, 0x45, 0xcb, 0x32, 0x63, - 0x11, 0xb4, 0x95, 0x06, 0xd5, 0xb3, 0x2c, 0x24, 0xfd, 0x35, 0xed, 0xca, 0x60, 0x1d, 0x6f, 0xe6, - 0xe4, 0x8b, 0xbf, 0x8b, 0xaf, 0x18, 0xc8, 0xe9, 0x53, 0x19, 0x6a, 0xcc, 0xce, 0x14, 0x1c, 0xe8, - 0x03, 0x58, 0x0b, 0x73, 0x11, 0xd0, 0x07, 0xa7, 0x8a, 0xf6, 0x6e, 0x5c, 0x2f, 0x68, 0x61, 0x39, - 0xca, 0xc7, 0x42, 0x48, 0xbc, 0x38, 0x84, 0x3f, 0x18, 0x48, 0xf9, 0x7e, 0x4b, 0x03, 0x0f, 0xb9, - 0xff, 0xe2, 0xeb, 0x9c, 0x1b, 0x14, 0x67, 0x8e, 0x0f, 0x8a, 0x58, 0x09, 0x92, 0xff, 0x57, 0x09, - 0xce, 0x86, 0x25, 0xa0, 0x27, 0xfc, 0x89, 0x01, 0x20, 0xc3, 0x27, 0x48, 0xca, 0x0e, 0xa4, 0xe9, - 0x27, 0x7f, 0xea, 0x78, 0xbc, 0x34, 0x19, 0x17, 0xd8, 0xd8, 0x94, 0xa0, 0xf3, 0x91, 0x8c, 0x88, - 0x13, 0xe6, 0x43, 0xe2, 0x1f, 0xce, 0x87, 0x2f, 0x61, 0x3d, 0x72, 0x39, 0x06, 0xb1, 0xb2, 0x90, - 0xec, 0x98, 0xde, 0x21, 0x6d, 0xe7, 0x60, 0xcd, 0x56, 0x61, 0x95, 0x8e, 0x06, 0x72, 0xa1, 0x25, - 0x16, 0x1c, 0xe0, 0xf2, 0x64, 0x5c, 0xb8, 0x10, 0x1b, 0x27, 0xf4, 0xca, 0x4a, 0x5b, 0xa1, 0x27, - 0xea, 0xfe, 0x1b, 0x06, 0xd8, 0xf8, 0x45, 0x72, 0x62, 0x08, 0x0f, 0x8e, 0x5f, 0xab, 0x8b, 0xa2, - 0xf8, 0x1b, 0x77, 0x27, 0x8d, 0xa5, 0x0f, 0x17, 0xe4, 0xd9, 0x83, 0x64, 0x71, 0x2c, 0x0a, 0x40, - 0xf8, 0x76, 0xa1, 0x61, 0xbc, 0x1a, 0xb4, 0x95, 0xff, 0x78, 0x29, 0x46, 0xde, 0x35, 0xe4, 0x52, - 0xa7, 0x3b, 0xc5, 0x69, 0x68, 0x11, 0x43, 0xea, 0xb7, 0x01, 0x19, 0x99, 0x3c, 0x71, 0x16, 0x3b, - 0xbd, 0x09, 0xe7, 0xe8, 0x53, 0x88, 0x7a, 0xbc, 0x1a, 0xf1, 0x48, 0xdf, 0x48, 0xbe, 0x3b, 0xb2, - 0xd4, 0xa6, 0x60, 0xea, 0xe5, 0x2e, 0x64, 0xab, 0xa6, 0xf5, 0x08, 0x79, 0x32, 0x6e, 0xb7, 0x6d, - 0xaf, 0x8d, 0x1c, 0xef, 0x44, 0x4f, 0x79, 0xff, 0x78, 0x53, 0x54, 0xe0, 0x6c, 0x55, 0x8b, 0x48, - 0x84, 0x07, 0xb0, 0x41, 0xb8, 0x24, 0xeb, 0x91, 0x83, 0x8f, 0x5a, 0xa8, 0xd1, 0x44, 0x0b, 0x09, - 0x37, 0x61, 0xdd, 0x8c, 0x43, 0x29, 0xeb, 0xbc, 0x58, 0x28, 0x42, 0x8e, 0x50, 0x6b, 0xc8, 0x42, - 0x76, 0xc7, 0x93, 0xea, 0xae, 0x3f, 0x07, 0x4e, 0x62, 0x16, 0x0e, 0x21, 0xab, 0xa2, 0xc7, 0xde, - 0xf4, 0xf1, 0xa5, 0x21, 0xab, 0x7f, 0x62, 0x14, 0xef, 0xc1, 0x79, 0x07, 0x3d, 0xf6, 0xfc, 0xa7, - 0x9b, 0xd1, 0x45, 0x56, 0x9f, 0xbe, 0xed, 0x22, 0xd7, 0x40, 0x4c, 0x2d, 0x68, 0x69, 0x87, 0x50, - 0xfb, 0xac, 0x6f, 0x7c, 0x9b, 0x84, 0x95, 0xe9, 0x60, 0x60, 0xdf, 0x85, 0x57, 0xca, 0x92, 0x2e, - 0x19, 0xfa, 0x83, 0xaa, 0x62, 0xec, 0xab, 0x15, 0xb5, 0xa2, 0x57, 0xa4, 0x9d, 0xca, 0x43, 0xa5, - 0x6c, 0xec, 0xab, 0xb5, 0xaa, 0x22, 0x57, 0x3e, 0xac, 0x28, 0xe5, 0xcc, 0x12, 0xb7, 0x3e, 0x1c, - 0xf1, 0xe9, 0x88, 0x88, 0xbd, 0x06, 0x97, 0x42, 0x4b, 0x79, 0xa7, 0xa2, 0xa8, 0xba, 0x51, 0xd3, - 0x25, 0x5d, 0xc9, 0x30, 0x1c, 0x0c, 0x47, 0xfc, 0x32, 0x91, 0xb1, 0x6f, 0xc2, 0x46, 0x04, 0xb7, - 0xa7, 0xd6, 0x14, 0xb5, 0xb6, 0x5f, 0xa3, 0xd0, 0x04, 0x77, 0x7e, 0x38, 0xe2, 0x53, 0x33, 0x31, - 0x5b, 0x04, 0x2e, 0x86, 0x56, 0x15, 0x59, 0xaf, 0xec, 0xa9, 0x14, 0x7e, 0x86, 0x5b, 0x1b, 0x8e, - 0x78, 0x08, 0xe5, 0xec, 0x26, 0x5c, 0x8e, 0xe0, 0xef, 0x48, 0xaa, 0xaa, 0xec, 0x50, 0x70, 0x92, - 0x4b, 0x0f, 0x47, 0xfc, 0x39, 0x2a, 0x64, 0xdf, 0x81, 0x2b, 0x21, 0xb2, 0x2a, 0xc9, 0xf7, 0x14, - 0xdd, 0x90, 0xf7, 0x76, 0x77, 0x2b, 0xfa, 0xae, 0xa2, 0xea, 0x99, 0xb3, 0x5c, 0x76, 0x38, 0xe2, - 0x33, 0x44, 0x11, 0xca, 0xd9, 0xf7, 0x81, 0x3f, 0x66, 0x26, 0xc9, 0xf7, 0xd4, 0xbd, 0x4f, 0x77, - 0x94, 0xf2, 0x47, 0x4a, 0x60, 0xbb, 0xcc, 0x6d, 0x0c, 0x47, 0xfc, 0x45, 0xa2, 0x9d, 0x53, 0xb2, - 0xb7, 0x5f, 0x40, 0xa0, 0x29, 0xb2, 0x52, 0xa9, 0xea, 0x86, 0x54, 0xaa, 0x29, 0xaa, 0xac, 0x64, - 0xce, 0x71, 0xb9, 0xe1, 0x88, 0xcf, 0x12, 0x2d, 0x55, 0x52, 0x1d, 0x7b, 0x13, 0xae, 0x86, 0xf6, - 0xaa, 0x72, 0x5f, 0x37, 0x6a, 0xca, 0xc7, 0xfb, 0xbe, 0xca, 0xa7, 0xf9, 0x24, 0xb3, 0x42, 0x02, - 0xf7, 0x35, 0x53, 0x85, 0x2f, 0x67, 0x79, 0xc8, 0x84, 0x76, 0x77, 0x14, 0xa9, 0xac, 0x68, 0x99, - 0x14, 0xa9, 0x0c, 0xd9, 0x71, 0xc9, 0x27, 0x3f, 0xe6, 0x97, 0x4a, 0xf7, 0x7f, 0x7d, 0x96, 0x67, - 0x9e, 0x3e, 0xcb, 0x33, 0x7f, 0x3e, 0xcb, 0x33, 0xdf, 0x3d, 0xcf, 0x2f, 0x3d, 0x7d, 0x9e, 0x5f, - 0xfa, 0xfd, 0x79, 0x7e, 0xe9, 0xe1, 0xed, 0xa6, 0xed, 0x1d, 0xf6, 0xea, 0x45, 0x0b, 0xb7, 0x45, - 0x0b, 0xbb, 0x6d, 0xec, 0x8a, 0x76, 0xdd, 0xba, 0xde, 0xc4, 0x62, 0xff, 0x6d, 0xb1, 0x8d, 0x1b, - 0xbd, 0x16, 0x72, 0xc9, 0x4f, 0xce, 0x8d, 0xed, 0xeb, 0x64, 0x24, 0x8a, 0x2d, 0xd4, 0x34, 0xad, - 0x81, 0xd8, 0xdf, 0xba, 0x71, 0xa3, 0xbe, 0x1c, 0xcc, 0xb1, 0xb7, 0xfe, 0x0a, 0x00, 0x00, 0xff, - 0xff, 0x66, 0x80, 0x87, 0xc6, 0x8a, 0x0d, 0x00, 0x00, -} - -func (m *ClientState) 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 *ClientState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.AllowUpdateAfterProposal { - i-- - if m.AllowUpdateAfterProposal { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x20 - } - if m.ConsensusState != nil { - { - size, err := m.ConsensusState.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.FrozenSequence != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.FrozenSequence)) - i-- - dAtA[i] = 0x10 - } - if m.Sequence != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Sequence)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *ConsensusState) 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 *ConsensusState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Timestamp != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) - i-- - dAtA[i] = 0x18 - } - if len(m.Diversifier) > 0 { - i -= len(m.Diversifier) - copy(dAtA[i:], m.Diversifier) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Diversifier))) - i-- - dAtA[i] = 0x12 - } - if m.PublicKey != nil { - { - size, err := m.PublicKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Header) 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 *Header) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.NewDiversifier) > 0 { - i -= len(m.NewDiversifier) - copy(dAtA[i:], m.NewDiversifier) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.NewDiversifier))) - i-- - dAtA[i] = 0x2a - } - if m.NewPublicKey != nil { - { - size, err := m.NewPublicKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if len(m.Signature) > 0 { - i -= len(m.Signature) - copy(dAtA[i:], m.Signature) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Signature))) - i-- - dAtA[i] = 0x1a - } - if m.Timestamp != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) - i-- - dAtA[i] = 0x10 - } - if m.Sequence != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Sequence)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *Misbehaviour) 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 *Misbehaviour) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Misbehaviour) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.SignatureTwo != nil { - { - size, err := m.SignatureTwo.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.SignatureOne != nil { - { - size, err := m.SignatureOne.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Sequence != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Sequence)) - i-- - dAtA[i] = 0x10 - } - if len(m.ClientId) > 0 { - i -= len(m.ClientId) - copy(dAtA[i:], m.ClientId) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.ClientId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *SignatureAndData) 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 *SignatureAndData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SignatureAndData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Timestamp != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) - i-- - dAtA[i] = 0x20 - } - if len(m.Data) > 0 { - i -= len(m.Data) - copy(dAtA[i:], m.Data) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Data))) - i-- - dAtA[i] = 0x1a - } - if m.DataType != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.DataType)) - i-- - dAtA[i] = 0x10 - } - if len(m.Signature) > 0 { - i -= len(m.Signature) - copy(dAtA[i:], m.Signature) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Signature))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *TimestampedSignatureData) 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 *TimestampedSignatureData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *TimestampedSignatureData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Timestamp != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) - i-- - dAtA[i] = 0x10 - } - if len(m.SignatureData) > 0 { - i -= len(m.SignatureData) - copy(dAtA[i:], m.SignatureData) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.SignatureData))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *SignBytes) 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 *SignBytes) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SignBytes) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Data) > 0 { - i -= len(m.Data) - copy(dAtA[i:], m.Data) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Data))) - i-- - dAtA[i] = 0x2a - } - if m.DataType != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.DataType)) - i-- - dAtA[i] = 0x20 - } - if len(m.Diversifier) > 0 { - i -= len(m.Diversifier) - copy(dAtA[i:], m.Diversifier) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Diversifier))) - i-- - dAtA[i] = 0x1a - } - if m.Timestamp != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) - i-- - dAtA[i] = 0x10 - } - if m.Sequence != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.Sequence)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *HeaderData) 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 *HeaderData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HeaderData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.NewDiversifier) > 0 { - i -= len(m.NewDiversifier) - copy(dAtA[i:], m.NewDiversifier) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.NewDiversifier))) - i-- - dAtA[i] = 0x12 - } - if m.NewPubKey != nil { - { - size, err := m.NewPubKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ClientStateData) 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 *ClientStateData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ClientStateData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ClientState != nil { - { - size, err := m.ClientState.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Path) > 0 { - i -= len(m.Path) - copy(dAtA[i:], m.Path) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ConsensusStateData) 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 *ConsensusStateData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ConsensusStateData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ConsensusState != nil { - { - size, err := m.ConsensusState.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Path) > 0 { - i -= len(m.Path) - copy(dAtA[i:], m.Path) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ConnectionStateData) 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 *ConnectionStateData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ConnectionStateData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Connection != nil { - { - size, err := m.Connection.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Path) > 0 { - i -= len(m.Path) - copy(dAtA[i:], m.Path) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ChannelStateData) 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 *ChannelStateData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ChannelStateData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Channel != nil { - { - size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSolomachine(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Path) > 0 { - i -= len(m.Path) - copy(dAtA[i:], m.Path) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *PacketCommitmentData) 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 *PacketCommitmentData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PacketCommitmentData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Commitment) > 0 { - i -= len(m.Commitment) - copy(dAtA[i:], m.Commitment) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Commitment))) - i-- - dAtA[i] = 0x12 - } - if len(m.Path) > 0 { - i -= len(m.Path) - copy(dAtA[i:], m.Path) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *PacketAcknowledgementData) 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 *PacketAcknowledgementData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PacketAcknowledgementData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Acknowledgement) > 0 { - i -= len(m.Acknowledgement) - copy(dAtA[i:], m.Acknowledgement) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Acknowledgement))) - i-- - dAtA[i] = 0x12 - } - if len(m.Path) > 0 { - i -= len(m.Path) - copy(dAtA[i:], m.Path) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *PacketReceiptAbsenceData) 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 *PacketReceiptAbsenceData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PacketReceiptAbsenceData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Path) > 0 { - i -= len(m.Path) - copy(dAtA[i:], m.Path) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *NextSequenceRecvData) 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 *NextSequenceRecvData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *NextSequenceRecvData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.NextSeqRecv != 0 { - i = encodeVarintSolomachine(dAtA, i, uint64(m.NextSeqRecv)) - i-- - dAtA[i] = 0x10 - } - if len(m.Path) > 0 { - i -= len(m.Path) - copy(dAtA[i:], m.Path) - i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintSolomachine(dAtA []byte, offset int, v uint64) int { - offset -= sovSolomachine(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *ClientState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Sequence != 0 { - n += 1 + sovSolomachine(uint64(m.Sequence)) - } - if m.FrozenSequence != 0 { - n += 1 + sovSolomachine(uint64(m.FrozenSequence)) - } - if m.ConsensusState != nil { - l = m.ConsensusState.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.AllowUpdateAfterProposal { - n += 2 - } - return n -} - -func (m *ConsensusState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.PublicKey != nil { - l = m.PublicKey.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - l = len(m.Diversifier) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.Timestamp != 0 { - n += 1 + sovSolomachine(uint64(m.Timestamp)) - } - return n -} - -func (m *Header) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Sequence != 0 { - n += 1 + sovSolomachine(uint64(m.Sequence)) - } - if m.Timestamp != 0 { - n += 1 + sovSolomachine(uint64(m.Timestamp)) - } - l = len(m.Signature) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.NewPublicKey != nil { - l = m.NewPublicKey.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - l = len(m.NewDiversifier) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *Misbehaviour) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ClientId) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.Sequence != 0 { - n += 1 + sovSolomachine(uint64(m.Sequence)) - } - if m.SignatureOne != nil { - l = m.SignatureOne.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.SignatureTwo != nil { - l = m.SignatureTwo.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *SignatureAndData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Signature) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.DataType != 0 { - n += 1 + sovSolomachine(uint64(m.DataType)) - } - l = len(m.Data) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.Timestamp != 0 { - n += 1 + sovSolomachine(uint64(m.Timestamp)) - } - return n -} - -func (m *TimestampedSignatureData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.SignatureData) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.Timestamp != 0 { - n += 1 + sovSolomachine(uint64(m.Timestamp)) - } - return n -} - -func (m *SignBytes) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Sequence != 0 { - n += 1 + sovSolomachine(uint64(m.Sequence)) - } - if m.Timestamp != 0 { - n += 1 + sovSolomachine(uint64(m.Timestamp)) - } - l = len(m.Diversifier) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.DataType != 0 { - n += 1 + sovSolomachine(uint64(m.DataType)) - } - l = len(m.Data) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *HeaderData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.NewPubKey != nil { - l = m.NewPubKey.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - l = len(m.NewDiversifier) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *ClientStateData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.ClientState != nil { - l = m.ClientState.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *ConsensusStateData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.ConsensusState != nil { - l = m.ConsensusState.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *ConnectionStateData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.Connection != nil { - l = m.Connection.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *ChannelStateData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.Channel != nil { - l = m.Channel.Size() - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *PacketCommitmentData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - l = len(m.Commitment) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *PacketAcknowledgementData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - l = len(m.Acknowledgement) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *PacketReceiptAbsenceData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - return n -} - -func (m *NextSequenceRecvData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - if l > 0 { - n += 1 + l + sovSolomachine(uint64(l)) - } - if m.NextSeqRecv != 0 { - n += 1 + sovSolomachine(uint64(m.NextSeqRecv)) - } - return n -} - -func sovSolomachine(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozSolomachine(x uint64) (n int) { - return sovSolomachine(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *ClientState) 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 ErrIntOverflowSolomachine - } - 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: ClientState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ClientState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) - } - m.Sequence = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Sequence |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field FrozenSequence", wireType) - } - m.FrozenSequence = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.FrozenSequence |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsensusState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ConsensusState == nil { - m.ConsensusState = &ConsensusState{} - } - if err := m.ConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowUpdateAfterProposal", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.AllowUpdateAfterProposal = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ConsensusState) 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 ErrIntOverflowSolomachine - } - 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: ConsensusState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConsensusState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.PublicKey == nil { - m.PublicKey = &types.Any{} - } - if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Diversifier", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - 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 ErrInvalidLengthSolomachine - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Diversifier = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - m.Timestamp = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Timestamp |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Header) 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 ErrIntOverflowSolomachine - } - 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: Header: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Header: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) - } - m.Sequence = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Sequence |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - m.Timestamp = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Timestamp |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) - if m.Signature == nil { - m.Signature = []byte{} - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NewPublicKey", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.NewPublicKey == nil { - m.NewPublicKey = &types.Any{} - } - if err := m.NewPublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NewDiversifier", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - 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 ErrInvalidLengthSolomachine - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.NewDiversifier = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Misbehaviour) 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 ErrIntOverflowSolomachine - } - 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: Misbehaviour: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Misbehaviour: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - 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 ErrInvalidLengthSolomachine - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ClientId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) - } - m.Sequence = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Sequence |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SignatureOne", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SignatureOne == nil { - m.SignatureOne = &SignatureAndData{} - } - if err := m.SignatureOne.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SignatureTwo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.SignatureTwo == nil { - m.SignatureTwo = &SignatureAndData{} - } - if err := m.SignatureTwo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SignatureAndData) 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 ErrIntOverflowSolomachine - } - 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: SignatureAndData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SignatureAndData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) - if m.Signature == nil { - m.Signature = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DataType", wireType) - } - m.DataType = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.DataType |= DataType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - m.Timestamp = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Timestamp |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *TimestampedSignatureData) 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 ErrIntOverflowSolomachine - } - 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: TimestampedSignatureData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TimestampedSignatureData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SignatureData", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SignatureData = append(m.SignatureData[:0], dAtA[iNdEx:postIndex]...) - if m.SignatureData == nil { - m.SignatureData = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - m.Timestamp = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Timestamp |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *SignBytes) 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 ErrIntOverflowSolomachine - } - 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: SignBytes: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SignBytes: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) - } - m.Sequence = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Sequence |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) - } - m.Timestamp = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Timestamp |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Diversifier", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - 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 ErrInvalidLengthSolomachine - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Diversifier = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DataType", wireType) - } - m.DataType = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.DataType |= DataType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *HeaderData) 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 ErrIntOverflowSolomachine - } - 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: HeaderData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HeaderData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NewPubKey", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.NewPubKey == nil { - m.NewPubKey = &types.Any{} - } - if err := m.NewPubKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NewDiversifier", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - 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 ErrInvalidLengthSolomachine - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.NewDiversifier = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ClientStateData) 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 ErrIntOverflowSolomachine - } - 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: ClientStateData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ClientStateData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) - if m.Path == nil { - m.Path = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClientState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ClientState == nil { - m.ClientState = &types.Any{} - } - if err := m.ClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ConsensusStateData) 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 ErrIntOverflowSolomachine - } - 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: ConsensusStateData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConsensusStateData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) - if m.Path == nil { - m.Path = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsensusState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ConsensusState == nil { - m.ConsensusState = &types.Any{} - } - if err := m.ConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ConnectionStateData) 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 ErrIntOverflowSolomachine - } - 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: ConnectionStateData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConnectionStateData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) - if m.Path == nil { - m.Path = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Connection", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Connection == nil { - m.Connection = &types1.ConnectionEnd{} - } - if err := m.Connection.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ChannelStateData) 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 ErrIntOverflowSolomachine - } - 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: ChannelStateData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ChannelStateData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) - if m.Path == nil { - m.Path = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Channel == nil { - m.Channel = &types2.Channel{} - } - if err := m.Channel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PacketCommitmentData) 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 ErrIntOverflowSolomachine - } - 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: PacketCommitmentData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PacketCommitmentData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) - if m.Path == nil { - m.Path = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Commitment", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Commitment = append(m.Commitment[:0], dAtA[iNdEx:postIndex]...) - if m.Commitment == nil { - m.Commitment = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PacketAcknowledgementData) 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 ErrIntOverflowSolomachine - } - 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: PacketAcknowledgementData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PacketAcknowledgementData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) - if m.Path == nil { - m.Path = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Acknowledgement", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Acknowledgement = append(m.Acknowledgement[:0], dAtA[iNdEx:postIndex]...) - if m.Acknowledgement == nil { - m.Acknowledgement = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PacketReceiptAbsenceData) 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 ErrIntOverflowSolomachine - } - 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: PacketReceiptAbsenceData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PacketReceiptAbsenceData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) - if m.Path == nil { - m.Path = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *NextSequenceRecvData) 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 ErrIntOverflowSolomachine - } - 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: NextSequenceRecvData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: NextSequenceRecvData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthSolomachine - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthSolomachine - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) - if m.Path == nil { - m.Path = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NextSeqRecv", wireType) - } - m.NextSeqRecv = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSolomachine - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NextSeqRecv |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipSolomachine(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSolomachine - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipSolomachine(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSolomachine - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSolomachine - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSolomachine - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthSolomachine - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupSolomachine - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthSolomachine - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthSolomachine = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowSolomachine = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupSolomachine = fmt.Errorf("proto: unexpected end of group") -) diff --git a/modules/core/02-client/legacy/v100/store.go b/modules/core/02-client/legacy/v100/store.go deleted file mode 100644 index 70827a89b6a..00000000000 --- a/modules/core/02-client/legacy/v100/store.go +++ /dev/null @@ -1,180 +0,0 @@ -package v100 - -import ( - "fmt" - "strings" - - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/store/prefix" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - smtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" -) - -// MigrateStore performs in-place store migrations from SDK v0.40 of the IBC module to v1.0.0 of ibc-go. -// The migration includes: -// -// - Migrating solo machine client states from v1 to v2 protobuf definition -// - Pruning all solo machine consensus states -// - Pruning expired tendermint consensus states -// - Adds ProcessedHeight and Iteration keys for unexpired tendermint consensus states -func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) (err error) { - store := ctx.KVStore(storeKey) - iterator := sdk.KVStorePrefixIterator(store, host.KeyClientStorePrefix) - - var clients []string - - // collect all clients - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - keySplit := strings.Split(string(iterator.Key()), "/") - if keySplit[len(keySplit)-1] != host.KeyClientState { - continue - } - - // key is clients/{clientid}/clientState - // Thus, keySplit[1] is clientID - clients = append(clients, keySplit[1]) - } - - for _, clientID := range clients { - clientType, _, err := types.ParseClientIdentifier(clientID) - if err != nil { - return err - } - - clientPrefix := []byte(fmt.Sprintf("%s/%s/", host.KeyClientStorePrefix, clientID)) - clientStore := prefix.NewStore(ctx.KVStore(storeKey), clientPrefix) - - bz := clientStore.Get(host.ClientStateKey()) - if bz == nil { - return clienttypes.ErrClientNotFound - } - - switch clientType { - case exported.Solomachine: - any := &codectypes.Any{} - if err := cdc.Unmarshal(bz, any); err != nil { - return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") - } - - clientState := &ClientState{} - if err := cdc.Unmarshal(any.Value, clientState); err != nil { - return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") - } - - updatedClientState := migrateSolomachine(clientState) - - bz, err := clienttypes.MarshalClientState(cdc, updatedClientState) - if err != nil { - return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") - } - - // update solomachine in store - clientStore.Set(host.ClientStateKey(), bz) - - pruneSolomachineConsensusStates(clientStore) - - case exported.Tendermint: - var clientState exported.ClientState - if err := cdc.UnmarshalInterface(bz, &clientState); err != nil { - return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into tendermint client state") - } - - tmClientState, ok := clientState.(*ibctmtypes.ClientState) - if !ok { - return sdkerrors.Wrap(types.ErrInvalidClient, "client state is not tendermint even though client id contains 07-tendermint") - } - - // add iteration keys so pruning will be successful - if err = addConsensusMetadata(ctx, clientStore, cdc, tmClientState); err != nil { - return err - } - - if err = ibctmtypes.PruneAllExpiredConsensusStates(ctx, clientStore, cdc, tmClientState); err != nil { - return err - } - - default: - continue - } - } - - return nil -} - -// migrateSolomachine migrates the solomachine from v1 to v2 solo machine protobuf defintion. -func migrateSolomachine(clientState *ClientState) *smtypes.ClientState { - isFrozen := clientState.FrozenSequence != 0 - consensusState := &smtypes.ConsensusState{ - PublicKey: clientState.ConsensusState.PublicKey, - Diversifier: clientState.ConsensusState.Diversifier, - Timestamp: clientState.ConsensusState.Timestamp, - } - - return &smtypes.ClientState{ - Sequence: clientState.Sequence, - IsFrozen: isFrozen, - ConsensusState: consensusState, - AllowUpdateAfterProposal: clientState.AllowUpdateAfterProposal, - } -} - -// pruneSolomachineConsensusStates removes all solomachine consensus states from the -// client store. -func pruneSolomachineConsensusStates(clientStore sdk.KVStore) { - iterator := sdk.KVStorePrefixIterator(clientStore, []byte(host.KeyConsensusStatePrefix)) - var heights []exported.Height - - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - keySplit := strings.Split(string(iterator.Key()), "/") - // key is in the format "consensusStates/" - if len(keySplit) != 2 || keySplit[0] != string(host.KeyConsensusStatePrefix) { - continue - } - - // collect consensus states to be pruned - heights = append(heights, types.MustParseHeight(keySplit[1])) - } - - // delete all consensus states - for _, height := range heights { - clientStore.Delete(host.ConsensusStateKey(height)) - } -} - -// addConsensusMetadata adds the iteration key and processed height for all tendermint consensus states -// These keys were not included in the previous release of the IBC module. Adding the iteration keys allows -// for pruning iteration. -func addConsensusMetadata(ctx sdk.Context, clientStore sdk.KVStore, cdc codec.BinaryCodec, clientState *ibctmtypes.ClientState) error { - var heights []exported.Height - iterator := sdk.KVStorePrefixIterator(clientStore, []byte(host.KeyConsensusStatePrefix)) - - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - keySplit := strings.Split(string(iterator.Key()), "/") - // consensus key is in the format "consensusStates/" - if len(keySplit) != 2 { - continue - } - - heights = append(heights, types.MustParseHeight(keySplit[1])) - } - - for _, height := range heights { - // set the iteration key and processed height - // these keys were not included in the SDK v0.42.0 release - ibctmtypes.SetProcessedHeight(clientStore, height, clienttypes.GetSelfHeight(ctx)) - ibctmtypes.SetIterationKey(clientStore, height) - } - - return nil -} diff --git a/modules/core/02-client/legacy/v100/store_test.go b/modules/core/02-client/legacy/v100/store_test.go deleted file mode 100644 index cb51908f05f..00000000000 --- a/modules/core/02-client/legacy/v100/store_test.go +++ /dev/null @@ -1,231 +0,0 @@ -package v100_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/suite" - - v100 "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -type LegacyTestSuite struct { - suite.Suite - - coordinator *ibctesting.Coordinator - - // testing chains used for convenience and readability - chainA *ibctesting.TestChain - chainB *ibctesting.TestChain -} - -// TestLegacyTestSuite runs all the tests within this package. -func TestLegacyTestSuite(t *testing.T) { - suite.Run(t, new(LegacyTestSuite)) -} - -// SetupTest creates a coordinator with 2 test chains. -func (suite *LegacyTestSuite) SetupTest() { - suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) - suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) - suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) - // commit some blocks so that QueryProof returns valid proof (cannot return valid query if height <= 1) - suite.coordinator.CommitNBlocks(suite.chainA, 2) - suite.coordinator.CommitNBlocks(suite.chainB, 2) -} - -// only test migration for solo machines -// ensure all client states are migrated and all consensus states -// are removed -func (suite *LegacyTestSuite) TestMigrateStoreSolomachine() { - path := ibctesting.NewPath(suite.chainA, suite.chainB) - - // create multiple legacy solo machine clients - solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1) - solomachineMulti := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4) - - // manually generate old proto buf definitions and set in store - // NOTE: we cannot use 'CreateClient' and 'UpdateClient' functions since we are - // using client states and consensus states which do not implement the exported.ClientState - // and exported.ConsensusState interface - for _, sm := range []*ibctesting.Solomachine{solomachine, solomachineMulti} { - clientStore := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(path.EndpointA.Chain.GetContext(), sm.ClientID) - clientState := sm.ClientState() - - var seq uint64 - if clientState.IsFrozen { - seq = 1 - } - - // generate old client state proto defintion - legacyClientState := &v100.ClientState{ - Sequence: clientState.Sequence, - FrozenSequence: seq, - ConsensusState: &v100.ConsensusState{ - PublicKey: clientState.ConsensusState.PublicKey, - Diversifier: clientState.ConsensusState.Diversifier, - Timestamp: clientState.ConsensusState.Timestamp, - }, - AllowUpdateAfterProposal: clientState.AllowUpdateAfterProposal, - } - - // set client state - bz, err := path.EndpointA.Chain.App.AppCodec().MarshalInterface(legacyClientState) - suite.Require().NoError(err) - clientStore.Set(host.ClientStateKey(), bz) - - // set some consensus states - height1 := types.NewHeight(0, 1) - height2 := types.NewHeight(1, 2) - height3 := types.NewHeight(0, 123) - - bz, err = path.EndpointA.Chain.App.AppCodec().MarshalInterface(legacyClientState.ConsensusState) - suite.Require().NoError(err) - clientStore.Set(host.ConsensusStateKey(height1), bz) - clientStore.Set(host.ConsensusStateKey(height2), bz) - clientStore.Set(host.ConsensusStateKey(height3), bz) - } - - // create tendermint clients - suite.coordinator.SetupClients(path) - - err := v100.MigrateStore(path.EndpointA.Chain.GetContext(), path.EndpointA.Chain.GetSimApp().GetKey(host.StoreKey), path.EndpointA.Chain.App.AppCodec()) - suite.Require().NoError(err) - - // verify client state has been migrated - for _, sm := range []*ibctesting.Solomachine{solomachine, solomachineMulti} { - clientState, ok := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.GetClientState(path.EndpointA.Chain.GetContext(), sm.ClientID) - suite.Require().True(ok) - suite.Require().Equal(sm.ClientState(), clientState) - } - - // verify consensus states have been removed - for _, sm := range []*ibctesting.Solomachine{solomachine, solomachineMulti} { - clientConsensusStates := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.GetAllConsensusStates(path.EndpointA.Chain.GetContext()) - for _, client := range clientConsensusStates { - // GetAllConsensusStates should not return consensus states for our solo machine clients - suite.Require().NotEqual(sm.ClientID, client.ClientId) - } - } -} - -// only test migration for tendermint clients -// ensure all expired consensus states are removed from tendermint client stores -func (suite *LegacyTestSuite) TestMigrateStoreTendermint() { - // create path and setup clients - path1 := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(path1) - - path2 := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(path2) - pruneHeightMap := make(map[*ibctesting.Path][]exported.Height) - unexpiredHeightMap := make(map[*ibctesting.Path][]exported.Height) - - for _, path := range []*ibctesting.Path{path1, path2} { - // collect all heights expected to be pruned - var pruneHeights []exported.Height - pruneHeights = append(pruneHeights, path.EndpointA.GetClientState().GetLatestHeight()) - - // these heights will be expired and also pruned - for i := 0; i < 3; i++ { - path.EndpointA.UpdateClient() - pruneHeights = append(pruneHeights, path.EndpointA.GetClientState().GetLatestHeight()) - } - - // double chedck all information is currently stored - for _, pruneHeight := range pruneHeights { - consState, ok := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) - suite.Require().True(ok) - suite.Require().NotNil(consState) - - ctx := path.EndpointA.Chain.GetContext() - clientStore := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - - processedTime, ok := ibctmtypes.GetProcessedTime(clientStore, pruneHeight) - suite.Require().True(ok) - suite.Require().NotNil(processedTime) - - processedHeight, ok := ibctmtypes.GetProcessedHeight(clientStore, pruneHeight) - suite.Require().True(ok) - suite.Require().NotNil(processedHeight) - - expectedConsKey := ibctmtypes.GetIterationKey(clientStore, pruneHeight) - suite.Require().NotNil(expectedConsKey) - } - pruneHeightMap[path] = pruneHeights - } - - // Increment the time by a week - suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) - - for _, path := range []*ibctesting.Path{path1, path2} { - // create the consensus state that can be used as trusted height for next update - var unexpiredHeights []exported.Height - path.EndpointA.UpdateClient() - unexpiredHeights = append(unexpiredHeights, path.EndpointA.GetClientState().GetLatestHeight()) - path.EndpointA.UpdateClient() - unexpiredHeights = append(unexpiredHeights, path.EndpointA.GetClientState().GetLatestHeight()) - - // remove processed height and iteration keys since these were missing from previous version of ibc module - clientStore := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(path.EndpointA.Chain.GetContext(), path.EndpointA.ClientID) - for _, height := range unexpiredHeights { - clientStore.Delete(ibctmtypes.ProcessedHeightKey(height)) - clientStore.Delete(ibctmtypes.IterationKey(height)) - } - - unexpiredHeightMap[path] = unexpiredHeights - } - - // Increment the time by another week, then update the client. - // This will cause the consensus states created before the first time increment - // to be expired - suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) - err := v100.MigrateStore(path1.EndpointA.Chain.GetContext(), path1.EndpointA.Chain.GetSimApp().GetKey(host.StoreKey), path1.EndpointA.Chain.App.AppCodec()) - suite.Require().NoError(err) - - for _, path := range []*ibctesting.Path{path1, path2} { - ctx := path.EndpointA.Chain.GetContext() - clientStore := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - - // ensure everything has been pruned - for i, pruneHeight := range pruneHeightMap[path] { - consState, ok := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) - suite.Require().False(ok, i) - suite.Require().Nil(consState, i) - - processedTime, ok := ibctmtypes.GetProcessedTime(clientStore, pruneHeight) - suite.Require().False(ok, i) - suite.Require().Equal(uint64(0), processedTime, i) - - processedHeight, ok := ibctmtypes.GetProcessedHeight(clientStore, pruneHeight) - suite.Require().False(ok, i) - suite.Require().Nil(processedHeight, i) - - expectedConsKey := ibctmtypes.GetIterationKey(clientStore, pruneHeight) - suite.Require().Nil(expectedConsKey, i) - } - - // ensure metadata is set for unexpired consensus state - for _, height := range unexpiredHeightMap[path] { - consState, ok := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, height) - suite.Require().True(ok) - suite.Require().NotNil(consState) - - processedTime, ok := ibctmtypes.GetProcessedTime(clientStore, height) - suite.Require().True(ok) - suite.Require().NotEqual(uint64(0), processedTime) - - processedHeight, ok := ibctmtypes.GetProcessedHeight(clientStore, height) - suite.Require().True(ok) - suite.Require().Equal(types.GetSelfHeight(path.EndpointA.Chain.GetContext()), processedHeight) - - consKey := ibctmtypes.GetIterationKey(clientStore, height) - suite.Require().Equal(host.ConsensusStateKey(height), consKey) - } - } -} diff --git a/modules/core/02-client/migrations/v7/expected_keepers.go b/modules/core/02-client/migrations/v7/expected_keepers.go new file mode 100644 index 00000000000..6d424cc0370 --- /dev/null +++ b/modules/core/02-client/migrations/v7/expected_keepers.go @@ -0,0 +1,14 @@ +package v7 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// ClientKeeper expected IBC client keeper +type ClientKeeper interface { + GetClientState(ctx sdk.Context, clientID string) (exported.ClientState, bool) + SetClientState(ctx sdk.Context, clientID string, clientState exported.ClientState) + ClientStore(ctx sdk.Context, clientID string) sdk.KVStore +} diff --git a/modules/core/02-client/migrations/v7/genesis.go b/modules/core/02-client/migrations/v7/genesis.go new file mode 100644 index 00000000000..e2f803dd35d --- /dev/null +++ b/modules/core/02-client/migrations/v7/genesis.go @@ -0,0 +1,77 @@ +package v7 + +import ( + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// MigrateGenesis accepts an exported IBC client genesis file and migrates it to: +// +// - Update solo machine client state protobuf definition (v2 to v3) +// - Remove all solo machine consensus states +// - Remove localhost client +func MigrateGenesis(clientGenState *clienttypes.GenesisState, cdc codec.ProtoCodecMarshaler) (*clienttypes.GenesisState, error) { + // To prune the client and consensus states, we will create new slices to fill up + // with information we want to keep. + var ( + clientsConsensus []clienttypes.ClientConsensusStates + clients []clienttypes.IdentifiedClientState + ) + + for _, client := range clientGenState.Clients { + clientType, _, err := clienttypes.ParseClientIdentifier(client.ClientId) + if err != nil { + return nil, err + } + + switch clientType { + case exported.Solomachine: + var clientState ClientState + if err := cdc.Unmarshal(client.ClientState.Value, &clientState); err != nil { + return nil, errorsmod.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") + } + + updatedClientState := migrateSolomachine(clientState) + + protoAny, err := clienttypes.PackClientState(&updatedClientState) + if err != nil { + return nil, err + } + + clients = append(clients, clienttypes.IdentifiedClientState{ + ClientId: client.ClientId, + ClientState: protoAny, + }) + + case Localhost: + // remove localhost client state by not adding client state + + default: + // add all other client states + clients = append(clients, client) + } + + // iterate consensus states by client + for _, clientConsensusStates := range clientGenState.ClientsConsensus { + // look for consensus states for the current client + if clientConsensusStates.ClientId == client.ClientId { + switch clientType { + case exported.Solomachine, Localhost: + // remove all consensus states for the solo machine and localhost + // do not add to new clientsConsensus + + default: + // ensure all consensus states added for other client types + clientsConsensus = append(clientsConsensus, clientConsensusStates) + } + } + } + } + + clientGenState.Clients = clients + clientGenState.ClientsConsensus = clientsConsensus + return clientGenState, nil +} diff --git a/modules/core/02-client/migrations/v7/genesis_test.go b/modules/core/02-client/migrations/v7/genesis_test.go new file mode 100644 index 00000000000..79e285ba58a --- /dev/null +++ b/modules/core/02-client/migrations/v7/genesis_test.go @@ -0,0 +1,139 @@ +package v7_test + +import ( + "encoding/json" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" + v7 "github.com/cosmos/ibc-go/v7/modules/core/02-client/migrations/v7" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func (suite *MigrationsV7TestSuite) TestMigrateGenesisSolomachine() { + // create tendermint clients + for i := 0; i < 3; i++ { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + + suite.coordinator.SetupClients(path) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // update a second time to add more state + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + } + + // create multiple legacy solo machine clients + solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1) + solomachineMulti := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4) + + clientGenState := ibcclient.ExportGenesis(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper) + + // manually generate old proto buf definitions and set in genesis + // NOTE: we cannot use 'ExportGenesis' for the solo machines since we are + // using client states and consensus states which do not implement the exported.ClientState + // and exported.ConsensusState interface + var clients []types.IdentifiedClientState + for _, sm := range []*ibctesting.Solomachine{solomachine, solomachineMulti} { + clientState := sm.ClientState() + + // generate old client state proto definition + legacyClientState := &v7.ClientState{ + Sequence: clientState.Sequence, + ConsensusState: &v7.ConsensusState{ + PublicKey: clientState.ConsensusState.PublicKey, + Diversifier: clientState.ConsensusState.Diversifier, + Timestamp: clientState.ConsensusState.Timestamp, + }, + AllowUpdateAfterProposal: true, + } + + // set client state + protoAny, err := codectypes.NewAnyWithValue(legacyClientState) + suite.Require().NoError(err) + suite.Require().NotNil(protoAny) + + clients = append(clients, types.IdentifiedClientState{ + ClientId: sm.ClientID, + ClientState: protoAny, + }) + + // set in store for ease of determining expected genesis + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), sm.ClientID) + + cdc := suite.chainA.App.AppCodec().(*codec.ProtoCodec) + v7.RegisterInterfaces(cdc.InterfaceRegistry()) + + bz, err := cdc.MarshalInterface(legacyClientState) + suite.Require().NoError(err) + clientStore.Set(host.ClientStateKey(), bz) + + protoAny, err = codectypes.NewAnyWithValue(legacyClientState.ConsensusState) + suite.Require().NoError(err) + suite.Require().NotNil(protoAny) + + // obtain marshalled bytes to set in client store + bz, err = cdc.MarshalInterface(legacyClientState.ConsensusState) + suite.Require().NoError(err) + + var consensusStates []types.ConsensusStateWithHeight + + // set consensus states in store and genesis + for i := uint64(0); i < numCreations; i++ { + height := types.NewHeight(1, i) + clientStore.Set(host.ConsensusStateKey(height), bz) + consensusStates = append(consensusStates, types.ConsensusStateWithHeight{ + Height: height, + ConsensusState: protoAny, + }) + } + + clientGenState.ClientsConsensus = append(clientGenState.ClientsConsensus, types.ClientConsensusStates{ + ClientId: sm.ClientID, + ConsensusStates: consensusStates, + }) + } + + // solo machine clients must come before tendermint in expected + clientGenState.Clients = append(clients, clientGenState.Clients...) + + // migrate store get expected genesis + // store migration and genesis migration should produce identical results + // NOTE: tendermint clients are not pruned in genesis so the test should not have expired tendermint clients + err := v7.MigrateStore(suite.chainA.GetContext(), suite.chainA.GetSimApp().GetKey(ibcexported.StoreKey), suite.chainA.App.AppCodec(), suite.chainA.GetSimApp().IBCKeeper.ClientKeeper) + suite.Require().NoError(err) + expectedClientGenState := ibcclient.ExportGenesis(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper) + + cdc, ok := suite.chainA.App.AppCodec().(codec.ProtoCodecMarshaler) + suite.Require().True(ok) + + migrated, err := v7.MigrateGenesis(&clientGenState, cdc) + suite.Require().NoError(err) + + bz, err := cdc.MarshalJSON(&expectedClientGenState) + suite.Require().NoError(err) + + // Indent the JSON bz correctly. + var jsonObj map[string]interface{} + err = json.Unmarshal(bz, &jsonObj) + suite.Require().NoError(err) + expectedIndentedBz, err := json.MarshalIndent(jsonObj, "", "\t") + suite.Require().NoError(err) + + bz, err = cdc.MarshalJSON(migrated) + suite.Require().NoError(err) + + // Indent the JSON bz correctly. + err = json.Unmarshal(bz, &jsonObj) + suite.Require().NoError(err) + indentedBz, err := json.MarshalIndent(jsonObj, "", "\t") + suite.Require().NoError(err) + + suite.Require().Equal(string(expectedIndentedBz), string(indentedBz)) +} diff --git a/modules/core/02-client/legacy/v100/solomachine.go b/modules/core/02-client/migrations/v7/solomachine.go similarity index 75% rename from modules/core/02-client/legacy/v100/solomachine.go rename to modules/core/02-client/migrations/v7/solomachine.go index a9b8fa49340..8996bae2e5f 100644 --- a/modules/core/02-client/legacy/v100/solomachine.go +++ b/modules/core/02-client/migrations/v7/solomachine.go @@ -1,13 +1,13 @@ -package v100 +package v7 import ( - ics23 "github.com/confio/ics23/go" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + ics23 "github.com/cosmos/ics23/go" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // NOTE: this is a mock implmentation for exported.ClientState. This implementation @@ -16,7 +16,7 @@ import ( // client state and consensus state and migrate them to the new implementations. When the proto // codec unmarshals, it calls UnpackInterfaces() to create a cached value of the any. The // UnpackInterfaces function for IdenitifiedClientState will attempt to unpack the any to -// exported.ClientState. If the solomachine v1 type is not registered against the exported.ClientState +// exported.ClientState. If the solomachine v2 type is not registered against the exported.ClientState // the unmarshal will fail. This implementation will panic on every interface function. // The same is done for the ConsensusState. @@ -27,6 +27,7 @@ var ( _ exported.ConsensusState = &ConsensusState{} ) +// RegisterInterfaces registers the solomachine v2 ClientState and ConsensusState types in the interface registry. func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterImplementations( (*exported.ClientState)(nil), @@ -88,16 +89,40 @@ func (cs ClientState) ExportMetadata(_ sdk.KVStore) []exported.GenesisMetadata { panic("legacy solo machine is deprecated!") } +// CheckForMisbehaviour panics! +func (cs ClientState) CheckForMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, msg exported.ClientMessage) bool { + panic("legacy solo machine is deprecated!") +} + +// UpdateStateOnMisbehaviour panics! +func (cs *ClientState) UpdateStateOnMisbehaviour( + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage, +) { + panic("legacy solo machine is deprecated!") +} + +// VerifyClientMessage panics! +func (cs *ClientState) VerifyClientMessage( + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage, +) error { + panic("legacy solo machine is deprecated!") +} + +// UpdateState panis! +func (cs *ClientState) UpdateState(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage) []exported.Height { + panic("legacy solo machine is deprecated!") +} + // CheckHeaderAndUpdateState panics! func (cs *ClientState) CheckHeaderAndUpdateState( - _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.Header, + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage, ) (exported.ClientState, exported.ConsensusState, error) { panic("legacy solo machine is deprecated!") } // CheckMisbehaviourAndUpdateState panics! func (cs ClientState) CheckMisbehaviourAndUpdateState( - _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.Misbehaviour, + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage, ) (exported.ClientState, error) { panic("legacy solo machine is deprecated!") } @@ -106,7 +131,7 @@ func (cs ClientState) CheckMisbehaviourAndUpdateState( func (cs ClientState) CheckSubstituteAndUpdateState( ctx sdk.Context, _ codec.BinaryCodec, _, _ sdk.KVStore, _ exported.ClientState, -) (exported.ClientState, error) { +) error { panic("legacy solo machine is deprecated!") } @@ -114,7 +139,7 @@ func (cs ClientState) CheckSubstituteAndUpdateState( func (cs ClientState) VerifyUpgradeAndUpdateState( _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, -) (exported.ClientState, exported.ConsensusState, error) { +) error { panic("legacy solo machine is deprecated!") } @@ -187,6 +212,42 @@ func (cs ClientState) VerifyNextSequenceRecv( panic("legacy solo machine is deprecated!") } +// GetTimestampAtHeight panics! +func (cs ClientState) GetTimestampAtHeight( + sdk.Context, sdk.KVStore, codec.BinaryCodec, exported.Height, +) (uint64, error) { + panic("legacy solo machine is deprecated!") +} + +// VerifyMembership panics! +func (cs *ClientState) VerifyMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height exported.Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path exported.Path, + value []byte, +) error { + panic("legacy solo machine is deprecated!") +} + +// VerifyNonMembership panics! +func (cs *ClientState) VerifyNonMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height exported.Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path exported.Path, +) error { + panic("legacy solo machine is deprecated") +} + // ClientType panics! func (ConsensusState) ClientType() string { panic("legacy solo machine is deprecated!") @@ -197,11 +258,6 @@ func (cs ConsensusState) GetTimestamp() uint64 { panic("legacy solo machine is deprecated!") } -// GetRoot panics! -func (cs ConsensusState) GetRoot() exported.Root { - panic("legacy solo machine is deprecated!") -} - // ValidateBasic panics! func (cs ConsensusState) ValidateBasic() error { panic("legacy solo machine is deprecated!") diff --git a/modules/light-clients/06-solomachine/types/solomachine.pb.go b/modules/core/02-client/migrations/v7/solomachine.pb.go similarity index 92% rename from modules/light-clients/06-solomachine/types/solomachine.pb.go rename to modules/core/02-client/migrations/v7/solomachine.pb.go index 238f9849ede..c51210cf69d 100644 --- a/modules/light-clients/06-solomachine/types/solomachine.pb.go +++ b/modules/core/02-client/migrations/v7/solomachine.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: ibc/lightclients/solomachine/v2/solomachine.proto -package types +package v7 import ( fmt "fmt" types "github.com/cosmos/cosmos-sdk/codec/types" - types1 "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - types2 "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types1 "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + types2 "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" io "io" math "math" math_bits "math/bits" @@ -823,93 +823,93 @@ func init() { } var fileDescriptor_141333b361aae010 = []byte{ - // 1370 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x5f, 0x8f, 0xdb, 0x44, - 0x10, 0x3f, 0xa7, 0xe9, 0xf5, 0x32, 0xb9, 0xde, 0x05, 0x37, 0x6d, 0x73, 0x6e, 0x95, 0x18, 0x23, - 0xca, 0x81, 0x68, 0xc2, 0x1d, 0x50, 0xa1, 0x0a, 0x01, 0x8e, 0xe3, 0xd2, 0xb4, 0x77, 0xbe, 0xe0, - 0xf8, 0x80, 0x56, 0x48, 0xc6, 0x71, 0xf6, 0x12, 0xab, 0x89, 0x37, 0x8d, 0x9d, 0xa4, 0x41, 0x42, - 0x42, 0x3c, 0x95, 0x88, 0x07, 0xbe, 0x40, 0x24, 0x04, 0xe2, 0x73, 0xf0, 0x06, 0x3c, 0xf6, 0x91, - 0xa7, 0x80, 0xda, 0x6f, 0x90, 0x4f, 0x80, 0xec, 0xdd, 0xc4, 0x76, 0xae, 0x97, 0x13, 0xff, 0xde, - 0x76, 0xe7, 0x37, 0xf3, 0x9b, 0xd9, 0x99, 0xf1, 0xec, 0x1a, 0x76, 0xac, 0x9a, 0x59, 0x68, 0x59, - 0x8d, 0xa6, 0x6b, 0xb6, 0x2c, 0x64, 0xbb, 0x4e, 0xc1, 0xc1, 0x2d, 0xdc, 0x36, 0xcc, 0xa6, 0x65, - 0xa3, 0x42, 0x7f, 0x37, 0xbc, 0xcd, 0x77, 0xba, 0xd8, 0xc5, 0x6c, 0xce, 0xaa, 0x99, 0xf9, 0xb0, - 0x49, 0x3e, 0xac, 0xd3, 0xdf, 0xe5, 0x5e, 0xf1, 0x38, 0x4d, 0xdc, 0x45, 0x05, 0x13, 0xdb, 0x36, - 0x32, 0x5d, 0x0b, 0xdb, 0x85, 0xfe, 0x4e, 0x68, 0x47, 0x98, 0xb8, 0x17, 0x03, 0xc5, 0xa6, 0x61, - 0xdb, 0xa8, 0xe5, 0x6b, 0x91, 0x25, 0x55, 0x49, 0x37, 0x70, 0x03, 0xfb, 0xcb, 0x82, 0xb7, 0xa2, - 0xd2, 0xad, 0x06, 0xc6, 0x8d, 0x16, 0x2a, 0xf8, 0xbb, 0x5a, 0xef, 0xa8, 0x60, 0xd8, 0x43, 0x02, - 0x09, 0x3f, 0xc7, 0x20, 0x29, 0xf9, 0x71, 0x55, 0x5d, 0xc3, 0x45, 0x2c, 0x07, 0x6b, 0x0e, 0x7a, - 0xd8, 0x43, 0xb6, 0x89, 0x32, 0x0c, 0xcf, 0x6c, 0xc7, 0xd5, 0xf9, 0x9e, 0xdd, 0x81, 0x84, 0xe5, - 0xe8, 0x47, 0x5d, 0xfc, 0x05, 0xb2, 0x33, 0x31, 0x9e, 0xd9, 0x5e, 0x2b, 0xa6, 0xa7, 0x93, 0x5c, - 0x6a, 0x68, 0xb4, 0x5b, 0x37, 0x85, 0x39, 0x24, 0xa8, 0x6b, 0x96, 0x73, 0xcb, 0x5f, 0xb2, 0x2e, - 0x6c, 0x9a, 0xd8, 0x76, 0x90, 0xed, 0xf4, 0x1c, 0xdd, 0xf1, 0x3c, 0x64, 0xce, 0xf0, 0xcc, 0x76, - 0x72, 0xb7, 0x90, 0x3f, 0x25, 0x2d, 0x79, 0x69, 0x66, 0xe7, 0x07, 0x56, 0xe4, 0xa6, 0x93, 0xdc, - 0x25, 0xe2, 0x69, 0x81, 0x51, 0x50, 0x37, 0xcc, 0x88, 0x2e, 0x8b, 0xe0, 0x8a, 0xd1, 0x6a, 0xe1, - 0x81, 0xde, 0xeb, 0xd4, 0x0d, 0x17, 0xe9, 0xc6, 0x91, 0x8b, 0xba, 0x7a, 0xa7, 0x8b, 0x3b, 0xd8, - 0x31, 0x5a, 0x99, 0xb8, 0x1f, 0xfa, 0xb5, 0xe9, 0x24, 0x27, 0x10, 0xc2, 0x25, 0xca, 0x82, 0x9a, - 0xf1, 0xd1, 0x43, 0x1f, 0x14, 0x3d, 0xac, 0x42, 0xa1, 0x9b, 0xf1, 0xc7, 0xdf, 0xe7, 0x56, 0x84, - 0x1f, 0x18, 0xd8, 0x88, 0xc6, 0xca, 0xde, 0x01, 0xe8, 0xf4, 0x6a, 0x2d, 0xcb, 0xd4, 0x1f, 0xa0, - 0xa1, 0x9f, 0xc6, 0xe4, 0x6e, 0x3a, 0x4f, 0x8a, 0x90, 0x9f, 0x15, 0x21, 0x2f, 0xda, 0xc3, 0xe2, - 0xc5, 0xe9, 0x24, 0xf7, 0x02, 0x09, 0x22, 0xb0, 0x10, 0xd4, 0x04, 0xd9, 0xdc, 0x45, 0x43, 0x96, - 0x87, 0x64, 0xdd, 0xea, 0xa3, 0xae, 0x63, 0x1d, 0x59, 0xa8, 0xeb, 0xa7, 0x3d, 0xa1, 0x86, 0x45, - 0xec, 0x55, 0x48, 0xb8, 0x56, 0x1b, 0x39, 0xae, 0xd1, 0xee, 0xf8, 0xd9, 0x8d, 0xab, 0x81, 0x80, - 0x06, 0xf9, 0x75, 0x0c, 0x56, 0x6f, 0x23, 0xa3, 0x8e, 0xba, 0x4b, 0x2b, 0x1c, 0xa1, 0x8a, 0x2d, - 0x50, 0x79, 0xa8, 0x63, 0x35, 0x6c, 0xc3, 0xed, 0x75, 0x49, 0x19, 0xd7, 0xd5, 0x40, 0xc0, 0x1e, - 0xc2, 0x86, 0x8d, 0x06, 0x7a, 0xe8, 0xe0, 0xf1, 0x25, 0x07, 0xdf, 0x9a, 0x4e, 0x72, 0x17, 0xc9, - 0xc1, 0xa3, 0x56, 0x82, 0xba, 0x6e, 0xa3, 0x41, 0x65, 0x7e, 0x7e, 0x09, 0x36, 0x3d, 0x85, 0x70, - 0x0e, 0xce, 0x7a, 0x39, 0x08, 0x37, 0xc4, 0x82, 0x82, 0xa0, 0x7a, 0x91, 0x94, 0x02, 0x01, 0x4d, - 0xc2, 0xaf, 0x31, 0x58, 0xdf, 0xb7, 0x9c, 0x1a, 0x6a, 0x1a, 0x7d, 0x0b, 0xf7, 0xba, 0x5e, 0x43, - 0x93, 0xe6, 0xd3, 0xad, 0xba, 0x9f, 0x8b, 0x44, 0xb8, 0xa1, 0xe7, 0x90, 0xa0, 0xae, 0x91, 0x75, - 0xb9, 0x1e, 0xc9, 0x5e, 0x6c, 0x21, 0x7b, 0x1d, 0x38, 0x3f, 0x4f, 0x87, 0x8e, 0xed, 0x59, 0xab, - 0xef, 0x9c, 0xda, 0xea, 0xd5, 0x99, 0x95, 0x68, 0xd7, 0x4b, 0x86, 0x6b, 0x14, 0x33, 0xd3, 0x49, - 0x2e, 0x4d, 0xa2, 0x88, 0x30, 0x0a, 0xea, 0xfa, 0x7c, 0x7f, 0x60, 0x2f, 0x78, 0x74, 0x07, 0x98, - 0xa6, 0xfc, 0xbf, 0xf2, 0xe8, 0x0e, 0x70, 0xd8, 0xa3, 0x36, 0xc0, 0x34, 0x93, 0xbf, 0x30, 0x90, - 0x5a, 0xa4, 0x88, 0xb6, 0x07, 0xb3, 0xd8, 0x1e, 0x9f, 0x41, 0xa2, 0x6e, 0xb8, 0x86, 0xee, 0x0e, - 0x3b, 0x24, 0x73, 0x1b, 0xbb, 0xaf, 0x9e, 0x1a, 0xa6, 0xc7, 0xab, 0x0d, 0x3b, 0x28, 0x5c, 0x96, - 0x39, 0x8b, 0xa0, 0xae, 0xd5, 0x29, 0xce, 0xb2, 0x10, 0xf7, 0xd6, 0xb4, 0x2b, 0xfd, 0x75, 0xb4, - 0x99, 0xe3, 0xcf, 0xff, 0x2e, 0xbe, 0x62, 0x20, 0xa3, 0xcd, 0x64, 0xa8, 0x3e, 0x3f, 0x93, 0x7f, - 0xa0, 0x0f, 0x60, 0x23, 0xc8, 0x85, 0x4f, 0xef, 0x9f, 0x2a, 0xdc, 0xbb, 0x51, 0x5c, 0x50, 0x83, - 0x72, 0x94, 0x8e, 0x85, 0x10, 0x7b, 0x7e, 0x08, 0x7f, 0x30, 0x90, 0xf0, 0xfc, 0x16, 0x87, 0x2e, - 0x72, 0xfe, 0xc5, 0xd7, 0xb9, 0x30, 0x28, 0xce, 0x1c, 0x1f, 0x14, 0x91, 0x12, 0xc4, 0xff, 0xaf, - 0x12, 0x9c, 0x0d, 0x4a, 0x40, 0x4f, 0xf8, 0x13, 0x03, 0x40, 0x86, 0x8f, 0x9f, 0x94, 0x3d, 0x48, - 0xd2, 0x4f, 0xfe, 0xd4, 0xf1, 0x78, 0x69, 0x3a, 0xc9, 0xb1, 0x91, 0x29, 0x41, 0xe7, 0x23, 0x19, - 0x11, 0x27, 0xcc, 0x87, 0xd8, 0x3f, 0x9c, 0x0f, 0x5f, 0xc2, 0x66, 0xe8, 0x2a, 0xf4, 0x63, 0x65, - 0x21, 0xde, 0x31, 0xdc, 0x26, 0x6d, 0x67, 0x7f, 0xcd, 0x56, 0x60, 0x9d, 0x8e, 0x06, 0x72, 0xa1, - 0xc5, 0x96, 0x1c, 0xe0, 0xf2, 0x74, 0x92, 0xbb, 0x10, 0x19, 0x27, 0xf4, 0xca, 0x4a, 0x9a, 0x81, - 0x27, 0xea, 0xfe, 0x1b, 0x06, 0xd8, 0xe8, 0x45, 0x72, 0x62, 0x08, 0xf7, 0x8e, 0x5f, 0xab, 0xcb, - 0xa2, 0xf8, 0x1b, 0x77, 0x27, 0x8d, 0xa5, 0x0f, 0x17, 0xa4, 0xf9, 0xf3, 0x63, 0x79, 0x2c, 0x32, - 0x40, 0xf0, 0x52, 0xa1, 0x61, 0xbc, 0xec, 0xb7, 0x95, 0xf7, 0x54, 0xc9, 0x87, 0x5e, 0x31, 0xfd, - 0x9d, 0x7c, 0x40, 0x2a, 0xdb, 0x75, 0x35, 0x64, 0x48, 0xfd, 0xd6, 0x21, 0x25, 0x91, 0x07, 0xcd, - 0x72, 0xa7, 0x37, 0xe0, 0x1c, 0x7d, 0xf8, 0x50, 0x8f, 0x57, 0x43, 0x1e, 0xe9, 0x8b, 0xc8, 0x73, - 0x47, 0x96, 0xea, 0x4c, 0x99, 0x7a, 0xb9, 0x03, 0xe9, 0x8a, 0x61, 0x3e, 0x40, 0xae, 0x84, 0xdb, - 0x6d, 0xcb, 0x6d, 0x23, 0xdb, 0x3d, 0xd1, 0x53, 0xd6, 0x3b, 0xde, 0x4c, 0xcb, 0x77, 0xb6, 0xae, - 0x86, 0x24, 0xc2, 0x3d, 0xd8, 0x22, 0x5c, 0xa2, 0xf9, 0xc0, 0xc6, 0x83, 0x16, 0xaa, 0x37, 0xd0, - 0x52, 0xc2, 0x6d, 0xd8, 0x34, 0xa2, 0xaa, 0x94, 0x75, 0x51, 0x2c, 0xe4, 0x21, 0x43, 0xa8, 0x55, - 0x64, 0x22, 0xab, 0xe3, 0x8a, 0x35, 0xc7, 0x9b, 0x03, 0x27, 0x31, 0x0b, 0x4d, 0x48, 0x2b, 0xe8, - 0x91, 0x5b, 0xa5, 0xf3, 0x42, 0x45, 0x66, 0xff, 0xc4, 0x28, 0xde, 0x85, 0xf3, 0x36, 0x7a, 0xe4, - 0xea, 0x0e, 0x7a, 0xa8, 0x77, 0x91, 0xd9, 0x27, 0xf3, 0x24, 0x7c, 0x0d, 0x44, 0x60, 0x41, 0x4d, - 0xda, 0x84, 0xda, 0x63, 0x7d, 0xed, 0xdb, 0x38, 0xac, 0xcd, 0x06, 0x03, 0xfb, 0x0e, 0xbc, 0x54, - 0x12, 0x35, 0x51, 0xd7, 0xee, 0x55, 0x64, 0xfd, 0x50, 0x29, 0x2b, 0x65, 0xad, 0x2c, 0xee, 0x95, - 0xef, 0xcb, 0x25, 0xfd, 0x50, 0xa9, 0x56, 0x64, 0xa9, 0x7c, 0xab, 0x2c, 0x97, 0x52, 0x2b, 0xdc, - 0xe6, 0x68, 0xcc, 0x27, 0x43, 0x22, 0xf6, 0x1a, 0x5c, 0x0a, 0x2c, 0xa5, 0xbd, 0xb2, 0xac, 0x68, - 0x7a, 0x55, 0x13, 0x35, 0x39, 0xc5, 0x70, 0x30, 0x1a, 0xf3, 0xab, 0x44, 0xc6, 0xbe, 0x0e, 0x5b, - 0x21, 0xbd, 0x03, 0xa5, 0x2a, 0x2b, 0xd5, 0xc3, 0x2a, 0x55, 0x8d, 0x71, 0xe7, 0x47, 0x63, 0x3e, - 0x31, 0x17, 0xb3, 0x79, 0xe0, 0x22, 0xda, 0x8a, 0x2c, 0x69, 0xe5, 0x03, 0x85, 0xaa, 0x9f, 0xe1, - 0x36, 0x46, 0x63, 0x1e, 0x02, 0x39, 0xbb, 0x0d, 0x97, 0x43, 0xfa, 0xb7, 0x45, 0x45, 0x91, 0xf7, - 0xa8, 0x72, 0x9c, 0x4b, 0x8e, 0xc6, 0xfc, 0x39, 0x2a, 0x64, 0xdf, 0x86, 0x2b, 0x81, 0x66, 0x45, - 0x94, 0xee, 0xca, 0x9a, 0x2e, 0x1d, 0xec, 0xef, 0x97, 0xb5, 0x7d, 0x59, 0xd1, 0x52, 0x67, 0xb9, - 0xf4, 0x68, 0xcc, 0xa7, 0x08, 0x10, 0xc8, 0xd9, 0xf7, 0x81, 0x3f, 0x66, 0x26, 0x4a, 0x77, 0x95, - 0x83, 0x4f, 0xf6, 0xe4, 0xd2, 0x87, 0xb2, 0x6f, 0xbb, 0xca, 0x6d, 0x8d, 0xc6, 0xfc, 0x45, 0x82, - 0x2e, 0x80, 0xec, 0x7b, 0xcf, 0x21, 0x50, 0x65, 0x49, 0x2e, 0x57, 0x34, 0x5d, 0x2c, 0x56, 0x65, - 0x45, 0x92, 0x53, 0xe7, 0xb8, 0xcc, 0x68, 0xcc, 0xa7, 0x09, 0x4a, 0x41, 0x8a, 0xb1, 0x37, 0xe0, - 0x6a, 0x60, 0xaf, 0xc8, 0x9f, 0x6a, 0x7a, 0x55, 0xfe, 0xe8, 0xd0, 0x83, 0x3c, 0x9a, 0x8f, 0x53, - 0x6b, 0x24, 0x70, 0x0f, 0x99, 0x01, 0x9e, 0x9c, 0xe5, 0x21, 0x15, 0xd8, 0xdd, 0x96, 0xc5, 0x92, - 0xac, 0xa6, 0x12, 0xa4, 0x32, 0x64, 0xc7, 0xc5, 0x1f, 0xff, 0x98, 0x5d, 0x29, 0x7e, 0xfe, 0xdb, - 0xd3, 0x2c, 0xf3, 0xe4, 0x69, 0x96, 0xf9, 0xf3, 0x69, 0x96, 0xf9, 0xee, 0x59, 0x76, 0xe5, 0xc9, - 0xb3, 0xec, 0xca, 0xef, 0xcf, 0xb2, 0x2b, 0xf7, 0x6f, 0x35, 0x2c, 0xb7, 0xd9, 0xab, 0xe5, 0x4d, - 0xdc, 0x2e, 0x98, 0xd8, 0x69, 0x63, 0xa7, 0x60, 0xd5, 0xcc, 0xeb, 0x0d, 0x5c, 0xe8, 0xbf, 0x55, - 0x68, 0xe3, 0x7a, 0xaf, 0x85, 0x1c, 0xf2, 0x3f, 0x75, 0x7d, 0xf6, 0x43, 0xf5, 0xc6, 0x8d, 0xeb, - 0xe1, 0x7f, 0x2a, 0xef, 0x9a, 0x71, 0x6a, 0xab, 0xfe, 0x3c, 0x7b, 0xf3, 0xaf, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x3f, 0x26, 0x7b, 0x3d, 0x80, 0x0d, 0x00, 0x00, + // 1374 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xdf, 0x8e, 0xdb, 0x44, + 0x17, 0x5f, 0xa7, 0xe9, 0x76, 0x33, 0xd9, 0xee, 0xe6, 0x73, 0xd3, 0x36, 0xeb, 0x56, 0x89, 0x3f, + 0x23, 0xca, 0x82, 0x68, 0xcc, 0x2e, 0xa2, 0x45, 0x15, 0x82, 0x3a, 0x8e, 0x4b, 0xd3, 0xee, 0x7a, + 0x83, 0xe3, 0x05, 0x5a, 0x21, 0x59, 0x8e, 0x3d, 0x9b, 0x58, 0x4d, 0x3c, 0x69, 0x3c, 0x49, 0x1a, + 0x24, 0x24, 0xc4, 0x55, 0x89, 0xb8, 0xe0, 0x05, 0x22, 0x21, 0x10, 0xcf, 0xc1, 0x1d, 0x70, 0xd9, + 0x4b, 0xae, 0x02, 0x6a, 0xdf, 0x20, 0x4f, 0x80, 0xec, 0x99, 0xc4, 0x76, 0xb6, 0x9b, 0x15, 0xff, + 0xee, 0x66, 0xce, 0xef, 0x9c, 0xdf, 0x39, 0x73, 0xce, 0xf1, 0x99, 0x31, 0xd8, 0x71, 0xea, 0x96, + 0xd8, 0x72, 0x1a, 0x4d, 0x6c, 0xb5, 0x1c, 0xe8, 0x62, 0x4f, 0xf4, 0x50, 0x0b, 0xb5, 0x4d, 0xab, + 0xe9, 0xb8, 0x50, 0xec, 0xef, 0x46, 0xb7, 0xc5, 0x4e, 0x17, 0x61, 0xc4, 0x16, 0x9c, 0xba, 0x55, + 0x8c, 0x9a, 0x14, 0xa3, 0x3a, 0xfd, 0x5d, 0xee, 0x35, 0x9f, 0xd3, 0x42, 0x5d, 0x28, 0x5a, 0xc8, + 0x75, 0xa1, 0x85, 0x1d, 0xe4, 0x8a, 0xfd, 0x9d, 0xc8, 0x8e, 0x30, 0x71, 0xff, 0x0f, 0x15, 0x9b, + 0xa6, 0xeb, 0xc2, 0x56, 0xa0, 0x45, 0x96, 0x54, 0x25, 0xdb, 0x40, 0x0d, 0x14, 0x2c, 0x45, 0x7f, + 0x45, 0xa5, 0x5b, 0x0d, 0x84, 0x1a, 0x2d, 0x28, 0x06, 0xbb, 0x7a, 0xef, 0x48, 0x34, 0xdd, 0x21, + 0x81, 0x84, 0x9f, 0x12, 0x20, 0x2d, 0x07, 0x71, 0xd5, 0xb0, 0x89, 0x21, 0xcb, 0x81, 0x35, 0x0f, + 0x3e, 0xee, 0x41, 0xd7, 0x82, 0x39, 0x86, 0x67, 0xb6, 0x93, 0xda, 0x7c, 0xcf, 0xee, 0x80, 0x94, + 0xe3, 0x19, 0x47, 0x5d, 0xf4, 0x39, 0x74, 0x73, 0x09, 0x9e, 0xd9, 0x5e, 0x2b, 0x65, 0xa7, 0x93, + 0x42, 0x66, 0x68, 0xb6, 0x5b, 0xb7, 0x84, 0x39, 0x24, 0x68, 0x6b, 0x8e, 0x77, 0x27, 0x58, 0xb2, + 0x18, 0x6c, 0x5a, 0xc8, 0xf5, 0xa0, 0xeb, 0xf5, 0x3c, 0xc3, 0xf3, 0x3d, 0xe4, 0xce, 0xf0, 0xcc, + 0x76, 0x7a, 0x57, 0x2c, 0x9e, 0x92, 0x96, 0xa2, 0x3c, 0xb3, 0x0b, 0x02, 0x2b, 0x71, 0xd3, 0x49, + 0xe1, 0x12, 0xf1, 0xb4, 0xc0, 0x28, 0x68, 0x1b, 0x56, 0x4c, 0x97, 0x85, 0xe0, 0x8a, 0xd9, 0x6a, + 0xa1, 0x81, 0xd1, 0xeb, 0xd8, 0x26, 0x86, 0x86, 0x79, 0x84, 0x61, 0xd7, 0xe8, 0x74, 0x51, 0x07, + 0x79, 0x66, 0x2b, 0x97, 0x0c, 0x42, 0xbf, 0x36, 0x9d, 0x14, 0x04, 0x42, 0xb8, 0x44, 0x59, 0xd0, + 0x72, 0x01, 0x7a, 0x18, 0x80, 0x92, 0x8f, 0x55, 0x29, 0x74, 0x2b, 0xf9, 0xf4, 0xbb, 0xc2, 0x8a, + 0xf0, 0x3d, 0x03, 0x36, 0xe2, 0xb1, 0xb2, 0xf7, 0x00, 0xe8, 0xf4, 0xea, 0x2d, 0xc7, 0x32, 0x1e, + 0xc1, 0x61, 0x90, 0xc6, 0xf4, 0x6e, 0xb6, 0x48, 0x8a, 0x50, 0x9c, 0x15, 0xa1, 0x28, 0xb9, 0xc3, + 0xd2, 0xc5, 0xe9, 0xa4, 0xf0, 0x3f, 0x12, 0x44, 0x68, 0x21, 0x68, 0x29, 0xb2, 0xb9, 0x0f, 0x87, + 0x2c, 0x0f, 0xd2, 0xb6, 0xd3, 0x87, 0x5d, 0xcf, 0x39, 0x72, 0x60, 0x37, 0x48, 0x7b, 0x4a, 0x8b, + 0x8a, 0xd8, 0xab, 0x20, 0x85, 0x9d, 0x36, 0xf4, 0xb0, 0xd9, 0xee, 0x04, 0xd9, 0x4d, 0x6a, 0xa1, + 0x80, 0x06, 0xf9, 0x55, 0x02, 0xac, 0xde, 0x85, 0xa6, 0x0d, 0xbb, 0x4b, 0x2b, 0x1c, 0xa3, 0x4a, + 0x2c, 0x50, 0xf9, 0xa8, 0xe7, 0x34, 0x5c, 0x13, 0xf7, 0xba, 0xa4, 0x8c, 0xeb, 0x5a, 0x28, 0x60, + 0x0f, 0xc1, 0x86, 0x0b, 0x07, 0x46, 0xe4, 0xe0, 0xc9, 0x25, 0x07, 0xdf, 0x9a, 0x4e, 0x0a, 0x17, + 0xc9, 0xc1, 0xe3, 0x56, 0x82, 0xb6, 0xee, 0xc2, 0x41, 0x75, 0x7e, 0x7e, 0x19, 0x6c, 0xfa, 0x0a, + 0xd1, 0x1c, 0x9c, 0xf5, 0x73, 0x10, 0x6d, 0x88, 0x05, 0x05, 0x41, 0xf3, 0x23, 0x29, 0x87, 0x02, + 0x9a, 0x84, 0x5f, 0x12, 0x60, 0x7d, 0xdf, 0xf1, 0xea, 0xb0, 0x69, 0xf6, 0x1d, 0xd4, 0xeb, 0xfa, + 0x0d, 0x4d, 0x9a, 0xcf, 0x70, 0xec, 0x20, 0x17, 0xa9, 0x68, 0x43, 0xcf, 0x21, 0x41, 0x5b, 0x23, + 0xeb, 0x8a, 0x1d, 0xcb, 0x5e, 0x62, 0x21, 0x7b, 0x1d, 0x70, 0x7e, 0x9e, 0x0e, 0x03, 0xb9, 0xb3, + 0x56, 0xdf, 0x39, 0xb5, 0xd5, 0x6b, 0x33, 0x2b, 0xc9, 0xb5, 0xcb, 0x26, 0x36, 0x4b, 0xb9, 0xe9, + 0xa4, 0x90, 0x25, 0x51, 0xc4, 0x18, 0x05, 0x6d, 0x7d, 0xbe, 0x3f, 0x70, 0x17, 0x3c, 0xe2, 0x01, + 0xa2, 0x29, 0xff, 0xb7, 0x3c, 0xe2, 0x01, 0x8a, 0x7a, 0xd4, 0x07, 0x88, 0x66, 0xf2, 0x67, 0x06, + 0x64, 0x16, 0x29, 0xe2, 0xed, 0xc1, 0x2c, 0xb6, 0xc7, 0x67, 0x20, 0x65, 0x9b, 0xd8, 0x34, 0xf0, + 0xb0, 0x43, 0x32, 0xb7, 0xb1, 0xfb, 0xfa, 0xa9, 0x61, 0xfa, 0xbc, 0xfa, 0xb0, 0x03, 0xa3, 0x65, + 0x99, 0xb3, 0x08, 0xda, 0x9a, 0x4d, 0x71, 0x96, 0x05, 0x49, 0x7f, 0x4d, 0xbb, 0x32, 0x58, 0xc7, + 0x9b, 0x39, 0xf9, 0xf2, 0xef, 0xe2, 0x4b, 0x06, 0xe4, 0xf4, 0x99, 0x0c, 0xda, 0xf3, 0x33, 0x05, + 0x07, 0xba, 0x0d, 0x36, 0xc2, 0x5c, 0x04, 0xf4, 0xc1, 0xa9, 0xa2, 0xbd, 0x1b, 0xc7, 0x05, 0x2d, + 0x2c, 0x47, 0xf9, 0x58, 0x08, 0x89, 0x97, 0x87, 0xf0, 0x3b, 0x03, 0x52, 0xbe, 0xdf, 0xd2, 0x10, + 0x43, 0xef, 0x1f, 0x7c, 0x9d, 0x0b, 0x83, 0xe2, 0xcc, 0xf1, 0x41, 0x11, 0x2b, 0x41, 0xf2, 0xbf, + 0x2a, 0xc1, 0xd9, 0xb0, 0x04, 0xf4, 0x84, 0x3f, 0x32, 0x00, 0x90, 0xe1, 0x13, 0x24, 0x65, 0x0f, + 0xa4, 0xe9, 0x27, 0x7f, 0xea, 0x78, 0xbc, 0x34, 0x9d, 0x14, 0xd8, 0xd8, 0x94, 0xa0, 0xf3, 0x91, + 0x8c, 0x88, 0x13, 0xe6, 0x43, 0xe2, 0x6f, 0xce, 0x87, 0x2f, 0xc0, 0x66, 0xe4, 0x2a, 0x0c, 0x62, + 0x65, 0x41, 0xb2, 0x63, 0xe2, 0x26, 0x6d, 0xe7, 0x60, 0xcd, 0x56, 0xc1, 0x3a, 0x1d, 0x0d, 0xe4, + 0x42, 0x4b, 0x2c, 0x39, 0xc0, 0xe5, 0xe9, 0xa4, 0x70, 0x21, 0x36, 0x4e, 0xe8, 0x95, 0x95, 0xb6, + 0x42, 0x4f, 0xd4, 0xfd, 0xd7, 0x0c, 0x60, 0xe3, 0x17, 0xc9, 0x89, 0x21, 0x3c, 0x38, 0x7e, 0xad, + 0x2e, 0x8b, 0xe2, 0x2f, 0xdc, 0x9d, 0x34, 0x96, 0x3e, 0xb8, 0x20, 0xcf, 0x9f, 0x1f, 0xcb, 0x63, + 0x51, 0x00, 0x08, 0x5f, 0x2a, 0x34, 0x8c, 0x57, 0x83, 0xb6, 0xf2, 0x9f, 0x2a, 0xc5, 0xc8, 0x2b, + 0xa6, 0xbf, 0x53, 0x0c, 0x49, 0x15, 0xd7, 0xd6, 0x22, 0x86, 0xd4, 0xaf, 0x0d, 0x32, 0x32, 0x79, + 0xd0, 0x2c, 0x77, 0x7a, 0x03, 0x9c, 0xa3, 0x0f, 0x1f, 0xea, 0xf1, 0x6a, 0xc4, 0x23, 0x7d, 0x11, + 0xf9, 0xee, 0xc8, 0x52, 0x9b, 0x29, 0x53, 0x2f, 0xf7, 0x40, 0xb6, 0x6a, 0x5a, 0x8f, 0x20, 0x96, + 0x51, 0xbb, 0xed, 0xe0, 0x36, 0x74, 0xf1, 0x89, 0x9e, 0xf2, 0xfe, 0xf1, 0x66, 0x5a, 0x81, 0xb3, + 0x75, 0x2d, 0x22, 0x11, 0x1e, 0x80, 0x2d, 0xc2, 0x25, 0x59, 0x8f, 0x5c, 0x34, 0x68, 0x41, 0xbb, + 0x01, 0x97, 0x12, 0x6e, 0x83, 0x4d, 0x33, 0xae, 0x4a, 0x59, 0x17, 0xc5, 0x42, 0x11, 0xe4, 0x08, + 0xb5, 0x06, 0x2d, 0xe8, 0x74, 0xb0, 0x54, 0xf7, 0xfc, 0x39, 0x70, 0x12, 0xb3, 0xd0, 0x04, 0x59, + 0x15, 0x3e, 0xc1, 0x35, 0x3a, 0x2f, 0x34, 0x68, 0xf5, 0x4f, 0x8c, 0xe2, 0x3d, 0x70, 0xde, 0x85, + 0x4f, 0xb0, 0xe1, 0xc1, 0xc7, 0x46, 0x17, 0x5a, 0x7d, 0x32, 0x4f, 0xa2, 0xd7, 0x40, 0x0c, 0x16, + 0xb4, 0xb4, 0x4b, 0xa8, 0x7d, 0xd6, 0x37, 0xbe, 0x49, 0x82, 0xb5, 0xd9, 0x60, 0x60, 0xdf, 0x05, + 0xaf, 0x94, 0x25, 0x5d, 0x32, 0xf4, 0x07, 0x55, 0xc5, 0x38, 0x54, 0x2b, 0x6a, 0x45, 0xaf, 0x48, + 0x7b, 0x95, 0x87, 0x4a, 0xd9, 0x38, 0x54, 0x6b, 0x55, 0x45, 0xae, 0xdc, 0xa9, 0x28, 0xe5, 0xcc, + 0x0a, 0xb7, 0x39, 0x1a, 0xf3, 0xe9, 0x88, 0x88, 0xbd, 0x06, 0x2e, 0x85, 0x96, 0xf2, 0x5e, 0x45, + 0x51, 0x75, 0xa3, 0xa6, 0x4b, 0xba, 0x92, 0x61, 0x38, 0x30, 0x1a, 0xf3, 0xab, 0x44, 0xc6, 0xbe, + 0x09, 0xb6, 0x22, 0x7a, 0x07, 0x6a, 0x4d, 0x51, 0x6b, 0x87, 0x35, 0xaa, 0x9a, 0xe0, 0xce, 0x8f, + 0xc6, 0x7c, 0x6a, 0x2e, 0x66, 0x8b, 0x80, 0x8b, 0x69, 0xab, 0x8a, 0xac, 0x57, 0x0e, 0x54, 0xaa, + 0x7e, 0x86, 0xdb, 0x18, 0x8d, 0x79, 0x10, 0xca, 0xd9, 0x6d, 0x70, 0x39, 0xa2, 0x7f, 0x57, 0x52, + 0x55, 0x65, 0x8f, 0x2a, 0x27, 0xb9, 0xf4, 0x68, 0xcc, 0x9f, 0xa3, 0x42, 0xf6, 0x1d, 0x70, 0x25, + 0xd4, 0xac, 0x4a, 0xf2, 0x7d, 0x45, 0x37, 0xe4, 0x83, 0xfd, 0xfd, 0x8a, 0xbe, 0xaf, 0xa8, 0x7a, + 0xe6, 0x2c, 0x97, 0x1d, 0x8d, 0xf9, 0x0c, 0x01, 0x42, 0x39, 0xfb, 0x01, 0xe0, 0x8f, 0x99, 0x49, + 0xf2, 0x7d, 0xf5, 0xe0, 0x93, 0x3d, 0xa5, 0xfc, 0xa1, 0x12, 0xd8, 0xae, 0x72, 0x5b, 0xa3, 0x31, + 0x7f, 0x91, 0xa0, 0x0b, 0x20, 0xfb, 0xfe, 0x4b, 0x08, 0x34, 0x45, 0x56, 0x2a, 0x55, 0xdd, 0x90, + 0x4a, 0x35, 0x45, 0x95, 0x95, 0xcc, 0x39, 0x2e, 0x37, 0x1a, 0xf3, 0x59, 0x82, 0x52, 0x90, 0x62, + 0xec, 0x0d, 0x70, 0x35, 0xb4, 0x57, 0x95, 0x4f, 0x75, 0xa3, 0xa6, 0x7c, 0x74, 0xe8, 0x43, 0x3e, + 0xcd, 0xc7, 0x99, 0x35, 0x12, 0xb8, 0x8f, 0xcc, 0x00, 0x5f, 0xce, 0xf2, 0x20, 0x13, 0xda, 0xdd, + 0x55, 0xa4, 0xb2, 0xa2, 0x65, 0x52, 0xa4, 0x32, 0x64, 0xc7, 0x25, 0x9f, 0xfe, 0x90, 0x5f, 0x29, + 0x3d, 0xfc, 0xf5, 0x79, 0x9e, 0x79, 0xf6, 0x3c, 0xcf, 0xfc, 0xf1, 0x3c, 0xcf, 0x7c, 0xfb, 0x22, + 0xbf, 0xf2, 0xec, 0x45, 0x7e, 0xe5, 0xb7, 0x17, 0xf9, 0x95, 0x87, 0xb7, 0x1b, 0x0e, 0x6e, 0xf6, + 0xea, 0x45, 0x0b, 0xb5, 0x45, 0x0b, 0x79, 0x6d, 0xe4, 0x89, 0x4e, 0xdd, 0xba, 0xde, 0x40, 0x62, + 0xff, 0xa6, 0xd8, 0x46, 0x76, 0xaf, 0x05, 0x3d, 0xf2, 0x4b, 0xf3, 0xd6, 0xee, 0x75, 0x32, 0x12, + 0xc5, 0xb6, 0xd3, 0xe8, 0x9a, 0xfe, 0x4c, 0xf0, 0xc4, 0xfe, 0xcd, 0xfa, 0x6a, 0x30, 0xc9, 0xde, + 0xfe, 0x33, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x8d, 0x81, 0x56, 0x7a, 0x0d, 0x00, 0x00, } func (m *ClientState) Marshal() (dAtA []byte, err error) { diff --git a/modules/core/02-client/migrations/v7/store.go b/modules/core/02-client/migrations/v7/store.go new file mode 100644 index 00000000000..56afc9e0c8b --- /dev/null +++ b/modules/core/02-client/migrations/v7/store.go @@ -0,0 +1,206 @@ +package v7 + +import ( + "fmt" + "strings" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" +) + +// Localhost is the client type for a localhost client. It is also used as the clientID +// for the localhost client. +const Localhost string = "09-localhost" + +// MigrateStore performs in-place store migrations from ibc-go v6 to ibc-go v7. +// The migration includes: +// +// - Migrating solo machine client states from v2 to v3 protobuf definition +// - Pruning all solo machine consensus states +// - Removing the localhost client +// - Asserting existing tendermint clients are properly registered on the chain codec +func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, clientKeeper ClientKeeper) error { + store := ctx.KVStore(storeKey) + + if err := handleSolomachineMigration(ctx, store, cdc, clientKeeper); err != nil { + return err + } + + if err := handleTendermintMigration(ctx, store, cdc, clientKeeper); err != nil { + return err + } + + if err := handleLocalhostMigration(ctx, store, cdc, clientKeeper); err != nil { + return err + } + + return nil +} + +// handleSolomachineMigration iterates over the solo machine clients and migrates client state from +// protobuf definition v2 to v3. All consensus states stored outside of the client state are pruned. +func handleSolomachineMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, clientKeeper ClientKeeper) error { + clients, err := collectClients(ctx, store, exported.Solomachine) + if err != nil { + return err + } + + for _, clientID := range clients { + clientStore := clientKeeper.ClientStore(ctx, clientID) + + bz := clientStore.Get(host.ClientStateKey()) + if len(bz) == 0 { + return errorsmod.Wrapf(clienttypes.ErrClientNotFound, "clientID %s", clientID) + } + + var any codectypes.Any + if err := cdc.Unmarshal(bz, &any); err != nil { + return errorsmod.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") + } + + var clientState ClientState + if err := cdc.Unmarshal(any.Value, &clientState); err != nil { + return errorsmod.Wrap(err, "failed to unmarshal client state bytes into solo machine client state") + } + + updatedClientState := migrateSolomachine(clientState) + + // update solomachine in store + clientKeeper.SetClientState(ctx, clientID, &updatedClientState) + + removeAllClientConsensusStates(clientStore) + } + + return nil +} + +// handlerTendermintMigration asserts that the tendermint client in state can be decoded properly. +// This ensures the upgrading chain properly registered the tendermint client types on the chain codec. +func handleTendermintMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, clientKeeper ClientKeeper) error { + clients, err := collectClients(ctx, store, exported.Tendermint) + if err != nil { + return err + } + + if len(clients) == 0 { + return nil // no-op if no tm clients exist + } + + if len(clients) > 1 { + return errorsmod.Wrap(ibcerrors.ErrLogic, "more than one Tendermint client collected") + } + + clientID := clients[0] + + // unregistered tendermint client types will panic when unmarshaling the client state + // in GetClientState + clientState, ok := clientKeeper.GetClientState(ctx, clientID) + if !ok { + return errorsmod.Wrapf(clienttypes.ErrClientNotFound, "clientID %s", clientID) + } + + _, ok = clientState.(*ibctm.ClientState) + if !ok { + return errorsmod.Wrap(clienttypes.ErrInvalidClient, "client state is not tendermint even though client id contains 07-tendermint") + } + + return nil +} + +// handleLocalhostMigration removes all client and consensus states associated with the localhost client type. +func handleLocalhostMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.BinaryCodec, clientKeeper ClientKeeper) error { + clients, err := collectClients(ctx, store, Localhost) + if err != nil { + return err + } + + for _, clientID := range clients { + clientStore := clientKeeper.ClientStore(ctx, clientID) + + // delete the client state + clientStore.Delete(host.ClientStateKey()) + + removeAllClientConsensusStates(clientStore) + } + + return nil +} + +// collectClients will iterate over the provided client type prefix in the client store +// and return a list of clientIDs associated with the client type. This is necessary to +// avoid state corruption as modifying state during iteration is unsafe. A special case +// for tendermint clients is included as only one tendermint clientID is required for +// v7 migrations. +func collectClients(ctx sdk.Context, store sdk.KVStore, clientType string) (clients []string, err error) { + clientPrefix := []byte(fmt.Sprintf("%s/%s", host.KeyClientStorePrefix, clientType)) + iterator := sdk.KVStorePrefixIterator(store, clientPrefix) + + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) + for ; iterator.Valid(); iterator.Next() { + path := string(iterator.Key()) + if !strings.Contains(path, host.KeyClientState) { + // skip non client state keys + continue + } + + clientID := host.MustParseClientStatePath(path) + clients = append(clients, clientID) + + // optimization: exit after a single tendermint client iteration + if strings.Contains(clientID, exported.Tendermint) { + return clients, nil + } + } + + return clients, nil +} + +// removeAllClientConsensusStates removes all client consensus states from the associated +// client store. +func removeAllClientConsensusStates(clientStore sdk.KVStore) { + iterator := sdk.KVStorePrefixIterator(clientStore, []byte(host.KeyConsensusStatePrefix)) + var heights []exported.Height + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + keySplit := strings.Split(string(iterator.Key()), "/") + // key is in the format "consensusStates/" + if len(keySplit) != 2 || keySplit[0] != string(host.KeyConsensusStatePrefix) { + continue + } + + // collect consensus states to be pruned + heights = append(heights, clienttypes.MustParseHeight(keySplit[1])) + } + + // delete all consensus states + for _, height := range heights { + clientStore.Delete(host.ConsensusStateKey(height)) + } +} + +// migrateSolomachine migrates the solomachine from v2 to v3 solo machine protobuf definition. +// Notably it drops the AllowUpdateAfterProposal field. +func migrateSolomachine(clientState ClientState) solomachine.ClientState { + consensusState := &solomachine.ConsensusState{ + PublicKey: clientState.ConsensusState.PublicKey, + Diversifier: clientState.ConsensusState.Diversifier, + Timestamp: clientState.ConsensusState.Timestamp, + } + + return solomachine.ClientState{ + Sequence: clientState.Sequence, + IsFrozen: clientState.IsFrozen, + ConsensusState: consensusState, + } +} diff --git a/modules/core/02-client/migrations/v7/store_test.go b/modules/core/02-client/migrations/v7/store_test.go new file mode 100644 index 00000000000..a098530af50 --- /dev/null +++ b/modules/core/02-client/migrations/v7/store_test.go @@ -0,0 +1,168 @@ +package v7_test + +import ( + "strconv" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/stretchr/testify/suite" + + v7 "github.com/cosmos/ibc-go/v7/modules/core/02-client/migrations/v7" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +// numCreations is the number of clients/consensus states created for +// solo machine and localhost clients +const numCreations = 10 + +type MigrationsV7TestSuite struct { + suite.Suite + + coordinator *ibctesting.Coordinator + + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain +} + +func (suite *MigrationsV7TestSuite) SetupTest() { + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) + + suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) + suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) +} + +func TestIBCTestSuite(t *testing.T) { + suite.Run(t, new(MigrationsV7TestSuite)) +} + +// create multiple solo machine clients, tendermint and localhost clients +// ensure that solo machine clients are migrated and their consensus states are removed +// ensure the localhost is deleted entirely. +func (suite *MigrationsV7TestSuite) TestMigrateStore() { + paths := []*ibctesting.Path{ + ibctesting.NewPath(suite.chainA, suite.chainB), + ibctesting.NewPath(suite.chainA, suite.chainB), + } + + // create tendermint clients + for _, path := range paths { + suite.coordinator.SetupClients(path) + } + + solomachines := []*ibctesting.Solomachine{ + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1), + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4), + } + + suite.createSolomachineClients(solomachines) + suite.createLocalhostClients() + + err := v7.MigrateStore(suite.chainA.GetContext(), suite.chainA.GetSimApp().GetKey(ibcexported.StoreKey), suite.chainA.App.AppCodec(), suite.chainA.GetSimApp().IBCKeeper.ClientKeeper) + suite.Require().NoError(err) + + suite.assertSolomachineClients(solomachines) + suite.assertNoLocalhostClients() +} + +func (suite *MigrationsV7TestSuite) TestMigrateStoreNoTendermintClients() { + solomachines := []*ibctesting.Solomachine{ + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1), + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4), + } + + suite.createSolomachineClients(solomachines) + suite.createLocalhostClients() + + err := v7.MigrateStore(suite.chainA.GetContext(), suite.chainA.GetSimApp().GetKey(ibcexported.StoreKey), suite.chainA.App.AppCodec(), suite.chainA.GetSimApp().IBCKeeper.ClientKeeper) + suite.Require().NoError(err) + + suite.assertSolomachineClients(solomachines) + suite.assertNoLocalhostClients() +} + +func (suite *MigrationsV7TestSuite) createSolomachineClients(solomachines []*ibctesting.Solomachine) { + // manually generate old protobuf definitions and set in store + // NOTE: we cannot use 'CreateClient' and 'UpdateClient' functions since we are + // using client states and consensus states which do not implement the exported.ClientState + // and exported.ConsensusState interface + for _, sm := range solomachines { + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), sm.ClientID) + clientState := sm.ClientState() + + // generate old client state proto definition + legacyClientState := &v7.ClientState{ + Sequence: clientState.Sequence, + ConsensusState: &v7.ConsensusState{ + PublicKey: clientState.ConsensusState.PublicKey, + Diversifier: clientState.ConsensusState.Diversifier, + Timestamp: clientState.ConsensusState.Timestamp, + }, + AllowUpdateAfterProposal: true, + } + + cdc := suite.chainA.App.AppCodec().(*codec.ProtoCodec) + v7.RegisterInterfaces(cdc.InterfaceRegistry()) + + bz, err := cdc.MarshalInterface(legacyClientState) + suite.Require().NoError(err) + clientStore.Set(host.ClientStateKey(), bz) + + bz, err = cdc.MarshalInterface(legacyClientState.ConsensusState) + suite.Require().NoError(err) + + // set some consensus states + for i := uint64(0); i < numCreations; i++ { + height := types.NewHeight(1, i) + clientStore.Set(host.ConsensusStateKey(height), bz) + } + + } +} + +func (suite *MigrationsV7TestSuite) assertSolomachineClients(solomachines []*ibctesting.Solomachine) { + // verify client state has been migrated + for _, sm := range solomachines { + clientState, ok := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), sm.ClientID) + suite.Require().True(ok) + suite.Require().Equal(sm.ClientState(), clientState) + + for i := uint64(0); i < numCreations; i++ { + height := types.NewHeight(1, i) + + consState, ok := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientConsensusState(suite.chainA.GetContext(), sm.ClientID, height) + suite.Require().False(ok) + suite.Require().Empty(consState) + } + } +} + +// createLocalhostClients clients creates multiple localhost clients and multiple consensus states for each +func (suite *MigrationsV7TestSuite) createLocalhostClients() { + for numClients := uint64(0); numClients < numCreations; numClients++ { + clientID := v7.Localhost + "-" + strconv.FormatUint(numClients, 10) + clientStore := suite.chainA.GetSimApp().IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientID) + + clientStore.Set(host.ClientStateKey(), []byte("clientState")) + + for i := 0; i < numCreations; i++ { + clientStore.Set(host.ConsensusStateKey(types.NewHeight(1, uint64(i))), []byte("consensusState")) + } + } +} + +// assertLocalhostClients asserts that all localhost information has been deleted +func (suite *MigrationsV7TestSuite) assertNoLocalhostClients() { + for numClients := uint64(0); numClients < numCreations; numClients++ { + clientID := v7.Localhost + "-" + strconv.FormatUint(numClients, 10) + clientStore := suite.chainA.GetSimApp().IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientID) + + suite.Require().False(clientStore.Has(host.ClientStateKey())) + + for i := uint64(0); i < numCreations; i++ { + suite.Require().False(clientStore.Has(host.ConsensusStateKey(types.NewHeight(1, i)))) + } + } +} diff --git a/modules/core/02-client/module.go b/modules/core/02-client/module.go index 6cef3aac5c0..a9690dcd374 100644 --- a/modules/core/02-client/module.go +++ b/modules/core/02-client/module.go @@ -1,11 +1,11 @@ package client import ( - "github.com/gogo/protobuf/grpc" + "github.com/cosmos/gogoproto/grpc" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/client/cli" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/client/cli" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) // Name returns the IBC client name diff --git a/modules/core/02-client/proposal_handler.go b/modules/core/02-client/proposal_handler.go index fbbdf311b7f..3d9f6002118 100644 --- a/modules/core/02-client/proposal_handler.go +++ b/modules/core/02-client/proposal_handler.go @@ -1,12 +1,13 @@ package client import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/keeper" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) // NewClientProposalHandler defines the 02-client proposal handler @@ -19,7 +20,7 @@ func NewClientProposalHandler(k keeper.Keeper) govtypes.Handler { return k.HandleUpgradeProposal(ctx, c) default: - return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ibc proposal content type: %T", c) + return errorsmod.Wrapf(ibcerrors.ErrUnknownRequest, "unrecognized ibc proposal content type: %T", c) } } } diff --git a/modules/core/02-client/proposal_handler_test.go b/modules/core/02-client/proposal_handler_test.go index d86794b7534..3a417197f71 100644 --- a/modules/core/02-client/proposal_handler_test.go +++ b/modules/core/02-client/proposal_handler_test.go @@ -3,12 +3,12 @@ package client_test import ( sdk "github.com/cosmos/cosmos-sdk/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - client "github.com/cosmos/ibc-go/v4/modules/core/02-client" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + client "github.com/cosmos/ibc-go/v7/modules/core/02-client" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *ClientTestSuite) TestNewClientUpdateProposalHandler() { @@ -38,14 +38,14 @@ func (suite *ClientTestSuite) TestNewClientUpdateProposalHandler() { suite.Require().NoError(err) substituteClientState := suite.chainA.GetClientState(substitutePath.EndpointA.ClientID) - tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState) + tmClientState, ok := subjectClientState.(*ibctm.ClientState) suite.Require().True(ok) tmClientState.AllowUpdateAfterMisbehaviour = true tmClientState.FrozenHeight = tmClientState.LatestHeight suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subjectPath.EndpointA.ClientID, tmClientState) // replicate changes to substitute (they must match) - tmClientState, ok = substituteClientState.(*ibctmtypes.ClientState) + tmClientState, ok = substituteClientState.(*ibctm.ClientState) suite.Require().True(ok) tmClientState.AllowUpdateAfterMisbehaviour = true suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitutePath.EndpointA.ClientID, tmClientState) @@ -60,7 +60,12 @@ func (suite *ClientTestSuite) TestNewClientUpdateProposalHandler() { }, { "unsupported proposal type", func() { - content = distributiontypes.NewCommunityPoolSpendProposal(ibctesting.Title, ibctesting.Description, suite.chainA.SenderAccount.GetAddress(), sdk.NewCoins(sdk.NewCoin("communityfunds", sdk.NewInt(10)))) + content = &distributiontypes.CommunityPoolSpendProposal{ //nolint:staticcheck + Title: ibctesting.Title, + Description: ibctesting.Description, + Recipient: suite.chainA.SenderAccount.GetAddress().String(), + Amount: sdk.NewCoins(sdk.NewCoin("communityfunds", sdk.NewInt(10))), + } }, false, }, } diff --git a/modules/core/02-client/simulation/decoder.go b/modules/core/02-client/simulation/decoder.go index 9334d1ca01a..2a85cf4a4c4 100644 --- a/modules/core/02-client/simulation/decoder.go +++ b/modules/core/02-client/simulation/decoder.go @@ -6,9 +6,9 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/keeper" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var _ ClientUnmarshaler = (*keeper.Keeper)(nil) diff --git a/modules/core/02-client/simulation/decoder_test.go b/modules/core/02-client/simulation/decoder_test.go index fcd6e847475..0fbaef2693c 100644 --- a/modules/core/02-client/simulation/decoder_test.go +++ b/modules/core/02-client/simulation/decoder_test.go @@ -8,11 +8,11 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/simulation" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/simulation" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) func TestDecodeStore(t *testing.T) { @@ -21,11 +21,11 @@ func TestDecodeStore(t *testing.T) { height := types.NewHeight(0, 10) - clientState := &ibctmtypes.ClientState{ + clientState := &ibctm.ClientState{ FrozenHeight: height, } - consState := &ibctmtypes.ConsensusState{ + consState := &ibctm.ConsensusState{ Timestamp: time.Now().UTC(), } diff --git a/modules/core/02-client/simulation/genesis.go b/modules/core/02-client/simulation/genesis.go index f4c6082628a..161efd74fcf 100644 --- a/modules/core/02-client/simulation/genesis.go +++ b/modules/core/02-client/simulation/genesis.go @@ -5,7 +5,7 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) // GenClientGenesis returns the default client genesis state. diff --git a/modules/core/02-client/types/client.go b/modules/core/02-client/types/client.go index a09a910e815..86039dc5847 100644 --- a/modules/core/02-client/types/client.go +++ b/modules/core/02-client/types/client.go @@ -6,12 +6,12 @@ import ( "sort" "strings" + errorsmod "cosmossdk.io/errors" codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( @@ -89,7 +89,7 @@ func (cswh ConsensusStateWithHeight) UnpackInterfaces(unpacker codectypes.AnyUnp // client identifier when used with '0' or the maximum uint64 as the sequence. func ValidateClientType(clientType string) error { if strings.TrimSpace(clientType) == "" { - return sdkerrors.Wrap(ErrInvalidClientType, "client type cannot be blank") + return errorsmod.Wrap(ErrInvalidClientType, "client type cannot be blank") } smallestPossibleClientID := FormatClientIdentifier(clientType, 0) @@ -97,14 +97,14 @@ func ValidateClientType(clientType string) error { // IsValidClientID will check client type format and if the sequence is a uint64 if !IsValidClientID(smallestPossibleClientID) { - return sdkerrors.Wrap(ErrInvalidClientType, "") + return errorsmod.Wrap(ErrInvalidClientType, "") } if err := host.ClientIdentifierValidator(smallestPossibleClientID); err != nil { - return sdkerrors.Wrap(err, "client type results in smallest client identifier being invalid") + return errorsmod.Wrap(err, "client type results in smallest client identifier being invalid") } if err := host.ClientIdentifierValidator(largestPossibleClientID); err != nil { - return sdkerrors.Wrap(err, "client type results in largest client identifier being invalid") + return errorsmod.Wrap(err, "client type results in largest client identifier being invalid") } return nil diff --git a/modules/core/02-client/types/client.pb.go b/modules/core/02-client/types/client.pb.go index cf3d0fd93a9..6b4f4351245 100644 --- a/modules/core/02-client/types/client.pb.go +++ b/modules/core/02-client/types/client.pb.go @@ -5,10 +5,11 @@ package types import ( fmt "fmt" + _ "github.com/cosmos/cosmos-proto" types "github.com/cosmos/cosmos-sdk/codec/types" types1 "github.com/cosmos/cosmos-sdk/x/upgrade/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -397,52 +398,53 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/client.proto", fileDescriptor_b6bc4c8185546947) } var fileDescriptor_b6bc4c8185546947 = []byte{ - // 705 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x3f, 0x6f, 0xd3, 0x4e, - 0x18, 0x8e, 0xdb, 0xfc, 0xa2, 0xe6, 0x52, 0x35, 0xfd, 0xb9, 0x29, 0x0d, 0xa1, 0xca, 0x45, 0x27, - 0x86, 0x0c, 0xd4, 0x26, 0x01, 0xa1, 0x2a, 0x1b, 0xc9, 0xd2, 0x0e, 0xa0, 0x60, 0x54, 0x21, 0x58, - 0x22, 0xff, 0xb9, 0x3a, 0x57, 0x39, 0xbe, 0xc8, 0x77, 0x0e, 0xe4, 0x1b, 0x30, 0x32, 0x32, 0x30, - 0xf4, 0x1b, 0xf0, 0x25, 0x18, 0x3a, 0x76, 0x64, 0xb2, 0x50, 0xbb, 0xb0, 0x92, 0x95, 0x05, 0xe5, - 0xee, 0xdc, 0xc6, 0xfd, 0x83, 0x10, 0x6c, 0x77, 0xcf, 0x3d, 0xf7, 0xdc, 0xf3, 0xbc, 0xf6, 0xfb, - 0x02, 0x48, 0x1c, 0xd7, 0x74, 0x69, 0x84, 0x4d, 0x37, 0x20, 0x38, 0xe4, 0xe6, 0xa4, 0xa5, 0x56, - 0xc6, 0x38, 0xa2, 0x9c, 0xea, 0x3a, 0x71, 0x5c, 0x63, 0x4e, 0x30, 0x14, 0x3c, 0x69, 0xd5, 0x2a, - 0x3e, 0xf5, 0xa9, 0x38, 0x36, 0xe7, 0x2b, 0xc9, 0xac, 0xdd, 0xf5, 0x29, 0xf5, 0x03, 0x6c, 0x8a, - 0x9d, 0x13, 0x1f, 0x9a, 0x76, 0x38, 0x55, 0x47, 0xf7, 0x5d, 0xca, 0x46, 0x94, 0x99, 0xf1, 0xd8, - 0x8f, 0x6c, 0x0f, 0x9b, 0x93, 0x96, 0x83, 0xb9, 0xdd, 0x4a, 0xf7, 0x92, 0x85, 0x3e, 0x69, 0x60, - 0x73, 0xdf, 0xc3, 0x21, 0x27, 0x87, 0x04, 0x7b, 0x3d, 0xf1, 0xdc, 0x4b, 0x6e, 0x73, 0xac, 0xb7, - 0x40, 0x51, 0xbe, 0x3e, 0x20, 0x5e, 0x55, 0x6b, 0x68, 0xcd, 0x62, 0xb7, 0x32, 0x4b, 0xe0, 0xfa, - 0xd4, 0x1e, 0x05, 0x1d, 0x74, 0x71, 0x84, 0xac, 0x15, 0xb9, 0xde, 0xf7, 0xf4, 0x3e, 0x58, 0x55, - 0x38, 0x9b, 0x4b, 0x54, 0x97, 0x1a, 0x5a, 0xb3, 0xd4, 0xae, 0x18, 0xd2, 0xa4, 0x91, 0x9a, 0x34, - 0x9e, 0x86, 0xd3, 0xee, 0xd6, 0x2c, 0x81, 0x1b, 0x19, 0x2d, 0x71, 0x07, 0x59, 0x25, 0xf7, 0xd2, - 0x04, 0xfa, 0xac, 0x81, 0x6a, 0x8f, 0x86, 0x0c, 0x87, 0x2c, 0x66, 0x02, 0x7a, 0x45, 0xf8, 0x70, - 0x0f, 0x13, 0x7f, 0xc8, 0xf5, 0x5d, 0x50, 0x18, 0x8a, 0x95, 0xb0, 0x57, 0x6a, 0xd7, 0x8c, 0xeb, - 0x75, 0x33, 0x24, 0xb7, 0x9b, 0x3f, 0x49, 0x60, 0xce, 0x52, 0x7c, 0xfd, 0x35, 0x28, 0xbb, 0xa9, - 0xea, 0x1f, 0x78, 0xad, 0xcd, 0x12, 0x78, 0x47, 0x79, 0xcd, 0x5e, 0x43, 0xd6, 0x9a, 0x9b, 0xb1, - 0x87, 0xbe, 0x68, 0x60, 0x53, 0x96, 0x31, 0xeb, 0x9b, 0xfd, 0x4d, 0x41, 0xdf, 0x81, 0xf5, 0x2b, - 0x0f, 0xb2, 0xea, 0x52, 0x63, 0xb9, 0x59, 0x6a, 0x3f, 0xb8, 0x29, 0xeb, 0x6d, 0x95, 0xea, 0xc2, - 0x79, 0xfa, 0x59, 0x02, 0xb7, 0x6e, 0x0c, 0xc1, 0x90, 0x55, 0xce, 0xa6, 0x60, 0xe8, 0x87, 0x06, - 0x2a, 0x32, 0xc6, 0xc1, 0xd8, 0xb3, 0x39, 0xee, 0x47, 0x74, 0x4c, 0x99, 0x1d, 0xe8, 0x15, 0xf0, - 0x1f, 0x27, 0x3c, 0xc0, 0x32, 0x81, 0x25, 0x37, 0x7a, 0x03, 0x94, 0x3c, 0xcc, 0xdc, 0x88, 0x8c, - 0x39, 0xa1, 0xa1, 0x28, 0x66, 0xd1, 0x5a, 0x84, 0xf4, 0x3d, 0xf0, 0x3f, 0x8b, 0x9d, 0x23, 0xec, - 0xf2, 0xc1, 0x65, 0x15, 0x96, 0x45, 0x15, 0xb6, 0x67, 0x09, 0xac, 0x4a, 0x67, 0xd7, 0x28, 0xc8, - 0x2a, 0x2b, 0xac, 0x97, 0x16, 0xe5, 0x05, 0xa8, 0xb0, 0xd8, 0x61, 0x9c, 0xf0, 0x98, 0xe3, 0x05, - 0xb1, 0xbc, 0x10, 0x83, 0xb3, 0x04, 0xde, 0xbb, 0x10, 0xbb, 0xc6, 0x42, 0x96, 0x7e, 0x09, 0xa7, - 0x92, 0x9d, 0xfc, 0xfb, 0x63, 0x98, 0x43, 0x3f, 0x35, 0x50, 0x3e, 0x90, 0xdd, 0xf1, 0xcf, 0x71, - 0x9f, 0x80, 0xfc, 0x38, 0xb0, 0x43, 0x91, 0xb0, 0xd4, 0xde, 0x36, 0x64, 0x33, 0x1a, 0x69, 0xf3, - 0xa9, 0x66, 0x34, 0xfa, 0x81, 0x1d, 0xaa, 0x7f, 0x53, 0xf0, 0xf5, 0x23, 0xb0, 0xa9, 0x38, 0xde, - 0x20, 0xd3, 0x4b, 0xf9, 0xdf, 0xfc, 0x9f, 0x8d, 0x59, 0x02, 0xb7, 0x65, 0xe6, 0x1b, 0x2f, 0x23, - 0x6b, 0x23, 0xc5, 0x17, 0x3a, 0xbc, 0xb3, 0x3a, 0x4f, 0xfd, 0xf1, 0x18, 0xe6, 0xbe, 0x1f, 0x43, - 0x6d, 0x3e, 0x09, 0x0a, 0xaa, 0xb1, 0x7a, 0xa0, 0x1c, 0xe1, 0x09, 0x61, 0x84, 0x86, 0x83, 0x30, - 0x1e, 0x39, 0x38, 0x12, 0xf1, 0xf3, 0x8b, 0x8d, 0x70, 0x85, 0x80, 0xac, 0xb5, 0x14, 0x79, 0x2e, - 0x80, 0x8c, 0x88, 0x6a, 0xd3, 0xa5, 0x5b, 0x45, 0x24, 0x61, 0x41, 0x44, 0x3a, 0xe9, 0xac, 0xa4, - 0x16, 0xd1, 0x33, 0x50, 0xe8, 0xdb, 0x91, 0x3d, 0x62, 0x73, 0x61, 0x3b, 0x08, 0xe8, 0xdb, 0x8b, - 0x90, 0xac, 0xaa, 0x35, 0x96, 0x9b, 0xc5, 0x45, 0xe1, 0x2b, 0x04, 0x64, 0xad, 0x29, 0x44, 0xe6, - 0x67, 0x5d, 0xeb, 0xe4, 0xac, 0xae, 0x9d, 0x9e, 0xd5, 0xb5, 0x6f, 0x67, 0x75, 0xed, 0xc3, 0x79, - 0x3d, 0x77, 0x7a, 0x5e, 0xcf, 0x7d, 0x3d, 0xaf, 0xe7, 0xde, 0xec, 0xfa, 0x84, 0x0f, 0x63, 0xc7, - 0x70, 0xe9, 0xc8, 0x54, 0x23, 0x94, 0x38, 0xee, 0x8e, 0x4f, 0xcd, 0xc9, 0x63, 0x73, 0x44, 0xbd, - 0x38, 0xc0, 0x4c, 0x4e, 0xef, 0x87, 0xed, 0x1d, 0x35, 0xc0, 0xf9, 0x74, 0x8c, 0x99, 0x53, 0x10, - 0x1f, 0xe5, 0xd1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9a, 0x92, 0x4e, 0x61, 0xe0, 0x05, 0x00, - 0x00, + // 734 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xbd, 0x6e, 0x13, 0x4b, + 0x18, 0xf5, 0x3a, 0xbe, 0x56, 0x3c, 0xbe, 0x8a, 0x73, 0x37, 0xce, 0x8d, 0xaf, 0x6f, 0xe4, 0xb1, + 0x46, 0x14, 0x16, 0x22, 0xbb, 0xd8, 0x48, 0x10, 0xb9, 0xc3, 0x6e, 0x92, 0x02, 0x64, 0x16, 0x45, + 0x08, 0x1a, 0x6b, 0x7f, 0x26, 0xeb, 0x89, 0xd6, 0x3b, 0xd6, 0xce, 0xac, 0xc1, 0x6f, 0x40, 0x07, + 0x25, 0x48, 0x29, 0xf2, 0x06, 0x34, 0x3c, 0x02, 0x45, 0x44, 0x95, 0x92, 0x6a, 0x85, 0x92, 0x86, + 0xda, 0x4f, 0x80, 0x3c, 0x33, 0x9b, 0xd8, 0xf9, 0x01, 0x04, 0xdd, 0xcc, 0x99, 0xb3, 0x67, 0xce, + 0x77, 0xbc, 0xc7, 0x0b, 0x20, 0x71, 0x5c, 0xd3, 0xa5, 0x11, 0x36, 0xdd, 0x80, 0xe0, 0x90, 0x9b, + 0xe3, 0xa6, 0x5a, 0x19, 0xa3, 0x88, 0x72, 0xaa, 0xeb, 0xc4, 0x71, 0x8d, 0x19, 0xc1, 0x50, 0xf0, + 0xb8, 0x59, 0x2d, 0xfb, 0xd4, 0xa7, 0xe2, 0xd8, 0x9c, 0xad, 0x24, 0xb3, 0xfa, 0x9f, 0x4f, 0xa9, + 0x1f, 0x60, 0x53, 0xec, 0x9c, 0x78, 0xdf, 0xb4, 0xc3, 0x89, 0x3a, 0xba, 0xe5, 0x52, 0x36, 0xa4, + 0xcc, 0x8c, 0x47, 0x7e, 0x64, 0x7b, 0xd8, 0x1c, 0x37, 0x1d, 0xcc, 0xed, 0x66, 0xba, 0x4f, 0x05, + 0x24, 0xab, 0x2f, 0x95, 0xe5, 0x46, 0x1e, 0xa1, 0x43, 0x0d, 0xac, 0xef, 0x7a, 0x38, 0xe4, 0x64, + 0x9f, 0x60, 0xaf, 0x2b, 0x9c, 0x3c, 0xe5, 0x36, 0xc7, 0x7a, 0x13, 0x14, 0xa4, 0xb1, 0x3e, 0xf1, + 0x2a, 0x5a, 0x5d, 0x6b, 0x14, 0x3a, 0xe5, 0x69, 0x02, 0x57, 0x27, 0xf6, 0x30, 0x68, 0xa3, 0xf3, + 0x23, 0x64, 0x2d, 0xcb, 0xf5, 0xae, 0xa7, 0xf7, 0xc0, 0xdf, 0x0a, 0x67, 0x33, 0x89, 0x4a, 0xb6, + 0xae, 0x35, 0x8a, 0xad, 0xb2, 0x21, 0xfd, 0x1b, 0xa9, 0x7f, 0xe3, 0x61, 0x38, 0xe9, 0x6c, 0x4c, + 0x13, 0xb8, 0xb6, 0xa0, 0x25, 0x9e, 0x41, 0x56, 0xd1, 0xbd, 0x30, 0x81, 0x3e, 0x68, 0xa0, 0xd2, + 0xa5, 0x21, 0xc3, 0x21, 0x8b, 0x99, 0x80, 0x9e, 0x11, 0x3e, 0xd8, 0xc1, 0xc4, 0x1f, 0x70, 0x7d, + 0x1b, 0xe4, 0x07, 0x62, 0x25, 0xec, 0x15, 0x5b, 0x55, 0xe3, 0x6a, 0xa4, 0x86, 0xe4, 0x76, 0x72, + 0xc7, 0x09, 0xcc, 0x58, 0x8a, 0xaf, 0x3f, 0x07, 0x25, 0x37, 0x55, 0xfd, 0x05, 0xaf, 0xd5, 0x69, + 0x02, 0xff, 0x55, 0x5e, 0x17, 0x1f, 0x43, 0xd6, 0x8a, 0xbb, 0x60, 0x0f, 0x7d, 0xd2, 0xc0, 0xba, + 0x8c, 0x71, 0xd1, 0x37, 0xfb, 0x9d, 0x40, 0x5f, 0x81, 0xd5, 0x4b, 0x17, 0xb2, 0x4a, 0xb6, 0xbe, + 0xd4, 0x28, 0xb6, 0xee, 0x5c, 0x37, 0xeb, 0x4d, 0x49, 0x75, 0xe0, 0x6c, 0xfa, 0x69, 0x02, 0x37, + 0xae, 0x1d, 0x82, 0x21, 0xab, 0xb4, 0x38, 0x05, 0x43, 0x6f, 0xb2, 0xa0, 0x2c, 0xc7, 0xd8, 0x1b, + 0x79, 0x36, 0xc7, 0xbd, 0x88, 0x8e, 0x28, 0xb3, 0x03, 0xbd, 0x0c, 0xfe, 0xe2, 0x84, 0x07, 0x58, + 0x4e, 0x60, 0xc9, 0x8d, 0x5e, 0x07, 0x45, 0x0f, 0x33, 0x37, 0x22, 0x23, 0x4e, 0x68, 0x28, 0xc2, + 0x2c, 0x58, 0xf3, 0x90, 0xbe, 0x03, 0xfe, 0x61, 0xb1, 0x73, 0x80, 0x5d, 0xde, 0xbf, 0x48, 0x61, + 0x49, 0xa4, 0xb0, 0x39, 0x4d, 0x60, 0x45, 0x3a, 0xbb, 0x42, 0x41, 0x56, 0x49, 0x61, 0xdd, 0x34, + 0x94, 0x27, 0xa0, 0xcc, 0x62, 0x87, 0x71, 0xc2, 0x63, 0x8e, 0xe7, 0xc4, 0x72, 0x42, 0x0c, 0x4e, + 0x13, 0xf8, 0xff, 0xb9, 0xd8, 0x15, 0x16, 0xb2, 0xf4, 0x0b, 0x38, 0x95, 0x6c, 0xa3, 0xd7, 0x47, + 0x30, 0xf3, 0xf9, 0xe3, 0x56, 0x55, 0x75, 0xc3, 0xa7, 0x63, 0x43, 0x55, 0x69, 0x16, 0x2a, 0xc7, + 0x21, 0x47, 0xef, 0xb3, 0xa0, 0xb4, 0x27, 0x6b, 0xf5, 0xc7, 0x61, 0xdc, 0x07, 0xb9, 0x51, 0x60, + 0x87, 0x62, 0xfe, 0x62, 0x6b, 0xd3, 0x50, 0xd7, 0xa6, 0xad, 0x4d, 0xaf, 0xee, 0x05, 0x76, 0xa8, + 0xde, 0x5c, 0xc1, 0xd7, 0x0f, 0xc0, 0xba, 0xe2, 0x78, 0xfd, 0x85, 0xa6, 0xe5, 0x7e, 0xf0, 0xf6, + 0xd6, 0xa7, 0x09, 0xdc, 0x94, 0x89, 0x5c, 0xfb, 0x30, 0xb2, 0xd6, 0x52, 0x7c, 0xae, 0xff, 0xed, + 0xdb, 0xb3, 0x4c, 0xde, 0x1d, 0xc1, 0xcc, 0xb7, 0x23, 0xa8, 0xfd, 0x24, 0x9b, 0x43, 0x0d, 0xe4, + 0x55, 0x29, 0xbb, 0xa0, 0x14, 0xe1, 0x31, 0x61, 0x84, 0x86, 0xfd, 0x30, 0x1e, 0x3a, 0x38, 0x12, + 0xe1, 0xe4, 0xe6, 0x4b, 0x74, 0x89, 0x80, 0xac, 0x95, 0x14, 0x79, 0x2c, 0x80, 0x05, 0x11, 0x55, + 0xf1, 0xec, 0x8d, 0x22, 0x92, 0x30, 0x27, 0x22, 0x9d, 0xb4, 0x97, 0xd3, 0x01, 0xd0, 0x23, 0x90, + 0xef, 0xd9, 0x91, 0x3d, 0x64, 0x33, 0x61, 0x3b, 0x08, 0xe8, 0xcb, 0xf3, 0x08, 0x58, 0x45, 0xab, + 0x2f, 0x35, 0x0a, 0xf3, 0xc2, 0x97, 0x08, 0xc8, 0x5a, 0x51, 0x88, 0x4c, 0x87, 0x75, 0xac, 0xe3, + 0xd3, 0x9a, 0x76, 0x72, 0x5a, 0xd3, 0xbe, 0x9e, 0xd6, 0xb4, 0xb7, 0x67, 0xb5, 0xcc, 0xc9, 0x59, + 0x2d, 0xf3, 0xe5, 0xac, 0x96, 0x79, 0xb1, 0xed, 0x13, 0x3e, 0x88, 0x1d, 0xc3, 0xa5, 0x43, 0xf5, + 0x37, 0x6b, 0x12, 0xc7, 0xdd, 0xf2, 0xa9, 0x39, 0x7e, 0x60, 0x0e, 0xa9, 0x17, 0x07, 0x98, 0xc9, + 0x8f, 0xc2, 0xdd, 0xd6, 0x96, 0xfa, 0x2e, 0xf0, 0xc9, 0x08, 0x33, 0x27, 0x2f, 0x7e, 0xb2, 0x7b, + 0xdf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x3d, 0x69, 0x32, 0x4f, 0x37, 0x06, 0x00, 0x00, } func (this *UpgradeProposal) Equal(that interface{}) bool { diff --git a/modules/core/02-client/types/client_test.go b/modules/core/02-client/types/client_test.go index dfc52f2190b..ecdfd1a31e3 100644 --- a/modules/core/02-client/types/client_test.go +++ b/modules/core/02-client/types/client_test.go @@ -5,8 +5,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *TypesTestSuite) TestMarshalConsensusStateWithHeight() { diff --git a/modules/core/02-client/types/codec.go b/modules/core/02-client/types/codec.go index 0aec6bc1d7c..766f414e376 100644 --- a/modules/core/02-client/types/codec.go +++ b/modules/core/02-client/types/codec.go @@ -1,14 +1,15 @@ package types import ( + errorsmod "cosmossdk.io/errors" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/msgservice" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - proto "github.com/gogo/protobuf/proto" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + proto "github.com/cosmos/gogoproto/proto" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // RegisterInterfaces registers the client interfaces to protobuf Any. @@ -23,7 +24,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { ) registry.RegisterInterface( "ibc.core.client.v1.Header", - (*exported.Header)(nil), + (*exported.ClientMessage)(nil), ) registry.RegisterInterface( "ibc.core.client.v1.Height", @@ -32,7 +33,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { ) registry.RegisterInterface( "ibc.core.client.v1.Misbehaviour", - (*exported.Misbehaviour)(nil), + (*exported.ClientMessage)(nil), ) registry.RegisterImplementations( (*govtypes.Content)(nil), @@ -56,12 +57,12 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { func PackClientState(clientState exported.ClientState) (*codectypes.Any, error) { msg, ok := clientState.(proto.Message) if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", clientState) + return nil, errorsmod.Wrapf(ibcerrors.ErrPackAny, "cannot proto marshal %T", clientState) } anyClientState, err := codectypes.NewAnyWithValue(msg) if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, err.Error()) + return nil, errorsmod.Wrap(ibcerrors.ErrPackAny, err.Error()) } return anyClientState, nil @@ -71,12 +72,12 @@ func PackClientState(clientState exported.ClientState) (*codectypes.Any, error) // client state can't be unpacked into a ClientState. func UnpackClientState(any *codectypes.Any) (exported.ClientState, error) { if any == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnpackAny, "protobuf Any message cannot be nil") + return nil, errorsmod.Wrap(ibcerrors.ErrUnpackAny, "protobuf Any message cannot be nil") } clientState, ok := any.GetCachedValue().(exported.ClientState) if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnpackAny, "cannot unpack Any into ClientState %T", any) + return nil, errorsmod.Wrapf(ibcerrors.ErrUnpackAny, "cannot unpack Any into ClientState %T", any) } return clientState, nil @@ -88,12 +89,12 @@ func UnpackClientState(any *codectypes.Any) (exported.ClientState, error) { func PackConsensusState(consensusState exported.ConsensusState) (*codectypes.Any, error) { msg, ok := consensusState.(proto.Message) if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", consensusState) + return nil, errorsmod.Wrapf(ibcerrors.ErrPackAny, "cannot proto marshal %T", consensusState) } anyConsensusState, err := codectypes.NewAnyWithValue(msg) if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, err.Error()) + return nil, errorsmod.Wrap(ibcerrors.ErrPackAny, err.Error()) } return anyConsensusState, nil @@ -113,77 +114,45 @@ func MustPackConsensusState(consensusState exported.ConsensusState) *codectypes. // consensus state can't be unpacked into a ConsensusState. func UnpackConsensusState(any *codectypes.Any) (exported.ConsensusState, error) { if any == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnpackAny, "protobuf Any message cannot be nil") + return nil, errorsmod.Wrap(ibcerrors.ErrUnpackAny, "protobuf Any message cannot be nil") } consensusState, ok := any.GetCachedValue().(exported.ConsensusState) if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnpackAny, "cannot unpack Any into ConsensusState %T", any) + return nil, errorsmod.Wrapf(ibcerrors.ErrUnpackAny, "cannot unpack Any into ConsensusState %T", any) } return consensusState, nil } -// PackHeader constructs a new Any packed with the given header value. It returns -// an error if the header can't be casted to a protobuf message or if the concrete +// PackClientMessage constructs a new Any packed with the given value. It returns +// an error if the value can't be casted to a protobuf message or if the concrete // implemention is not registered to the protobuf codec. -func PackHeader(header exported.Header) (*codectypes.Any, error) { - msg, ok := header.(proto.Message) +func PackClientMessage(clientMessage exported.ClientMessage) (*codectypes.Any, error) { + msg, ok := clientMessage.(proto.Message) if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", header) + return nil, errorsmod.Wrapf(ibcerrors.ErrPackAny, "cannot proto marshal %T", clientMessage) } - anyHeader, err := codectypes.NewAnyWithValue(msg) + protoAny, err := codectypes.NewAnyWithValue(msg) if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, err.Error()) + return nil, errorsmod.Wrap(ibcerrors.ErrPackAny, err.Error()) } - return anyHeader, nil + return protoAny, nil } -// UnpackHeader unpacks an Any into a Header. It returns an error if the -// consensus state can't be unpacked into a Header. -func UnpackHeader(any *codectypes.Any) (exported.Header, error) { +// UnpackClientMessage unpacks an Any into a ClientMessage. It returns an error if the +// consensus state can't be unpacked into a ClientMessage. +func UnpackClientMessage(any *codectypes.Any) (exported.ClientMessage, error) { if any == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnpackAny, "protobuf Any message cannot be nil") + return nil, errorsmod.Wrap(ibcerrors.ErrUnpackAny, "protobuf Any message cannot be nil") } - header, ok := any.GetCachedValue().(exported.Header) + clientMessage, ok := any.GetCachedValue().(exported.ClientMessage) if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnpackAny, "cannot unpack Any into Header %T", any) + return nil, errorsmod.Wrapf(ibcerrors.ErrUnpackAny, "cannot unpack Any into Header %T", any) } - return header, nil -} - -// PackMisbehaviour constructs a new Any packed with the given misbehaviour value. It returns -// an error if the misbehaviour can't be casted to a protobuf message or if the concrete -// implemention is not registered to the protobuf codec. -func PackMisbehaviour(misbehaviour exported.Misbehaviour) (*codectypes.Any, error) { - msg, ok := misbehaviour.(proto.Message) - if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", misbehaviour) - } - - anyMisbhaviour, err := codectypes.NewAnyWithValue(msg) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrPackAny, err.Error()) - } - - return anyMisbhaviour, nil -} - -// UnpackMisbehaviour unpacks an Any into a Misbehaviour. It returns an error if the -// Any can't be unpacked into a Misbehaviour. -func UnpackMisbehaviour(any *codectypes.Any) (exported.Misbehaviour, error) { - if any == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnpackAny, "protobuf Any message cannot be nil") - } - - misbehaviour, ok := any.GetCachedValue().(exported.Misbehaviour) - if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnpackAny, "cannot unpack Any into Misbehaviour %T", any) - } - - return misbehaviour, nil + return clientMessage, nil } diff --git a/modules/core/02-client/types/codec_test.go b/modules/core/02-client/types/codec_test.go index da970cd181a..28e22b04e0d 100644 --- a/modules/core/02-client/types/codec_test.go +++ b/modules/core/02-client/types/codec_test.go @@ -3,12 +3,11 @@ package types_test import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - localhosttypes "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + 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/ibc-go/v7/testing" ) type caseAny struct { @@ -30,12 +29,7 @@ func (suite *TypesTestSuite) TestPackClientState() { }, { "tendermint client", - ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - true, - }, - { - "localhost client", - localhosttypes.NewClientState(chainID, clientHeight), + ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), true, }, { @@ -48,14 +42,14 @@ func (suite *TypesTestSuite) TestPackClientState() { testCasesAny := []caseAny{} for _, tc := range testCases { - clientAny, err := types.PackClientState(tc.clientState) + protoAny, err := types.PackClientState(tc.clientState) if tc.expPass { suite.Require().NoError(err, tc.name) } else { suite.Require().Error(err, tc.name) } - testCasesAny = append(testCasesAny, caseAny{tc.name, clientAny, tc.expPass}) + testCasesAny = append(testCasesAny, caseAny{tc.name, protoAny, tc.expPass}) } for i, tc := range testCasesAny { @@ -95,13 +89,13 @@ func (suite *TypesTestSuite) TestPackConsensusState() { testCasesAny := []caseAny{} for _, tc := range testCases { - clientAny, err := types.PackConsensusState(tc.consensusState) + protoAny, err := types.PackConsensusState(tc.consensusState) if tc.expPass { suite.Require().NoError(err, tc.name) } else { suite.Require().Error(err, tc.name) } - testCasesAny = append(testCasesAny, caseAny{tc.name, clientAny, tc.expPass}) + testCasesAny = append(testCasesAny, caseAny{tc.name, protoAny, tc.expPass}) } for i, tc := range testCasesAny { @@ -115,15 +109,15 @@ func (suite *TypesTestSuite) TestPackConsensusState() { } } -func (suite *TypesTestSuite) TestPackHeader() { +func (suite *TypesTestSuite) TestPackClientMessage() { testCases := []struct { - name string - header exported.Header - expPass bool + name string + clientMessage exported.ClientMessage + expPass bool }{ { "solo machine header", - ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2).CreateHeader(), + ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2).CreateHeader("solomachine"), true, }, { @@ -141,68 +135,21 @@ func (suite *TypesTestSuite) TestPackHeader() { testCasesAny := []caseAny{} for _, tc := range testCases { - clientAny, err := types.PackHeader(tc.header) - if tc.expPass { - suite.Require().NoError(err, tc.name) - } else { - suite.Require().Error(err, tc.name) - } - - testCasesAny = append(testCasesAny, caseAny{tc.name, clientAny, tc.expPass}) - } - - for i, tc := range testCasesAny { - cs, err := types.UnpackHeader(tc.any) - if tc.expPass { - suite.Require().NoError(err, tc.name) - suite.Require().Equal(testCases[i].header, cs, tc.name) - } else { - suite.Require().Error(err, tc.name) - } - } -} - -func (suite *TypesTestSuite) TestPackMisbehaviour() { - testCases := []struct { - name string - misbehaviour exported.Misbehaviour - expPass bool - }{ - { - "solo machine misbehaviour", - ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2).CreateMisbehaviour(), - true, - }, - { - "tendermint misbehaviour", - ibctmtypes.NewMisbehaviour("tendermint", suite.chainA.LastHeader, suite.chainA.LastHeader), - true, - }, - { - "nil", - nil, - false, - }, - } - - testCasesAny := []caseAny{} - - for _, tc := range testCases { - clientAny, err := types.PackMisbehaviour(tc.misbehaviour) + protoAny, err := types.PackClientMessage(tc.clientMessage) if tc.expPass { suite.Require().NoError(err, tc.name) } else { suite.Require().Error(err, tc.name) } - testCasesAny = append(testCasesAny, caseAny{tc.name, clientAny, tc.expPass}) + testCasesAny = append(testCasesAny, caseAny{tc.name, protoAny, tc.expPass}) } for i, tc := range testCasesAny { - cs, err := types.UnpackMisbehaviour(tc.any) + cs, err := types.UnpackClientMessage(tc.any) if tc.expPass { suite.Require().NoError(err, tc.name) - suite.Require().Equal(testCases[i].misbehaviour, cs, tc.name) + suite.Require().Equal(testCases[i].clientMessage, cs, tc.name) } else { suite.Require().Error(err, tc.name) } diff --git a/modules/core/02-client/types/encoding.go b/modules/core/02-client/types/encoding.go index 26a6bf32626..63a544ec85a 100644 --- a/modules/core/02-client/types/encoding.go +++ b/modules/core/02-client/types/encoding.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // MustUnmarshalClientState attempts to decode and return an ClientState object from @@ -86,29 +86,29 @@ func UnmarshalConsensusState(cdc codec.BinaryCodec, bz []byte) (exported.Consens return consensusState, nil } -// MarshalHeader protobuf serializes a Header interface -func MarshalHeader(cdc codec.BinaryCodec, h exported.Header) ([]byte, error) { - return cdc.MarshalInterface(h) +// MarshalClientMessage protobuf serializes a ClientMessage interface +func MarshalClientMessage(cdc codec.BinaryCodec, clientMessage exported.ClientMessage) ([]byte, error) { + return cdc.MarshalInterface(clientMessage) } -// MustMarshalHeader attempts to encode a Header object and returns the +// MustMarshalClientMessage attempts to encode a ClientMessage object and returns the // raw encoded bytes. It panics on error. -func MustMarshalHeader(cdc codec.BinaryCodec, header exported.Header) []byte { - bz, err := MarshalHeader(cdc, header) +func MustMarshalClientMessage(cdc codec.BinaryCodec, clientMessage exported.ClientMessage) []byte { + bz, err := MarshalClientMessage(cdc, clientMessage) if err != nil { - panic(fmt.Errorf("failed to encode header: %w", err)) + panic(fmt.Errorf("failed to encode ClientMessage: %w", err)) } return bz } -// UnmarshalHeader returns a Header interface from raw proto encoded header bytes. +// UnmarshalClientMessage returns a ClientMessage interface from raw proto encoded header bytes. // An error is returned upon decoding failure. -func UnmarshalHeader(cdc codec.BinaryCodec, bz []byte) (exported.Header, error) { - var header exported.Header - if err := cdc.UnmarshalInterface(bz, &header); err != nil { +func UnmarshalClientMessage(cdc codec.BinaryCodec, bz []byte) (exported.ClientMessage, error) { + var clientMessage exported.ClientMessage + if err := cdc.UnmarshalInterface(bz, &clientMessage); err != nil { return nil, err } - return header, nil + return clientMessage, nil } diff --git a/modules/core/02-client/types/encoding_test.go b/modules/core/02-client/types/encoding_test.go index 298285a828f..4611d4cf945 100644 --- a/modules/core/02-client/types/encoding_test.go +++ b/modules/core/02-client/types/encoding_test.go @@ -1,28 +1,28 @@ package types_test import ( - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ) func (suite *TypesTestSuite) TestMarshalHeader() { cdc := suite.chainA.App.AppCodec() - h := &ibctmtypes.Header{ + h := &ibctm.Header{ TrustedHeight: types.NewHeight(4, 100), } // marshal header - bz, err := types.MarshalHeader(cdc, h) + bz, err := types.MarshalClientMessage(cdc, h) suite.Require().NoError(err) // unmarshal header - newHeader, err := types.UnmarshalHeader(cdc, bz) + newHeader, err := types.UnmarshalClientMessage(cdc, bz) suite.Require().NoError(err) suite.Require().Equal(h, newHeader) // use invalid bytes - invalidHeader, err := types.UnmarshalHeader(cdc, []byte("invalid bytes")) + invalidHeader, err := types.UnmarshalClientMessage(cdc, []byte("invalid bytes")) suite.Require().Error(err) suite.Require().Nil(invalidHeader) } diff --git a/modules/core/02-client/types/errors.go b/modules/core/02-client/types/errors.go index c40bae878cc..a0fa91e8dac 100644 --- a/modules/core/02-client/types/errors.go +++ b/modules/core/02-client/types/errors.go @@ -1,37 +1,37 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // IBC client sentinel errors var ( - ErrClientExists = sdkerrors.Register(SubModuleName, 2, "light client already exists") - ErrInvalidClient = sdkerrors.Register(SubModuleName, 3, "light client is invalid") - ErrClientNotFound = sdkerrors.Register(SubModuleName, 4, "light client not found") - ErrClientFrozen = sdkerrors.Register(SubModuleName, 5, "light client is frozen due to misbehaviour") - ErrInvalidClientMetadata = sdkerrors.Register(SubModuleName, 6, "invalid client metadata") - ErrConsensusStateNotFound = sdkerrors.Register(SubModuleName, 7, "consensus state not found") - ErrInvalidConsensus = sdkerrors.Register(SubModuleName, 8, "invalid consensus state") - ErrClientTypeNotFound = sdkerrors.Register(SubModuleName, 9, "client type not found") - ErrInvalidClientType = sdkerrors.Register(SubModuleName, 10, "invalid client type") - ErrRootNotFound = sdkerrors.Register(SubModuleName, 11, "commitment root not found") - ErrInvalidHeader = sdkerrors.Register(SubModuleName, 12, "invalid client header") - ErrInvalidMisbehaviour = sdkerrors.Register(SubModuleName, 13, "invalid light client misbehaviour") - ErrFailedClientStateVerification = sdkerrors.Register(SubModuleName, 14, "client state verification failed") - ErrFailedClientConsensusStateVerification = sdkerrors.Register(SubModuleName, 15, "client consensus state verification failed") - ErrFailedConnectionStateVerification = sdkerrors.Register(SubModuleName, 16, "connection state verification failed") - ErrFailedChannelStateVerification = sdkerrors.Register(SubModuleName, 17, "channel state verification failed") - ErrFailedPacketCommitmentVerification = sdkerrors.Register(SubModuleName, 18, "packet commitment verification failed") - ErrFailedPacketAckVerification = sdkerrors.Register(SubModuleName, 19, "packet acknowledgement verification failed") - ErrFailedPacketReceiptVerification = sdkerrors.Register(SubModuleName, 20, "packet receipt verification failed") - ErrFailedNextSeqRecvVerification = sdkerrors.Register(SubModuleName, 21, "next sequence receive verification failed") - ErrSelfConsensusStateNotFound = sdkerrors.Register(SubModuleName, 22, "self consensus state not found") - ErrUpdateClientFailed = sdkerrors.Register(SubModuleName, 23, "unable to update light client") - ErrInvalidUpdateClientProposal = sdkerrors.Register(SubModuleName, 24, "invalid update client proposal") - ErrInvalidUpgradeClient = sdkerrors.Register(SubModuleName, 25, "invalid client upgrade") - ErrInvalidHeight = sdkerrors.Register(SubModuleName, 26, "invalid height") - ErrInvalidSubstitute = sdkerrors.Register(SubModuleName, 27, "invalid client state substitute") - ErrInvalidUpgradeProposal = sdkerrors.Register(SubModuleName, 28, "invalid upgrade proposal") - ErrClientNotActive = sdkerrors.Register(SubModuleName, 29, "client is not active") + ErrClientExists = errorsmod.Register(SubModuleName, 2, "light client already exists") + ErrInvalidClient = errorsmod.Register(SubModuleName, 3, "light client is invalid") + ErrClientNotFound = errorsmod.Register(SubModuleName, 4, "light client not found") + ErrClientFrozen = errorsmod.Register(SubModuleName, 5, "light client is frozen due to misbehaviour") + ErrInvalidClientMetadata = errorsmod.Register(SubModuleName, 6, "invalid client metadata") + ErrConsensusStateNotFound = errorsmod.Register(SubModuleName, 7, "consensus state not found") + ErrInvalidConsensus = errorsmod.Register(SubModuleName, 8, "invalid consensus state") + ErrClientTypeNotFound = errorsmod.Register(SubModuleName, 9, "client type not found") + ErrInvalidClientType = errorsmod.Register(SubModuleName, 10, "invalid client type") + ErrRootNotFound = errorsmod.Register(SubModuleName, 11, "commitment root not found") + ErrInvalidHeader = errorsmod.Register(SubModuleName, 12, "invalid client header") + ErrInvalidMisbehaviour = errorsmod.Register(SubModuleName, 13, "invalid light client misbehaviour") + ErrFailedClientStateVerification = errorsmod.Register(SubModuleName, 14, "client state verification failed") + ErrFailedClientConsensusStateVerification = errorsmod.Register(SubModuleName, 15, "client consensus state verification failed") + ErrFailedConnectionStateVerification = errorsmod.Register(SubModuleName, 16, "connection state verification failed") + ErrFailedChannelStateVerification = errorsmod.Register(SubModuleName, 17, "channel state verification failed") + ErrFailedPacketCommitmentVerification = errorsmod.Register(SubModuleName, 18, "packet commitment verification failed") + ErrFailedPacketAckVerification = errorsmod.Register(SubModuleName, 19, "packet acknowledgement verification failed") + ErrFailedPacketReceiptVerification = errorsmod.Register(SubModuleName, 20, "packet receipt verification failed") + ErrFailedNextSeqRecvVerification = errorsmod.Register(SubModuleName, 21, "next sequence receive verification failed") + ErrSelfConsensusStateNotFound = errorsmod.Register(SubModuleName, 22, "self consensus state not found") + ErrUpdateClientFailed = errorsmod.Register(SubModuleName, 23, "unable to update light client") + ErrInvalidUpdateClientProposal = errorsmod.Register(SubModuleName, 24, "invalid update client proposal") + ErrInvalidUpgradeClient = errorsmod.Register(SubModuleName, 25, "invalid client upgrade") + ErrInvalidHeight = errorsmod.Register(SubModuleName, 26, "invalid height") + ErrInvalidSubstitute = errorsmod.Register(SubModuleName, 27, "invalid client state substitute") + ErrInvalidUpgradeProposal = errorsmod.Register(SubModuleName, 28, "invalid upgrade proposal") + ErrClientNotActive = errorsmod.Register(SubModuleName, 29, "client state is not active") ) diff --git a/modules/core/02-client/types/events.go b/modules/core/02-client/types/events.go index d23f6d24e02..9671cf9dcb9 100644 --- a/modules/core/02-client/types/events.go +++ b/modules/core/02-client/types/events.go @@ -3,7 +3,7 @@ package types import ( "fmt" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // IBC client events @@ -12,9 +12,11 @@ const ( AttributeKeySubjectClientID = "subject_client_id" AttributeKeyClientType = "client_type" AttributeKeyConsensusHeight = "consensus_height" + AttributeKeyConsensusHeights = "consensus_heights" AttributeKeyHeader = "header" + AttributeKeyUpgradeStore = "upgrade_store" + AttributeKeyUpgradePlanHeight = "upgrade_plan_height" AttributeKeyUpgradePlanTitle = "title" - AttributeKeyUpgradePlanHeight = "height" ) // IBC client events vars @@ -24,7 +26,8 @@ var ( EventTypeUpgradeClient = "upgrade_client" EventTypeSubmitMisbehaviour = "client_misbehaviour" EventTypeUpdateClientProposal = "update_client_proposal" + EventTypeUpgradeChain = "upgrade_chain" EventTypeUpgradeClientProposal = "upgrade_client_proposal" - AttributeValueCategory = fmt.Sprintf("%s_%s", host.ModuleName, SubModuleName) + AttributeValueCategory = fmt.Sprintf("%s_%s", ibcexported.ModuleName, SubModuleName) ) diff --git a/modules/core/02-client/types/genesis.go b/modules/core/02-client/types/genesis.go index 4dd61fdc7a2..f2ada0f55de 100644 --- a/modules/core/02-client/types/genesis.go +++ b/modules/core/02-client/types/genesis.go @@ -6,8 +6,8 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( @@ -110,7 +110,7 @@ func (gs GenesisState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { func (gs GenesisState) Validate() error { // keep track of the max sequence to ensure it is less than // the next sequence used in creating client identifers. - var maxSequence uint64 = 0 + var maxSequence uint64 if err := gs.Params.Validate(); err != nil { return err @@ -200,10 +200,6 @@ func (gs GenesisState) Validate() error { } - if gs.CreateLocalhost && !gs.Params.IsAllowedClient(exported.Localhost) { - return fmt.Errorf("localhost client is not registered on the allowlist") - } - if maxSequence != 0 && maxSequence >= gs.NextClientSequence { return fmt.Errorf("next client identifier sequence %d must be greater than the maximum sequence used in the provided client identifiers %d", gs.NextClientSequence, maxSequence) } diff --git a/modules/core/02-client/types/genesis.pb.go b/modules/core/02-client/types/genesis.pb.go index 4edc4f302b8..d6d4fad8cd5 100644 --- a/modules/core/02-client/types/genesis.pb.go +++ b/modules/core/02-client/types/genesis.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -221,7 +221,7 @@ var fileDescriptor_bcd0c0f1f2e6a91a = []byte{ // 539 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x53, 0x41, 0x6e, 0xd3, 0x40, 0x14, 0xcd, 0x34, 0x69, 0x68, 0xa7, 0x15, 0x0d, 0xa3, 0xa8, 0x98, 0x54, 0xb2, 0x2d, 0xb3, 0x09, - 0x8b, 0xd8, 0x24, 0xb0, 0xa8, 0xb2, 0x41, 0x72, 0x25, 0x50, 0x25, 0x90, 0xc0, 0xec, 0xd8, 0x58, + 0x8b, 0xd8, 0x24, 0x2c, 0xa8, 0xb2, 0x41, 0x72, 0x25, 0x50, 0x25, 0x90, 0xc0, 0xec, 0xd8, 0x58, 0x93, 0xf1, 0x90, 0x8e, 0xb0, 0x3d, 0x21, 0x33, 0x89, 0xc8, 0x0d, 0x58, 0x22, 0x4e, 0xc0, 0x9a, 0x33, 0x70, 0x80, 0x2e, 0xbb, 0xec, 0x2a, 0xa0, 0xe4, 0x06, 0x39, 0x01, 0xf2, 0xcc, 0x98, 0xb6, 0x69, 0xca, 0xee, 0xe7, 0xf9, 0xbd, 0xf7, 0x9f, 0xde, 0xcf, 0x40, 0x97, 0x0d, 0x48, 0x40, 0xf8, @@ -252,7 +252,7 @@ var fileDescriptor_bcd0c0f1f2e6a91a = []byte{ 0x2b, 0x1f, 0x8e, 0x87, 0x4c, 0x9e, 0x4d, 0x06, 0x3e, 0xe1, 0x59, 0x40, 0xb8, 0xc8, 0xb8, 0x08, 0xd8, 0x80, 0x74, 0x86, 0x3c, 0x98, 0x3e, 0x0f, 0x32, 0x9e, 0x4c, 0x52, 0x2a, 0xf4, 0x5b, 0x7e, 0xda, 0xeb, 0x98, 0xe7, 0x2c, 0x67, 0x23, 0x2a, 0x06, 0x75, 0xf5, 0x6a, 0x9f, 0xfd, 0x0d, 0x00, - 0x00, 0xff, 0xff, 0x05, 0xb6, 0x71, 0xe6, 0x24, 0x04, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x62, 0xb6, 0x99, 0xab, 0x24, 0x04, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/modules/core/02-client/types/genesis_test.go b/modules/core/02-client/types/genesis_test.go index c627d173327..16c87f58411 100644 --- a/modules/core/02-client/types/genesis_test.go +++ b/modules/core/02-client/types/genesis_test.go @@ -5,27 +5,27 @@ import ( tmtypes "github.com/tendermint/tendermint/types" - client "github.com/cosmos/ibc-go/v4/modules/core/02-client" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - localhosttypes "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibctestingmock "github.com/cosmos/ibc-go/v4/testing/mock" + client "github.com/cosmos/ibc-go/v7/modules/core/02-client" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctestingmock "github.com/cosmos/ibc-go/v7/testing/mock" ) const ( - chainID = "chainID" - tmClientID0 = "07-tendermint-0" - tmClientID1 = "07-tendermint-1" - invalidClientID = "myclient-0" - clientID = tmClientID0 + tmClientID0 = "07-tendermint-0" + tmClientID1 = "07-tendermint-1" + invalidClientID = "myclient-0" + soloMachineClientID = "06-solomachine-0" + clientID = tmClientID0 height = 10 ) -var clientHeight = types.NewHeight(0, 10) +var clientHeight = types.NewHeight(1, 10) func (suite *TypesTestSuite) TestMarshalGenesisState() { cdc := suite.chainA.App.AppCodec() @@ -58,8 +58,8 @@ func (suite *TypesTestSuite) TestValidateGenesis() { signers := make(map[string]tmtypes.PrivValidator) signers[val.Address.String()] = privVal - heightMinus1 := types.NewHeight(0, height-1) - header := suite.chainA.CreateTMClientHeader(chainID, int64(clientHeight.RevisionHeight), heightMinus1, now, valSet, valSet, valSet, signers) + heightMinus1 := types.NewHeight(1, height-1) + header := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(clientHeight.RevisionHeight), heightMinus1, now, valSet, valSet, valSet, signers) testCases := []struct { name string @@ -76,10 +76,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost+"-1", localhosttypes.NewClientState("chainID", clientHeight), + tmClientID0, ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -88,7 +85,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -104,21 +101,35 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, ), }, - types.NewParams(exported.Tendermint, exported.Localhost), + types.NewParams(exported.Tendermint), false, 2, ), expPass: true, }, { - name: "invalid clientid", + name: "invalid client type", genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - invalidClientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + soloMachineClientID, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), + types.NewIdentifiedClientState(tmClientID0, solomachine.NewClientState(0, &solomachine.ConsensusState{PublicKey: suite.solomachine.ConsensusState().PublicKey, Diversifier: suite.solomachine.Diversifier, Timestamp: suite.solomachine.Time})), + }, + nil, + nil, + types.NewParams(exported.Tendermint), + false, + 0, + ), + expPass: false, + }, + { + name: "invalid clientid", + genState: types.NewGenesisState( + []types.IdentifiedClientState{ types.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight), + invalidClientID, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -127,7 +138,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -141,32 +152,12 @@ func (suite *TypesTestSuite) TestValidateGenesis() { ), expPass: false, }, - { - name: "invalid client", - genState: types.NewGenesisState( - []types.IdentifiedClientState{ - types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState(exported.Localhost, localhosttypes.NewClientState("chaindID", types.ZeroHeight())), - }, - nil, - nil, - types.NewParams(exported.Tendermint), - false, - 0, - ), - expPass: false, - }, { name: "consensus state client id does not match client id in genesis clients", genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight), + tmClientID0, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -174,8 +165,8 @@ func (suite *TypesTestSuite) TestValidateGenesis() { tmClientID1, []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( - types.NewHeight(0, 1), - ibctmtypes.NewConsensusState( + types.NewHeight(1, 1), + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -194,10 +185,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight), + tmClientID0, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -206,7 +194,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( types.ZeroHeight(), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -225,10 +213,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight), + tmClientID0, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -236,8 +221,8 @@ func (suite *TypesTestSuite) TestValidateGenesis() { tmClientID0, []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( - types.NewHeight(0, 1), - ibctmtypes.NewConsensusState( + types.NewHeight(1, 1), + ibctm.NewConsensusState( time.Time{}, commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -256,10 +241,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight), + tmClientID0, ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -268,7 +250,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -287,10 +269,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight), + clientID, ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -299,7 +278,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -315,7 +294,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, ), }, - types.NewParams(exported.Tendermint, exported.Localhost), + types.NewParams(exported.Tendermint), false, 0, ), @@ -326,7 +305,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + clientID, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -335,7 +314,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -361,10 +340,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight), + tmClientID0, ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -373,7 +349,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -392,10 +368,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight), + tmClientID0, ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -404,7 +377,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -413,51 +386,20 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, nil, types.NewParams(" "), - true, + false, 0, ), expPass: false, }, - { - name: "localhost client not registered on allowlist", - genState: types.NewGenesisState( - []types.IdentifiedClientState{ - types.NewIdentifiedClientState( - tmClientID1, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost+"-0", localhosttypes.NewClientState("chainID", clientHeight), - ), - }, - []types.ClientConsensusStates{ - types.NewClientConsensusStates( - tmClientID1, - []types.ConsensusStateWithHeight{ - types.NewConsensusStateWithHeight( - header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( - header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, - ), - ), - }, - ), - }, - nil, - types.NewParams(exported.Tendermint), - true, - 2, - ), - expPass: false, - }, { name: "next sequence too small", genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - tmClientID0, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + tmClientID0, ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), types.NewIdentifiedClientState( - exported.Localhost+"-1", localhosttypes.NewClientState("chainID", clientHeight), + tmClientID1, ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -466,7 +408,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -474,7 +416,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { ), }, nil, - types.NewParams(exported.Tendermint, exported.Localhost), + types.NewParams(exported.Tendermint), false, 0, ), @@ -485,10 +427,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( - "my-client", ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - types.NewIdentifiedClientState( - exported.Localhost+"-1", localhosttypes.NewClientState("chainID", clientHeight), + "my-client", ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []types.ClientConsensusStates{ @@ -497,7 +436,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -505,7 +444,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { ), }, nil, - types.NewParams(exported.Tendermint, exported.Localhost), + types.NewParams(exported.Tendermint), false, 5, ), @@ -514,18 +453,14 @@ func (suite *TypesTestSuite) TestValidateGenesis() { { name: "consensus state different than client state type", genState: types.NewGenesisState( - []types.IdentifiedClientState{ - types.NewIdentifiedClientState( - exported.Localhost+"-1", localhosttypes.NewClientState("chainID", clientHeight), - ), - }, + []types.IdentifiedClientState{}, []types.ClientConsensusStates{ types.NewClientConsensusStates( - exported.Localhost+"-1", + tmClientID0, []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, ), ), @@ -533,7 +468,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { ), }, nil, - types.NewParams(exported.Tendermint, exported.Localhost), + types.NewParams(exported.Tendermint), false, 5, ), diff --git a/modules/core/02-client/types/height.go b/modules/core/02-client/types/height.go index 152c052cf1b..b4df09e5324 100644 --- a/modules/core/02-client/types/height.go +++ b/modules/core/02-client/types/height.go @@ -7,10 +7,11 @@ import ( "strconv" "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var _ exported.Height = (*Height)(nil) @@ -135,15 +136,15 @@ func MustParseHeight(heightStr string) Height { func ParseHeight(heightStr string) (Height, error) { splitStr := strings.Split(heightStr, "-") if len(splitStr) != 2 { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "expected height string format: {revision}-{height}. Got: %s", heightStr) + return Height{}, errorsmod.Wrapf(ibcerrors.ErrInvalidHeight, "expected height string format: {revision}-{height}. Got: %s", heightStr) } revisionNumber, err := strconv.ParseUint(splitStr[0], 10, 64) if err != nil { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid revision number. parse err: %s", err) + return Height{}, errorsmod.Wrapf(ibcerrors.ErrInvalidHeight, "invalid revision number. parse err: %s", err) } revisionHeight, err := strconv.ParseUint(splitStr[1], 10, 64) if err != nil { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid revision height. parse err: %s", err) + return Height{}, errorsmod.Wrapf(ibcerrors.ErrInvalidHeight, "invalid revision height. parse err: %s", err) } return NewHeight(revisionNumber, revisionHeight), nil } @@ -152,8 +153,8 @@ func ParseHeight(heightStr string) (Height, error) { // in the chainID with the given revision number. func SetRevisionNumber(chainID string, revision uint64) (string, error) { if !IsRevisionFormat(chainID) { - return "", sdkerrors.Wrapf( - sdkerrors.ErrInvalidChainID, "chainID is not in revision format: %s", chainID, + return "", errorsmod.Wrapf( + ibcerrors.ErrInvalidChainID, "chainID is not in revision format: %s", chainID, ) } diff --git a/modules/core/02-client/types/height_test.go b/modules/core/02-client/types/height_test.go index d7e2c3650d2..fa4ae59700a 100644 --- a/modules/core/02-client/types/height_test.go +++ b/modules/core/02-client/types/height_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) func TestZeroHeight(t *testing.T) { diff --git a/modules/core/02-client/types/keys.go b/modules/core/02-client/types/keys.go index c90e3784a1b..12345c46e6c 100644 --- a/modules/core/02-client/types/keys.go +++ b/modules/core/02-client/types/keys.go @@ -6,9 +6,9 @@ import ( "strconv" "strings" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) const ( @@ -34,7 +34,11 @@ func FormatClientIdentifier(clientType string, sequence uint64) string { // IsClientIDFormat checks if a clientID is in the format required on the SDK for // parsing client identifiers. The client identifier must be in the form: `{client-type}-{N} -var IsClientIDFormat = regexp.MustCompile(`^.*[^\n-]-[0-9]{1,20}$`).MatchString +// which per the specification only permits ASCII for the {client-type} segment and +// 1 to 20 digits for the {N} segment. +// `([\w-]+\w)?` allows for a letter or hyphen, with the {client-type} starting with a letter +// and ending with a letter, i.e. `letter+(letter|hypen+letter)?`. +var IsClientIDFormat = regexp.MustCompile(`^\w+([\w-]+\w)?-[0-9]{1,20}$`).MatchString // IsValidClientID checks if the clientID is valid and can be parsed into the client // identifier format. @@ -46,7 +50,7 @@ func IsValidClientID(clientID string) bool { // ParseClientIdentifier parses the client type and sequence from the client identifier. func ParseClientIdentifier(clientID string) (string, uint64, error) { if !IsClientIDFormat(clientID) { - return "", 0, sdkerrors.Wrapf(host.ErrInvalidID, "invalid client identifier %s is not in format: `{client-type}-{N}`", clientID) + return "", 0, errorsmod.Wrapf(host.ErrInvalidID, "invalid client identifier %s is not in format: `{client-type}-{N}`", clientID) } splitStr := strings.Split(clientID, "-") @@ -54,12 +58,12 @@ func ParseClientIdentifier(clientID string) (string, uint64, error) { clientType := strings.Join(splitStr[:lastIndex], "-") if strings.TrimSpace(clientType) == "" { - return "", 0, sdkerrors.Wrap(host.ErrInvalidID, "client identifier must be in format: `{client-type}-{N}` and client type cannot be blank") + return "", 0, errorsmod.Wrap(host.ErrInvalidID, "client identifier must be in format: `{client-type}-{N}` and client type cannot be blank") } sequence, err := strconv.ParseUint(splitStr[lastIndex], 10, 64) if err != nil { - return "", 0, sdkerrors.Wrap(err, "failed to parse client identifier sequence") + return "", 0, errorsmod.Wrap(err, "failed to parse client identifier sequence") } return clientType, sequence, nil diff --git a/modules/core/02-client/types/keys_test.go b/modules/core/02-client/types/keys_test.go index 2a042b82eae..93c295df627 100644 --- a/modules/core/02-client/types/keys_test.go +++ b/modules/core/02-client/types/keys_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) // tests ParseClientIdentifier and IsValidClientID @@ -35,22 +35,31 @@ func TestParseClientIdentifier(t *testing.T) { {"negative sequence", "tendermint--1", "tendermint", 0, false}, {"invalid format", "tendermint-tm", "tendermint", 0, false}, {"empty clientype", " -100", "tendermint", 0, false}, + {"with in the middle tabs", "a\t\t\t-100", "tendermint", 0, false}, + {"leading tabs", "\t\t\ta-100", "tendermint", 0, false}, + {"with whitespace", " a-100", "tendermint", 0, false}, + {"leading hyphens", "-----a-100", "tendermint", 0, false}, + {"with slash", "tendermint/-100", "tendermint", 0, false}, + {"non-ASCII:: emoji", "🚨😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎-100", "tendermint", 0, false}, + {"non-ASCII:: others", "世界-100", "tendermint", 0, false}, } for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + clientType, seq, err := types.ParseClientIdentifier(tc.clientID) + valid := types.IsValidClientID(tc.clientID) + require.Equal(t, tc.expSeq, seq, tc.clientID) - clientType, seq, err := types.ParseClientIdentifier(tc.clientID) - valid := types.IsValidClientID(tc.clientID) - require.Equal(t, tc.expSeq, seq, tc.clientID) - - if tc.expPass { - require.NoError(t, err, tc.name) - require.True(t, valid) - require.Equal(t, tc.clientType, clientType) - } else { - require.Error(t, err, tc.name, tc.clientID) - require.False(t, valid) - require.Equal(t, "", clientType) - } + if tc.expPass { + require.NoError(t, err, tc.name) + require.True(t, valid) + require.Equal(t, tc.clientType, clientType) + } else { + require.Error(t, err, tc.name, tc.clientID) + require.False(t, valid) + require.Equal(t, "", clientType) + } + }) } } diff --git a/modules/core/02-client/types/msgs.go b/modules/core/02-client/types/msgs.go index 58586887b51..9f2c76f4141 100644 --- a/modules/core/02-client/types/msgs.go +++ b/modules/core/02-client/types/msgs.go @@ -1,20 +1,13 @@ package types import ( + errorsmod "cosmossdk.io/errors" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -// message types for the IBC client -const ( - TypeMsgCreateClient string = "create_client" - TypeMsgUpdateClient string = "update_client" - TypeMsgUpgradeClient string = "upgrade_client" - TypeMsgSubmitMisbehaviour string = "submit_misbehaviour" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( @@ -30,6 +23,7 @@ var ( ) // NewMsgCreateClient creates a new MsgCreateClient instance +// //nolint:interfacer func NewMsgCreateClient( clientState exported.ClientState, consensusState exported.ConsensusState, signer string, @@ -55,7 +49,7 @@ func NewMsgCreateClient( func (msg MsgCreateClient) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } clientState, err := UnpackClientState(msg.ClientState) if err != nil { @@ -64,18 +58,15 @@ func (msg MsgCreateClient) ValidateBasic() error { if err := clientState.Validate(); err != nil { return err } - if clientState.ClientType() == exported.Localhost { - return sdkerrors.Wrap(ErrInvalidClient, "localhost client can only be created on chain initialization") - } consensusState, err := UnpackConsensusState(msg.ConsensusState) if err != nil { return err } if clientState.ClientType() != consensusState.ClientType() { - return sdkerrors.Wrap(ErrInvalidClientType, "client type for client state and consensus state do not match") + return errorsmod.Wrap(ErrInvalidClientType, "client type for client state and consensus state do not match") } if err := ValidateClientType(clientState.ClientType()); err != nil { - return sdkerrors.Wrap(err, "client type does not meet naming constraints") + return errorsmod.Wrap(err, "client type does not meet naming constraints") } return consensusState.ValidateBasic() } @@ -102,17 +93,18 @@ func (msg MsgCreateClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) err } // NewMsgUpdateClient creates a new MsgUpdateClient instance +// //nolint:interfacer -func NewMsgUpdateClient(id string, header exported.Header, signer string) (*MsgUpdateClient, error) { - anyHeader, err := PackHeader(header) +func NewMsgUpdateClient(id string, clientMsg exported.ClientMessage, signer string) (*MsgUpdateClient, error) { + anyClientMsg, err := PackClientMessage(clientMsg) if err != nil { return nil, err } return &MsgUpdateClient{ - ClientId: id, - Header: anyHeader, - Signer: signer, + ClientId: id, + ClientMessage: anyClientMsg, + Signer: signer, }, nil } @@ -120,18 +112,15 @@ func NewMsgUpdateClient(id string, header exported.Header, signer string) (*MsgU func (msg MsgUpdateClient) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } - header, err := UnpackHeader(msg.Header) + clientMsg, err := UnpackClientMessage(msg.ClientMessage) if err != nil { return err } - if err := header.ValidateBasic(); err != nil { + if err := clientMsg.ValidateBasic(); err != nil { return err } - if msg.ClientId == exported.Localhost { - return sdkerrors.Wrap(ErrInvalidClient, "localhost client is only updated on ABCI BeginBlock") - } return host.ClientIdentifierValidator(msg.ClientId) } @@ -146,12 +135,13 @@ func (msg MsgUpdateClient) GetSigners() []sdk.AccAddress { // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (msg MsgUpdateClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - var header exported.Header - return unpacker.UnpackAny(msg.Header, &header) + var clientMsg exported.ClientMessage + return unpacker.UnpackAny(msg.ClientMessage, &clientMsg) } // NewMsgUpgradeClient creates a new MsgUpgradeClient instance -// nolint: interfacer +// +//nolint:interfacer func NewMsgUpgradeClient(clientID string, clientState exported.ClientState, consState exported.ConsensusState, proofUpgradeClient, proofUpgradeConsState []byte, signer string, ) (*MsgUpgradeClient, error) { @@ -190,18 +180,18 @@ func (msg MsgUpgradeClient) ValidateBasic() error { } if clientState.ClientType() != consensusState.ClientType() { - return sdkerrors.Wrapf(ErrInvalidUpgradeClient, "consensus state's client-type does not match client. expected: %s, got: %s", + return errorsmod.Wrapf(ErrInvalidUpgradeClient, "consensus state's client-type does not match client. expected: %s, got: %s", clientState.ClientType(), consensusState.ClientType()) } if len(msg.ProofUpgradeClient) == 0 { - return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade client cannot be empty") + return errorsmod.Wrap(ErrInvalidUpgradeClient, "proof of upgrade client cannot be empty") } if len(msg.ProofUpgradeConsensusState) == 0 { - return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade consensus state cannot be empty") + return errorsmod.Wrap(ErrInvalidUpgradeClient, "proof of upgrade consensus state cannot be empty") } _, err = sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return host.ClientIdentifierValidator(msg.ClientId) } @@ -228,9 +218,10 @@ func (msg MsgUpgradeClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) er } // NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance. +// //nolint:interfacer -func NewMsgSubmitMisbehaviour(clientID string, misbehaviour exported.Misbehaviour, signer string) (*MsgSubmitMisbehaviour, error) { - anyMisbehaviour, err := PackMisbehaviour(misbehaviour) +func NewMsgSubmitMisbehaviour(clientID string, misbehaviour exported.ClientMessage, signer string) (*MsgSubmitMisbehaviour, error) { + anyMisbehaviour, err := PackClientMessage(misbehaviour) if err != nil { return nil, err } @@ -246,22 +237,15 @@ func NewMsgSubmitMisbehaviour(clientID string, misbehaviour exported.Misbehaviou func (msg MsgSubmitMisbehaviour) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } - misbehaviour, err := UnpackMisbehaviour(msg.Misbehaviour) + misbehaviour, err := UnpackClientMessage(msg.Misbehaviour) if err != nil { return err } if err := misbehaviour.ValidateBasic(); err != nil { return err } - if misbehaviour.GetClientID() != msg.ClientId { - return sdkerrors.Wrapf( - ErrInvalidMisbehaviour, - "misbehaviour client-id doesn't match client-id from message (%s ≠ %s)", - misbehaviour.GetClientID(), msg.ClientId, - ) - } return host.ClientIdentifierValidator(msg.ClientId) } @@ -277,6 +261,6 @@ func (msg MsgSubmitMisbehaviour) GetSigners() []sdk.AccAddress { // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (msg MsgSubmitMisbehaviour) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - var misbehaviour exported.Misbehaviour + var misbehaviour exported.ClientMessage return unpacker.UnpackAny(msg.Misbehaviour, &misbehaviour) } diff --git a/modules/core/02-client/types/msgs_test.go b/modules/core/02-client/types/msgs_test.go index cf625f93bcc..9eeac2e3908 100644 --- a/modules/core/02-client/types/msgs_test.go +++ b/modules/core/02-client/types/msgs_test.go @@ -4,15 +4,14 @@ import ( "testing" "time" - "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/proto" //nolint:staticcheck "github.com/stretchr/testify/suite" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - solomachinetypes "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type TypesTestSuite struct { @@ -20,14 +19,16 @@ type TypesTestSuite struct { coordinator *ibctesting.Coordinator - chainA *ibctesting.TestChain - chainB *ibctesting.TestChain + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain + solomachine *ibctesting.Solomachine } func (suite *TypesTestSuite) SetupTest() { suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) + suite.solomachine = ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinesingle", "testing", 1) } func TestTypesTestSuite(t *testing.T) { @@ -55,7 +56,7 @@ func (suite *TypesTestSuite) TestMarshalMsgCreateClient() { }, { "tendermint client", func() { - tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + tendermintClient := ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) msg, err = types.NewMsgCreateClient(tendermintClient, suite.chainA.CurrentTMClientHeader().ConsensusState(), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, @@ -100,7 +101,7 @@ func (suite *TypesTestSuite) TestMsgCreateClient_ValidateBasic() { { "valid - tendermint client", func() { - tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + tendermintClient := ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) msg, err = types.NewMsgCreateClient(tendermintClient, suite.chainA.CurrentTMClientHeader().ConsensusState(), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, @@ -109,7 +110,7 @@ func (suite *TypesTestSuite) TestMsgCreateClient_ValidateBasic() { { "invalid tendermint client", func() { - msg, err = types.NewMsgCreateClient(&ibctmtypes.ClientState{}, suite.chainA.CurrentTMClientHeader().ConsensusState(), suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgCreateClient(&ibctm.ClientState{}, suite.chainA.CurrentTMClientHeader().ConsensusState(), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, false, @@ -124,7 +125,7 @@ func (suite *TypesTestSuite) TestMsgCreateClient_ValidateBasic() { { "failed to unpack consensus state", func() { - tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + tendermintClient := ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) msg, err = types.NewMsgCreateClient(tendermintClient, suite.chainA.CurrentTMClientHeader().ConsensusState(), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) msg.ConsensusState = nil @@ -151,7 +152,7 @@ func (suite *TypesTestSuite) TestMsgCreateClient_ValidateBasic() { "invalid solomachine client", func() { soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2) - msg, err = types.NewMsgCreateClient(&solomachinetypes.ClientState{}, soloMachine.ConsensusState(), suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgCreateClient(&solomachine.ClientState{}, soloMachine.ConsensusState(), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, false, @@ -160,7 +161,7 @@ func (suite *TypesTestSuite) TestMsgCreateClient_ValidateBasic() { "invalid solomachine consensus state", func() { soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2) - msg, err = types.NewMsgCreateClient(soloMachine.ClientState(), &solomachinetypes.ConsensusState{}, suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgCreateClient(soloMachine.ClientState(), &solomachine.ConsensusState{}, suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, false, @@ -168,7 +169,7 @@ func (suite *TypesTestSuite) TestMsgCreateClient_ValidateBasic() { { "invalid - client state and consensus state client types do not match", func() { - tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + tendermintClient := ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2) msg, err = types.NewMsgCreateClient(tendermintClient, soloMachine.ConsensusState(), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) @@ -203,7 +204,7 @@ func (suite *TypesTestSuite) TestMarshalMsgUpdateClient() { { "solo machine client", func() { soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2) - msg, err = types.NewMsgUpdateClient(soloMachine.ClientID, soloMachine.CreateHeader(), suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgUpdateClient(soloMachine.ClientID, soloMachine.CreateHeader(soloMachine.Diversifier), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, }, @@ -268,7 +269,7 @@ func (suite *TypesTestSuite) TestMsgUpdateClient_ValidateBasic() { { "invalid tendermint header", func() { - msg, err = types.NewMsgUpdateClient("tendermint", &ibctmtypes.Header{}, suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgUpdateClient("tendermint", &ibctm.Header{}, suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, false, @@ -276,7 +277,7 @@ func (suite *TypesTestSuite) TestMsgUpdateClient_ValidateBasic() { { "failed to unpack header", func() { - msg.Header = nil + msg.ClientMessage = nil }, false, }, @@ -291,7 +292,8 @@ func (suite *TypesTestSuite) TestMsgUpdateClient_ValidateBasic() { "valid - solomachine header", func() { soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2) - msg, err = types.NewMsgUpdateClient(soloMachine.ClientID, soloMachine.CreateHeader(), suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgUpdateClient(soloMachine.ClientID, soloMachine.CreateHeader(soloMachine.Diversifier), suite.chainA.SenderAccount.GetAddress().String()) + suite.Require().NoError(err) }, true, @@ -299,15 +301,7 @@ func (suite *TypesTestSuite) TestMsgUpdateClient_ValidateBasic() { { "invalid solomachine header", func() { - msg, err = types.NewMsgUpdateClient("solomachine", &solomachinetypes.Header{}, suite.chainA.SenderAccount.GetAddress().String()) - suite.Require().NoError(err) - }, - false, - }, - { - "unsupported - localhost", - func() { - msg, err = types.NewMsgUpdateClient(exported.Localhost, suite.chainA.CurrentTMClientHeader(), suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgUpdateClient("solomachine", &solomachine.Header{}, suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, false, @@ -338,8 +332,8 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { { "client upgrades to new tendermint client", func() { - tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - tendermintConsState := &ibctmtypes.ConsensusState{NextValidatorsHash: []byte("nextValsHash")} + tendermintClient := ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) + tendermintConsState := &ibctm.ConsensusState{NextValidatorsHash: []byte("nextValsHash")} msg, err = types.NewMsgUpgradeClient("clientid", tendermintClient, tendermintConsState, []byte("proofUpgradeClient"), []byte("proofUpgradeConsState"), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, @@ -451,8 +445,8 @@ func (suite *TypesTestSuite) TestMsgUpgradeClient_ValidateBasic() { for _, tc := range cases { tc := tc - clientState := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - consState := &ibctmtypes.ConsensusState{NextValidatorsHash: []byte("nextValsHash")} + clientState := ibctm.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) + consState := &ibctm.ConsensusState{NextValidatorsHash: []byte("nextValsHash")} msg, err := types.NewMsgUpgradeClient("testclientid", clientState, consState, []byte("proofUpgradeClient"), []byte("proofUpgradeConsState"), suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) @@ -492,7 +486,7 @@ func (suite *TypesTestSuite) TestMarshalMsgSubmitMisbehaviour() { header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) - misbehaviour := ibctmtypes.NewMisbehaviour("tendermint", header1, header2) + misbehaviour := ibctm.NewMisbehaviour("tendermint", header1, header2) msg, err = types.NewMsgSubmitMisbehaviour("tendermint", misbehaviour, suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, @@ -549,7 +543,7 @@ func (suite *TypesTestSuite) TestMsgSubmitMisbehaviour_ValidateBasic() { header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) - misbehaviour := ibctmtypes.NewMisbehaviour("tendermint", header1, header2) + misbehaviour := ibctm.NewMisbehaviour("tendermint", header1, header2) msg, err = types.NewMsgSubmitMisbehaviour("tendermint", misbehaviour, suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, @@ -558,7 +552,7 @@ func (suite *TypesTestSuite) TestMsgSubmitMisbehaviour_ValidateBasic() { { "invalid tendermint misbehaviour", func() { - msg, err = types.NewMsgSubmitMisbehaviour("tendermint", &ibctmtypes.Misbehaviour{}, suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgSubmitMisbehaviour("tendermint", &ibctm.Misbehaviour{}, suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, false, @@ -589,7 +583,7 @@ func (suite *TypesTestSuite) TestMsgSubmitMisbehaviour_ValidateBasic() { { "invalid solomachine misbehaviour", func() { - msg, err = types.NewMsgSubmitMisbehaviour("solomachine", &solomachinetypes.Misbehaviour{}, suite.chainA.SenderAccount.GetAddress().String()) + msg, err = types.NewMsgSubmitMisbehaviour("solomachine", &solomachine.Misbehaviour{}, suite.chainA.SenderAccount.GetAddress().String()) suite.Require().NoError(err) }, false, diff --git a/modules/core/02-client/types/params.go b/modules/core/02-client/types/params.go index ce4af7d0369..21ad31007df 100644 --- a/modules/core/02-client/types/params.go +++ b/modules/core/02-client/types/params.go @@ -6,7 +6,7 @@ import ( paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( diff --git a/modules/core/02-client/types/params_test.go b/modules/core/02-client/types/params_test.go index bcff83f1f46..447b0ffa5c7 100644 --- a/modules/core/02-client/types/params_test.go +++ b/modules/core/02-client/types/params_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) func TestValidateParams(t *testing.T) { diff --git a/modules/core/02-client/types/proposal.go b/modules/core/02-client/types/proposal.go index 3040122a35f..2e6655d0ce9 100644 --- a/modules/core/02-client/types/proposal.go +++ b/modules/core/02-client/types/proposal.go @@ -2,13 +2,14 @@ package types import ( "fmt" + "reflect" + errorsmod "cosmossdk.io/errors" codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) const ( @@ -58,7 +59,7 @@ func (cup *ClientUpdateProposal) ValidateBasic() error { } if cup.SubjectClientId == cup.SubstituteClientId { - return sdkerrors.Wrap(ErrInvalidSubstitute, "subject and substitute client identifiers are equal") + return errorsmod.Wrap(ErrInvalidSubstitute, "subject and substitute client identifiers are equal") } if _, _, err := ParseClientIdentifier(cup.SubjectClientId); err != nil { return err @@ -72,7 +73,7 @@ func (cup *ClientUpdateProposal) ValidateBasic() error { // NewUpgradeProposal creates a new IBC breaking upgrade proposal. func NewUpgradeProposal(title, description string, plan upgradetypes.Plan, upgradedClientState exported.ClientState) (govtypes.Content, error) { - any, err := PackClientState(upgradedClientState) + protoAny, err := PackClientState(upgradedClientState) if err != nil { return nil, err } @@ -81,7 +82,7 @@ func NewUpgradeProposal(title, description string, plan upgradetypes.Plan, upgra Title: title, Description: description, Plan: plan, - UpgradedClientState: any, + UpgradedClientState: protoAny, }, nil } @@ -108,12 +109,16 @@ func (up *UpgradeProposal) ValidateBasic() error { } if up.UpgradedClientState == nil { - return sdkerrors.Wrap(ErrInvalidUpgradeProposal, "upgraded client state cannot be nil") + return errorsmod.Wrap(ErrInvalidUpgradeProposal, "upgraded client state cannot be nil") } - _, err := UnpackClientState(up.UpgradedClientState) + clientState, err := UnpackClientState(up.UpgradedClientState) if err != nil { - return sdkerrors.Wrap(err, "failed to unpack upgraded client state") + return errorsmod.Wrap(err, "failed to unpack upgraded client state") + } + + if !reflect.DeepEqual(clientState, clientState.ZeroCustomFields()) { + return errorsmod.Wrap(ErrInvalidUpgradeProposal, "upgraded client state is not zeroed out") } return nil diff --git a/modules/core/02-client/types/proposal_test.go b/modules/core/02-client/types/proposal_test.go index c722cc3c886..8009e4ebd8b 100644 --- a/modules/core/02-client/types/proposal_test.go +++ b/modules/core/02-client/types/proposal_test.go @@ -5,12 +5,12 @@ import ( "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *TypesTestSuite) TestValidateBasic() { @@ -109,20 +109,30 @@ func (suite *TypesTestSuite) TestUpgradeProposalValidateBasic() { }{ { "success", func() { - proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, cs) + proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, cs.ZeroCustomFields()) suite.Require().NoError(err) }, true, }, { "fails validate abstract - empty title", func() { - proposal, err = types.NewUpgradeProposal("", ibctesting.Description, plan, cs) + proposal, err = types.NewUpgradeProposal("", ibctesting.Description, plan, cs.ZeroCustomFields()) + suite.Require().NoError(err) + }, false, + }, + { + "non zeroed fields", func() { + proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, &ibctm.ClientState{ + FrozenHeight: types.Height{ + RevisionHeight: 10, + }, + }) suite.Require().NoError(err) }, false, }, { "plan height is zero", func() { invalidPlan := upgradetypes.Plan{Name: "ibc upgrade", Height: 0} - proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, invalidPlan, cs) + proposal, err = types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, invalidPlan, cs.ZeroCustomFields()) suite.Require().NoError(err) }, false, }, @@ -138,14 +148,14 @@ func (suite *TypesTestSuite) TestUpgradeProposalValidateBasic() { }, { "failed to unpack client state", func() { - any, err := types.PackConsensusState(&ibctmtypes.ConsensusState{}) + protoAny, err := types.PackConsensusState(&ibctm.ConsensusState{}) suite.Require().NoError(err) proposal = &types.UpgradeProposal{ Title: ibctesting.Title, Description: ibctesting.Description, Plan: plan, - UpgradedClientState: any, + UpgradedClientState: protoAny, } }, false, }, @@ -173,7 +183,7 @@ func (suite *TypesTestSuite) TestMarshalUpgradeProposal() { Name: "upgrade ibc", Height: 1000, } - content, err := types.NewUpgradeProposal("title", "description", plan, &ibctmtypes.ClientState{}) + content, err := types.NewUpgradeProposal("title", "description", plan, &ibctm.ClientState{}) suite.Require().NoError(err) up, ok := content.(*types.UpgradeProposal) @@ -183,7 +193,7 @@ func (suite *TypesTestSuite) TestMarshalUpgradeProposal() { ir := codectypes.NewInterfaceRegistry() types.RegisterInterfaces(ir) govtypes.RegisterInterfaces(ir) - ibctmtypes.RegisterInterfaces(ir) + ibctm.RegisterInterfaces(ir) cdc := codec.NewProtoCodec(ir) // marshal message @@ -207,10 +217,10 @@ func (suite *TypesTestSuite) TestUpgradeString() { Height: 1000, } - proposal, err := types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, &ibctmtypes.ClientState{}) + proposal, err := types.NewUpgradeProposal(ibctesting.Title, ibctesting.Description, plan, &ibctm.ClientState{}) suite.Require().NoError(err) - expect := fmt.Sprintf("IBC Upgrade Proposal\n Title: title\n Description: description\n Upgrade Plan\n Name: ibc upgrade\n height: 1000\n Info: https://foo.bar/baz.\n Upgraded IBC Client: %s", &ibctmtypes.ClientState{}) + expect := fmt.Sprintf("IBC Upgrade Proposal\n Title: title\n Description: description\n Upgrade Plan\n Name: ibc upgrade\n height: 1000\n Info: https://foo.bar/baz.\n Upgraded IBC Client: %s", &ibctm.ClientState{}) suite.Require().Equal(expect, proposal.String()) } diff --git a/modules/core/02-client/types/query.go b/modules/core/02-client/types/query.go index 81e80dc8793..6bf1fb5c7ba 100644 --- a/modules/core/02-client/types/query.go +++ b/modules/core/02-client/types/query.go @@ -3,7 +3,7 @@ package types import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( diff --git a/modules/core/02-client/types/query.pb.go b/modules/core/02-client/types/query.pb.go index 9b733d70b51..727629ff673 100644 --- a/modules/core/02-client/types/query.pb.go +++ b/modules/core/02-client/types/query.pb.go @@ -8,9 +8,9 @@ import ( fmt "fmt" types "github.com/cosmos/cosmos-sdk/codec/types" query "github.com/cosmos/cosmos-sdk/types/query" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -984,73 +984,73 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/query.proto", fileDescriptor_dc42cdfd1d52d76e) } var fileDescriptor_dc42cdfd1d52d76e = []byte{ - // 1056 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcd, 0x6f, 0x1b, 0x45, - 0x14, 0xcf, 0xa4, 0x69, 0xd4, 0x3e, 0xbb, 0x09, 0x9a, 0xe6, 0xc3, 0xdd, 0x16, 0xc7, 0xd9, 0x20, - 0x9a, 0x96, 0x64, 0x27, 0x71, 0xda, 0x24, 0x42, 0x42, 0x82, 0x54, 0x2a, 0xed, 0xa5, 0x94, 0x45, - 0x08, 0x84, 0x84, 0xa2, 0xdd, 0xf5, 0x64, 0xb3, 0x92, 0xbd, 0xe3, 0x7a, 0x76, 0x2d, 0x45, 0x55, - 0x2e, 0x3d, 0x21, 0x4e, 0x48, 0x48, 0x5c, 0x91, 0x38, 0x72, 0xa8, 0x38, 0x20, 0x71, 0xe5, 0x04, - 0x39, 0x70, 0xa8, 0x04, 0x07, 0x4e, 0x14, 0x25, 0xfc, 0x21, 0xc8, 0x33, 0xb3, 0xf6, 0xae, 0x3d, - 0xae, 0xd7, 0xa8, 0xf4, 0xb6, 0xfb, 0x3e, 0x7f, 0xef, 0xf7, 0x9e, 0xdf, 0x5b, 0x43, 0x39, 0x70, - 0x3d, 0xe2, 0xb1, 0x16, 0x25, 0x5e, 0x3d, 0xa0, 0x61, 0x44, 0xda, 0x9b, 0xe4, 0x51, 0x4c, 0x5b, - 0x47, 0x56, 0xb3, 0xc5, 0x22, 0x86, 0x71, 0xe0, 0x7a, 0x56, 0x47, 0x6f, 0x49, 0xbd, 0xd5, 0xde, - 0x34, 0x6e, 0x7a, 0x8c, 0x37, 0x18, 0x27, 0xae, 0xc3, 0xa9, 0x34, 0x26, 0xed, 0x4d, 0x97, 0x46, - 0xce, 0x26, 0x69, 0x3a, 0x7e, 0x10, 0x3a, 0x51, 0xc0, 0x42, 0xe9, 0x6f, 0x2c, 0x69, 0xe2, 0xab, - 0x48, 0xd2, 0xe0, 0x8a, 0xcf, 0x98, 0x5f, 0xa7, 0x44, 0xbc, 0xb9, 0xf1, 0x01, 0x71, 0x42, 0x95, - 0xdb, 0xb8, 0xa6, 0x54, 0x4e, 0x33, 0x20, 0x4e, 0x18, 0xb2, 0x48, 0x04, 0xe6, 0x4a, 0x3b, 0xe7, - 0x33, 0x9f, 0x89, 0x47, 0xd2, 0x79, 0x92, 0x52, 0x73, 0x1b, 0x16, 0x3f, 0xec, 0x20, 0xba, 0x23, - 0x72, 0x7c, 0x14, 0x39, 0x11, 0xb5, 0xe9, 0xa3, 0x98, 0xf2, 0x08, 0x5f, 0x85, 0x8b, 0x32, 0xf3, - 0x7e, 0x50, 0x2b, 0xa1, 0x0a, 0x5a, 0xbd, 0x68, 0x5f, 0x90, 0x82, 0xfb, 0x35, 0xf3, 0x29, 0x82, - 0xd2, 0xa0, 0x23, 0x6f, 0xb2, 0x90, 0x53, 0xbc, 0x03, 0x45, 0xe5, 0xc9, 0x3b, 0x72, 0xe1, 0x5c, - 0xa8, 0xce, 0x59, 0x12, 0x9f, 0x95, 0x40, 0xb7, 0xde, 0x0b, 0x8f, 0xec, 0x82, 0xd7, 0x0b, 0x80, - 0xe7, 0xe0, 0x7c, 0xb3, 0xc5, 0xd8, 0x41, 0x69, 0xb2, 0x82, 0x56, 0x8b, 0xb6, 0x7c, 0xc1, 0x77, - 0xa0, 0x28, 0x1e, 0xf6, 0x0f, 0x69, 0xe0, 0x1f, 0x46, 0xa5, 0x73, 0x22, 0x9c, 0x61, 0x0d, 0x52, - 0x6d, 0xdd, 0x13, 0x16, 0x7b, 0x53, 0x27, 0x7f, 0x2d, 0x4d, 0xd8, 0x05, 0xe1, 0x25, 0x45, 0xa6, - 0x3b, 0x88, 0x97, 0x27, 0x95, 0xde, 0x05, 0xe8, 0x35, 0x42, 0xa1, 0x7d, 0xd3, 0x92, 0x5d, 0xb3, - 0x3a, 0x5d, 0xb3, 0x64, 0x8b, 0x55, 0xd7, 0xac, 0x87, 0x8e, 0x9f, 0xb0, 0x64, 0xa7, 0x3c, 0xcd, - 0x3f, 0x10, 0x5c, 0xd1, 0x24, 0x51, 0xac, 0x84, 0x70, 0x29, 0xcd, 0x0a, 0x2f, 0xa1, 0xca, 0xb9, - 0xd5, 0x42, 0xf5, 0x86, 0xae, 0x8e, 0xfb, 0x35, 0x1a, 0x46, 0xc1, 0x41, 0x40, 0x6b, 0xa9, 0x50, - 0x7b, 0xe5, 0x4e, 0x59, 0xdf, 0x3f, 0x5f, 0x5a, 0xd0, 0xaa, 0xb9, 0x5d, 0x4c, 0x71, 0xc9, 0xf1, - 0xfb, 0x99, 0xaa, 0x26, 0x45, 0x55, 0xd7, 0x47, 0x56, 0x25, 0xc1, 0x66, 0xca, 0xfa, 0x01, 0x81, - 0x21, 0xcb, 0xea, 0xa8, 0x42, 0x1e, 0xf3, 0xdc, 0x73, 0x82, 0xaf, 0xc3, 0x6c, 0x8b, 0xb6, 0x03, - 0x1e, 0xb0, 0x70, 0x3f, 0x8c, 0x1b, 0x2e, 0x6d, 0x09, 0x24, 0x53, 0xf6, 0x4c, 0x22, 0x7e, 0x20, - 0xa4, 0x19, 0xc3, 0x54, 0x9f, 0x53, 0x86, 0xb2, 0x91, 0x78, 0x05, 0x2e, 0xd5, 0x3b, 0xf5, 0x45, - 0x89, 0xd9, 0x54, 0x05, 0xad, 0x5e, 0xb0, 0x8b, 0x52, 0xa8, 0xba, 0xfd, 0x13, 0x82, 0xab, 0x5a, - 0xc8, 0xaa, 0x17, 0xef, 0xc0, 0xac, 0x97, 0x68, 0x72, 0x0c, 0xe9, 0x8c, 0x97, 0x09, 0xf3, 0x7f, - 0xce, 0xe9, 0x13, 0x3d, 0x72, 0x9e, 0x8b, 0xed, 0xbb, 0x9a, 0x96, 0xff, 0x97, 0x41, 0xfe, 0x05, - 0xc1, 0x35, 0x3d, 0x08, 0xc5, 0xdf, 0xe7, 0xf0, 0x5a, 0x1f, 0x7f, 0xc9, 0x38, 0xaf, 0xe9, 0xca, - 0xcd, 0x86, 0xf9, 0x24, 0x88, 0x0e, 0x33, 0x04, 0xcc, 0x66, 0xe9, 0x7d, 0x89, 0xa3, 0xfb, 0x05, - 0x82, 0x65, 0x4d, 0x21, 0x32, 0xfb, 0xab, 0xe5, 0xf4, 0x57, 0x04, 0xe6, 0x8b, 0xa0, 0x28, 0x66, - 0x3f, 0x85, 0xc5, 0x3e, 0x66, 0xd5, 0x38, 0x25, 0x04, 0x8f, 0x9e, 0xa7, 0x79, 0x4f, 0x97, 0xe1, - 0xe5, 0x91, 0xba, 0x33, 0xb0, 0x4a, 0xe3, 0x5c, 0x54, 0x9a, 0x5b, 0x03, 0xeb, 0x31, 0xee, 0x15, - 0xbe, 0x00, 0xd3, 0x5c, 0x48, 0x94, 0x9b, 0x7a, 0x33, 0x8d, 0x4c, 0xb6, 0x87, 0x4e, 0xcb, 0x69, - 0x24, 0xd9, 0xcc, 0x0f, 0x32, 0x01, 0x13, 0x9d, 0x0a, 0x58, 0x85, 0xe9, 0xa6, 0x90, 0xa8, 0x9f, - 0xb6, 0x96, 0x38, 0xe5, 0xa3, 0x2c, 0xcd, 0x65, 0x58, 0x12, 0x01, 0x3f, 0x6e, 0xfa, 0x2d, 0xa7, - 0x96, 0x59, 0xaf, 0x49, 0xce, 0x3a, 0x54, 0x86, 0x9b, 0xa8, 0xd4, 0xf7, 0x60, 0x3e, 0x56, 0xea, - 0xfd, 0xdc, 0x97, 0xf0, 0x72, 0x3c, 0x18, 0xd1, 0x7c, 0x43, 0x0d, 0x4d, 0x37, 0x9b, 0x6e, 0x05, - 0x9b, 0x31, 0xac, 0xbc, 0xd0, 0x4a, 0xc1, 0x7a, 0x00, 0xa5, 0x1e, 0xac, 0x31, 0xd6, 0xdf, 0x42, - 0xac, 0x8d, 0x5b, 0xfd, 0xad, 0x08, 0xe7, 0x45, 0x5e, 0xfc, 0x2d, 0x82, 0x42, 0x0a, 0x36, 0x7e, - 0x4b, 0xc7, 0xf5, 0x90, 0x0f, 0x0d, 0x63, 0x2d, 0x9f, 0xb1, 0x2c, 0xc2, 0xbc, 0xfd, 0xe4, 0xf7, - 0x7f, 0xbe, 0x9e, 0x24, 0x78, 0x9d, 0x0c, 0xfd, 0x54, 0x52, 0x1b, 0x89, 0x3c, 0xee, 0x8e, 0xe2, - 0x31, 0xfe, 0x06, 0x41, 0x31, 0x7d, 0x2c, 0x71, 0xae, 0xac, 0xc9, 0xa4, 0x19, 0xeb, 0x39, 0xad, - 0x15, 0xc8, 0x1b, 0x02, 0xe4, 0x0a, 0x5e, 0x1e, 0x09, 0x12, 0x3f, 0x47, 0x30, 0x93, 0xe5, 0x15, - 0x5b, 0xc3, 0x93, 0xe9, 0xda, 0x6f, 0x90, 0xdc, 0xf6, 0x0a, 0x5e, 0x5d, 0xc0, 0x3b, 0xc0, 0x35, - 0x2d, 0xbc, 0xbe, 0xc5, 0x9e, 0xa6, 0x91, 0x24, 0xc7, 0x98, 0x3c, 0xee, 0x3b, 0xeb, 0xc7, 0x44, - 0xae, 0xa9, 0x94, 0x42, 0x0a, 0x8e, 0xf1, 0x53, 0x04, 0xb3, 0x7d, 0x87, 0x04, 0xe7, 0x85, 0xdc, - 0x6d, 0xc0, 0x46, 0x7e, 0x07, 0x55, 0xe4, 0xae, 0x28, 0xb2, 0x8a, 0x37, 0xc6, 0x2d, 0x12, 0x9f, - 0x20, 0x98, 0xd7, 0x6e, 0x69, 0x7c, 0x3b, 0x27, 0x8a, 0xec, 0x81, 0x31, 0xb6, 0xc7, 0x75, 0x53, - 0x25, 0xbc, 0x2b, 0x4a, 0x78, 0x1b, 0xef, 0x8e, 0xdd, 0x27, 0x75, 0x33, 0xf0, 0x77, 0x99, 0xb1, - 0x8f, 0xf3, 0x8d, 0x7d, 0x3c, 0xd6, 0xd8, 0xf7, 0x76, 0x78, 0xee, 0xdf, 0x66, 0x9c, 0xe5, 0xfb, - 0xcb, 0x2e, 0x48, 0xb9, 0x8e, 0x47, 0x82, 0xcc, 0x5c, 0x81, 0x91, 0x20, 0xb3, 0x77, 0xc1, 0x7c, - 0x5d, 0x80, 0x5c, 0xc4, 0xf3, 0x12, 0x64, 0x17, 0x9f, 0x3c, 0x01, 0xf8, 0x47, 0x04, 0x97, 0x35, - 0xbb, 0x1d, 0x6f, 0x0d, 0xcd, 0x32, 0xfc, 0x58, 0x18, 0xb7, 0xc6, 0x73, 0x52, 0x08, 0xab, 0x02, - 0xe1, 0x1a, 0xbe, 0xa9, 0xa3, 0x51, 0x7b, 0x58, 0x38, 0xfe, 0x19, 0xc1, 0x82, 0x7e, 0xfd, 0xe3, - 0xed, 0xd1, 0x20, 0xb4, 0x6b, 0x65, 0x67, 0x6c, 0xbf, 0x3c, 0x63, 0x30, 0xec, 0x02, 0xf1, 0x3d, - 0xfb, 0xe4, 0xb4, 0x8c, 0x9e, 0x9d, 0x96, 0xd1, 0xdf, 0xa7, 0x65, 0xf4, 0xd5, 0x59, 0x79, 0xe2, - 0xd9, 0x59, 0x79, 0xe2, 0xcf, 0xb3, 0xf2, 0xc4, 0x67, 0xbb, 0x7e, 0x10, 0x1d, 0xc6, 0xae, 0xe5, - 0xb1, 0x06, 0x51, 0x7f, 0xa6, 0x03, 0xd7, 0x5b, 0xf7, 0x19, 0x69, 0xdf, 0x22, 0x0d, 0x56, 0x8b, - 0xeb, 0x94, 0xcb, 0x3c, 0x1b, 0xd5, 0x75, 0x95, 0x2a, 0x3a, 0x6a, 0x52, 0xee, 0x4e, 0x8b, 0x43, - 0xb6, 0xf5, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6e, 0xea, 0xa4, 0x42, 0xb8, 0x0f, 0x00, 0x00, + // 1051 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0x1b, 0x45, + 0x14, 0xce, 0xa4, 0x69, 0xd4, 0x3e, 0xbb, 0x09, 0x9a, 0x26, 0xa9, 0xbb, 0x8d, 0x1c, 0x67, 0x83, + 0x68, 0x5a, 0x92, 0x9d, 0xc4, 0xa1, 0x49, 0x84, 0x84, 0x04, 0xa9, 0x54, 0xda, 0x4b, 0x29, 0x8b, + 0x10, 0x08, 0x09, 0x45, 0xbb, 0xeb, 0xc9, 0x66, 0x25, 0x7b, 0xc7, 0xf5, 0xec, 0x5a, 0x8a, 0xaa, + 0x5c, 0x7a, 0xe2, 0x06, 0x12, 0x12, 0x57, 0x24, 0x8e, 0x1c, 0x2a, 0x0e, 0x48, 0x5c, 0x39, 0x41, + 0x8e, 0x45, 0x70, 0xe0, 0x44, 0x51, 0xc2, 0x1f, 0x82, 0x3c, 0x33, 0x6b, 0xef, 0xda, 0xe3, 0x7a, + 0x8d, 0x42, 0x6f, 0xbb, 0xef, 0xe7, 0xf7, 0xbe, 0xf7, 0xfc, 0xde, 0x1a, 0xca, 0x81, 0xeb, 0x11, + 0x8f, 0xb5, 0x28, 0xf1, 0xea, 0x01, 0x0d, 0x23, 0xd2, 0xde, 0x24, 0x8f, 0x63, 0xda, 0x3a, 0xb2, + 0x9a, 0x2d, 0x16, 0x31, 0x8c, 0x03, 0xd7, 0xb3, 0x3a, 0x7a, 0x4b, 0xea, 0xad, 0xf6, 0xa6, 0x71, + 0xdb, 0x63, 0xbc, 0xc1, 0x38, 0x71, 0x1d, 0x4e, 0xa5, 0x31, 0x69, 0x6f, 0xba, 0x34, 0x72, 0x36, + 0x49, 0xd3, 0xf1, 0x83, 0xd0, 0x89, 0x02, 0x16, 0x4a, 0x7f, 0x63, 0x49, 0x13, 0x5f, 0x45, 0x92, + 0x06, 0xd7, 0x7d, 0xc6, 0xfc, 0x3a, 0x25, 0xe2, 0xcd, 0x8d, 0x0f, 0x88, 0x13, 0xaa, 0xdc, 0xc6, + 0xa2, 0x52, 0x39, 0xcd, 0x80, 0x38, 0x61, 0xc8, 0x22, 0x11, 0x98, 0x2b, 0xed, 0x9c, 0xcf, 0x7c, + 0x26, 0x1e, 0x49, 0xe7, 0x49, 0x4a, 0xcd, 0x6d, 0xb8, 0xf6, 0x61, 0x07, 0xd1, 0x5d, 0x91, 0xe3, + 0xa3, 0xc8, 0x89, 0xa8, 0x4d, 0x1f, 0xc7, 0x94, 0x47, 0xf8, 0x06, 0x5c, 0x96, 0x99, 0xf7, 0x83, + 0x5a, 0x09, 0x55, 0xd0, 0xea, 0x65, 0xfb, 0x92, 0x14, 0x3c, 0xa8, 0x99, 0xcf, 0x10, 0x94, 0x06, + 0x1d, 0x79, 0x93, 0x85, 0x9c, 0xe2, 0x1d, 0x28, 0x2a, 0x4f, 0xde, 0x91, 0x0b, 0xe7, 0x42, 0x75, + 0xce, 0x92, 0xf8, 0xac, 0x04, 0xba, 0xf5, 0x5e, 0x78, 0x64, 0x17, 0xbc, 0x5e, 0x00, 0x3c, 0x07, + 0x17, 0x9b, 0x2d, 0xc6, 0x0e, 0x4a, 0x93, 0x15, 0xb4, 0x5a, 0xb4, 0xe5, 0x0b, 0xbe, 0x0b, 0x45, + 0xf1, 0xb0, 0x7f, 0x48, 0x03, 0xff, 0x30, 0x2a, 0x5d, 0x10, 0xe1, 0x0c, 0x6b, 0x90, 0x6a, 0xeb, + 0xbe, 0xb0, 0xd8, 0x9b, 0x3a, 0xf9, 0x6b, 0x69, 0xc2, 0x2e, 0x08, 0x2f, 0x29, 0x32, 0xdd, 0x41, + 0xbc, 0x3c, 0xa9, 0xf4, 0x1e, 0x40, 0xaf, 0x11, 0x0a, 0xed, 0x1b, 0x96, 0xec, 0x9a, 0xd5, 0xe9, + 0x9a, 0x25, 0x5b, 0xac, 0xba, 0x66, 0x3d, 0x72, 0xfc, 0x84, 0x25, 0x3b, 0xe5, 0x69, 0xfe, 0x81, + 0xe0, 0xba, 0x26, 0x89, 0x62, 0x25, 0x84, 0x2b, 0x69, 0x56, 0x78, 0x09, 0x55, 0x2e, 0xac, 0x16, + 0xaa, 0xb7, 0x74, 0x75, 0x3c, 0xa8, 0xd1, 0x30, 0x0a, 0x0e, 0x02, 0x5a, 0x4b, 0x85, 0xda, 0x2b, + 0x77, 0xca, 0xfa, 0xfe, 0xc5, 0xd2, 0x82, 0x56, 0xcd, 0xed, 0x62, 0x8a, 0x4b, 0x8e, 0xdf, 0xcf, + 0x54, 0x35, 0x29, 0xaa, 0xba, 0x39, 0xb2, 0x2a, 0x09, 0x36, 0x53, 0xd6, 0x0f, 0x08, 0x0c, 0x59, + 0x56, 0x47, 0x15, 0xf2, 0x98, 0xe7, 0x9e, 0x13, 0x7c, 0x13, 0x66, 0x5b, 0xb4, 0x1d, 0xf0, 0x80, + 0x85, 0xfb, 0x61, 0xdc, 0x70, 0x69, 0x4b, 0x20, 0x99, 0xb2, 0x67, 0x12, 0xf1, 0x43, 0x21, 0xcd, + 0x18, 0xa6, 0xfa, 0x9c, 0x32, 0x94, 0x8d, 0xc4, 0x2b, 0x70, 0xa5, 0xde, 0xa9, 0x2f, 0x4a, 0xcc, + 0xa6, 0x2a, 0x68, 0xf5, 0x92, 0x5d, 0x94, 0x42, 0xd5, 0xed, 0x9f, 0x10, 0xdc, 0xd0, 0x42, 0x56, + 0xbd, 0x78, 0x07, 0x66, 0xbd, 0x44, 0x93, 0x63, 0x48, 0x67, 0xbc, 0x4c, 0x98, 0xff, 0x73, 0x4e, + 0x9f, 0xea, 0x91, 0xf3, 0x5c, 0x6c, 0xdf, 0xd3, 0xb4, 0xfc, 0xbf, 0x0c, 0xf2, 0x2f, 0x08, 0x16, + 0xf5, 0x20, 0x14, 0x7f, 0x9f, 0xc3, 0x6b, 0x7d, 0xfc, 0x25, 0xe3, 0xbc, 0xa6, 0x2b, 0x37, 0x1b, + 0xe6, 0x93, 0x20, 0x3a, 0xcc, 0x10, 0x30, 0x9b, 0xa5, 0xf7, 0x1c, 0x47, 0xf7, 0x0b, 0x04, 0xcb, + 0x9a, 0x42, 0x64, 0xf6, 0x57, 0xcb, 0xe9, 0xaf, 0x08, 0xcc, 0x97, 0x41, 0x51, 0xcc, 0x7e, 0x0a, + 0xd7, 0xfa, 0x98, 0x55, 0xe3, 0x94, 0x10, 0x3c, 0x7a, 0x9e, 0xe6, 0x3d, 0x5d, 0x86, 0xf3, 0x23, + 0x75, 0x67, 0x60, 0x95, 0xc6, 0xb9, 0xa8, 0x34, 0xb7, 0x06, 0xd6, 0x63, 0xdc, 0x2b, 0x7c, 0x01, + 0xa6, 0xb9, 0x90, 0x28, 0x37, 0xf5, 0x66, 0x1a, 0x99, 0x6c, 0x8f, 0x9c, 0x96, 0xd3, 0x48, 0xb2, + 0x99, 0x1f, 0x64, 0x02, 0x26, 0x3a, 0x15, 0xb0, 0x0a, 0xd3, 0x4d, 0x21, 0x51, 0x3f, 0x6d, 0x2d, + 0x71, 0xca, 0x47, 0x59, 0x9a, 0xcb, 0xb0, 0x24, 0x02, 0x7e, 0xdc, 0xf4, 0x5b, 0x4e, 0x2d, 0xb3, + 0x5e, 0x93, 0x9c, 0x75, 0xa8, 0x0c, 0x37, 0x51, 0xa9, 0xef, 0xc3, 0x7c, 0xac, 0xd4, 0xfb, 0xb9, + 0x2f, 0xe1, 0xd5, 0x78, 0x30, 0xa2, 0xf9, 0xba, 0x1a, 0x9a, 0x6e, 0x36, 0xdd, 0x0a, 0x36, 0x63, + 0x58, 0x79, 0xa9, 0x95, 0x82, 0xf5, 0x10, 0x4a, 0x3d, 0x58, 0x63, 0xac, 0xbf, 0x85, 0x58, 0x1b, + 0xb7, 0xfa, 0x5b, 0x11, 0x2e, 0x8a, 0xbc, 0xf8, 0x5b, 0x04, 0x85, 0x14, 0x6c, 0xfc, 0xa6, 0x8e, + 0xeb, 0x21, 0x1f, 0x1a, 0xc6, 0x5a, 0x3e, 0x63, 0x59, 0x84, 0x79, 0xe7, 0xe9, 0xef, 0xff, 0x7c, + 0x3d, 0x49, 0xf0, 0x3a, 0x19, 0xfa, 0xa9, 0xa4, 0x36, 0x12, 0x79, 0xd2, 0x1d, 0xc5, 0x63, 0xfc, + 0x0d, 0x82, 0x62, 0xfa, 0x58, 0xe2, 0x5c, 0x59, 0x93, 0x49, 0x33, 0xd6, 0x73, 0x5a, 0x2b, 0x90, + 0xb7, 0x04, 0xc8, 0x15, 0xbc, 0x3c, 0x12, 0x24, 0x7e, 0x81, 0x60, 0x26, 0xcb, 0x2b, 0xb6, 0x86, + 0x27, 0xd3, 0xb5, 0xdf, 0x20, 0xb9, 0xed, 0x15, 0xbc, 0xba, 0x80, 0x77, 0x80, 0x6b, 0x5a, 0x78, + 0x7d, 0x8b, 0x3d, 0x4d, 0x23, 0x49, 0x8e, 0x31, 0x79, 0xd2, 0x77, 0xd6, 0x8f, 0x89, 0x5c, 0x53, + 0x29, 0x85, 0x14, 0x1c, 0xe3, 0x67, 0x08, 0x66, 0xfb, 0x0e, 0x09, 0xce, 0x0b, 0xb9, 0xdb, 0x80, + 0x8d, 0xfc, 0x0e, 0xaa, 0xc8, 0x5d, 0x51, 0x64, 0x15, 0x6f, 0x8c, 0x5b, 0x24, 0x3e, 0x41, 0x30, + 0xaf, 0xdd, 0xd2, 0xf8, 0x4e, 0x4e, 0x14, 0xd9, 0x03, 0x63, 0x6c, 0x8f, 0xeb, 0xa6, 0x4a, 0x78, + 0x57, 0x94, 0xf0, 0x36, 0xde, 0x1d, 0xbb, 0x4f, 0xea, 0x66, 0xe0, 0xef, 0x32, 0x63, 0x1f, 0xe7, + 0x1b, 0xfb, 0x78, 0xac, 0xb1, 0xef, 0xed, 0xf0, 0xdc, 0xbf, 0xcd, 0x38, 0xcb, 0xf7, 0x97, 0x5d, + 0x90, 0x72, 0x1d, 0x8f, 0x04, 0x99, 0xb9, 0x02, 0x23, 0x41, 0x66, 0xef, 0x82, 0x69, 0x0a, 0x90, + 0x8b, 0xd8, 0xd0, 0x81, 0x94, 0x77, 0x00, 0xff, 0x88, 0xe0, 0xaa, 0x66, 0xc1, 0xe3, 0xad, 0xa1, + 0xa9, 0x86, 0x5f, 0x0c, 0xe3, 0xad, 0xf1, 0x9c, 0x14, 0xcc, 0xaa, 0x80, 0xb9, 0x86, 0x6f, 0xeb, + 0x60, 0x6a, 0xaf, 0x0b, 0xc7, 0x3f, 0x23, 0x58, 0xd0, 0xdf, 0x00, 0xbc, 0x3d, 0x1a, 0x84, 0x76, + 0xb7, 0xec, 0x8c, 0xed, 0x97, 0x67, 0x16, 0x86, 0x9d, 0x21, 0xbe, 0x67, 0x9f, 0x9c, 0x96, 0xd1, + 0xf3, 0xd3, 0x32, 0xfa, 0xfb, 0xb4, 0x8c, 0xbe, 0x3a, 0x2b, 0x4f, 0x3c, 0x3f, 0x2b, 0x4f, 0xfc, + 0x79, 0x56, 0x9e, 0xf8, 0x6c, 0xd7, 0x0f, 0xa2, 0xc3, 0xd8, 0xb5, 0x3c, 0xd6, 0x20, 0xea, 0x1f, + 0x75, 0xe0, 0x7a, 0xeb, 0x3e, 0x23, 0xed, 0x1d, 0xd2, 0x60, 0xb5, 0xb8, 0x4e, 0xb9, 0xcc, 0xb3, + 0x51, 0x5d, 0x57, 0xa9, 0xa2, 0xa3, 0x26, 0xe5, 0xee, 0xb4, 0xb8, 0x66, 0x5b, 0xff, 0x06, 0x00, + 0x00, 0xff, 0xff, 0xd5, 0xf9, 0x22, 0x36, 0xbd, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1079,7 +1079,7 @@ type QueryClient interface { ConsensusStateHeights(ctx context.Context, in *QueryConsensusStateHeightsRequest, opts ...grpc.CallOption) (*QueryConsensusStateHeightsResponse, error) // Status queries the status of an IBC client. ClientStatus(ctx context.Context, in *QueryClientStatusRequest, opts ...grpc.CallOption) (*QueryClientStatusResponse, error) - // ClientParams queries all parameters of the ibc client. + // ClientParams queries all parameters of the ibc client submodule. ClientParams(ctx context.Context, in *QueryClientParamsRequest, opts ...grpc.CallOption) (*QueryClientParamsResponse, error) // UpgradedClientState queries an Upgraded IBC light client. UpgradedClientState(ctx context.Context, in *QueryUpgradedClientStateRequest, opts ...grpc.CallOption) (*QueryUpgradedClientStateResponse, error) @@ -1192,7 +1192,7 @@ type QueryServer interface { ConsensusStateHeights(context.Context, *QueryConsensusStateHeightsRequest) (*QueryConsensusStateHeightsResponse, error) // Status queries the status of an IBC client. ClientStatus(context.Context, *QueryClientStatusRequest) (*QueryClientStatusResponse, error) - // ClientParams queries all parameters of the ibc client. + // ClientParams queries all parameters of the ibc client submodule. ClientParams(context.Context, *QueryClientParamsRequest) (*QueryClientParamsResponse, error) // UpgradedClientState queries an Upgraded IBC light client. UpgradedClientState(context.Context, *QueryUpgradedClientStateRequest) (*QueryUpgradedClientStateResponse, error) diff --git a/modules/core/02-client/types/query.pb.gw.go b/modules/core/02-client/types/query.pb.gw.go index 4286cc772ae..1e0e41f2579 100644 --- a/modules/core/02-client/types/query.pb.gw.go +++ b/modules/core/02-client/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join func request_Query_ClientState_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryClientStateRequest @@ -492,12 +494,14 @@ func local_request_Query_UpgradedConsensusState_0(ctx context.Context, marshaler // 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. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_ClientState_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 { @@ -505,6 +509,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ClientState_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) @@ -518,6 +523,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ClientStates_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 { @@ -525,6 +532,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ClientStates_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) @@ -538,6 +546,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ConsensusState_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 { @@ -545,6 +555,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ConsensusState_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) @@ -558,6 +569,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ConsensusStates_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 { @@ -565,6 +578,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ConsensusStates_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) @@ -578,6 +592,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ConsensusStateHeights_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 { @@ -585,6 +601,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ConsensusStateHeights_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) @@ -598,6 +615,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ClientStatus_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 { @@ -605,6 +624,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ClientStatus_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) @@ -618,6 +638,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ClientParams_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 { @@ -625,6 +647,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ClientParams_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) @@ -638,6 +661,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_UpgradedClientState_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 { @@ -645,6 +670,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_UpgradedClientState_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) @@ -658,6 +684,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_UpgradedConsensusState_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 { @@ -665,6 +693,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_UpgradedConsensusState_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) @@ -900,23 +929,23 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_ClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1", "client_states", "client_id"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1", "client_states", "client_id"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ClientStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1", "client_states"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ClientStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1", "client_states"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "client", "v1", "consensus_states", "client_id", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "client", "v1", "consensus_states", "client_id", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ConsensusStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1", "consensus_states", "client_id"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConsensusStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1", "consensus_states", "client_id"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ConsensusStateHeights_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"ibc", "core", "client", "v1", "consensus_states", "client_id", "heights"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConsensusStateHeights_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"ibc", "core", "client", "v1", "consensus_states", "client_id", "heights"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ClientStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1", "client_status", "client_id"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ClientStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1", "client_status", "client_id"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ClientParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ibc", "client", "v1", "params"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ClientParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_UpgradedClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1", "upgraded_client_states"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UpgradedClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1", "upgraded_client_states"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_UpgradedConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1", "upgraded_consensus_states"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UpgradedConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1", "upgraded_consensus_states"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/modules/core/02-client/types/tx.pb.go b/modules/core/02-client/types/tx.pb.go index 1ed94c0c49b..ce17ca96ad7 100644 --- a/modules/core/02-client/types/tx.pb.go +++ b/modules/core/02-client/types/tx.pb.go @@ -7,9 +7,9 @@ import ( context "context" fmt "fmt" types "github.com/cosmos/cosmos-sdk/codec/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -111,12 +111,12 @@ func (m *MsgCreateClientResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCreateClientResponse proto.InternalMessageInfo // MsgUpdateClient defines an sdk.Msg to update a IBC client state using -// the given header. +// the given client message. type MsgUpdateClient struct { // client unique identifier ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` - // header to update the light client - Header *types.Any `protobuf:"bytes,2,opt,name=header,proto3" json:"header,omitempty"` + // client message to update the light client + ClientMessage *types.Any `protobuf:"bytes,2,opt,name=client_message,json=clientMessage,proto3" json:"client_message,omitempty"` // signer address Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` } @@ -281,13 +281,14 @@ var xxx_messageInfo_MsgUpgradeClientResponse proto.InternalMessageInfo // MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for // light client misbehaviour. +// Warning: DEPRECATED type MsgSubmitMisbehaviour struct { // client unique identifier - ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` // Deprecated: Do not use. // misbehaviour used for freezing the light client - Misbehaviour *types.Any `protobuf:"bytes,2,opt,name=misbehaviour,proto3" json:"misbehaviour,omitempty"` + Misbehaviour *types.Any `protobuf:"bytes,2,opt,name=misbehaviour,proto3" json:"misbehaviour,omitempty"` // Deprecated: Do not use. // signer address - Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` // Deprecated: Do not use. } func (m *MsgSubmitMisbehaviour) Reset() { *m = MsgSubmitMisbehaviour{} } @@ -375,45 +376,46 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/tx.proto", fileDescriptor_cb5dc4651eb49a04) } var fileDescriptor_cb5dc4651eb49a04 = []byte{ - // 602 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x3f, 0x6f, 0xd3, 0x4e, - 0x18, 0x8e, 0x9b, 0xdf, 0x2f, 0x6a, 0xae, 0x81, 0x56, 0x26, 0xb4, 0xa9, 0xab, 0xda, 0x91, 0xe9, - 0x10, 0x44, 0x7b, 0x47, 0x02, 0x43, 0xd5, 0x8d, 0x74, 0x62, 0x88, 0x04, 0xae, 0x18, 0x60, 0x09, - 0xfe, 0x73, 0xbd, 0x9c, 0x88, 0x7d, 0x91, 0xcf, 0x8e, 0xc8, 0x37, 0x60, 0x64, 0xe0, 0x03, 0x54, - 0x0c, 0x7c, 0x16, 0xc6, 0x0e, 0x0c, 0x4c, 0x51, 0x95, 0x2c, 0xcc, 0xf9, 0x04, 0x28, 0x3e, 0x27, - 0xc4, 0x6e, 0x1c, 0x45, 0xfc, 0xd9, 0x7c, 0x7e, 0x9f, 0x7b, 0x9e, 0xf7, 0xf1, 0xf3, 0x9e, 0x0f, - 0x1c, 0x50, 0xcb, 0x46, 0x36, 0xf3, 0x31, 0xb2, 0xbb, 0x14, 0x7b, 0x01, 0xea, 0xd7, 0x51, 0xf0, - 0x1e, 0xf6, 0x7c, 0x16, 0x30, 0x59, 0xa6, 0x96, 0x0d, 0xa7, 0x45, 0x28, 0x8a, 0xb0, 0x5f, 0x57, - 0xca, 0x84, 0x11, 0x16, 0x95, 0xd1, 0xf4, 0x49, 0x20, 0x95, 0x7d, 0xc2, 0x18, 0xe9, 0x62, 0x14, - 0xad, 0xac, 0xf0, 0x12, 0x99, 0xde, 0x40, 0x94, 0xf4, 0x1b, 0x09, 0x6c, 0xb7, 0x38, 0x39, 0xf7, - 0xb1, 0x19, 0xe0, 0xf3, 0x88, 0x47, 0x7e, 0x01, 0x4a, 0x82, 0xb1, 0xcd, 0x03, 0x33, 0xc0, 0x15, - 0xa9, 0x2a, 0xd5, 0xb6, 0x1a, 0x65, 0x28, 0x58, 0xe0, 0x8c, 0x05, 0x3e, 0xf3, 0x06, 0xcd, 0xbd, - 0xc9, 0x50, 0xbb, 0x37, 0x30, 0xdd, 0xee, 0x99, 0xbe, 0xb8, 0x47, 0x37, 0xb6, 0xc4, 0xf2, 0x62, - 0xba, 0x92, 0x5f, 0x83, 0x6d, 0x9b, 0x79, 0x1c, 0x7b, 0x3c, 0xe4, 0x31, 0xe9, 0xc6, 0x0a, 0x52, - 0x65, 0x32, 0xd4, 0x76, 0x63, 0xd2, 0xe4, 0x36, 0xdd, 0xb8, 0x3b, 0x7f, 0x23, 0xa8, 0x77, 0x41, - 0x81, 0x53, 0xe2, 0x61, 0xbf, 0x92, 0xaf, 0x4a, 0xb5, 0xa2, 0x11, 0xaf, 0xce, 0x36, 0x3f, 0x5c, - 0x69, 0xb9, 0x1f, 0x57, 0x5a, 0x4e, 0xdf, 0x07, 0x7b, 0x29, 0x87, 0x06, 0xe6, 0xbd, 0x29, 0x8b, - 0xfe, 0x49, 0xb8, 0x7f, 0xd5, 0x73, 0x7e, 0xb9, 0xaf, 0x83, 0x62, 0xec, 0x84, 0x3a, 0x91, 0xf5, - 0x62, 0xb3, 0x3c, 0x19, 0x6a, 0x3b, 0x09, 0x93, 0xd4, 0xd1, 0x8d, 0x4d, 0xf1, 0xfc, 0xdc, 0x91, - 0x8f, 0x41, 0xa1, 0x83, 0x4d, 0x07, 0xfb, 0xab, 0x5c, 0x19, 0x31, 0x66, 0xed, 0x8e, 0x17, 0xbb, - 0x9a, 0x77, 0xfc, 0x2d, 0x0f, 0x76, 0xa2, 0x1a, 0xf1, 0x4d, 0xe7, 0x0f, 0x5a, 0x4e, 0x67, 0xbc, - 0xf1, 0x2f, 0x32, 0xce, 0xff, 0xa5, 0x8c, 0x5f, 0x82, 0x72, 0xcf, 0x67, 0xec, 0xb2, 0x1d, 0x0a, - 0xdb, 0x6d, 0xa1, 0x5b, 0xf9, 0xaf, 0x2a, 0xd5, 0x4a, 0x4d, 0x6d, 0x32, 0xd4, 0x0e, 0x04, 0xd3, - 0x32, 0x94, 0x6e, 0xc8, 0xd1, 0xeb, 0xe4, 0x27, 0x7b, 0x07, 0x0e, 0x53, 0xe0, 0x54, 0xef, 0xff, - 0x47, 0xdc, 0xb5, 0xc9, 0x50, 0x3b, 0x5a, 0xca, 0x9d, 0xee, 0x59, 0x49, 0x88, 0x64, 0xcd, 0x68, - 0x21, 0x23, 0x71, 0x05, 0x54, 0xd2, 0xa9, 0xce, 0x23, 0xff, 0x22, 0x81, 0xfb, 0x2d, 0x4e, 0x2e, - 0x42, 0xcb, 0xa5, 0x41, 0x8b, 0x72, 0x0b, 0x77, 0xcc, 0x3e, 0x65, 0xa1, 0xff, 0x3b, 0xb9, 0x9f, - 0x82, 0x92, 0xbb, 0x40, 0xb1, 0x72, 0x60, 0x13, 0xc8, 0x35, 0xc6, 0x56, 0x03, 0x87, 0x4b, 0xfb, - 0x9c, 0x39, 0x69, 0x7c, 0xce, 0x83, 0x7c, 0x8b, 0x13, 0xf9, 0x2d, 0x28, 0x25, 0x7e, 0x38, 0x0f, - 0xe0, 0xed, 0x5f, 0x19, 0x4c, 0x9d, 0x59, 0xe5, 0xd1, 0x1a, 0xa0, 0x99, 0xd2, 0x54, 0x21, 0x71, - 0xa8, 0xb3, 0x14, 0x16, 0x41, 0x99, 0x0a, 0xcb, 0x0e, 0xa2, 0x6c, 0x83, 0x3b, 0xc9, 0x89, 0x3a, - 0xca, 0xdc, 0xbd, 0x80, 0x52, 0x8e, 0xd7, 0x41, 0xcd, 0x45, 0x7c, 0x20, 0x2f, 0x89, 0xfd, 0x61, - 0x06, 0xc7, 0x6d, 0xa8, 0x52, 0x5f, 0x1b, 0x3a, 0xd3, 0x6c, 0x1a, 0x5f, 0x47, 0xaa, 0x74, 0x3d, - 0x52, 0xa5, 0x9b, 0x91, 0x2a, 0x7d, 0x1c, 0xab, 0xb9, 0xeb, 0xb1, 0x9a, 0xfb, 0x3e, 0x56, 0x73, - 0x6f, 0x4e, 0x09, 0x0d, 0x3a, 0xa1, 0x05, 0x6d, 0xe6, 0x22, 0x9b, 0x71, 0x97, 0x71, 0x44, 0x2d, - 0xfb, 0x84, 0x30, 0xd4, 0x7f, 0x8a, 0x5c, 0xe6, 0x84, 0x5d, 0xcc, 0xc5, 0x6d, 0xf5, 0xb8, 0x71, - 0x12, 0x5f, 0x58, 0xc1, 0xa0, 0x87, 0xb9, 0x55, 0x88, 0xe6, 0xea, 0xc9, 0xcf, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x48, 0x1a, 0x96, 0xf0, 0xd0, 0x06, 0x00, 0x00, + // 623 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6e, 0xd3, 0x4c, + 0x14, 0x8d, 0x9b, 0xef, 0x8b, 0x9a, 0x69, 0xfa, 0x23, 0x13, 0x52, 0xd7, 0x55, 0xed, 0xc8, 0x74, + 0x11, 0x04, 0xb5, 0x49, 0xba, 0x00, 0x15, 0x36, 0xa4, 0x2b, 0x16, 0x91, 0xc0, 0x15, 0x0b, 0xd8, + 0x04, 0xff, 0x4c, 0xa7, 0x23, 0x62, 0x4f, 0xe4, 0xb1, 0x23, 0xf2, 0x06, 0x2c, 0x79, 0x84, 0x0a, + 0x5e, 0x80, 0xc7, 0x60, 0xd9, 0x05, 0x0b, 0x56, 0x51, 0x95, 0x6c, 0x58, 0xe7, 0x09, 0x50, 0x3c, + 0x4e, 0xb0, 0x1d, 0x3b, 0x8a, 0x04, 0xec, 0x3c, 0x73, 0xcf, 0x9c, 0x73, 0x8f, 0xcf, 0x1d, 0x1b, + 0x1c, 0x62, 0xd3, 0xd2, 0x2c, 0xe2, 0x41, 0xcd, 0xea, 0x61, 0xe8, 0xfa, 0xda, 0xa0, 0xa9, 0xf9, + 0x1f, 0xd4, 0xbe, 0x47, 0x7c, 0xc2, 0xf3, 0xd8, 0xb4, 0xd4, 0x59, 0x51, 0x65, 0x45, 0x75, 0xd0, + 0x14, 0xab, 0x88, 0x20, 0x12, 0x96, 0xb5, 0xd9, 0x13, 0x43, 0x8a, 0x07, 0x88, 0x10, 0xd4, 0x83, + 0x5a, 0xb8, 0x32, 0x83, 0x4b, 0xcd, 0x70, 0x87, 0xac, 0xa4, 0xdc, 0x72, 0x60, 0xb7, 0x43, 0xd1, + 0xb9, 0x07, 0x0d, 0x1f, 0x9e, 0x87, 0x3c, 0xfc, 0x4b, 0x50, 0x61, 0x8c, 0x5d, 0xea, 0x1b, 0x3e, + 0x14, 0xb8, 0x3a, 0xd7, 0xd8, 0x6a, 0x55, 0x55, 0xc6, 0xa2, 0xce, 0x59, 0xd4, 0xe7, 0xee, 0xb0, + 0xbd, 0x3f, 0x1d, 0xc9, 0x77, 0x86, 0x86, 0xd3, 0x3b, 0x53, 0xe2, 0x67, 0x14, 0x7d, 0x8b, 0x2d, + 0x2f, 0x66, 0x2b, 0xfe, 0x0d, 0xd8, 0xb5, 0x88, 0x4b, 0xa1, 0x4b, 0x03, 0x1a, 0x91, 0x6e, 0xac, + 0x20, 0x15, 0xa7, 0x23, 0xb9, 0x16, 0x91, 0x26, 0x8f, 0x29, 0xfa, 0xce, 0x62, 0x87, 0x51, 0xd7, + 0x40, 0x89, 0x62, 0xe4, 0x42, 0x4f, 0x28, 0xd6, 0xb9, 0x46, 0x59, 0x8f, 0x56, 0x67, 0x9b, 0x1f, + 0xaf, 0xe5, 0xc2, 0xcf, 0x6b, 0xb9, 0xa0, 0x1c, 0x80, 0xfd, 0x94, 0x43, 0x1d, 0xd2, 0xfe, 0x8c, + 0x45, 0xf9, 0xc2, 0xdc, 0xbf, 0xee, 0xdb, 0xbf, 0xdd, 0x37, 0x41, 0x39, 0x72, 0x82, 0xed, 0xd0, + 0x7a, 0xb9, 0x5d, 0x9d, 0x8e, 0xe4, 0xbd, 0x84, 0x49, 0x6c, 0x2b, 0xfa, 0x26, 0x7b, 0x7e, 0x61, + 0xf3, 0x4f, 0xc1, 0x4e, 0xb4, 0xef, 0x40, 0x4a, 0x0d, 0xb4, 0xd2, 0x9d, 0xbe, 0xcd, 0xb0, 0x1d, + 0x06, 0x5d, 0xdb, 0x40, 0xbc, 0xc9, 0x85, 0x81, 0xef, 0x45, 0xb0, 0x17, 0xd6, 0x90, 0x67, 0xd8, + 0x7f, 0xe0, 0x20, 0x1d, 0xf9, 0xc6, 0xbf, 0x88, 0xbc, 0xf8, 0x97, 0x22, 0x7f, 0x05, 0xaa, 0x7d, + 0x8f, 0x90, 0xcb, 0x6e, 0xc0, 0x6c, 0x77, 0x99, 0xae, 0xf0, 0x5f, 0x9d, 0x6b, 0x54, 0xda, 0xf2, + 0x74, 0x24, 0x1f, 0x32, 0xa6, 0x2c, 0x94, 0xa2, 0xf3, 0xe1, 0x76, 0xf2, 0x95, 0xbd, 0x07, 0x47, + 0x29, 0x70, 0xaa, 0xf7, 0xff, 0x43, 0xee, 0xc6, 0x74, 0x24, 0x1f, 0x67, 0x72, 0xa7, 0x7b, 0x16, + 0x13, 0x22, 0x79, 0x23, 0x5b, 0xca, 0x49, 0x5c, 0x04, 0x42, 0x3a, 0xd5, 0x45, 0xe4, 0x5f, 0x39, + 0x70, 0xb7, 0x43, 0xd1, 0x45, 0x60, 0x3a, 0xd8, 0xef, 0x60, 0x6a, 0xc2, 0x2b, 0x63, 0x80, 0x49, + 0xe0, 0xf1, 0xa7, 0xcb, 0xb9, 0xd7, 0xb2, 0x72, 0x17, 0xb8, 0x58, 0xf2, 0xcf, 0x40, 0xc5, 0x89, + 0x91, 0xac, 0x4c, 0x7e, 0x43, 0xe0, 0xf4, 0x04, 0x9a, 0x17, 0x93, 0xc3, 0x1b, 0x22, 0x96, 0xed, + 0xc8, 0xe0, 0x28, 0xb3, 0xe3, 0xb9, 0xa7, 0xd6, 0xe7, 0x22, 0x28, 0x76, 0x28, 0xe2, 0xdf, 0x81, + 0x4a, 0xe2, 0x4b, 0x74, 0x4f, 0x5d, 0xfe, 0xc6, 0xa9, 0xa9, 0xcb, 0x2c, 0x3e, 0x58, 0x03, 0x34, + 0x57, 0x9a, 0x29, 0x24, 0x6e, 0x7b, 0x9e, 0x42, 0x1c, 0x94, 0xab, 0x90, 0x75, 0x25, 0x79, 0x0b, + 0x6c, 0x27, 0x67, 0xeb, 0x38, 0xf7, 0x74, 0x0c, 0x25, 0x3e, 0x5c, 0x07, 0xb5, 0x10, 0xf1, 0x00, + 0x9f, 0x31, 0x00, 0xf7, 0x73, 0x38, 0x96, 0xa1, 0x62, 0x73, 0x6d, 0xe8, 0x5c, 0xb3, 0xad, 0x7f, + 0x1b, 0x4b, 0xdc, 0xcd, 0x58, 0xe2, 0x6e, 0xc7, 0x12, 0xf7, 0x69, 0x22, 0x15, 0x6e, 0x26, 0x52, + 0xe1, 0xc7, 0x44, 0x2a, 0xbc, 0x7d, 0x82, 0xb0, 0x7f, 0x15, 0x98, 0xaa, 0x45, 0x1c, 0xcd, 0x22, + 0xd4, 0x21, 0x54, 0xc3, 0xa6, 0x75, 0x82, 0x88, 0x36, 0x78, 0xac, 0x39, 0xc4, 0x0e, 0x7a, 0x90, + 0xb2, 0xdf, 0xd8, 0xa3, 0xd6, 0x49, 0xf4, 0x27, 0xf3, 0x87, 0x7d, 0x48, 0xcd, 0x52, 0x38, 0x5f, + 0xa7, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x8f, 0x23, 0x99, 0xe9, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -716,9 +718,9 @@ func (m *MsgUpdateClient) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - if m.Header != nil { + if m.ClientMessage != nil { { - size, err := m.Header.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ClientMessage.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -982,8 +984,8 @@ func (m *MsgUpdateClient) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - if m.Header != nil { - l = m.Header.Size() + if m.ClientMessage != nil { + l = m.ClientMessage.Size() n += 1 + l + sovTx(uint64(l)) } l = len(m.Signer) @@ -1347,7 +1349,7 @@ func (m *MsgUpdateClient) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ClientMessage", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1374,10 +1376,10 @@ func (m *MsgUpdateClient) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Header == nil { - m.Header = &types.Any{} + if m.ClientMessage == nil { + m.ClientMessage = &types.Any{} } - if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ClientMessage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/modules/core/03-connection/client/cli/cli.go b/modules/core/03-connection/client/cli/cli.go index d4972654569..aba7df4d967 100644 --- a/modules/core/03-connection/client/cli/cli.go +++ b/modules/core/03-connection/client/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) // GetQueryCmd returns the query commands for IBC connections @@ -19,6 +19,7 @@ func GetQueryCmd() *cobra.Command { GetCmdQueryConnections(), GetCmdQueryConnection(), GetCmdQueryClientConnections(), + GetCmdConnectionParams(), ) return queryCmd diff --git a/modules/core/03-connection/client/cli/query.go b/modules/core/03-connection/client/cli/query.go index 310e21bef82..e0d6d917d5b 100644 --- a/modules/core/03-connection/client/cli/query.go +++ b/modules/core/03-connection/client/cli/query.go @@ -8,9 +8,9 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/client/utils" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/client/utils" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // GetCmdQueryConnections defines the command to query all the connection ends @@ -20,7 +20,7 @@ func GetCmdQueryConnections() *cobra.Command { Use: "connections", Short: "Query all connections", Long: "Query all connections ends from a chain", - Example: fmt.Sprintf("%s query %s %s connections", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s connections", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -59,7 +59,7 @@ func GetCmdQueryConnection() *cobra.Command { Use: "end [connection-id]", Short: "Query stored connection end", Long: "Query stored connection end", - Example: fmt.Sprintf("%s query %s %s end [connection-id]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s end [connection-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -91,7 +91,7 @@ func GetCmdQueryClientConnections() *cobra.Command { Use: "path [client-id]", Short: "Query stored client connection paths", Long: "Query stored client connection paths", - Example: fmt.Sprintf("%s query %s %s path [client-id]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s path [client-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -116,3 +116,28 @@ func GetCmdQueryClientConnections() *cobra.Command { return cmd } + +// GetCmdConnectionParams returns the command handler for ibc connection parameter querying. +func GetCmdConnectionParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query the current ibc connection parameters", + Long: "Query the current ibc connection parameters", + Args: cobra.NoArgs, + Example: fmt.Sprintf("%s query %s %s params", version.AppName, ibcexported.ModuleName, types.SubModuleName), + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, _ := queryClient.ConnectionParams(cmd.Context(), &types.QueryConnectionParamsRequest{}) + return clientCtx.PrintProto(res.Params) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/modules/core/03-connection/client/utils/utils.go b/modules/core/03-connection/client/utils/utils.go index bb1b8f7f1c5..a7cab07d6bf 100644 --- a/modules/core/03-connection/client/utils/utils.go +++ b/modules/core/03-connection/client/utils/utils.go @@ -4,19 +4,19 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - clientutils "github.com/cosmos/ibc-go/v4/modules/core/02-client/client/utils" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/client" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + + clientutils "github.com/cosmos/ibc-go/v7/modules/core/02-client/client/utils" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/client" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // QueryConnection returns a connection end. @@ -47,7 +47,7 @@ func queryConnectionABCI(clientCtx client.Context, connectionID string) (*types. // check if connection exists if len(value) == 0 { - return nil, sdkerrors.Wrap(types.ErrConnectionNotFound, connectionID) + return nil, errorsmod.Wrap(types.ErrConnectionNotFound, connectionID) } cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) @@ -88,7 +88,7 @@ func queryClientConnectionsABCI(clientCtx client.Context, clientID string) (*typ // check if connection paths exist if len(value) == 0 { - return nil, sdkerrors.Wrap(types.ErrClientConnectionPathsNotFound, clientID) + return nil, errorsmod.Wrap(types.ErrClientConnectionPathsNotFound, clientID) } var paths []string @@ -169,7 +169,7 @@ func ParseClientState(cdc *codec.LegacyAmino, arg string) (exported.ClientState, var clientState exported.ClientState if err := cdc.UnmarshalJSON([]byte(arg), &clientState); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(arg) + contents, err := os.ReadFile(arg) if err != nil { return nil, errors.New("either JSON input nor path to .json file were provided") } @@ -186,7 +186,7 @@ func ParsePrefix(cdc *codec.LegacyAmino, arg string) (commitmenttypes.MerklePref var prefix commitmenttypes.MerklePrefix if err := cdc.UnmarshalJSON([]byte(arg), &prefix); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(arg) + contents, err := os.ReadFile(arg) if err != nil { return commitmenttypes.MerklePrefix{}, errors.New("neither JSON input nor path to .json file were provided") } @@ -204,7 +204,7 @@ func ParseProof(cdc *codec.LegacyAmino, arg string) ([]byte, error) { var merkleProof commitmenttypes.MerkleProof if err := cdc.UnmarshalJSON([]byte(arg), &merkleProof); err != nil { // check for file path if JSON input is not provided - contents, err := ioutil.ReadFile(arg) + contents, err := os.ReadFile(arg) if err != nil { return nil, errors.New("neither JSON input nor path to .json file were provided") } diff --git a/modules/core/03-connection/doc.go b/modules/core/03-connection/doc.go new file mode 100644 index 00000000000..9f89e3bbf67 --- /dev/null +++ b/modules/core/03-connection/doc.go @@ -0,0 +1,12 @@ +/* +Package connection implements the ICS 03 - Connection Semantics specification +(https://github.com/cosmos/ibc/tree/main/spec/core/ics-003-connection-semantics). This +concrete implementation defines types and methods for safely creating two +stateful objects (connection ends) on two separate chains, each associated with a +light client of the other chain, which together facilitate cross-chain +sub-state verification and packet association (through channels). + +The main type is ConnectionEnd, which defines a stateful object on a +chain connected to another. +*/ +package connection diff --git a/modules/core/03-connection/genesis.go b/modules/core/03-connection/genesis.go index b0070d79197..44a8585bcdb 100644 --- a/modules/core/03-connection/genesis.go +++ b/modules/core/03-connection/genesis.go @@ -3,8 +3,8 @@ package connection import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/keeper" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/keeper" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) // InitGenesis initializes the ibc connection submodule's state from a provided genesis diff --git a/modules/core/03-connection/keeper/events.go b/modules/core/03-connection/keeper/events.go index ac6cae539e3..e9e5a575990 100644 --- a/modules/core/03-connection/keeper/events.go +++ b/modules/core/03-connection/keeper/events.go @@ -3,11 +3,11 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) -// EmitConnectionOpenInitEvent emits a connection open init event -func EmitConnectionOpenInitEvent(ctx sdk.Context, connectionID string, clientID string, counterparty types.Counterparty) { +// emitConnectionOpenInitEvent emits a connection open init event +func emitConnectionOpenInitEvent(ctx sdk.Context, connectionID string, clientID string, counterparty types.Counterparty) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeConnectionOpenInit, @@ -23,8 +23,8 @@ func EmitConnectionOpenInitEvent(ctx sdk.Context, connectionID string, clientID }) } -// EmitConnectionOpenTryEvent emits a connection open try event -func EmitConnectionOpenTryEvent(ctx sdk.Context, connectionID string, clientID string, counterparty types.Counterparty) { +// emitConnectionOpenTryEvent emits a connection open try event +func emitConnectionOpenTryEvent(ctx sdk.Context, connectionID string, clientID string, counterparty types.Counterparty) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeConnectionOpenTry, @@ -40,8 +40,8 @@ func EmitConnectionOpenTryEvent(ctx sdk.Context, connectionID string, clientID s }) } -// EmitConnectionOpenAckEvent emits a connection open acknowledge event -func EmitConnectionOpenAckEvent(ctx sdk.Context, connectionID string, connectionEnd types.ConnectionEnd) { +// emitConnectionOpenAckEvent emits a connection open acknowledge event +func emitConnectionOpenAckEvent(ctx sdk.Context, connectionID string, connectionEnd types.ConnectionEnd) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeConnectionOpenAck, @@ -57,8 +57,8 @@ func EmitConnectionOpenAckEvent(ctx sdk.Context, connectionID string, connection }) } -// EmitConnectionOpenConfirmEvent emits a connection open confirm event -func EmitConnectionOpenConfirmEvent(ctx sdk.Context, connectionID string, connectionEnd types.ConnectionEnd) { +// emitConnectionOpenConfirmEvent emits a connection open confirm event +func emitConnectionOpenConfirmEvent(ctx sdk.Context, connectionID string, connectionEnd types.ConnectionEnd) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeConnectionOpenConfirm, diff --git a/modules/core/03-connection/keeper/grpc_query.go b/modules/core/03-connection/keeper/grpc_query.go index d07616163f6..c2a0afb2bf5 100644 --- a/modules/core/03-connection/keeper/grpc_query.go +++ b/modules/core/03-connection/keeper/grpc_query.go @@ -3,16 +3,16 @@ package keeper import ( "context" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) var _ types.QueryServer = Keeper{} @@ -32,7 +32,7 @@ func (q Keeper) Connection(c context.Context, req *types.QueryConnectionRequest) if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrap(types.ErrConnectionNotFound, req.ConnectionId).Error(), + errorsmod.Wrap(types.ErrConnectionNotFound, req.ConnectionId).Error(), ) } @@ -94,7 +94,7 @@ func (q Keeper) ClientConnections(c context.Context, req *types.QueryClientConne if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrap(types.ErrClientConnectionPathsNotFound, req.ClientId).Error(), + errorsmod.Wrap(types.ErrClientConnectionPathsNotFound, req.ClientId).Error(), ) } @@ -120,7 +120,7 @@ func (q Keeper) ConnectionClientState(c context.Context, req *types.QueryConnect if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(types.ErrConnectionNotFound, "connection-id: %s", req.ConnectionId).Error(), + errorsmod.Wrapf(types.ErrConnectionNotFound, "connection-id: %s", req.ConnectionId).Error(), ) } @@ -128,7 +128,7 @@ func (q Keeper) ConnectionClientState(c context.Context, req *types.QueryConnect if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(clienttypes.ErrClientNotFound, "client-id: %s", connection.ClientId).Error(), + errorsmod.Wrapf(clienttypes.ErrClientNotFound, "client-id: %s", connection.ClientId).Error(), ) } @@ -154,7 +154,7 @@ func (q Keeper) ConnectionConsensusState(c context.Context, req *types.QueryConn if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(types.ErrConnectionNotFound, "connection-id: %s", req.ConnectionId).Error(), + errorsmod.Wrapf(types.ErrConnectionNotFound, "connection-id: %s", req.ConnectionId).Error(), ) } @@ -163,7 +163,7 @@ func (q Keeper) ConnectionConsensusState(c context.Context, req *types.QueryConn if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(clienttypes.ErrConsensusStateNotFound, "client-id: %s", connection.ClientId).Error(), + errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "client-id: %s", connection.ClientId).Error(), ) } @@ -175,3 +175,13 @@ func (q Keeper) ConnectionConsensusState(c context.Context, req *types.QueryConn proofHeight := clienttypes.GetSelfHeight(ctx) return types.NewQueryConnectionConsensusStateResponse(connection.ClientId, anyConsensusState, height, nil, proofHeight), nil } + +// ConnectionParams implements the Query/ConnectionParams gRPC method. +func (q Keeper) ConnectionParams(c context.Context, req *types.QueryConnectionParamsRequest) (*types.QueryConnectionParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + params := q.GetParams(ctx) + + return &types.QueryConnectionParamsResponse{ + Params: ¶ms, + }, nil +} diff --git a/modules/core/03-connection/keeper/grpc_query_test.go b/modules/core/03-connection/keeper/grpc_query_test.go index b1ffb50b910..dd9531fb43e 100644 --- a/modules/core/03-connection/keeper/grpc_query_test.go +++ b/modules/core/03-connection/keeper/grpc_query_test.go @@ -6,10 +6,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *KeeperTestSuite) TestQueryConnection() { @@ -440,3 +440,10 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { }) } } + +func (suite *KeeperTestSuite) TestQueryConnectionParams() { + ctx := sdk.WrapSDKContext(suite.chainA.GetContext()) + expParams := types.DefaultParams() + res, _ := suite.chainA.QueryServer.ConnectionParams(ctx, &types.QueryConnectionParamsRequest{}) + suite.Require().Equal(&expParams, res.Params) +} diff --git a/modules/core/03-connection/keeper/handshake.go b/modules/core/03-connection/keeper/handshake.go index faca5c0f74c..602547c7781 100644 --- a/modules/core/03-connection/keeper/handshake.go +++ b/modules/core/03-connection/keeper/handshake.go @@ -1,14 +1,15 @@ package keeper import ( + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // ConnOpenInit initialises a connection attempt on chain A. The generated connection identifier @@ -26,28 +27,28 @@ func (k Keeper) ConnOpenInit( versions := types.GetCompatibleVersions() if version != nil { if !types.IsSupportedVersion(types.GetCompatibleVersions(), version) { - return "", sdkerrors.Wrap(types.ErrInvalidVersion, "version is not supported") + return "", errorsmod.Wrap(types.ErrInvalidVersion, "version is not supported") } versions = []exported.Version{version} } - // connection defines chain A's ConnectionEnd connectionID := k.GenerateConnectionIdentifier(ctx) - connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.ExportedVersionsToProto(versions), delayPeriod) - k.SetConnection(ctx, connectionID, connection) - if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { return "", err } + // connection defines chain A's ConnectionEnd + connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.ExportedVersionsToProto(versions), delayPeriod) + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", "NONE", "new-state", "INIT") defer func() { telemetry.IncrCounter(1, "ibc", "connection", "open-init") }() - EmitConnectionOpenInitEvent(ctx, connectionID, clientID, counterparty) + emitConnectionOpenInitEvent(ctx, connectionID, clientID, counterparty) return connectionID, nil } @@ -56,8 +57,8 @@ func (k Keeper) ConnOpenInit( // code is executed on chain B). // // NOTE: -// - Here chain A acts as the counterparty -// - Identifiers are checked on msg validation +// - Here chain A acts as the counterparty +// - Identifiers are checked on msg validation func (k Keeper) ConnOpenTry( ctx sdk.Context, counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier @@ -71,14 +72,13 @@ func (k Keeper) ConnOpenTry( proofHeight exported.Height, // height at which relayer constructs proof of A storing connectionEnd in state consensusHeight exported.Height, // latest height of chain B which chain A has stored in its chain B client ) (string, error) { - // generate a new connection connectionID := k.GenerateConnectionIdentifier(ctx) selfHeight := clienttypes.GetSelfHeight(ctx) if consensusHeight.GTE(selfHeight) { - return "", sdkerrors.Wrapf( - sdkerrors.ErrInvalidHeight, + return "", errorsmod.Wrapf( + ibcerrors.ErrInvalidHeight, "consensus height is greater than or equal to the current block height (%s >= %s)", consensusHeight, selfHeight, ) } @@ -90,7 +90,7 @@ func (k Keeper) ConnOpenTry( expectedConsensusState, err := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if err != nil { - return "", sdkerrors.Wrapf(err, "self consensus state not found for height %s", consensusHeight.String()) + return "", errorsmod.Wrapf(err, "self consensus state not found for height %s", consensusHeight.String()) } // expectedConnection defines Chain A's ConnectionEnd @@ -133,7 +133,7 @@ func (k Keeper) ConnOpenTry( // store connection in chainB state if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { - return "", sdkerrors.Wrapf(err, "failed to add connection with ID %s to client with ID %s", connectionID, clientID) + return "", errorsmod.Wrapf(err, "failed to add connection with ID %s to client with ID %s", connectionID, clientID) } k.SetConnection(ctx, connectionID, connection) @@ -143,7 +143,7 @@ func (k Keeper) ConnOpenTry( telemetry.IncrCounter(1, "ibc", "connection", "open-try") }() - EmitConnectionOpenTryEvent(ctx, connectionID, clientID, counterparty) + emitConnectionOpenTryEvent(ctx, connectionID, clientID, counterparty) return connectionID, nil } @@ -167,8 +167,8 @@ func (k Keeper) ConnOpenAck( // Check that chainB client hasn't stored invalid height selfHeight := clienttypes.GetSelfHeight(ctx) if consensusHeight.GTE(selfHeight) { - return sdkerrors.Wrapf( - sdkerrors.ErrInvalidHeight, + return errorsmod.Wrapf( + ibcerrors.ErrInvalidHeight, "consensus height is greater than or equal to the current block height (%s >= %s)", consensusHeight, selfHeight, ) } @@ -176,12 +176,12 @@ func (k Keeper) ConnOpenAck( // Retrieve connection connection, found := k.GetConnection(ctx, connectionID) if !found { - return sdkerrors.Wrap(types.ErrConnectionNotFound, connectionID) + return errorsmod.Wrap(types.ErrConnectionNotFound, connectionID) } // verify the previously set connection state if connection.State != types.INIT { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidConnectionState, "connection state is not INIT (got %s)", connection.State.String(), ) @@ -189,7 +189,7 @@ func (k Keeper) ConnOpenAck( // ensure selected version is supported if !types.IsSupportedVersion(types.ProtoVersionsToExported(connection.Versions), version) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidConnectionState, "the counterparty selected version %s is not supported by versions selected on INIT", version, ) @@ -203,7 +203,7 @@ func (k Keeper) ConnOpenAck( // Retrieve chainA's consensus state at consensusheight expectedConsensusState, err := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if err != nil { - return sdkerrors.Wrapf(err, "self consensus state not found for height %s", consensusHeight.String()) + return errorsmod.Wrapf(err, "self consensus state not found for height %s", consensusHeight.String()) } prefix := k.GetCommitmentPrefix() @@ -242,7 +242,7 @@ func (k Keeper) ConnOpenAck( connection.Counterparty.ConnectionId = counterpartyConnectionID k.SetConnection(ctx, connectionID, connection) - EmitConnectionOpenAckEvent(ctx, connectionID, connection) + emitConnectionOpenAckEvent(ctx, connectionID, connection) return nil } @@ -260,12 +260,12 @@ func (k Keeper) ConnOpenConfirm( // Retrieve connection connection, found := k.GetConnection(ctx, connectionID) if !found { - return sdkerrors.Wrap(types.ErrConnectionNotFound, connectionID) + return errorsmod.Wrap(types.ErrConnectionNotFound, connectionID) } // Check that connection state on ChainB is on state: TRYOPEN if connection.State != types.TRYOPEN { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidConnectionState, "connection state is not TRYOPEN (got %s)", connection.State.String(), ) @@ -292,7 +292,7 @@ func (k Keeper) ConnOpenConfirm( telemetry.IncrCounter(1, "ibc", "connection", "open-confirm") }() - EmitConnectionOpenConfirmEvent(ctx, connectionID, connection) + emitConnectionOpenConfirmEvent(ctx, connectionID, connection) return nil } diff --git a/modules/core/03-connection/keeper/handshake_test.go b/modules/core/03-connection/keeper/handshake_test.go index aeabf5718c2..c14ec879204 100644 --- a/modules/core/03-connection/keeper/handshake_test.go +++ b/modules/core/03-connection/keeper/handshake_test.go @@ -3,12 +3,12 @@ package keeper_test import ( "time" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "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/ibc-go/v7/testing" ) // TestConnOpenInit - chainA initializes (INIT state) a connection with @@ -112,7 +112,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // commit in order for proof to return correct value suite.coordinator.CommitBlock(suite.chainA) - path.EndpointB.UpdateClient() + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) @@ -125,7 +126,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) // Set an invalid client of chainA on chainB - tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) + tmClient, ok := counterpartyClient.(*ibctm.ClientState) suite.Require().True(ok) tmClient.ChainId = "wrongchainid" @@ -182,7 +183,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) // modify counterparty client without setting in store so it still passes validate but fails proof verification - tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) + tmClient, ok := counterpartyClient.(*ibctm.ClientState) suite.Require().True(ok) tmClient.LatestHeight = tmClient.LatestHeight.Increment().(clienttypes.Height) }, false}, @@ -194,7 +195,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { consState, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetLatestClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID) suite.Require().True(found) - tmConsState, ok := consState.(*ibctmtypes.ConsensusState) + tmConsState, ok := consState.(*ibctm.ConsensusState) suite.Require().True(ok) tmConsState.Timestamp = time.Now() @@ -291,7 +292,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) // Set an invalid client of chainA on chainB - tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) + tmClient, ok := counterpartyClient.(*ibctm.ClientState) suite.Require().True(ok) tmClient.ChainId = "wrongchainid" @@ -431,7 +432,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) // modify counterparty client without setting in store so it still passes validate but fails proof verification - tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) + tmClient, ok := counterpartyClient.(*ibctm.ClientState) suite.Require().True(ok) tmClient.LatestHeight = tmClient.LatestHeight.Increment().(clienttypes.Height) @@ -449,7 +450,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { consState, found := suite.chainB.App.GetIBCKeeper().ClientKeeper.GetLatestClientConsensusState(suite.chainB.GetContext(), path.EndpointB.ClientID) suite.Require().True(found) - tmConsState, ok := consState.(*ibctmtypes.ConsensusState) + tmConsState, ok := consState.(*ibctm.ConsensusState) suite.Require().True(ok) tmConsState.Timestamp = tmConsState.Timestamp.Add(time.Second) diff --git a/modules/core/03-connection/keeper/keeper.go b/modules/core/03-connection/keeper/keeper.go index e6370da8d26..c38fa2e07df 100644 --- a/modules/core/03-connection/keeper/keeper.go +++ b/modules/core/03-connection/keeper/keeper.go @@ -1,18 +1,18 @@ package keeper import ( - "github.com/tendermint/tendermint/libs/log" - + 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" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/tendermint/tendermint/libs/log" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // Keeper defines the IBC connection keeper @@ -20,14 +20,14 @@ type Keeper struct { // implements gRPC QueryServer interface types.QueryServer - storeKey sdk.StoreKey + storeKey storetypes.StoreKey paramSpace paramtypes.Subspace cdc codec.BinaryCodec clientKeeper types.ClientKeeper } // NewKeeper creates a new IBC connection Keeper instance -func NewKeeper(cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Subspace, ck types.ClientKeeper) Keeper { +func NewKeeper(cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, ck types.ClientKeeper) Keeper { // set KeyTable if it has not already been set if !paramSpace.HasKeyTable() { paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) @@ -43,7 +43,7 @@ func NewKeeper(cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Su // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+host.ModuleName+"/"+types.SubModuleName) + return ctx.Logger().With("module", "x/"+exported.ModuleName+"/"+types.SubModuleName) } // GetCommitmentPrefix returns the IBC connection store prefix as a commitment @@ -66,7 +66,7 @@ func (k Keeper) GenerateConnectionIdentifier(ctx sdk.Context) string { func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(host.ConnectionKey(connectionID)) - if bz == nil { + if len(bz) == 0 { return types.ConnectionEnd{}, false } @@ -76,6 +76,13 @@ func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.Conne return connection, true } +// HasConnection returns a true if the connection with the given identifier +// exists in the store. +func (k Keeper) HasConnection(ctx sdk.Context, connectionID string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(host.ConnectionKey(connectionID)) +} + // SetConnection sets a connection to the store func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) { store := ctx.KVStore(k.storeKey) @@ -86,18 +93,19 @@ func (k Keeper) SetConnection(ctx sdk.Context, connectionID string, connection t // GetTimestampAtHeight returns the timestamp in nanoseconds of the consensus state at the // given height. func (k Keeper) GetTimestampAtHeight(ctx sdk.Context, connection types.ConnectionEnd, height exported.Height) (uint64, error) { - consensusState, found := k.clientKeeper.GetClientConsensusState( - ctx, connection.GetClientID(), height, - ) - + clientState, found := k.clientKeeper.GetClientState(ctx, connection.GetClientID()) if !found { - return 0, sdkerrors.Wrapf( - clienttypes.ErrConsensusStateNotFound, - "clientID (%s), height (%s)", connection.GetClientID(), height, + return 0, errorsmod.Wrapf( + clienttypes.ErrClientNotFound, "clientID (%s)", connection.GetClientID(), ) } - return consensusState.GetTimestamp(), nil + timestamp, err := clientState.GetTimestampAtHeight(ctx, k.clientKeeper.ClientStore(ctx, connection.GetClientID()), k.cdc, height) + if err != nil { + return 0, err + } + + return timestamp, nil } // GetClientConnectionPaths returns all the connection paths stored under a @@ -105,7 +113,7 @@ func (k Keeper) GetTimestampAtHeight(ctx sdk.Context, connection types.Connectio func (k Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(host.ClientConnectionsKey(clientID)) - if bz == nil { + if len(bz) == 0 { return nil, false } @@ -126,7 +134,7 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths func (k Keeper) GetNextConnectionSequence(ctx sdk.Context) uint64 { store := ctx.KVStore(k.storeKey) bz := store.Get([]byte(types.KeyNextConnectionSequence)) - if bz == nil { + if len(bz) == 0 { panic("next connection sequence is nil") } @@ -145,7 +153,7 @@ func (k Keeper) SetNextConnectionSequence(ctx sdk.Context, sequence uint64) { // no paths are stored. func (k Keeper) GetAllClientConnectionPaths(ctx sdk.Context) []types.ConnectionPaths { var allConnectionPaths []types.ConnectionPaths - k.clientKeeper.IterateClients(ctx, func(clientID string, cs exported.ClientState) bool { + k.clientKeeper.IterateClientStates(ctx, nil, func(clientID string, cs exported.ClientState) bool { paths, found := k.GetClientConnectionPaths(ctx, clientID) if !found { // continue when connection handshake is not initialized @@ -166,7 +174,7 @@ func (k Keeper) IterateConnections(ctx sdk.Context, cb func(types.IdentifiedConn store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(host.KeyConnectionPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { var connection types.ConnectionEnd k.cdc.MustUnmarshal(iterator.Value(), &connection) @@ -193,7 +201,7 @@ func (k Keeper) GetAllConnections(ctx sdk.Context) (connections []types.Identifi func (k Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) error { _, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } conns, found := k.GetClientConnectionPaths(ctx, clientID) diff --git a/modules/core/03-connection/keeper/keeper_test.go b/modules/core/03-connection/keeper/keeper_test.go index dd72a9cc620..a82573788d3 100644 --- a/modules/core/03-connection/keeper/keeper_test.go +++ b/modules/core/03-connection/keeper/keeper_test.go @@ -6,8 +6,9 @@ import ( "github.com/stretchr/testify/suite" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type KeeperTestSuite struct { @@ -59,7 +60,7 @@ func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() { } // create 2 connections: A0 - B0, A1 - B1 -func (suite KeeperTestSuite) TestGetAllConnections() { +func (suite KeeperTestSuite) TestGetAllConnections() { //nolint:govet // this is a test, we are okay with copying locks path1 := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path1) @@ -87,7 +88,7 @@ func (suite KeeperTestSuite) TestGetAllConnections() { // the test creates 2 clients path.EndpointA.ClientID0 and path.EndpointA.ClientID1. path.EndpointA.ClientID0 has a single // connection and path.EndpointA.ClientID1 has 2 connections. -func (suite KeeperTestSuite) TestGetAllClientConnectionPaths() { +func (suite KeeperTestSuite) TestGetAllClientConnectionPaths() { //nolint:govet // this is a test, we are okay with copying locks path1 := ibctesting.NewPath(suite.chainA, suite.chainB) path2 := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path1) @@ -111,7 +112,10 @@ func (suite KeeperTestSuite) TestGetAllClientConnectionPaths() { // TestGetTimestampAtHeight verifies if the clients on each chain return the // correct timestamp for the other chain. func (suite *KeeperTestSuite) TestGetTimestampAtHeight() { - var connection types.ConnectionEnd + var ( + connection types.ConnectionEnd + height exported.Height + ) cases := []struct { msg string @@ -122,10 +126,14 @@ func (suite *KeeperTestSuite) TestGetTimestampAtHeight() { path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) connection = path.EndpointA.GetConnection() + height = suite.chainB.LastHeader.GetHeight() }, true}, + {"client state not found", func() {}, false}, {"consensus state not found", func() { - // any non-nil value of connection is valid - suite.Require().NotNil(connection) + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + connection = path.EndpointA.GetConnection() + height = suite.chainB.LastHeader.GetHeight().Increment() }, false}, } @@ -136,7 +144,7 @@ func (suite *KeeperTestSuite) TestGetTimestampAtHeight() { tc.malleate() actualTimestamp, err := suite.chainA.App.GetIBCKeeper().ConnectionKeeper.GetTimestampAtHeight( - suite.chainA.GetContext(), connection, suite.chainB.LastHeader.GetHeight(), + suite.chainA.GetContext(), connection, height, ) if tc.expPass { diff --git a/modules/core/03-connection/keeper/params.go b/modules/core/03-connection/keeper/params.go index 26d2d4e843f..8723d5d7246 100644 --- a/modules/core/03-connection/keeper/params.go +++ b/modules/core/03-connection/keeper/params.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) // GetMaxExpectedTimePerBlock retrieves the maximum expected time per block from the paramstore diff --git a/modules/core/03-connection/keeper/params_test.go b/modules/core/03-connection/keeper/params_test.go index 7e6ea66bbca..30450beb528 100644 --- a/modules/core/03-connection/keeper/params_test.go +++ b/modules/core/03-connection/keeper/params_test.go @@ -1,7 +1,7 @@ package keeper_test import ( - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) func (suite *KeeperTestSuite) TestParams() { @@ -12,6 +12,6 @@ func (suite *KeeperTestSuite) TestParams() { expParams.MaxExpectedTimePerBlock = 10 suite.chainA.App.GetIBCKeeper().ConnectionKeeper.SetParams(suite.chainA.GetContext(), expParams) - params = suite.chainA.App.GetIBCKeeper().ConnectionKeeper.GetParams(suite.chainA.GetContext()) + _ = suite.chainA.App.GetIBCKeeper().ConnectionKeeper.GetParams(suite.chainA.GetContext()) suite.Require().Equal(uint64(10), expParams.MaxExpectedTimePerBlock) } diff --git a/modules/core/03-connection/keeper/verify.go b/modules/core/03-connection/keeper/verify.go index e0cdbfcad03..4300ae3fa64 100644 --- a/modules/core/03-connection/keeper/verify.go +++ b/modules/core/03-connection/keeper/verify.go @@ -3,11 +3,16 @@ package keeper import ( "math" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // VerifyClientState verifies a proof of a client state of the running machine @@ -24,17 +29,30 @@ func (k Keeper) VerifyClientState( targetClient, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } if status := targetClient.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) } - if err := targetClient.VerifyClientState( - clientStore, k.cdc, height, - connection.GetCounterparty().GetPrefix(), connection.GetCounterparty().GetClientID(), proof, clientState); err != nil { - return sdkerrors.Wrapf(err, "failed client state verification for target client: %s", clientID) + merklePath := commitmenttypes.NewMerklePath(host.FullClientStatePath(connection.GetCounterparty().GetClientID())) + merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + bz, err := k.cdc.MarshalInterface(clientState) + if err != nil { + return err + } + + if err := targetClient.VerifyMembership( + ctx, clientStore, k.cdc, height, + 0, 0, // skip delay period checks for non-packet processing verification + proof, merklePath, bz, + ); err != nil { + return errorsmod.Wrapf(err, "failed client state verification for target client: %s", clientID) } return nil @@ -55,18 +73,30 @@ func (k Keeper) VerifyClientConsensusState( clientState, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + } + + merklePath := commitmenttypes.NewMerklePath(host.FullConsensusStatePath(connection.GetCounterparty().GetClientID(), consensusHeight)) + merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err } - if err := clientState.VerifyClientConsensusState( - clientStore, k.cdc, height, - connection.GetCounterparty().GetClientID(), consensusHeight, connection.GetCounterparty().GetPrefix(), proof, consensusState, + bz, err := k.cdc.MarshalInterface(consensusState) + if err != nil { + return err + } + + if err := clientState.VerifyMembership( + ctx, clientStore, k.cdc, height, + 0, 0, // skip delay period checks for non-packet processing verification + proof, merklePath, bz, ); err != nil { - return sdkerrors.Wrapf(err, "failed consensus state verification for client (%s)", clientID) + return errorsmod.Wrapf(err, "failed consensus state verification for client (%s)", clientID) } return nil @@ -80,25 +110,42 @@ func (k Keeper) VerifyConnectionState( height exported.Height, proof []byte, connectionID string, - connectionEnd exported.ConnectionI, // opposite connection + counterpartyConnection exported.ConnectionI, // opposite connection ) error { clientID := connection.GetClientID() clientStore := k.clientKeeper.ClientStore(ctx, clientID) clientState, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + } + + merklePath := commitmenttypes.NewMerklePath(host.ConnectionPath(connectionID)) + merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + connectionEnd, ok := counterpartyConnection.(connectiontypes.ConnectionEnd) + if !ok { + return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "invalid connection type %T", counterpartyConnection) + } + + bz, err := k.cdc.Marshal(&connectionEnd) + if err != nil { + return err } - if err := clientState.VerifyConnectionState( - clientStore, k.cdc, height, - connection.GetCounterparty().GetPrefix(), proof, connectionID, connectionEnd, + if err := clientState.VerifyMembership( + ctx, clientStore, k.cdc, height, + 0, 0, // skip delay period checks for non-packet processing verification + proof, merklePath, bz, ); err != nil { - return sdkerrors.Wrapf(err, "failed connection state verification for client (%s)", clientID) + return errorsmod.Wrapf(err, "failed connection state verification for client (%s)", clientID) } return nil @@ -120,19 +167,35 @@ func (k Keeper) VerifyChannelState( clientState, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + } + + merklePath := commitmenttypes.NewMerklePath(host.ChannelPath(portID, channelID)) + merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + channelEnd, ok := channel.(channeltypes.Channel) + if !ok { + return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "invalid channel type %T", channel) + } + + bz, err := k.cdc.Marshal(&channelEnd) + if err != nil { + return err } - if err := clientState.VerifyChannelState( - clientStore, k.cdc, height, - connection.GetCounterparty().GetPrefix(), proof, - portID, channelID, channel, + if err := clientState.VerifyMembership( + ctx, clientStore, k.cdc, height, + 0, 0, // skip delay period checks for non-packet processing verification + proof, merklePath, bz, ); err != nil { - return sdkerrors.Wrapf(err, "failed channel state verification for client (%s)", clientID) + return errorsmod.Wrapf(err, "failed channel state verification for client (%s)", clientID) } return nil @@ -155,24 +218,29 @@ func (k Keeper) VerifyPacketCommitment( clientState, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) } // get time and block delays timeDelay := connection.GetDelayPeriod() blockDelay := k.getBlockDelay(ctx, connection) - if err := clientState.VerifyPacketCommitment( + merklePath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, sequence)) + merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + if err := clientState.VerifyMembership( ctx, clientStore, k.cdc, height, timeDelay, blockDelay, - connection.GetCounterparty().GetPrefix(), proof, portID, channelID, - sequence, commitmentBytes, + proof, merklePath, commitmentBytes, ); err != nil { - return sdkerrors.Wrapf(err, "failed packet commitment verification for client (%s)", clientID) + return errorsmod.Wrapf(err, "failed packet commitment verification for client (%s)", clientID) } return nil @@ -195,24 +263,29 @@ func (k Keeper) VerifyPacketAcknowledgement( clientState, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) } // get time and block delays timeDelay := connection.GetDelayPeriod() blockDelay := k.getBlockDelay(ctx, connection) - if err := clientState.VerifyPacketAcknowledgement( + merklePath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, sequence)) + merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + if err := clientState.VerifyMembership( ctx, clientStore, k.cdc, height, timeDelay, blockDelay, - connection.GetCounterparty().GetPrefix(), proof, portID, channelID, - sequence, acknowledgement, + proof, merklePath, channeltypes.CommitAcknowledgement(acknowledgement), ); err != nil { - return sdkerrors.Wrapf(err, "failed packet acknowledgement verification for client (%s)", clientID) + return errorsmod.Wrapf(err, "failed packet acknowledgement verification for client (%s)", clientID) } return nil @@ -235,24 +308,29 @@ func (k Keeper) VerifyPacketReceiptAbsence( clientState, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) } // get time and block delays timeDelay := connection.GetDelayPeriod() blockDelay := k.getBlockDelay(ctx, connection) - if err := clientState.VerifyPacketReceiptAbsence( + merklePath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, sequence)) + merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + if err := clientState.VerifyNonMembership( ctx, clientStore, k.cdc, height, timeDelay, blockDelay, - connection.GetCounterparty().GetPrefix(), proof, portID, channelID, - sequence, + proof, merklePath, ); err != nil { - return sdkerrors.Wrapf(err, "failed packet receipt absence verification for client (%s)", clientID) + return errorsmod.Wrapf(err, "failed packet receipt absence verification for client (%s)", clientID) } return nil @@ -274,24 +352,29 @@ func (k Keeper) VerifyNextSequenceRecv( clientState, found := k.clientKeeper.GetClientState(ctx, clientID) if !found { - return sdkerrors.Wrap(clienttypes.ErrClientNotFound, clientID) + return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID) } if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) } // get time and block delays timeDelay := connection.GetDelayPeriod() blockDelay := k.getBlockDelay(ctx, connection) - if err := clientState.VerifyNextSequenceRecv( + merklePath := commitmenttypes.NewMerklePath(host.NextSequenceRecvPath(portID, channelID)) + merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + if err := clientState.VerifyMembership( ctx, clientStore, k.cdc, height, timeDelay, blockDelay, - connection.GetCounterparty().GetPrefix(), proof, portID, channelID, - nextSequenceRecv, + proof, merklePath, sdk.Uint64ToBigEndian(nextSequenceRecv), ); err != nil { - return sdkerrors.Wrapf(err, "failed next sequence receive verification for client (%s)", clientID) + return errorsmod.Wrapf(err, "failed next sequence receive verification for client (%s)", clientID) } return nil diff --git a/modules/core/03-connection/keeper/verify_test.go b/modules/core/03-connection/keeper/verify_test.go index 6641bf790bd..12600e8d9c3 100644 --- a/modules/core/03-connection/keeper/verify_test.go +++ b/modules/core/03-connection/keeper/verify_test.go @@ -4,17 +4,17 @@ import ( "fmt" "time" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "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" + "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/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) -var defaultTimeoutHeight = clienttypes.NewHeight(0, 100000) +var defaultTimeoutHeight = clienttypes.NewHeight(1, 100000) // TestVerifyClientState verifies a client state of chainA // stored on path.EndpointB (which is on chainB) @@ -38,12 +38,12 @@ func (suite *KeeperTestSuite) TestVerifyClientState() { heightDiff = 5 }, false}, {"verification failed", func() { - counterpartyClient := path.EndpointB.GetClientState().(*ibctmtypes.ClientState) + counterpartyClient := path.EndpointB.GetClientState().(*ibctm.ClientState) counterpartyClient.ChainId = "wrongChainID" path.EndpointB.SetClientState(counterpartyClient) }, false}, {"client status is not active - client is expired", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = clienttypes.NewHeight(0, 1) path.EndpointA.SetClientState(clientState) }, false}, @@ -62,7 +62,7 @@ func (suite *KeeperTestSuite) TestVerifyClientState() { tc.malleate() counterpartyClient, clientProof := path.EndpointB.QueryClientStateProof() - proofHeight := clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()-1)) + proofHeight := clienttypes.NewHeight(1, uint64(suite.chainB.GetContext().BlockHeight()-1)) connection := path.EndpointA.GetConnection() @@ -109,7 +109,7 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { consState, found := suite.chainB.App.GetIBCKeeper().ClientKeeper.GetLatestClientConsensusState(suite.chainB.GetContext(), path.EndpointB.ClientID) suite.Require().True(found) - tmConsState, ok := consState.(*ibctmtypes.ConsensusState) + tmConsState, ok := consState.(*ibctm.ConsensusState) suite.Require().True(ok) tmConsState.Timestamp = time.Now() @@ -118,7 +118,7 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { suite.coordinator.CommitBlock(suite.chainB) }, false}, {"client status is not active - client is expired", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = clienttypes.NewHeight(0, 1) path.EndpointA.SetClientState(clientState) }, false}, @@ -138,7 +138,7 @@ func (suite *KeeperTestSuite) TestVerifyClientConsensusState() { connection := path.EndpointA.GetConnection() proof, consensusHeight := suite.chainB.QueryConsensusStateProof(path.EndpointB.ClientID) - proofHeight := clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()-1)) + proofHeight := clienttypes.NewHeight(1, uint64(suite.chainB.GetContext().BlockHeight()-1)) consensusState, err := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetSelfConsensusState(suite.chainA.GetContext(), consensusHeight) suite.Require().NoError(err) @@ -183,7 +183,7 @@ func (suite *KeeperTestSuite) TestVerifyConnectionState() { path.EndpointA.SetConnection(connection) }, false}, {"client status is not active - client is expired", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = clienttypes.NewHeight(0, 1) path.EndpointA.SetClientState(clientState) }, false}, @@ -248,7 +248,7 @@ func (suite *KeeperTestSuite) TestVerifyChannelState() { path.EndpointA.SetChannel(channel) }, false}, {"client status is not active - client is expired", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = clienttypes.NewHeight(0, 1) path.EndpointA.SetClientState(clientState) }, false}, @@ -326,7 +326,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { packet.Data = []byte(ibctesting.InvalidID) }, false}, {"client status is not active - client is expired", func() { - clientState := path.EndpointB.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointB.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = clienttypes.NewHeight(0, 1) path.EndpointB.SetClientState(clientState) }, false}, @@ -341,9 +341,9 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { path = ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, 0) // reset variables heightDiff = 0 @@ -418,7 +418,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { ack = ibcmock.MockFailAcknowledgement }, false}, {"client status is not active - client is expired", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = clienttypes.NewHeight(0, 1) path.EndpointA.SetClientState(clientState) }, false}, @@ -435,14 +435,14 @@ func (suite *KeeperTestSuite) TestVerifyPacketAcknowledgement() { suite.coordinator.Setup(path) // send and receive packet - packet := channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) // increment receiving chain's (chainB) time by 2 hour to always pass receive suite.coordinator.IncrementTimeBy(time.Hour * 2) suite.coordinator.CommitBlock(suite.chainB) + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -524,7 +524,7 @@ func (suite *KeeperTestSuite) TestVerifyPacketReceiptAbsence() { suite.Require().NoError(err) }, false}, {"client status is not active - client is expired", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = clienttypes.NewHeight(0, 1) path.EndpointA.SetClientState(clientState) }, false}, @@ -540,9 +540,9 @@ func (suite *KeeperTestSuite) TestVerifyPacketReceiptAbsence() { suite.coordinator.Setup(path) // send, only receive in malleate if applicable - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, 0) // reset variables heightDiff = 0 @@ -553,11 +553,12 @@ func (suite *KeeperTestSuite) TestVerifyPacketReceiptAbsence() { connection := path.EndpointA.GetConnection() connection.DelayPeriod = delayTimePeriod - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) if clientState.FrozenHeight.IsZero() { // need to update height to prove absence or receipt suite.coordinator.CommitBlock(suite.chainA, suite.chainB) - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) } packetReceiptKey := host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) @@ -624,7 +625,7 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { offsetSeq = 1 }, false}, {"client status is not active - client is expired", func() { - clientState := path.EndpointA.GetClientState().(*ibctmtypes.ClientState) + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) clientState.FrozenHeight = clienttypes.NewHeight(0, 1) path.EndpointA.SetClientState(clientState) }, false}, @@ -640,14 +641,14 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { suite.coordinator.Setup(path) // send and receive packet - packet := channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) // increment receiving chain's (chainB) time by 2 hour to always pass receive suite.coordinator.IncrementTimeBy(time.Hour * 2) suite.coordinator.CommitBlock(suite.chainB) + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) diff --git a/modules/core/03-connection/module.go b/modules/core/03-connection/module.go index 17132c269a9..cded57fb4af 100644 --- a/modules/core/03-connection/module.go +++ b/modules/core/03-connection/module.go @@ -1,11 +1,11 @@ package connection import ( - "github.com/gogo/protobuf/grpc" + "github.com/cosmos/gogoproto/grpc" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/client/cli" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/client/cli" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) // Name returns the IBC connection ICS name. diff --git a/modules/core/03-connection/simulation/decoder.go b/modules/core/03-connection/simulation/decoder.go index 803bdda728e..8fdf6c389e3 100644 --- a/modules/core/03-connection/simulation/decoder.go +++ b/modules/core/03-connection/simulation/decoder.go @@ -7,8 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/types/kv" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // NewDecodeStore returns a decoder function closure that unmarshals the KVPair's diff --git a/modules/core/03-connection/simulation/decoder_test.go b/modules/core/03-connection/simulation/decoder_test.go index 77ac0f7e630..d93c1f10742 100644 --- a/modules/core/03-connection/simulation/decoder_test.go +++ b/modules/core/03-connection/simulation/decoder_test.go @@ -7,10 +7,10 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/simulation" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/simulation" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) func TestDecodeStore(t *testing.T) { diff --git a/modules/core/03-connection/simulation/genesis.go b/modules/core/03-connection/simulation/genesis.go index d60803babe0..5ffc3d4e522 100644 --- a/modules/core/03-connection/simulation/genesis.go +++ b/modules/core/03-connection/simulation/genesis.go @@ -5,7 +5,7 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) // GenConnectionGenesis returns the default connection genesis state. diff --git a/modules/core/03-connection/types/codec.go b/modules/core/03-connection/types/codec.go index f09a14f283c..8f6ad752fbf 100644 --- a/modules/core/03-connection/types/codec.go +++ b/modules/core/03-connection/types/codec.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // RegisterInterfaces register the ibc interfaces submodule implementations to protobuf diff --git a/modules/core/03-connection/types/connection.go b/modules/core/03-connection/types/connection.go index 508140a2de3..eddd471d51a 100644 --- a/modules/core/03-connection/types/connection.go +++ b/modules/core/03-connection/types/connection.go @@ -1,11 +1,12 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var _ exported.ConnectionI = (*ConnectionEnd)(nil) @@ -51,10 +52,10 @@ func (c ConnectionEnd) GetDelayPeriod() uint64 { // counterparty's. func (c ConnectionEnd) ValidateBasic() error { if err := host.ClientIdentifierValidator(c.ClientId); err != nil { - return sdkerrors.Wrap(err, "invalid client ID") + return errorsmod.Wrap(err, "invalid client ID") } if len(c.Versions) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidVersion, "empty connection versions") + return errorsmod.Wrap(ibcerrors.ErrInvalidVersion, "empty connection versions") } for _, version := range c.Versions { if err := ValidateVersion(version); err != nil { @@ -94,14 +95,14 @@ func (c Counterparty) GetPrefix() exported.Prefix { func (c Counterparty) ValidateBasic() error { if c.ConnectionId != "" { if err := host.ConnectionIdentifierValidator(c.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty connection ID") + return errorsmod.Wrap(err, "invalid counterparty connection ID") } } if err := host.ClientIdentifierValidator(c.ClientId); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty client ID") + return errorsmod.Wrap(err, "invalid counterparty client ID") } if c.Prefix.Empty() { - return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty prefix cannot be empty") + return errorsmod.Wrap(ErrInvalidCounterparty, "counterparty prefix cannot be empty") } return nil } @@ -121,7 +122,7 @@ func NewIdentifiedConnection(connectionID string, conn ConnectionEnd) Identified // ValidateBasic performs a basic validation of the connection identifier and connection fields. func (ic IdentifiedConnection) ValidateBasic() error { if err := host.ConnectionIdentifierValidator(ic.Id); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") + return errorsmod.Wrap(err, "invalid connection ID") } connection := NewConnectionEnd(ic.State, ic.ClientId, ic.Counterparty, ic.Versions, ic.DelayPeriod) return connection.ValidateBasic() diff --git a/modules/core/03-connection/types/connection.pb.go b/modules/core/03-connection/types/connection.pb.go index 893debbba18..86d1741edaf 100644 --- a/modules/core/03-connection/types/connection.pb.go +++ b/modules/core/03-connection/types/connection.pb.go @@ -5,9 +5,9 @@ package types import ( fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" io "io" math "math" math_bits "math/bits" @@ -421,49 +421,49 @@ var fileDescriptor_90572467c054e43a = []byte{ // 721 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4f, 0x6f, 0xda, 0x48, 0x14, 0xc7, 0xc6, 0x10, 0x18, 0xc2, 0x2e, 0x3b, 0x8b, 0x36, 0x16, 0xab, 0xd8, 0x96, 0x77, 0xb5, - 0x8b, 0x56, 0x0a, 0x5e, 0x92, 0xd5, 0x1e, 0xd2, 0xf6, 0x10, 0x08, 0x95, 0xac, 0xb6, 0x14, 0x39, - 0x24, 0x52, 0x73, 0x41, 0xc6, 0x9e, 0x90, 0x51, 0xb0, 0x07, 0xd9, 0x03, 0x82, 0x6f, 0x10, 0xe5, - 0xd4, 0x6b, 0x0f, 0x91, 0x2a, 0xf5, 0xbb, 0x54, 0x51, 0x4f, 0x39, 0xf6, 0x84, 0xaa, 0xe4, 0xda, - 0x13, 0x9f, 0xa0, 0xb2, 0xc7, 0x80, 0x13, 0x35, 0x95, 0x92, 0xf6, 0xf6, 0x9e, 0x7f, 0x7f, 0x78, - 0xef, 0xc7, 0xc3, 0x80, 0xbf, 0x71, 0xd7, 0xd2, 0x2c, 0xe2, 0x21, 0xcd, 0x22, 0xae, 0x8b, 0x2c, - 0x8a, 0x89, 0xab, 0x8d, 0xaa, 0xb1, 0xae, 0x32, 0xf0, 0x08, 0x25, 0xf0, 0x37, 0xdc, 0xb5, 0x2a, - 0x01, 0xb1, 0x12, 0x83, 0x46, 0xd5, 0x52, 0xb1, 0x47, 0x7a, 0x24, 0xa4, 0x68, 0x41, 0xc5, 0xd8, - 0xa5, 0xb8, 0xad, 0xe3, 0x60, 0xea, 0x20, 0x97, 0x32, 0xdb, 0x79, 0xc7, 0x88, 0xea, 0x7b, 0x1e, - 0xe4, 0xeb, 0x0b, 0xc3, 0x86, 0x6b, 0xc3, 0x2a, 0xc8, 0x5a, 0x7d, 0x8c, 0x5c, 0xda, 0xc1, 0xb6, - 0xc8, 0x29, 0x5c, 0x39, 0x5b, 0x2b, 0xce, 0xa6, 0x72, 0x61, 0x62, 0x3a, 0xfd, 0x6d, 0x75, 0x01, - 0xa9, 0x46, 0x86, 0xd5, 0xba, 0x0d, 0x1f, 0x81, 0xcc, 0x08, 0x79, 0x3e, 0x26, 0xae, 0x2f, 0xf2, - 0x4a, 0xb2, 0x9c, 0xdb, 0x94, 0x2b, 0x5f, 0x1f, 0xb7, 0x72, 0xc0, 0x78, 0xc6, 0x42, 0x00, 0xb7, - 0x40, 0xca, 0xa7, 0x26, 0x45, 0x62, 0x52, 0xe1, 0xca, 0x3f, 0x6d, 0xae, 0xdf, 0xa5, 0xdc, 0x0b, - 0x48, 0x06, 0xe3, 0xc2, 0x26, 0x58, 0xb5, 0xc8, 0xd0, 0xa5, 0xc8, 0x1b, 0x98, 0x1e, 0x9d, 0x88, - 0x82, 0xc2, 0x95, 0x73, 0x9b, 0x7f, 0xde, 0xa5, 0xad, 0xc7, 0xb8, 0x35, 0xe1, 0x62, 0x2a, 0x27, - 0x8c, 0x1b, 0x7a, 0xb8, 0x0d, 0x56, 0x6d, 0xd4, 0x37, 0x27, 0x9d, 0x01, 0xf2, 0x30, 0xb1, 0xc5, - 0x94, 0xc2, 0x95, 0x85, 0xda, 0xda, 0x6c, 0x2a, 0xff, 0xca, 0xf6, 0x8e, 0xa3, 0xaa, 0x91, 0x0b, - 0xdb, 0x56, 0xd8, 0x6d, 0x0b, 0xa7, 0x6f, 0xe5, 0x84, 0xfa, 0x99, 0x07, 0x45, 0xdd, 0x46, 0x2e, - 0xc5, 0x47, 0x18, 0xd9, 0xcb, 0x48, 0xe1, 0x3a, 0xe0, 0x17, 0x41, 0xe6, 0x67, 0x53, 0x39, 0xcb, - 0x0c, 0x83, 0x04, 0x79, 0x7c, 0x2b, 0x6e, 0xfe, 0xde, 0x71, 0x27, 0x1f, 0x1c, 0xb7, 0xf0, 0x1d, - 0x71, 0xa7, 0x7e, 0x70, 0xdc, 0xe9, 0x7b, 0xc7, 0xfd, 0x81, 0x03, 0xab, 0xf1, 0x8f, 0x79, 0xc8, - 0xd9, 0x3e, 0x01, 0xf9, 0xe5, 0xdc, 0xcb, 0xf8, 0xc5, 0xd9, 0x54, 0x2e, 0x46, 0xb2, 0x38, 0xac, - 0x06, 0x4b, 0xcc, 0x7b, 0xdd, 0x86, 0x35, 0x90, 0x1e, 0x78, 0xe8, 0x08, 0x8f, 0xc3, 0xcb, 0xbd, - 0x15, 0xc7, 0xe2, 0x67, 0x36, 0xaa, 0x56, 0x5e, 0x20, 0xef, 0xa4, 0x8f, 0x5a, 0x21, 0x37, 0x8a, - 0x23, 0x52, 0x46, 0xcb, 0xfc, 0x01, 0x72, 0xf5, 0x70, 0xa8, 0x96, 0x49, 0x8f, 0x7d, 0x58, 0x04, - 0xa9, 0x41, 0x50, 0x88, 0x9c, 0x92, 0x2c, 0x67, 0x0d, 0xd6, 0xa8, 0x87, 0xe0, 0xe7, 0xe5, 0x55, - 0x31, 0xe2, 0x03, 0x76, 0x5e, 0x78, 0xf3, 0x71, 0xef, 0x67, 0x60, 0x25, 0xba, 0x14, 0x28, 0x01, - 0x80, 0xe7, 0x67, 0xec, 0x31, 0x53, 0x23, 0xf6, 0x04, 0x96, 0x40, 0xe6, 0x08, 0x99, 0x74, 0xe8, - 0xa1, 0xb9, 0xc7, 0xa2, 0x8f, 0xb6, 0x71, 0x41, 0xba, 0x65, 0x7a, 0xa6, 0xe3, 0x43, 0x1b, 0xfc, - 0xee, 0x98, 0xe3, 0x0e, 0x1a, 0x0f, 0x90, 0x45, 0x91, 0xdd, 0xa1, 0xd8, 0x41, 0xc1, 0x97, 0xda, - 0xe9, 0xf6, 0x89, 0x75, 0x12, 0x9a, 0x0b, 0xb5, 0xbf, 0x66, 0x53, 0x59, 0x65, 0x13, 0x7f, 0x83, - 0xac, 0x1a, 0x6b, 0x8e, 0x39, 0x6e, 0x44, 0x60, 0x1b, 0x3b, 0xa8, 0x85, 0xbc, 0x5a, 0x80, 0xfc, - 0xf3, 0x86, 0x03, 0xa9, 0xf0, 0x5a, 0xe1, 0xff, 0x40, 0xde, 0x6b, 0xef, 0xb4, 0x1b, 0x9d, 0xfd, - 0xa6, 0xde, 0xd4, 0xdb, 0xfa, 0xce, 0x73, 0xfd, 0xb0, 0xb1, 0xdb, 0xd9, 0x6f, 0xee, 0xb5, 0x1a, - 0x75, 0xfd, 0xa9, 0xde, 0xd8, 0x2d, 0x24, 0x4a, 0xbf, 0x9c, 0x9d, 0x2b, 0xf9, 0x1b, 0x04, 0x28, - 0x02, 0xc0, 0x74, 0xc1, 0xc3, 0x02, 0x57, 0xca, 0x9c, 0x9d, 0x2b, 0x42, 0x50, 0x43, 0x09, 0xe4, - 0x19, 0xd2, 0x36, 0x5e, 0xbd, 0x6c, 0x35, 0x9a, 0x05, 0xbe, 0x94, 0x3b, 0x3b, 0x57, 0x56, 0xa2, - 0x76, 0xa9, 0x0c, 0xc1, 0x24, 0x53, 0x06, 0x75, 0x49, 0x38, 0x7d, 0x27, 0x25, 0x6a, 0x07, 0x17, - 0x57, 0x12, 0x77, 0x79, 0x25, 0x71, 0x9f, 0xae, 0x24, 0xee, 0xf5, 0xb5, 0x94, 0xb8, 0xbc, 0x96, - 0x12, 0x1f, 0xaf, 0xa5, 0xc4, 0xe1, 0xe3, 0x1e, 0xa6, 0xc7, 0xc3, 0x6e, 0x70, 0x2a, 0x9a, 0x45, - 0x7c, 0x87, 0xf8, 0x1a, 0xee, 0x5a, 0x1b, 0x3d, 0xa2, 0x8d, 0xfe, 0xd3, 0x1c, 0x62, 0x0f, 0xfb, - 0xc8, 0x67, 0x6f, 0xf0, 0x7f, 0xb7, 0x36, 0x62, 0xff, 0x0d, 0x74, 0x32, 0x40, 0x7e, 0x37, 0x1d, - 0xbe, 0xbd, 0xb7, 0xbe, 0x04, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x2c, 0xbf, 0x64, 0x3f, 0x06, 0x00, + 0x8b, 0x56, 0x0a, 0x5e, 0x12, 0x69, 0x57, 0x4a, 0xdb, 0x43, 0x20, 0x54, 0xb2, 0xda, 0x52, 0xe4, + 0x90, 0x48, 0xcd, 0x05, 0x19, 0x7b, 0x42, 0x46, 0xc1, 0x1e, 0x64, 0x0f, 0x08, 0xbe, 0x41, 0x94, + 0x53, 0xaf, 0x3d, 0x44, 0xaa, 0xd4, 0xef, 0x52, 0x45, 0x3d, 0xe5, 0xd8, 0x13, 0xaa, 0x92, 0x6b, + 0x4f, 0x7c, 0x82, 0xca, 0x1e, 0x03, 0x4e, 0xd4, 0x54, 0x4a, 0xda, 0xdb, 0x7b, 0xfe, 0xfd, 0xe1, + 0xbd, 0x1f, 0x0f, 0x03, 0xfe, 0xc6, 0x5d, 0x4b, 0xb3, 0x88, 0x87, 0x34, 0x8b, 0xb8, 0x2e, 0xb2, + 0x28, 0x26, 0xae, 0x36, 0xaa, 0xc6, 0xba, 0xca, 0xc0, 0x23, 0x94, 0xc0, 0xdf, 0x70, 0xd7, 0xaa, + 0x04, 0xc4, 0x4a, 0x0c, 0x1a, 0x55, 0x4b, 0xc5, 0x1e, 0xe9, 0x91, 0x90, 0xa2, 0x05, 0x15, 0x63, + 0x97, 0xe2, 0xb6, 0x8e, 0x83, 0xa9, 0x83, 0x5c, 0xca, 0x6c, 0xe7, 0x1d, 0x23, 0xaa, 0xef, 0x79, + 0x90, 0xaf, 0x2f, 0x0c, 0x1b, 0xae, 0x0d, 0xab, 0x20, 0x6b, 0xf5, 0x31, 0x72, 0x69, 0x07, 0xdb, + 0x22, 0xa7, 0x70, 0xe5, 0x6c, 0xad, 0x38, 0x9b, 0xca, 0x85, 0x89, 0xe9, 0xf4, 0xb7, 0xd5, 0x05, + 0xa4, 0x1a, 0x19, 0x56, 0xeb, 0x36, 0x7c, 0x04, 0x32, 0x23, 0xe4, 0xf9, 0x98, 0xb8, 0xbe, 0xc8, + 0x2b, 0xc9, 0x72, 0x6e, 0x53, 0xae, 0x7c, 0x7d, 0xdc, 0xca, 0x01, 0xe3, 0x19, 0x0b, 0x01, 0xdc, + 0x02, 0x29, 0x9f, 0x9a, 0x14, 0x89, 0x49, 0x85, 0x2b, 0xff, 0xb4, 0xb9, 0x7e, 0x97, 0x72, 0x2f, + 0x20, 0x19, 0x8c, 0x0b, 0x9b, 0x60, 0xd5, 0x22, 0x43, 0x97, 0x22, 0x6f, 0x60, 0x7a, 0x74, 0x22, + 0x0a, 0x0a, 0x57, 0xce, 0x6d, 0xfe, 0x79, 0x97, 0xb6, 0x1e, 0xe3, 0xd6, 0x84, 0x8b, 0xa9, 0x9c, + 0x30, 0x6e, 0xe8, 0xe1, 0x36, 0x58, 0xb5, 0x51, 0xdf, 0x9c, 0x74, 0x06, 0xc8, 0xc3, 0xc4, 0x16, + 0x53, 0x0a, 0x57, 0x16, 0x6a, 0x6b, 0xb3, 0xa9, 0xfc, 0x2b, 0xdb, 0x3b, 0x8e, 0xaa, 0x46, 0x2e, + 0x6c, 0x5b, 0x61, 0xb7, 0x2d, 0x9c, 0xbe, 0x95, 0x13, 0xea, 0x67, 0x1e, 0x14, 0x75, 0x1b, 0xb9, + 0x14, 0x1f, 0x61, 0x64, 0x2f, 0x23, 0x85, 0xeb, 0x80, 0x5f, 0x04, 0x99, 0x9f, 0x4d, 0xe5, 0x2c, + 0x33, 0x0c, 0x12, 0xe4, 0xf1, 0xad, 0xb8, 0xf9, 0x7b, 0xc7, 0x9d, 0x7c, 0x70, 0xdc, 0xc2, 0x77, + 0xc4, 0x9d, 0xfa, 0xc1, 0x71, 0xa7, 0xef, 0x1d, 0xf7, 0x07, 0x0e, 0xac, 0xc6, 0x3f, 0xe6, 0x21, + 0x67, 0xfb, 0x04, 0xe4, 0x97, 0x73, 0x2f, 0xe3, 0x17, 0x67, 0x53, 0xb9, 0x18, 0xc9, 0xe2, 0xb0, + 0x1a, 0x2c, 0x31, 0xef, 0x75, 0x1b, 0xd6, 0x40, 0x7a, 0xe0, 0xa1, 0x23, 0x3c, 0x0e, 0x2f, 0xf7, + 0x56, 0x1c, 0x8b, 0x9f, 0xd9, 0xa8, 0x5a, 0x79, 0x81, 0xbc, 0x93, 0x3e, 0x6a, 0x85, 0xdc, 0x28, + 0x8e, 0x48, 0x19, 0x2d, 0xf3, 0x07, 0xc8, 0xd5, 0xc3, 0xa1, 0x5a, 0x26, 0x3d, 0xf6, 0x61, 0x11, + 0xa4, 0x06, 0x41, 0x21, 0x72, 0x4a, 0xb2, 0x9c, 0x35, 0x58, 0xa3, 0x1e, 0x82, 0x9f, 0x97, 0x57, + 0xc5, 0x88, 0x0f, 0xd8, 0x79, 0xe1, 0xcd, 0xc7, 0xbd, 0x9f, 0x81, 0x95, 0xe8, 0x52, 0xa0, 0x04, + 0x00, 0x9e, 0x9f, 0xb1, 0xc7, 0x4c, 0x8d, 0xd8, 0x13, 0x58, 0x02, 0x99, 0x23, 0x64, 0xd2, 0xa1, + 0x87, 0xe6, 0x1e, 0x8b, 0x3e, 0xda, 0xc6, 0x05, 0xe9, 0x96, 0xe9, 0x99, 0x8e, 0x0f, 0x6d, 0xf0, + 0xbb, 0x63, 0x8e, 0x3b, 0x68, 0x3c, 0x40, 0x16, 0x45, 0x76, 0x87, 0x62, 0x07, 0x05, 0x5f, 0x6a, + 0xa7, 0xdb, 0x27, 0xd6, 0x49, 0x68, 0x2e, 0xd4, 0xfe, 0x9a, 0x4d, 0x65, 0x95, 0x4d, 0xfc, 0x0d, + 0xb2, 0x6a, 0xac, 0x39, 0xe6, 0xb8, 0x11, 0x81, 0x6d, 0xec, 0xa0, 0x16, 0xf2, 0x6a, 0x01, 0xf2, + 0xcf, 0x1b, 0x0e, 0xa4, 0xc2, 0x6b, 0x85, 0xff, 0x01, 0x79, 0xaf, 0xbd, 0xd3, 0x6e, 0x74, 0xf6, + 0x9b, 0x7a, 0x53, 0x6f, 0xeb, 0x3b, 0xcf, 0xf5, 0xc3, 0xc6, 0x6e, 0x67, 0xbf, 0xb9, 0xd7, 0x6a, + 0xd4, 0xf5, 0xa7, 0x7a, 0x63, 0xb7, 0x90, 0x28, 0xfd, 0x72, 0x76, 0xae, 0xe4, 0x6f, 0x10, 0xa0, + 0x08, 0x00, 0xd3, 0x05, 0x0f, 0x0b, 0x5c, 0x29, 0x73, 0x76, 0xae, 0x08, 0x41, 0x0d, 0x25, 0x90, + 0x67, 0x48, 0xdb, 0x78, 0xf5, 0xb2, 0xd5, 0x68, 0x16, 0xf8, 0x52, 0xee, 0xec, 0x5c, 0x59, 0x89, + 0xda, 0xa5, 0x32, 0x04, 0x93, 0x4c, 0x19, 0xd4, 0x25, 0xe1, 0xf4, 0x9d, 0x94, 0xa8, 0x1d, 0x5c, + 0x5c, 0x49, 0xdc, 0xe5, 0x95, 0xc4, 0x7d, 0xba, 0x92, 0xb8, 0xd7, 0xd7, 0x52, 0xe2, 0xf2, 0x5a, + 0x4a, 0x7c, 0xbc, 0x96, 0x12, 0x87, 0x8f, 0x7b, 0x98, 0x1e, 0x0f, 0xbb, 0xc1, 0xa9, 0x68, 0x16, + 0xf1, 0x1d, 0xe2, 0x6b, 0xb8, 0x6b, 0x6d, 0xf4, 0x88, 0x36, 0xfa, 0x5f, 0x73, 0x88, 0x3d, 0xec, + 0x23, 0x9f, 0xbd, 0xc1, 0xff, 0xdd, 0xda, 0x88, 0xfd, 0x37, 0xd0, 0xc9, 0x00, 0xf9, 0xdd, 0x74, + 0xf8, 0xf6, 0xde, 0xfa, 0x12, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xa7, 0x84, 0x5c, 0x3f, 0x06, 0x00, 0x00, } diff --git a/modules/core/03-connection/types/connection_test.go b/modules/core/03-connection/types/connection_test.go index f844052f5c8..56daca299b8 100644 --- a/modules/core/03-connection/types/connection_test.go +++ b/modules/core/03-connection/types/connection_test.go @@ -5,10 +5,10 @@ import ( "github.com/stretchr/testify/require" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) var ( diff --git a/modules/core/03-connection/types/errors.go b/modules/core/03-connection/types/errors.go index 107a0e087c1..d131db91d93 100644 --- a/modules/core/03-connection/types/errors.go +++ b/modules/core/03-connection/types/errors.go @@ -1,19 +1,19 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // IBC connection sentinel errors var ( - ErrConnectionExists = sdkerrors.Register(SubModuleName, 2, "connection already exists") - ErrConnectionNotFound = sdkerrors.Register(SubModuleName, 3, "connection not found") - ErrClientConnectionPathsNotFound = sdkerrors.Register(SubModuleName, 4, "light client connection paths not found") - ErrConnectionPath = sdkerrors.Register(SubModuleName, 5, "connection path is not associated to the given light client") - ErrInvalidConnectionState = sdkerrors.Register(SubModuleName, 6, "invalid connection state") - ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 7, "invalid counterparty connection") - ErrInvalidConnection = sdkerrors.Register(SubModuleName, 8, "invalid connection") - ErrInvalidVersion = sdkerrors.Register(SubModuleName, 9, "invalid connection version") - ErrVersionNegotiationFailed = sdkerrors.Register(SubModuleName, 10, "connection version negotiation failed") - ErrInvalidConnectionIdentifier = sdkerrors.Register(SubModuleName, 11, "invalid connection identifier") + ErrConnectionExists = errorsmod.Register(SubModuleName, 2, "connection already exists") + ErrConnectionNotFound = errorsmod.Register(SubModuleName, 3, "connection not found") + ErrClientConnectionPathsNotFound = errorsmod.Register(SubModuleName, 4, "light client connection paths not found") + ErrConnectionPath = errorsmod.Register(SubModuleName, 5, "connection path is not associated to the given light client") + ErrInvalidConnectionState = errorsmod.Register(SubModuleName, 6, "invalid connection state") + ErrInvalidCounterparty = errorsmod.Register(SubModuleName, 7, "invalid counterparty connection") + ErrInvalidConnection = errorsmod.Register(SubModuleName, 8, "invalid connection") + ErrInvalidVersion = errorsmod.Register(SubModuleName, 9, "invalid connection version") + ErrVersionNegotiationFailed = errorsmod.Register(SubModuleName, 10, "connection version negotiation failed") + ErrInvalidConnectionIdentifier = errorsmod.Register(SubModuleName, 11, "invalid connection identifier") ) diff --git a/modules/core/03-connection/types/events.go b/modules/core/03-connection/types/events.go index 5afbb5fb904..64e40853d21 100644 --- a/modules/core/03-connection/types/events.go +++ b/modules/core/03-connection/types/events.go @@ -3,7 +3,7 @@ package types import ( "fmt" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // IBC connection events @@ -21,5 +21,5 @@ var ( EventTypeConnectionOpenAck = "connection_open_ack" EventTypeConnectionOpenConfirm = "connection_open_confirm" - AttributeValueCategory = fmt.Sprintf("%s_%s", host.ModuleName, SubModuleName) + AttributeValueCategory = fmt.Sprintf("%s_%s", ibcexported.ModuleName, SubModuleName) ) diff --git a/modules/core/03-connection/types/expected_keepers.go b/modules/core/03-connection/types/expected_keepers.go index fdb248423b5..5945766726d 100644 --- a/modules/core/03-connection/types/expected_keepers.go +++ b/modules/core/03-connection/types/expected_keepers.go @@ -3,7 +3,7 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // ClientKeeper expected account IBC client keeper @@ -12,6 +12,6 @@ type ClientKeeper interface { GetClientConsensusState(ctx sdk.Context, clientID string, height exported.Height) (exported.ConsensusState, bool) GetSelfConsensusState(ctx sdk.Context, height exported.Height) (exported.ConsensusState, error) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error - IterateClients(ctx sdk.Context, cb func(string, exported.ClientState) bool) + IterateClientStates(ctx sdk.Context, prefix []byte, cb func(string, exported.ClientState) bool) ClientStore(ctx sdk.Context, clientID string) sdk.KVStore } diff --git a/modules/core/03-connection/types/genesis.go b/modules/core/03-connection/types/genesis.go index 9f6bab811e3..3a4e5595f35 100644 --- a/modules/core/03-connection/types/genesis.go +++ b/modules/core/03-connection/types/genesis.go @@ -3,7 +3,7 @@ package types import ( "fmt" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // NewConnectionPaths creates a ConnectionPaths instance. @@ -42,7 +42,7 @@ func DefaultGenesisState() GenesisState { func (gs GenesisState) Validate() error { // keep track of the max sequence to ensure it is less than // the next sequence used in creating connection identifers. - var maxSequence uint64 = 0 + var maxSequence uint64 for i, conn := range gs.Connections { sequence, err := ParseConnectionSequence(conn.Id) diff --git a/modules/core/03-connection/types/genesis.pb.go b/modules/core/03-connection/types/genesis.pb.go index 98fd5a14f67..126cc211457 100644 --- a/modules/core/03-connection/types/genesis.pb.go +++ b/modules/core/03-connection/types/genesis.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -102,30 +102,30 @@ func init() { } var fileDescriptor_1879d34bc6ac3cd7 = []byte{ - // 358 bytes of a gzipped FileDescriptorProto + // 359 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xc1, 0x4e, 0xea, 0x40, 0x14, 0x86, 0xdb, 0x0b, 0x61, 0x51, 0xee, 0xaa, 0xb9, 0x17, 0x1b, 0x16, 0x53, 0x52, 0x8d, 0xb0, - 0x90, 0x19, 0x01, 0x57, 0x86, 0x55, 0x5d, 0x18, 0x77, 0x04, 0x8c, 0x0b, 0x13, 0x43, 0xda, 0xe1, - 0x58, 0x26, 0xa1, 0x33, 0x95, 0x19, 0x88, 0x3c, 0x81, 0x0b, 0x37, 0x3e, 0x16, 0x4b, 0x96, 0xae, - 0x88, 0x81, 0x37, 0xe0, 0x09, 0x4c, 0x5b, 0x62, 0xd1, 0xd8, 0x5d, 0x73, 0xce, 0xf7, 0x7f, 0x7f, - 0x3a, 0xc7, 0x38, 0x61, 0x3e, 0x25, 0x54, 0x4c, 0x81, 0x50, 0xc1, 0x39, 0x50, 0xc5, 0x04, 0x27, - 0xf3, 0x16, 0x09, 0x80, 0x83, 0x64, 0x12, 0x47, 0x53, 0xa1, 0x84, 0x59, 0x61, 0x3e, 0xc5, 0x31, - 0x85, 0x33, 0x0a, 0xcf, 0x5b, 0xd5, 0x7f, 0x81, 0x08, 0x44, 0x82, 0x90, 0xf8, 0x2b, 0xa5, 0xab, - 0xf5, 0x1c, 0xe7, 0x41, 0x36, 0x01, 0x9d, 0xd7, 0x82, 0xf1, 0xf7, 0x3a, 0x2d, 0x1a, 0x28, 0x4f, - 0x81, 0x79, 0x6b, 0x94, 0x33, 0x48, 0x5a, 0x7a, 0xad, 0xd0, 0x28, 0xb7, 0xcf, 0xf0, 0xef, 0xed, - 0xf8, 0x66, 0x04, 0x5c, 0xb1, 0x47, 0x06, 0xa3, 0xab, 0xaf, 0xb9, 0x5b, 0x5c, 0xae, 0x6d, 0xad, - 0x7f, 0xa8, 0x31, 0x5f, 0x74, 0xe3, 0x88, 0x4e, 0x18, 0x70, 0x35, 0xcc, 0xc6, 0xc3, 0xc8, 0x53, - 0x63, 0x69, 0xfd, 0x49, 0x2a, 0xea, 0x79, 0x15, 0x99, 0xb8, 0x17, 0xe3, 0xee, 0x69, 0x6c, 0xdf, - 0xad, 0x6d, 0xb4, 0xf0, 0xc2, 0xc9, 0xa5, 0x93, 0x63, 0x75, 0xfa, 0xff, 0xd3, 0xcd, 0x8f, 0xb8, - 0xf9, 0x60, 0x58, 0x1c, 0x9e, 0xbf, 0x05, 0x24, 0x3c, 0xcd, 0x80, 0x53, 0xb0, 0x0a, 0x35, 0xbd, - 0x51, 0x74, 0x8f, 0x77, 0x6b, 0xdb, 0x4e, 0xe5, 0x79, 0xa4, 0xd3, 0xaf, 0xc4, 0xab, 0xcc, 0x3d, - 0xd8, 0x2f, 0xcc, 0xae, 0x51, 0x8a, 0xbc, 0xa9, 0x17, 0x4a, 0xab, 0x58, 0xd3, 0x1b, 0xe5, 0x36, - 0xca, 0xfb, 0xad, 0x5e, 0x42, 0xed, 0xdf, 0x6a, 0x9f, 0x71, 0xef, 0x96, 0x1b, 0xa4, 0xaf, 0x36, - 0x48, 0xff, 0xd8, 0x20, 0xfd, 0x6d, 0x8b, 0xb4, 0xd5, 0x16, 0x69, 0xef, 0x5b, 0xa4, 0xdd, 0x77, - 0x03, 0xa6, 0xc6, 0x33, 0x1f, 0x53, 0x11, 0x12, 0x2a, 0x64, 0x28, 0x24, 0x61, 0x3e, 0x6d, 0x06, - 0x82, 0xcc, 0x2f, 0x48, 0x28, 0x46, 0xb3, 0x09, 0xc8, 0xf4, 0xe0, 0xe7, 0x9d, 0xe6, 0xc1, 0xcd, - 0xd5, 0x22, 0x02, 0xe9, 0x97, 0x92, 0x63, 0x77, 0x3e, 0x03, 0x00, 0x00, 0xff, 0xff, 0x25, 0x96, - 0xe3, 0x66, 0x6b, 0x02, 0x00, 0x00, + 0x90, 0x19, 0x81, 0x85, 0x89, 0x61, 0x55, 0x17, 0xc6, 0x1d, 0x01, 0xe3, 0xc2, 0xc4, 0x90, 0x76, + 0x38, 0x96, 0x49, 0xe8, 0x4c, 0x65, 0x06, 0x22, 0x4f, 0xe0, 0xc2, 0x8d, 0x8f, 0xc5, 0x92, 0xa5, + 0x2b, 0x62, 0xe0, 0x0d, 0x78, 0x02, 0xd3, 0x96, 0x58, 0x34, 0x76, 0xd7, 0x9c, 0xf3, 0xfd, 0xdf, + 0x9f, 0xce, 0x31, 0x4e, 0x98, 0x4f, 0x09, 0x15, 0x53, 0x20, 0x54, 0x70, 0x0e, 0x54, 0x31, 0xc1, + 0xc9, 0xbc, 0x45, 0x02, 0xe0, 0x20, 0x99, 0xc4, 0xd1, 0x54, 0x28, 0x61, 0x56, 0x98, 0x4f, 0x71, + 0x4c, 0xe1, 0x8c, 0xc2, 0xf3, 0x56, 0xf5, 0x5f, 0x20, 0x02, 0x91, 0x20, 0x24, 0xfe, 0x4a, 0xe9, + 0x6a, 0x3d, 0xc7, 0x79, 0x90, 0x4d, 0x40, 0xe7, 0xb5, 0x60, 0xfc, 0xbd, 0x4e, 0x8b, 0x06, 0xca, + 0x53, 0x60, 0xde, 0x1a, 0xe5, 0x0c, 0x92, 0x96, 0x5e, 0x2b, 0x34, 0xca, 0xed, 0x33, 0xfc, 0x7b, + 0x3b, 0xbe, 0x19, 0x01, 0x57, 0xec, 0x91, 0xc1, 0xe8, 0xea, 0x6b, 0xee, 0x16, 0x97, 0x6b, 0x5b, + 0xeb, 0x1f, 0x6a, 0xcc, 0x17, 0xdd, 0x38, 0xa2, 0x13, 0x06, 0x5c, 0x0d, 0xb3, 0xf1, 0x30, 0xf2, + 0xd4, 0x58, 0x5a, 0x7f, 0x92, 0x8a, 0x7a, 0x5e, 0x45, 0x26, 0xee, 0xc5, 0xb8, 0x7b, 0x1a, 0xdb, + 0x77, 0x6b, 0x1b, 0x2d, 0xbc, 0x70, 0x72, 0xe9, 0xe4, 0x58, 0x9d, 0xfe, 0xff, 0x74, 0xf3, 0x23, + 0x6e, 0x3e, 0x18, 0x16, 0x87, 0xe7, 0x6f, 0x01, 0x09, 0x4f, 0x33, 0xe0, 0x14, 0xac, 0x42, 0x4d, + 0x6f, 0x14, 0xdd, 0xe3, 0xdd, 0xda, 0xb6, 0x53, 0x79, 0x1e, 0xe9, 0xf4, 0x2b, 0xf1, 0x2a, 0x73, + 0x0f, 0xf6, 0x0b, 0xb3, 0x6b, 0x94, 0x22, 0x6f, 0xea, 0x85, 0xd2, 0x2a, 0xd6, 0xf4, 0x46, 0xb9, + 0x8d, 0xf2, 0x7e, 0xab, 0x97, 0x50, 0xfb, 0xb7, 0xda, 0x67, 0xdc, 0xbb, 0xe5, 0x06, 0xe9, 0xab, + 0x0d, 0xd2, 0x3f, 0x36, 0x48, 0x7f, 0xdb, 0x22, 0x6d, 0xb5, 0x45, 0xda, 0xfb, 0x16, 0x69, 0xf7, + 0xdd, 0x80, 0xa9, 0xf1, 0xcc, 0xc7, 0x54, 0x84, 0x84, 0x0a, 0x19, 0x0a, 0x49, 0x98, 0x4f, 0x9b, + 0x81, 0x20, 0xf3, 0x0b, 0x12, 0x8a, 0xd1, 0x6c, 0x02, 0x32, 0x3d, 0xf8, 0x79, 0xa7, 0x79, 0x70, + 0x73, 0xb5, 0x88, 0x40, 0xfa, 0xa5, 0xe4, 0xd8, 0x9d, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x56, + 0x1d, 0xd8, 0x5e, 0x6b, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/modules/core/03-connection/types/genesis_test.go b/modules/core/03-connection/types/genesis_test.go index eec0a61c9af..0b513cfdace 100644 --- a/modules/core/03-connection/types/genesis_test.go +++ b/modules/core/03-connection/types/genesis_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func TestValidateGenesis(t *testing.T) { diff --git a/modules/core/03-connection/types/keys.go b/modules/core/03-connection/types/keys.go index eaf6eb18e97..1b0b5132d90 100644 --- a/modules/core/03-connection/types/keys.go +++ b/modules/core/03-connection/types/keys.go @@ -4,9 +4,9 @@ import ( "fmt" "regexp" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) const ( @@ -50,12 +50,12 @@ func IsValidConnectionID(connectionID string) bool { // ParseConnectionSequence parses the connection sequence from the connection identifier. func ParseConnectionSequence(connectionID string) (uint64, error) { if !IsConnectionIDFormat(connectionID) { - return 0, sdkerrors.Wrap(host.ErrInvalidID, "connection identifier is not in the format: `connection-{N}`") + return 0, errorsmod.Wrap(host.ErrInvalidID, "connection identifier is not in the format: `connection-{N}`") } sequence, err := host.ParseIdentifier(connectionID, ConnectionPrefix) if err != nil { - return 0, sdkerrors.Wrap(err, "invalid connection identifier") + return 0, errorsmod.Wrap(err, "invalid connection identifier") } return sequence, nil diff --git a/modules/core/03-connection/types/keys_test.go b/modules/core/03-connection/types/keys_test.go index 1df435836da..2185ebc462c 100644 --- a/modules/core/03-connection/types/keys_test.go +++ b/modules/core/03-connection/types/keys_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) // tests ParseConnectionSequence and IsValidConnectionID diff --git a/modules/core/03-connection/types/msgs.go b/modules/core/03-connection/types/msgs.go index fb410d095b2..d05efe72758 100644 --- a/modules/core/03-connection/types/msgs.go +++ b/modules/core/03-connection/types/msgs.go @@ -1,14 +1,15 @@ package types import ( + errorsmod "cosmossdk.io/errors" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( @@ -23,6 +24,7 @@ var ( // NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance. It sets the // counterparty connection identifier to be empty. +// //nolint:interfacer func NewMsgConnectionOpenInit( clientID, counterpartyClientID string, @@ -43,21 +45,21 @@ func NewMsgConnectionOpenInit( // ValidateBasic implements sdk.Msg. func (msg MsgConnectionOpenInit) ValidateBasic() error { if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { - return sdkerrors.Wrap(err, "invalid client ID") + return errorsmod.Wrap(err, "invalid client ID") } if msg.Counterparty.ConnectionId != "" { - return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty connection identifier must be empty") + return errorsmod.Wrap(ErrInvalidCounterparty, "counterparty connection identifier must be empty") } // NOTE: Version can be nil on MsgConnectionOpenInit if msg.Version != nil { if err := ValidateVersion(msg.Version); err != nil { - return sdkerrors.Wrap(err, "basic validation of the provided version failed") + return errorsmod.Wrap(err, "basic validation of the provided version failed") } } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return msg.Counterparty.ValidateBasic() } @@ -72,21 +74,21 @@ func (msg MsgConnectionOpenInit) GetSigners() []sdk.AccAddress { } // NewMsgConnectionOpenTry creates a new MsgConnectionOpenTry instance +// //nolint:interfacer func NewMsgConnectionOpenTry( - previousConnectionID, clientID, counterpartyConnectionID, - counterpartyClientID string, counterpartyClient exported.ClientState, + clientID, counterpartyConnectionID, counterpartyClientID string, + counterpartyClient exported.ClientState, counterpartyPrefix commitmenttypes.MerklePrefix, counterpartyVersions []*Version, delayPeriod uint64, proofInit, proofClient, proofConsensus []byte, proofHeight, consensusHeight clienttypes.Height, signer string, ) *MsgConnectionOpenTry { counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) - csAny, _ := clienttypes.PackClientState(counterpartyClient) + protoAny, _ := clienttypes.PackClientState(counterpartyClient) return &MsgConnectionOpenTry{ - PreviousConnectionId: previousConnectionID, ClientId: clientID, - ClientState: csAny, + ClientState: protoAny, Counterparty: counterparty, CounterpartyVersions: counterpartyVersions, DelayPeriod: delayPeriod, @@ -101,55 +103,49 @@ func NewMsgConnectionOpenTry( // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenTry) ValidateBasic() error { - // an empty connection identifier indicates that a connection identifier should be generated if msg.PreviousConnectionId != "" { - if !IsValidConnectionID(msg.PreviousConnectionId) { - return sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "invalid previous connection ID") - } + return errorsmod.Wrap(ErrInvalidConnectionIdentifier, "previous connection identifier must be empty, this field has been deprecated as crossing hellos are no longer supported") } if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { - return sdkerrors.Wrap(err, "invalid client ID") + return errorsmod.Wrap(err, "invalid client ID") } // counterparty validate basic allows empty counterparty connection identifiers if err := host.ConnectionIdentifierValidator(msg.Counterparty.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty connection ID") + return errorsmod.Wrap(err, "invalid counterparty connection ID") } if msg.ClientState == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "counterparty client is nil") + return errorsmod.Wrap(clienttypes.ErrInvalidClient, "counterparty client is nil") } clientState, err := clienttypes.UnpackClientState(msg.ClientState) if err != nil { - return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "unpack err: %v", err) + return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "unpack err: %v", err) } if err := clientState.Validate(); err != nil { - return sdkerrors.Wrap(err, "counterparty client is invalid") + return errorsmod.Wrap(err, "counterparty client is invalid") } if len(msg.CounterpartyVersions) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidVersion, "empty counterparty versions") + return errorsmod.Wrap(ibcerrors.ErrInvalidVersion, "empty counterparty versions") } for i, version := range msg.CounterpartyVersions { if err := ValidateVersion(version); err != nil { - return sdkerrors.Wrapf(err, "basic validation failed on version with index %d", i) + return errorsmod.Wrapf(err, "basic validation failed on version with index %d", i) } } if len(msg.ProofInit) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") } if len(msg.ProofClient) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit empty proof client") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit empty proof client") } if len(msg.ProofConsensus) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof of consensus state") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof of consensus state") } if msg.ConsensusHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "consensus height must be non-zero") + return errorsmod.Wrap(ibcerrors.ErrInvalidHeight, "consensus height must be non-zero") } _, err = sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return msg.Counterparty.ValidateBasic() } @@ -169,6 +165,7 @@ func (msg MsgConnectionOpenTry) GetSigners() []sdk.AccAddress { } // NewMsgConnectionOpenAck creates a new MsgConnectionOpenAck instance +// //nolint:interfacer func NewMsgConnectionOpenAck( connectionID, counterpartyConnectionID string, counterpartyClient exported.ClientState, @@ -177,11 +174,11 @@ func NewMsgConnectionOpenAck( version *Version, signer string, ) *MsgConnectionOpenAck { - csAny, _ := clienttypes.PackClientState(counterpartyClient) + protoAny, _ := clienttypes.PackClientState(counterpartyClient) return &MsgConnectionOpenAck{ ConnectionId: connectionID, CounterpartyConnectionId: counterpartyConnectionID, - ClientState: csAny, + ClientState: protoAny, ProofTry: proofTry, ProofClient: proofClient, ProofConsensus: proofConsensus, @@ -203,39 +200,36 @@ func (msg MsgConnectionOpenAck) ValidateBasic() error { return ErrInvalidConnectionIdentifier } if err := host.ConnectionIdentifierValidator(msg.CounterpartyConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty connection ID") + return errorsmod.Wrap(err, "invalid counterparty connection ID") } if err := ValidateVersion(msg.Version); err != nil { return err } if msg.ClientState == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "counterparty client is nil") + return errorsmod.Wrap(clienttypes.ErrInvalidClient, "counterparty client is nil") } clientState, err := clienttypes.UnpackClientState(msg.ClientState) if err != nil { - return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "unpack err: %v", err) + return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "unpack err: %v", err) } if err := clientState.Validate(); err != nil { - return sdkerrors.Wrap(err, "counterparty client is invalid") + return errorsmod.Wrap(err, "counterparty client is invalid") } if len(msg.ProofTry) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof try") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof try") } if len(msg.ProofClient) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit empty proof client") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit empty proof client") } if len(msg.ProofConsensus) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof of consensus state") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof of consensus state") } if msg.ConsensusHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "consensus height must be non-zero") + return errorsmod.Wrap(ibcerrors.ErrInvalidHeight, "consensus height must be non-zero") } _, err = sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil } @@ -250,6 +244,7 @@ func (msg MsgConnectionOpenAck) GetSigners() []sdk.AccAddress { } // NewMsgConnectionOpenConfirm creates a new MsgConnectionOpenConfirm instance +// //nolint:interfacer func NewMsgConnectionOpenConfirm( connectionID string, proofAck []byte, proofHeight clienttypes.Height, @@ -269,14 +264,11 @@ func (msg MsgConnectionOpenConfirm) ValidateBasic() error { return ErrInvalidConnectionIdentifier } if len(msg.ProofAck) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil } diff --git a/modules/core/03-connection/types/msgs_test.go b/modules/core/03-connection/types/msgs_test.go index 8c4945973bf..c146f782c40 100644 --- a/modules/core/03-connection/types/msgs_test.go +++ b/modules/core/03-connection/types/msgs_test.go @@ -10,14 +10,15 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + log "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - "github.com/cosmos/ibc-go/v4/testing/simapp" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) var ( @@ -46,11 +47,13 @@ func (suite *MsgTestSuite) SetupTest() { app := simapp.Setup(false) db := dbm.NewMemDB() - store := rootmulti.NewStore(db) + dblog := log.TestingLogger() + store := rootmulti.NewStore(db, dblog) storeKey := storetypes.NewKVStoreKey("iavlStoreKey") store.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) - store.LoadVersion(0) + err := store.LoadVersion(0) + suite.Require().NoError(err) iavlStore := store.GetCommitStore(storeKey).(*iavl.Store) iavlStore.Set([]byte("KEY"), []byte("VALUE")) @@ -107,20 +110,22 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() { func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { prefix := commitmenttypes.NewMerklePrefix([]byte("storePrefixKey")) - clientState := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + clientState := ibctm.NewClientState( + chainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, ) + protoAny, err := clienttypes.PackClientState(clientState) + suite.Require().NoError(err) // Pack consensus state into any to test unpacking error - consState := ibctmtypes.NewConsensusState( + consState := ibctm.NewConsensusState( time.Now(), commitmenttypes.NewMerkleRoot([]byte("root")), []byte("nextValsHash"), ) invalidAny := clienttypes.MustPackConsensusState(consState) counterparty := types.NewCounterparty("connectiontotest", "clienttotest", prefix) // invalidClientState fails validateBasic - invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + invalidClient := ibctm.NewClientState( + chainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, ) testCases := []struct { @@ -128,24 +133,22 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { msg *types.MsgConnectionOpenTry expPass bool }{ - {"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid connection ID", types.NewMsgConnectionOpenTry("(invalidconnection)", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid client ID", types.NewMsgConnectionOpenTry(connectionID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid counterparty client ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid nil counterparty client", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid client unpacking", &types.MsgConnectionOpenTry{connectionID, "clienttotesta", invalidAny, counterparty, 500, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer}, false}, - {"counterparty failed validate", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty counterparty prefix", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty counterpartyVersions", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofInit", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofClient", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofConsensus", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, - {"invalid proofHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false}, - {"invalid consensusHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, - {"empty singer", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, ""), false}, - {"success", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, - {"invalid version", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"non empty connection ID", &types.MsgConnectionOpenTry{"connection-0", "clienttotesta", protoAny, counterparty, 500, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer, nil}, false}, + {"invalid client ID", types.NewMsgConnectionOpenTry("test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry("clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid counterparty client ID", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid nil counterparty client", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid client unpacking", &types.MsgConnectionOpenTry{"", "clienttotesta", invalidAny, counterparty, 500, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer, nil}, false}, + {"counterparty failed validate", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty counterparty prefix", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty counterpartyVersions", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofInit", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofClient", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofConsensus", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, + {"invalid consensusHeight", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, + {"empty singer", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, ""), false}, + {"success", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, + {"invalid version", types.NewMsgConnectionOpenTry("clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, 500, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, } for _, tc := range testCases { @@ -159,19 +162,19 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { } func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { - clientState := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + clientState := ibctm.NewClientState( + chainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, ) // Pack consensus state into any to test unpacking error - consState := ibctmtypes.NewConsensusState( + consState := ibctm.NewConsensusState( time.Now(), commitmenttypes.NewMerkleRoot([]byte("root")), []byte("nextValsHash"), ) invalidAny := clienttypes.MustPackConsensusState(consState) // invalidClientState fails validateBasic - invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + invalidClient := ibctm.NewClientState( + chainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, ) connectionID := "connection-0" @@ -183,12 +186,11 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { {"invalid connection ID", types.NewMsgConnectionOpenAck("test/conn1", connectionID, clientState, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, ibctesting.ConnectionVersion, signer), false}, {"invalid counterparty connection ID", types.NewMsgConnectionOpenAck(connectionID, "test/conn1", clientState, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, ibctesting.ConnectionVersion, signer), false}, {"invalid nil counterparty client", types.NewMsgConnectionOpenAck(connectionID, connectionID, nil, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, ibctesting.ConnectionVersion, signer), false}, - {"invalid unpacking counterparty client", &types.MsgConnectionOpenAck{connectionID, connectionID, ibctesting.ConnectionVersion, invalidAny, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer}, false}, + {"invalid unpacking counterparty client", &types.MsgConnectionOpenAck{connectionID, connectionID, ibctesting.ConnectionVersion, invalidAny, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer, nil}, false}, {"counterparty client failed validate", types.NewMsgConnectionOpenAck(connectionID, connectionID, invalidClient, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, ibctesting.ConnectionVersion, signer), false}, {"empty proofTry", types.NewMsgConnectionOpenAck(connectionID, connectionID, clientState, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, ibctesting.ConnectionVersion, signer), false}, {"empty proofClient", types.NewMsgConnectionOpenAck(connectionID, connectionID, clientState, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, ibctesting.ConnectionVersion, signer), false}, {"empty proofConsensus", types.NewMsgConnectionOpenAck(connectionID, connectionID, clientState, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, ibctesting.ConnectionVersion, signer), false}, - {"invalid proofHeight", types.NewMsgConnectionOpenAck(connectionID, connectionID, clientState, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, ibctesting.ConnectionVersion, signer), false}, {"invalid consensusHeight", types.NewMsgConnectionOpenAck(connectionID, connectionID, clientState, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), ibctesting.ConnectionVersion, signer), false}, {"invalid version", types.NewMsgConnectionOpenAck(connectionID, connectionID, clientState, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, &types.Version{}, signer), false}, {"empty signer", types.NewMsgConnectionOpenAck(connectionID, connectionID, clientState, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, ibctesting.ConnectionVersion, ""), false}, @@ -209,7 +211,6 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { testMsgs := []*types.MsgConnectionOpenConfirm{ types.NewMsgConnectionOpenConfirm("test/conn1", suite.proof, clientHeight, signer), types.NewMsgConnectionOpenConfirm(connectionID, emptyProof, clientHeight, signer), - types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clienttypes.ZeroHeight(), signer), types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clientHeight, ""), types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clientHeight, signer), } @@ -221,9 +222,8 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { }{ {testMsgs[0], false, "invalid connection ID"}, {testMsgs[1], false, "empty proofTry"}, - {testMsgs[2], false, "invalid proofHeight"}, - {testMsgs[3], false, "empty signer"}, - {testMsgs[4], true, "success"}, + {testMsgs[2], false, "empty signer"}, + {testMsgs[3], true, "success"}, } for i, tc := range testCases { diff --git a/modules/core/03-connection/types/params_test.go b/modules/core/03-connection/types/params_test.go index fa8e61a7556..8afc407d723 100644 --- a/modules/core/03-connection/types/params_test.go +++ b/modules/core/03-connection/types/params_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" ) func TestValidateParams(t *testing.T) { diff --git a/modules/core/03-connection/types/query.go b/modules/core/03-connection/types/query.go index 095995cec63..a5277bee696 100644 --- a/modules/core/03-connection/types/query.go +++ b/modules/core/03-connection/types/query.go @@ -3,8 +3,8 @@ package types import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( diff --git a/modules/core/03-connection/types/query.pb.go b/modules/core/03-connection/types/query.pb.go index b180904f9c5..2d87fa0c3ff 100644 --- a/modules/core/03-connection/types/query.pb.go +++ b/modules/core/03-connection/types/query.pb.go @@ -8,10 +8,10 @@ import ( fmt "fmt" types1 "github.com/cosmos/cosmos-sdk/codec/types" query "github.com/cosmos/cosmos-sdk/types/query" - types "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -617,6 +617,89 @@ func (m *QueryConnectionConsensusStateResponse) GetProofHeight() types.Height { return types.Height{} } +// QueryConnectionParamsRequest is the request type for the Query/ConnectionParams RPC method. +type QueryConnectionParamsRequest struct { +} + +func (m *QueryConnectionParamsRequest) Reset() { *m = QueryConnectionParamsRequest{} } +func (m *QueryConnectionParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryConnectionParamsRequest) ProtoMessage() {} +func (*QueryConnectionParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cd8d529f8c7cd06b, []int{10} +} +func (m *QueryConnectionParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryConnectionParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConnectionParamsRequest.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 *QueryConnectionParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConnectionParamsRequest.Merge(m, src) +} +func (m *QueryConnectionParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryConnectionParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConnectionParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryConnectionParamsRequest proto.InternalMessageInfo + +// QueryConnectionParamsResponse is the response type for the Query/ConnectionParams RPC method. +type QueryConnectionParamsResponse struct { + // params defines the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (m *QueryConnectionParamsResponse) Reset() { *m = QueryConnectionParamsResponse{} } +func (m *QueryConnectionParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryConnectionParamsResponse) ProtoMessage() {} +func (*QueryConnectionParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cd8d529f8c7cd06b, []int{11} +} +func (m *QueryConnectionParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryConnectionParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConnectionParamsResponse.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 *QueryConnectionParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConnectionParamsResponse.Merge(m, src) +} +func (m *QueryConnectionParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryConnectionParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConnectionParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryConnectionParamsResponse proto.InternalMessageInfo + +func (m *QueryConnectionParamsResponse) GetParams() *Params { + if m != nil { + return m.Params + } + return nil +} + func init() { proto.RegisterType((*QueryConnectionRequest)(nil), "ibc.core.connection.v1.QueryConnectionRequest") proto.RegisterType((*QueryConnectionResponse)(nil), "ibc.core.connection.v1.QueryConnectionResponse") @@ -628,6 +711,8 @@ func init() { proto.RegisterType((*QueryConnectionClientStateResponse)(nil), "ibc.core.connection.v1.QueryConnectionClientStateResponse") proto.RegisterType((*QueryConnectionConsensusStateRequest)(nil), "ibc.core.connection.v1.QueryConnectionConsensusStateRequest") proto.RegisterType((*QueryConnectionConsensusStateResponse)(nil), "ibc.core.connection.v1.QueryConnectionConsensusStateResponse") + proto.RegisterType((*QueryConnectionParamsRequest)(nil), "ibc.core.connection.v1.QueryConnectionParamsRequest") + proto.RegisterType((*QueryConnectionParamsResponse)(nil), "ibc.core.connection.v1.QueryConnectionParamsResponse") } func init() { @@ -635,63 +720,67 @@ func init() { } var fileDescriptor_cd8d529f8c7cd06b = []byte{ - // 895 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x31, 0x6f, 0x23, 0x45, - 0x14, 0xf6, 0x38, 0xb9, 0xd3, 0x65, 0x1c, 0xee, 0x60, 0xe4, 0xbb, 0x33, 0x0b, 0x38, 0x61, 0x8f, - 0x90, 0x1c, 0x70, 0x33, 0xe7, 0x84, 0x3b, 0x1d, 0x21, 0x46, 0xe0, 0x28, 0x90, 0x34, 0x51, 0x58, - 0x24, 0x0a, 0x9a, 0x68, 0x77, 0x3d, 0x59, 0xaf, 0x64, 0xef, 0x38, 0x9e, 0xb5, 0x91, 0x15, 0x59, - 0x48, 0xfc, 0x01, 0x90, 0x68, 0x68, 0x68, 0x29, 0xf8, 0x03, 0x14, 0x74, 0x54, 0x29, 0x23, 0xd1, - 0xa4, 0x8a, 0x90, 0x43, 0x4b, 0xc3, 0x2f, 0x40, 0x3b, 0x33, 0xce, 0xce, 0xda, 0xeb, 0xc4, 0xb1, - 0x2e, 0xdd, 0xe6, 0xcd, 0x7b, 0xf3, 0xbe, 0xef, 0x7b, 0x6f, 0x3e, 0x07, 0x9a, 0xbe, 0xe3, 0x12, - 0x97, 0xb5, 0x28, 0x71, 0x59, 0x10, 0x50, 0x37, 0xf4, 0x59, 0x40, 0x3a, 0x25, 0x72, 0xd8, 0xa6, - 0xad, 0x2e, 0x6e, 0xb6, 0x58, 0xc8, 0xd0, 0x03, 0xdf, 0x71, 0x71, 0x94, 0x83, 0xe3, 0x1c, 0xdc, - 0x29, 0x19, 0x79, 0x8f, 0x79, 0x4c, 0xa4, 0x90, 0xe8, 0x4b, 0x66, 0x1b, 0xef, 0xb9, 0x8c, 0x37, - 0x18, 0x27, 0x8e, 0xcd, 0xa9, 0xbc, 0x86, 0x74, 0x4a, 0x0e, 0x0d, 0xed, 0x12, 0x69, 0xda, 0x9e, - 0x1f, 0xd8, 0xa2, 0x5c, 0xe6, 0x2e, 0xc4, 0xdd, 0xeb, 0x3e, 0x0d, 0xc2, 0xa8, 0xb3, 0xfc, 0x52, - 0x09, 0xcb, 0x63, 0xe0, 0x69, 0x40, 0x64, 0xe2, 0x9b, 0x1e, 0x63, 0x5e, 0x9d, 0x12, 0xbb, 0xe9, - 0x13, 0x3b, 0x08, 0x58, 0x28, 0xda, 0x70, 0x75, 0xfa, 0xba, 0x3a, 0x15, 0x7f, 0x39, 0xed, 0x03, - 0x62, 0x07, 0x8a, 0x9c, 0x59, 0x86, 0x0f, 0xbe, 0x8c, 0x40, 0x6e, 0x5e, 0xdc, 0x68, 0xd1, 0xc3, - 0x36, 0xe5, 0x21, 0x7a, 0x04, 0x5f, 0x89, 0xdb, 0xec, 0xfb, 0xd5, 0x02, 0x58, 0x04, 0x2b, 0x73, - 0xd6, 0x7c, 0x1c, 0xdc, 0xa9, 0x9a, 0x7f, 0x00, 0xf8, 0x70, 0xa4, 0x9e, 0x37, 0x59, 0xc0, 0x29, - 0xda, 0x82, 0x30, 0xce, 0x15, 0xd5, 0xb9, 0xd5, 0x25, 0x9c, 0x2e, 0x26, 0x8e, 0xeb, 0xb7, 0x82, - 0xaa, 0xa5, 0x15, 0xa2, 0x3c, 0xbc, 0xd5, 0x6c, 0x31, 0x76, 0x50, 0xc8, 0x2e, 0x82, 0x95, 0x79, - 0x4b, 0xfe, 0x81, 0x36, 0xe1, 0xbc, 0xf8, 0xd8, 0xaf, 0x51, 0xdf, 0xab, 0x85, 0x85, 0x19, 0x71, - 0xbd, 0xa1, 0x5d, 0x2f, 0x75, 0xec, 0x94, 0xf0, 0xb6, 0xc8, 0xa8, 0xcc, 0x1e, 0x9f, 0x2d, 0x64, - 0xac, 0x9c, 0xa8, 0x92, 0x21, 0xd3, 0x1e, 0x01, 0xcf, 0x07, 0xec, 0x3f, 0x87, 0x30, 0x1e, 0x97, - 0x02, 0xff, 0x2e, 0x96, 0xb3, 0xc5, 0xd1, 0x6c, 0xb1, 0x5c, 0x11, 0x35, 0x5b, 0xbc, 0x67, 0x7b, - 0x54, 0xd5, 0x5a, 0x5a, 0xa5, 0xf9, 0x2f, 0x80, 0x85, 0xd1, 0x1e, 0x4a, 0xa1, 0x5d, 0x98, 0x8b, - 0x89, 0xf2, 0x02, 0x58, 0x9c, 0x59, 0xc9, 0xad, 0x7e, 0x30, 0x4e, 0xa2, 0x9d, 0x2a, 0x0d, 0x42, - 0xff, 0xc0, 0xa7, 0x55, 0x4d, 0x6c, 0xfd, 0x02, 0xf4, 0x45, 0x02, 0x74, 0x56, 0x80, 0x5e, 0xbe, - 0x12, 0xb4, 0x04, 0xa3, 0xa3, 0x46, 0x2f, 0xe0, 0xed, 0x6b, 0xea, 0xaa, 0xf2, 0xcd, 0x0d, 0xf8, - 0x96, 0xa4, 0x2b, 0xd2, 0x52, 0x84, 0x7d, 0x03, 0xce, 0xc9, 0x2b, 0xe2, 0x95, 0xba, 0x23, 0x03, - 0x3b, 0x55, 0xf3, 0x57, 0x00, 0x8b, 0xe3, 0xca, 0x95, 0x66, 0x8f, 0xe1, 0xab, 0xda, 0x5a, 0x36, - 0xed, 0xb0, 0x26, 0x85, 0x9b, 0xb3, 0xee, 0xc5, 0xf1, 0xbd, 0x28, 0x7c, 0x93, 0x9b, 0xe3, 0xc0, - 0xb7, 0x87, 0xa6, 0x2a, 0x11, 0x7f, 0x15, 0xda, 0xe1, 0x60, 0x0f, 0x50, 0x39, 0xf5, 0x05, 0x55, - 0x0a, 0xff, 0x9d, 0x2d, 0xe4, 0xbb, 0x76, 0xa3, 0xbe, 0x6e, 0x26, 0x8e, 0xcd, 0xa1, 0xb7, 0xd5, - 0x07, 0xd0, 0xbc, 0xac, 0x89, 0x12, 0xc4, 0x86, 0x0f, 0xfd, 0x8b, 0xcd, 0xd8, 0x57, 0xda, 0xf2, - 0x28, 0x45, 0xad, 0xed, 0xe3, 0x34, 0x6a, 0xda, 0x32, 0x69, 0x77, 0xde, 0xf7, 0xd3, 0xc2, 0x37, - 0x29, 0xe4, 0xef, 0x00, 0xbe, 0x33, 0x4c, 0x32, 0xa2, 0x15, 0xf0, 0x36, 0x7f, 0x89, 0x62, 0xa2, - 0x65, 0x78, 0xaf, 0x45, 0x3b, 0x3e, 0x8f, 0x4e, 0x83, 0x76, 0xc3, 0xa1, 0x2d, 0x41, 0x66, 0xd6, - 0xba, 0x3b, 0x08, 0xef, 0x8a, 0x68, 0x22, 0x51, 0x23, 0xa6, 0x25, 0x2a, 0xe4, 0x67, 0x00, 0x2e, - 0x5d, 0x81, 0x5c, 0x4d, 0xa8, 0x0c, 0xa3, 0xd5, 0x94, 0x27, 0x89, 0xc9, 0xe4, 0xb1, 0x34, 0x66, - 0x3c, 0x30, 0x66, 0xfc, 0x59, 0xd0, 0xb5, 0xee, 0xba, 0x89, 0x6b, 0x92, 0x2f, 0x26, 0x9b, 0x7c, - 0x31, 0xf1, 0x68, 0x66, 0x2e, 0x1b, 0xcd, 0xec, 0x14, 0xa3, 0x59, 0xfd, 0xe1, 0x0e, 0xbc, 0x25, - 0x08, 0xa2, 0xdf, 0x00, 0x84, 0x31, 0x4b, 0x84, 0xc7, 0x39, 0x54, 0xfa, 0x2f, 0x89, 0x41, 0x26, - 0xce, 0x97, 0x82, 0x99, 0x1f, 0x7f, 0xff, 0xd7, 0x3f, 0x3f, 0x65, 0x9f, 0xa1, 0x35, 0x72, 0xe5, - 0xef, 0x1f, 0x27, 0x47, 0x89, 0xb9, 0xf7, 0xd0, 0x2f, 0x00, 0xe6, 0x34, 0xe3, 0x40, 0x93, 0x76, - 0x1f, 0x38, 0x94, 0xf1, 0x74, 0xf2, 0x02, 0x85, 0xf7, 0x7d, 0x81, 0x77, 0x09, 0x3d, 0x9a, 0x00, - 0x2f, 0xfa, 0x13, 0xc0, 0xd7, 0x46, 0xec, 0x0d, 0x3d, 0xbb, 0xbc, 0xe9, 0x18, 0x37, 0x35, 0x9e, - 0x5f, 0xb7, 0x4c, 0x21, 0xfe, 0x44, 0x20, 0x7e, 0x81, 0x9e, 0x8f, 0x45, 0x2c, 0x37, 0x2e, 0x29, - 0xf4, 0x60, 0x0b, 0x7b, 0xe8, 0x14, 0xc0, 0xfb, 0xa9, 0xb6, 0x84, 0x3e, 0x9a, 0x50, 0xbd, 0x51, - 0xbf, 0x34, 0xd6, 0xa7, 0x29, 0x55, 0x84, 0xb6, 0x05, 0xa1, 0x0a, 0xfa, 0x74, 0x8a, 0x95, 0x21, - 0xba, 0x69, 0xa2, 0x9f, 0xb3, 0xb0, 0x30, 0xee, 0x49, 0xa3, 0x8d, 0x49, 0x21, 0xa6, 0x79, 0x98, - 0x51, 0x9e, 0xb2, 0x5a, 0x71, 0xfc, 0x4e, 0x70, 0xec, 0xa2, 0x6f, 0xa7, 0xe2, 0x98, 0x74, 0x20, - 0x32, 0x70, 0x33, 0x72, 0x34, 0xe4, 0x8b, 0x3d, 0x22, 0x4d, 0x43, 0x3b, 0x90, 0x81, 0x5e, 0xe5, - 0xeb, 0xe3, 0x7e, 0x11, 0x9c, 0xf4, 0x8b, 0xe0, 0xef, 0x7e, 0x11, 0xfc, 0x78, 0x5e, 0xcc, 0x9c, - 0x9c, 0x17, 0x33, 0xa7, 0xe7, 0xc5, 0xcc, 0x37, 0x1b, 0x9e, 0x1f, 0xd6, 0xda, 0x0e, 0x76, 0x59, - 0x83, 0xa8, 0x7f, 0x80, 0x7d, 0xc7, 0x7d, 0xe2, 0x31, 0xd2, 0xf9, 0x90, 0x34, 0x58, 0xb5, 0x5d, - 0xa7, 0x5c, 0x22, 0x7e, 0xba, 0xf6, 0x44, 0x03, 0x1d, 0x76, 0x9b, 0x94, 0x3b, 0xb7, 0x85, 0xff, - 0xad, 0xfd, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x76, 0x45, 0xa5, 0xf9, 0x8e, 0x0b, 0x00, 0x00, + // 958 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x41, 0x6f, 0xdc, 0x44, + 0x14, 0xce, 0x6c, 0xd2, 0x88, 0xbc, 0x0d, 0x6d, 0x19, 0xa5, 0xed, 0x62, 0x8a, 0x13, 0x5c, 0xd2, + 0xa4, 0x40, 0x3d, 0xdd, 0x84, 0x84, 0x52, 0x12, 0x04, 0xa9, 0x0a, 0xcd, 0xa5, 0x0a, 0x46, 0x02, + 0x89, 0x4b, 0x64, 0x7b, 0x27, 0x8e, 0xa5, 0xac, 0x67, 0xbb, 0xe3, 0x5d, 0xb4, 0xaa, 0x22, 0x24, + 0x7e, 0x01, 0x12, 0x17, 0x2e, 0x5c, 0x41, 0xe2, 0x0f, 0x20, 0xc4, 0x8d, 0x53, 0x8f, 0x95, 0xb8, + 0xf4, 0x14, 0xa1, 0x0d, 0x57, 0x2e, 0xfc, 0x02, 0xe4, 0x99, 0x71, 0x3d, 0xde, 0xb5, 0x93, 0xcd, + 0x8a, 0xdc, 0x36, 0x6f, 0xde, 0x7b, 0xf3, 0x7d, 0xdf, 0x7b, 0xf3, 0x59, 0x01, 0x2b, 0xf4, 0x7c, + 0xe2, 0xb3, 0x36, 0x25, 0x3e, 0x8b, 0x22, 0xea, 0xc7, 0x21, 0x8b, 0x48, 0xb7, 0x4e, 0x1e, 0x77, + 0x68, 0xbb, 0x67, 0xb7, 0xda, 0x2c, 0x66, 0xf8, 0x6a, 0xe8, 0xf9, 0x76, 0x92, 0x63, 0x67, 0x39, + 0x76, 0xb7, 0x6e, 0xcc, 0x05, 0x2c, 0x60, 0x22, 0x85, 0x24, 0xbf, 0x64, 0xb6, 0xf1, 0x96, 0xcf, + 0x78, 0x93, 0x71, 0xe2, 0xb9, 0x9c, 0xca, 0x36, 0xa4, 0x5b, 0xf7, 0x68, 0xec, 0xd6, 0x49, 0xcb, + 0x0d, 0xc2, 0xc8, 0x15, 0xe5, 0x32, 0x77, 0x3e, 0xbb, 0xfd, 0x20, 0xa4, 0x51, 0x9c, 0xdc, 0x2c, + 0x7f, 0xa9, 0x84, 0xa5, 0x12, 0x78, 0x1a, 0x10, 0x99, 0x78, 0x3d, 0x60, 0x2c, 0x38, 0xa0, 0xc4, + 0x6d, 0x85, 0xc4, 0x8d, 0x22, 0x16, 0x8b, 0x6b, 0xb8, 0x3a, 0x7d, 0x55, 0x9d, 0x8a, 0xbf, 0xbc, + 0xce, 0x1e, 0x71, 0x23, 0x45, 0xce, 0xda, 0x84, 0xab, 0x9f, 0x25, 0x20, 0xef, 0xbf, 0xe8, 0xe8, + 0xd0, 0xc7, 0x1d, 0xca, 0x63, 0x7c, 0x03, 0x5e, 0xce, 0xae, 0xd9, 0x0d, 0x1b, 0x35, 0xb4, 0x80, + 0x96, 0x67, 0x9c, 0xd9, 0x2c, 0xb8, 0xdd, 0xb0, 0x7e, 0x47, 0x70, 0x6d, 0xa8, 0x9e, 0xb7, 0x58, + 0xc4, 0x29, 0x7e, 0x00, 0x90, 0xe5, 0x8a, 0xea, 0xea, 0xca, 0xa2, 0x5d, 0x2c, 0xa6, 0x9d, 0xd5, + 0x3f, 0x88, 0x1a, 0x8e, 0x56, 0x88, 0xe7, 0xe0, 0x42, 0xab, 0xcd, 0xd8, 0x5e, 0xad, 0xb2, 0x80, + 0x96, 0x67, 0x1d, 0xf9, 0x07, 0xbe, 0x0f, 0xb3, 0xe2, 0xc7, 0xee, 0x3e, 0x0d, 0x83, 0xfd, 0xb8, + 0x36, 0x29, 0xda, 0x1b, 0x5a, 0x7b, 0xa9, 0x63, 0xb7, 0x6e, 0x3f, 0x14, 0x19, 0x5b, 0x53, 0x4f, + 0x8f, 0xe6, 0x27, 0x9c, 0xaa, 0xa8, 0x92, 0x21, 0xcb, 0x1d, 0x02, 0xcf, 0x53, 0xf6, 0x9f, 0x00, + 0x64, 0xe3, 0x52, 0xe0, 0x6f, 0xda, 0x72, 0xb6, 0x76, 0x32, 0x5b, 0x5b, 0xae, 0x88, 0x9a, 0xad, + 0xbd, 0xe3, 0x06, 0x54, 0xd5, 0x3a, 0x5a, 0xa5, 0xf5, 0x0f, 0x82, 0xda, 0xf0, 0x1d, 0x4a, 0xa1, + 0x47, 0x50, 0xcd, 0x88, 0xf2, 0x1a, 0x5a, 0x98, 0x5c, 0xae, 0xae, 0xbc, 0x53, 0x26, 0xd1, 0x76, + 0x83, 0x46, 0x71, 0xb8, 0x17, 0xd2, 0x86, 0x26, 0xb6, 0xde, 0x00, 0x7f, 0x9a, 0x03, 0x5d, 0x11, + 0xa0, 0x97, 0x4e, 0x05, 0x2d, 0xc1, 0xe8, 0xa8, 0xf1, 0x5d, 0x98, 0x3e, 0xa3, 0xae, 0x2a, 0xdf, + 0xda, 0x80, 0xd7, 0x25, 0x5d, 0x91, 0x56, 0x20, 0xec, 0x6b, 0x30, 0x23, 0x5b, 0x64, 0x2b, 0xf5, + 0x92, 0x0c, 0x6c, 0x37, 0xac, 0x9f, 0x10, 0x98, 0x65, 0xe5, 0x4a, 0xb3, 0x5b, 0x70, 0x59, 0x5b, + 0xcb, 0x96, 0x1b, 0xef, 0x4b, 0xe1, 0x66, 0x9c, 0x4b, 0x59, 0x7c, 0x27, 0x09, 0x9f, 0xe7, 0xe6, + 0x78, 0xf0, 0xc6, 0xc0, 0x54, 0x25, 0xe2, 0xcf, 0x63, 0x37, 0x4e, 0xf7, 0x00, 0x6f, 0x16, 0xbe, + 0xa0, 0xad, 0xda, 0xbf, 0x47, 0xf3, 0x73, 0x3d, 0xb7, 0x79, 0x70, 0xcf, 0xca, 0x1d, 0x5b, 0x03, + 0x6f, 0xab, 0x8f, 0xc0, 0x3a, 0xe9, 0x12, 0x25, 0x88, 0x0b, 0xd7, 0xc2, 0x17, 0x9b, 0xb1, 0xab, + 0xb4, 0xe5, 0x49, 0x8a, 0x5a, 0xdb, 0x5b, 0x45, 0xd4, 0xb4, 0x65, 0xd2, 0x7a, 0x5e, 0x09, 0x8b, + 0xc2, 0xe7, 0x29, 0xe4, 0xaf, 0x08, 0xde, 0x1c, 0x24, 0x99, 0xd0, 0x8a, 0x78, 0x87, 0xff, 0x8f, + 0x62, 0xe2, 0x25, 0xb8, 0xd4, 0xa6, 0xdd, 0x90, 0x27, 0xa7, 0x51, 0xa7, 0xe9, 0xd1, 0xb6, 0x20, + 0x33, 0xe5, 0x5c, 0x4c, 0xc3, 0x8f, 0x44, 0x34, 0x97, 0xa8, 0x11, 0xd3, 0x12, 0x15, 0xf2, 0x23, + 0x04, 0x8b, 0xa7, 0x20, 0x57, 0x13, 0xda, 0x84, 0x64, 0x35, 0xe5, 0x49, 0x6e, 0x32, 0x73, 0xb6, + 0x34, 0x66, 0x3b, 0x35, 0x66, 0xfb, 0xe3, 0xa8, 0xe7, 0x5c, 0xf4, 0x73, 0x6d, 0xf2, 0x2f, 0xa6, + 0x92, 0x7f, 0x31, 0xd9, 0x68, 0x26, 0x4f, 0x1a, 0xcd, 0xd4, 0x38, 0xa3, 0x31, 0xe1, 0xfa, 0x00, + 0xbf, 0x1d, 0xb7, 0xed, 0x36, 0xd3, 0x97, 0x6c, 0x7d, 0x99, 0x3e, 0xf5, 0xa1, 0x73, 0xc5, 0x7b, + 0x1d, 0xa6, 0x5b, 0x22, 0xa2, 0xe8, 0x9a, 0x65, 0xce, 0xa6, 0xea, 0x54, 0xf6, 0xca, 0x6f, 0x33, + 0x70, 0x41, 0x74, 0xc6, 0xbf, 0x20, 0x80, 0xac, 0x3d, 0xb6, 0xcb, 0x1a, 0x14, 0x7f, 0xc2, 0x0c, + 0x32, 0x72, 0xbe, 0x44, 0x6c, 0x7d, 0xf0, 0xed, 0x9f, 0x7f, 0x7f, 0x5f, 0x59, 0xc3, 0xab, 0xe4, + 0xd4, 0x0f, 0x2f, 0x27, 0x4f, 0x72, 0x0b, 0x77, 0x88, 0x7f, 0x44, 0x50, 0xd5, 0x1c, 0x0b, 0x8f, + 0x7a, 0x7b, 0x2a, 0xa8, 0x71, 0x67, 0xf4, 0x02, 0x85, 0xf7, 0x6d, 0x81, 0x77, 0x11, 0xdf, 0x18, + 0x01, 0x2f, 0xfe, 0x03, 0xc1, 0x2b, 0x43, 0xbe, 0x8a, 0xd7, 0x4e, 0xbe, 0xb4, 0xc4, 0xc6, 0x8d, + 0xf5, 0xb3, 0x96, 0x29, 0xc4, 0x1f, 0x0a, 0xc4, 0x77, 0xf1, 0x7a, 0x29, 0x62, 0xb9, 0xea, 0x79, + 0xa1, 0xd3, 0xf5, 0x3f, 0xc4, 0xcf, 0x11, 0x5c, 0x29, 0xf4, 0x43, 0xfc, 0xfe, 0x88, 0xea, 0x0d, + 0x1b, 0xb5, 0x71, 0x6f, 0x9c, 0x52, 0x45, 0xe8, 0xa1, 0x20, 0xb4, 0x85, 0x3f, 0x1a, 0x63, 0x65, + 0x88, 0xee, 0xd6, 0xf8, 0x87, 0x0a, 0xd4, 0xca, 0xbc, 0x04, 0x6f, 0x8c, 0x0a, 0xb1, 0xc8, 0x3c, + 0x8d, 0xcd, 0x31, 0xab, 0x15, 0xc7, 0x6f, 0x04, 0xc7, 0x1e, 0xfe, 0x7a, 0x2c, 0x8e, 0x79, 0xeb, + 0x23, 0xa9, 0x8d, 0x92, 0x27, 0x03, 0x86, 0x7c, 0x48, 0xa4, 0x5b, 0x69, 0x07, 0x32, 0x70, 0x88, + 0x7f, 0x46, 0x70, 0x79, 0xd0, 0x66, 0xf0, 0xbb, 0x23, 0x92, 0xca, 0xb9, 0x96, 0xb1, 0x76, 0xc6, + 0x2a, 0x25, 0xc1, 0x4d, 0x21, 0xc1, 0x02, 0x36, 0xcb, 0x24, 0x90, 0xde, 0xb5, 0xf5, 0xc5, 0xd3, + 0xbe, 0x89, 0x9e, 0xf5, 0x4d, 0xf4, 0x57, 0xdf, 0x44, 0xdf, 0x1d, 0x9b, 0x13, 0xcf, 0x8e, 0xcd, + 0x89, 0xe7, 0xc7, 0xe6, 0xc4, 0x57, 0x1b, 0x41, 0x18, 0xef, 0x77, 0x3c, 0xdb, 0x67, 0x4d, 0xa2, + 0xfe, 0x47, 0x08, 0x3d, 0xff, 0x76, 0xc0, 0x48, 0xf7, 0x3d, 0xd2, 0x64, 0x8d, 0xce, 0x01, 0xe5, + 0xb2, 0xf1, 0x9d, 0xd5, 0xdb, 0x5a, 0xef, 0xb8, 0xd7, 0xa2, 0xdc, 0x9b, 0x16, 0x9f, 0x88, 0xd5, + 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x40, 0x19, 0x02, 0xb1, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -719,6 +808,8 @@ type QueryClient interface { // ConnectionConsensusState queries the consensus state associated with the // connection. ConnectionConsensusState(ctx context.Context, in *QueryConnectionConsensusStateRequest, opts ...grpc.CallOption) (*QueryConnectionConsensusStateResponse, error) + // ConnectionParams queries all parameters of the ibc connection submodule. + ConnectionParams(ctx context.Context, in *QueryConnectionParamsRequest, opts ...grpc.CallOption) (*QueryConnectionParamsResponse, error) } type queryClient struct { @@ -774,6 +865,15 @@ func (c *queryClient) ConnectionConsensusState(ctx context.Context, in *QueryCon return out, nil } +func (c *queryClient) ConnectionParams(ctx context.Context, in *QueryConnectionParamsRequest, opts ...grpc.CallOption) (*QueryConnectionParamsResponse, error) { + out := new(QueryConnectionParamsResponse) + err := c.cc.Invoke(ctx, "/ibc.core.connection.v1.Query/ConnectionParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Connection queries an IBC connection end. @@ -789,6 +889,8 @@ type QueryServer interface { // ConnectionConsensusState queries the consensus state associated with the // connection. ConnectionConsensusState(context.Context, *QueryConnectionConsensusStateRequest) (*QueryConnectionConsensusStateResponse, error) + // ConnectionParams queries all parameters of the ibc connection submodule. + ConnectionParams(context.Context, *QueryConnectionParamsRequest) (*QueryConnectionParamsResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -810,6 +912,9 @@ func (*UnimplementedQueryServer) ConnectionClientState(ctx context.Context, req func (*UnimplementedQueryServer) ConnectionConsensusState(ctx context.Context, req *QueryConnectionConsensusStateRequest) (*QueryConnectionConsensusStateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ConnectionConsensusState not implemented") } +func (*UnimplementedQueryServer) ConnectionParams(ctx context.Context, req *QueryConnectionParamsRequest) (*QueryConnectionParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConnectionParams not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -905,6 +1010,24 @@ func _Query_ConnectionConsensusState_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _Query_ConnectionParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConnectionParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ConnectionParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.connection.v1.Query/ConnectionParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ConnectionParams(ctx, req.(*QueryConnectionParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "ibc.core.connection.v1.Query", HandlerType: (*QueryServer)(nil), @@ -929,6 +1052,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "ConnectionConsensusState", Handler: _Query_ConnectionConsensusState_Handler, }, + { + MethodName: "ConnectionParams", + Handler: _Query_ConnectionParams_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "ibc/core/connection/v1/query.proto", @@ -1370,6 +1497,64 @@ func (m *QueryConnectionConsensusStateResponse) MarshalToSizedBuffer(dAtA []byte return len(dAtA) - i, nil } +func (m *QueryConnectionParamsRequest) 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 *QueryConnectionParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConnectionParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryConnectionParamsResponse) 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 *QueryConnectionParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConnectionParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Params != nil { + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -1555,6 +1740,28 @@ func (m *QueryConnectionConsensusStateResponse) Size() (n int) { return n } +func (m *QueryConnectionParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryConnectionParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Params != nil { + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2806,6 +3013,142 @@ func (m *QueryConnectionConsensusStateResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryConnectionParamsRequest) 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: QueryConnectionParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConnectionParamsRequest: 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 *QueryConnectionParamsResponse) 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: QueryConnectionParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConnectionParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Params == nil { + m.Params = &Params{} + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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/modules/core/03-connection/types/query.pb.gw.go b/modules/core/03-connection/types/query.pb.gw.go index 2de52353c78..71acc0e9997 100644 --- a/modules/core/03-connection/types/query.pb.gw.go +++ b/modules/core/03-connection/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join func request_Query_Connection_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryConnectionRequest @@ -327,15 +329,35 @@ func local_request_Query_ConnectionConsensusState_0(ctx context.Context, marshal } +func request_Query_ConnectionParams_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConnectionParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.ConnectionParams(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ConnectionParams_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConnectionParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.ConnectionParams(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. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_Connection_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 { @@ -343,6 +365,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Connection_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) @@ -356,6 +379,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_Connections_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 { @@ -363,6 +388,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Connections_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) @@ -376,6 +402,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ClientConnections_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 { @@ -383,6 +411,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ClientConnections_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) @@ -396,6 +425,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ConnectionClientState_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 { @@ -403,6 +434,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ConnectionClientState_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) @@ -416,6 +448,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ConnectionConsensusState_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 { @@ -423,6 +457,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ConnectionConsensusState_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) @@ -433,6 +468,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_ConnectionParams_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_ConnectionParams_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_ConnectionParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -574,19 +632,41 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_ConnectionParams_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_ConnectionParams_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_ConnectionParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } var ( - pattern_Query_Connection_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "connection", "v1", "connections", "connection_id"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Connection_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "connection", "v1", "connections", "connection_id"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Connections_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "connection", "v1", "connections"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Connections_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "connection", "v1", "connections"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ClientConnections_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "connection", "v1", "client_connections", "client_id"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ClientConnections_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "connection", "v1", "client_connections", "client_id"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConnectionClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"ibc", "core", "connection", "v1", "connections", "connection_id", "client_state"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ConnectionClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"ibc", "core", "connection", "v1", "connections", "connection_id", "client_state"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConnectionConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 2, 7, 1, 0, 4, 1, 5, 8, 2, 9, 1, 0, 4, 1, 5, 10}, []string{"ibc", "core", "connection", "v1", "connections", "connection_id", "consensus_state", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ConnectionConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 2, 7, 1, 0, 4, 1, 5, 8, 2, 9, 1, 0, 4, 1, 5, 10}, []string{"ibc", "core", "connection", "v1", "connections", "connection_id", "consensus_state", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConnectionParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "connection", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -599,4 +679,6 @@ var ( forward_Query_ConnectionClientState_0 = runtime.ForwardResponseMessage forward_Query_ConnectionConsensusState_0 = runtime.ForwardResponseMessage + + forward_Query_ConnectionParams_0 = runtime.ForwardResponseMessage ) diff --git a/modules/core/03-connection/types/tx.pb.go b/modules/core/03-connection/types/tx.pb.go index 4862d905716..acfeff2341d 100644 --- a/modules/core/03-connection/types/tx.pb.go +++ b/modules/core/03-connection/types/tx.pb.go @@ -7,10 +7,10 @@ import ( context "context" fmt "fmt" types "github.com/cosmos/cosmos-sdk/codec/types" - types1 "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types1 "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -131,6 +131,8 @@ type MsgConnectionOpenTry struct { ProofConsensus []byte `protobuf:"bytes,10,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` ConsensusHeight types1.Height `protobuf:"bytes,11,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` Signer string `protobuf:"bytes,12,opt,name=signer,proto3" json:"signer,omitempty"` + // optional proof data for host state machines that are unable to introspect their own consensus state + HostConsensusStateProof []byte `protobuf:"bytes,13,opt,name=host_consensus_state_proof,json=hostConsensusStateProof,proto3" json:"host_consensus_state_proof,omitempty"` } func (m *MsgConnectionOpenTry) Reset() { *m = MsgConnectionOpenTry{} } @@ -220,6 +222,8 @@ type MsgConnectionOpenAck struct { ProofConsensus []byte `protobuf:"bytes,8,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` ConsensusHeight types1.Height `protobuf:"bytes,9,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` Signer string `protobuf:"bytes,10,opt,name=signer,proto3" json:"signer,omitempty"` + // optional proof data for host state machines that are unable to introspect their own consensus state + HostConsensusStateProof []byte `protobuf:"bytes,11,opt,name=host_consensus_state_proof,json=hostConsensusStateProof,proto3" json:"host_consensus_state_proof,omitempty"` } func (m *MsgConnectionOpenAck) Reset() { *m = MsgConnectionOpenAck{} } @@ -387,66 +391,68 @@ func init() { func init() { proto.RegisterFile("ibc/core/connection/v1/tx.proto", fileDescriptor_5d00fde5fc97399e) } var fileDescriptor_5d00fde5fc97399e = []byte{ - // 929 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x31, 0x73, 0xe3, 0x44, - 0x14, 0xb6, 0x62, 0x27, 0xb1, 0xd7, 0x86, 0xbb, 0x5b, 0x9c, 0x44, 0x88, 0x3b, 0xcb, 0x08, 0x18, - 0x52, 0x10, 0xe9, 0x7c, 0x17, 0x66, 0x20, 0x03, 0x45, 0xec, 0x86, 0x14, 0x07, 0x37, 0xe2, 0xe6, - 0x66, 0xb8, 0xc6, 0x63, 0xcb, 0x1b, 0x65, 0xc7, 0xb6, 0x56, 0xa3, 0x95, 0x0d, 0xa2, 0xa5, 0x61, - 0xa8, 0xe8, 0x68, 0xef, 0x3f, 0xf0, 0x27, 0xae, 0xbc, 0x92, 0x4a, 0x03, 0x49, 0x43, 0xad, 0x8e, - 0x8e, 0xd1, 0xae, 0x24, 0xaf, 0x6d, 0x79, 0xb0, 0x71, 0xae, 0xdb, 0xb7, 0xef, 0x7b, 0xef, 0xed, - 0xbe, 0xf7, 0x7d, 0x3b, 0x0b, 0x54, 0xdc, 0xb7, 0x0c, 0x8b, 0x78, 0xc8, 0xb0, 0x88, 0xe3, 0x20, - 0xcb, 0xc7, 0xc4, 0x31, 0xa6, 0x2d, 0xc3, 0xff, 0x41, 0x77, 0x3d, 0xe2, 0x13, 0x78, 0x88, 0xfb, - 0x96, 0x1e, 0x03, 0xf4, 0x19, 0x40, 0x9f, 0xb6, 0x94, 0xba, 0x4d, 0x6c, 0xc2, 0x20, 0x46, 0xbc, - 0xe2, 0x68, 0xe5, 0x5d, 0x9b, 0x10, 0x7b, 0x84, 0x0c, 0x66, 0xf5, 0x27, 0x97, 0x46, 0xcf, 0x09, - 0x12, 0x97, 0x50, 0x69, 0x84, 0x91, 0xe3, 0xc7, 0x55, 0xf8, 0x2a, 0x01, 0x7c, 0xbc, 0xe2, 0x28, - 0x42, 0x5d, 0x06, 0xd4, 0x7e, 0xdf, 0x01, 0x07, 0x4f, 0xa8, 0xdd, 0xc9, 0xf6, 0xbf, 0x71, 0x91, - 0x73, 0xe1, 0x60, 0x1f, 0xb6, 0x40, 0x85, 0xa7, 0xec, 0xe2, 0x81, 0x2c, 0x35, 0xa5, 0xe3, 0x4a, - 0xbb, 0x1e, 0x85, 0xea, 0xdd, 0xa0, 0x37, 0x1e, 0x9d, 0x69, 0x99, 0x4b, 0x33, 0xcb, 0x7c, 0x7d, - 0x31, 0x80, 0x5f, 0x83, 0x9a, 0x45, 0x26, 0x8e, 0x8f, 0x3c, 0xb7, 0xe7, 0xf9, 0x81, 0xbc, 0xd3, - 0x94, 0x8e, 0xab, 0x8f, 0x3e, 0xd4, 0xf3, 0xaf, 0xad, 0x77, 0x04, 0x6c, 0xbb, 0xf4, 0x2a, 0x54, - 0x0b, 0xe6, 0x5c, 0x3c, 0xfc, 0x1c, 0xec, 0x4f, 0x91, 0x47, 0x31, 0x71, 0xe4, 0x22, 0x4b, 0xa5, - 0xae, 0x4a, 0xf5, 0x9c, 0xc3, 0xcc, 0x14, 0x0f, 0xcf, 0x40, 0x6d, 0x80, 0x46, 0xbd, 0xa0, 0xeb, - 0x22, 0x0f, 0x93, 0x81, 0x5c, 0x6a, 0x4a, 0xc7, 0xa5, 0xf6, 0x51, 0x14, 0xaa, 0xef, 0xf0, 0x0b, - 0x88, 0x5e, 0xcd, 0xac, 0x32, 0xf3, 0x29, 0xb3, 0xe0, 0x21, 0xd8, 0xa3, 0xd8, 0x76, 0x90, 0x27, - 0xef, 0xc6, 0xd7, 0x36, 0x13, 0xeb, 0xac, 0xfc, 0xf3, 0x4b, 0xb5, 0xf0, 0xf7, 0x4b, 0xb5, 0xa0, - 0xa9, 0xe0, 0x41, 0x6e, 0xd3, 0x4c, 0x44, 0x5d, 0xe2, 0x50, 0xa4, 0xfd, 0xb6, 0x0f, 0xea, 0x4b, - 0x88, 0x67, 0x5e, 0xf0, 0x7f, 0xba, 0xfa, 0x1d, 0x38, 0x74, 0x3d, 0x34, 0xc5, 0x64, 0x42, 0xbb, - 0xb3, 0x5b, 0xc7, 0xf1, 0x3b, 0x2c, 0xfe, 0x83, 0x28, 0x54, 0x1f, 0xf0, 0xf8, 0x7c, 0x9c, 0x26, - 0x4b, 0x66, 0x3d, 0x75, 0xcd, 0x8e, 0x74, 0x31, 0x80, 0x4f, 0x41, 0x2d, 0x29, 0x49, 0xfd, 0x9e, - 0x8f, 0x92, 0x2e, 0xd7, 0x75, 0xce, 0x3c, 0x3d, 0x65, 0x9e, 0x7e, 0xee, 0x04, 0x62, 0xef, 0xc4, - 0x18, 0xcd, 0xac, 0x72, 0xf3, 0xdb, 0xd8, 0x5a, 0xa2, 0x40, 0x69, 0x4b, 0x0a, 0x2c, 0xce, 0x71, - 0x77, 0x83, 0x39, 0x4e, 0xc1, 0x81, 0x98, 0xab, 0x9b, 0x70, 0x83, 0xca, 0x7b, 0xcd, 0xe2, 0x1a, - 0x64, 0x6a, 0x37, 0xa3, 0x50, 0xbd, 0x9f, 0xdc, 0x38, 0x2f, 0x8f, 0x66, 0xd6, 0xc5, 0xfd, 0x24, - 0x8c, 0xc2, 0x17, 0xa0, 0xe6, 0x7a, 0x84, 0x5c, 0x76, 0xaf, 0x10, 0xb6, 0xaf, 0x7c, 0x79, 0x9f, - 0xf5, 0x40, 0x11, 0xca, 0x71, 0xa9, 0x4e, 0x5b, 0xfa, 0x57, 0x0c, 0xd1, 0x7e, 0x2f, 0xbe, 0xf9, - 0xec, 0x4e, 0x62, 0xb4, 0x66, 0x56, 0x99, 0xc9, 0x91, 0xf0, 0x14, 0x00, 0xee, 0xc5, 0x0e, 0xf6, - 0xe5, 0x72, 0x53, 0x3a, 0xae, 0xb5, 0x0f, 0xa2, 0x50, 0xbd, 0x27, 0x46, 0xc6, 0x3e, 0xcd, 0xac, - 0x30, 0x83, 0x69, 0xf9, 0x2c, 0x3d, 0x11, 0xaf, 0x2c, 0x57, 0x58, 0xdc, 0xd1, 0x62, 0x45, 0xee, - 0x4d, 0x2b, 0x76, 0x98, 0x05, 0x3b, 0xe0, 0x4e, 0xe2, 0x8d, 0x99, 0xed, 0xd0, 0x09, 0x95, 0x01, - 0x0b, 0x57, 0xa2, 0x50, 0x3d, 0x9c, 0x0b, 0x4f, 0x01, 0x9a, 0xf9, 0x36, 0xcf, 0x90, 0x6e, 0xc0, - 0x4b, 0x70, 0x37, 0xf3, 0xa6, 0x6d, 0xa9, 0xfe, 0x67, 0x5b, 0xd4, 0xa4, 0x2d, 0x47, 0xe9, 0x10, - 0xe6, 0x33, 0x68, 0xe6, 0x9d, 0x6c, 0x2b, 0x69, 0xcf, 0x4c, 0xba, 0xb5, 0x15, 0xd2, 0x6d, 0x80, - 0xfb, 0x79, 0xc2, 0xcc, 0x94, 0xfb, 0xd7, 0x6e, 0x8e, 0x72, 0xcf, 0xad, 0x21, 0xfc, 0x12, 0xbc, - 0x35, 0xaf, 0x3e, 0xae, 0x5e, 0x39, 0x0a, 0xd5, 0x7a, 0x76, 0x3e, 0x41, 0x74, 0x31, 0x91, 0x05, - 0xa9, 0x59, 0x40, 0x99, 0x23, 0x51, 0x9e, 0x92, 0x3f, 0x8a, 0x42, 0xf5, 0xfd, 0x1c, 0xc2, 0x2d, - 0x24, 0x96, 0x45, 0xe7, 0x9c, 0x9e, 0xb7, 0x78, 0x30, 0x17, 0x9f, 0x82, 0xd2, 0xd6, 0x4f, 0xc1, - 0xa2, 0x0c, 0x76, 0x6f, 0x51, 0x06, 0x2d, 0xc0, 0xd9, 0xdd, 0xf5, 0xbd, 0x40, 0xde, 0x63, 0x74, - 0x14, 0x9e, 0xd1, 0xcc, 0xa5, 0x99, 0x65, 0xb6, 0x8e, 0x5f, 0xde, 0x45, 0x0d, 0xec, 0x6f, 0xa7, - 0x81, 0xf2, 0xad, 0x68, 0xa0, 0xf2, 0x46, 0x35, 0x00, 0x36, 0xd0, 0xc0, 0xb9, 0x35, 0xcc, 0x34, - 0xf0, 0xcb, 0x0e, 0x90, 0x97, 0x00, 0x1d, 0xe2, 0x5c, 0x62, 0x6f, 0xbc, 0xad, 0x0e, 0xb2, 0xc9, - 0xf5, 0xac, 0x21, 0xa3, 0x7d, 0xce, 0xe4, 0x7a, 0xd6, 0x30, 0x9d, 0x5c, 0xac, 0xbc, 0x45, 0x22, - 0x15, 0x6f, 0x91, 0x48, 0xb3, 0x66, 0x95, 0x56, 0x34, 0x4b, 0x03, 0xcd, 0x55, 0xbd, 0x48, 0x1b, - 0xf6, 0xe8, 0x9f, 0x22, 0x28, 0x3e, 0xa1, 0x36, 0xfc, 0x11, 0xc0, 0x9c, 0x9f, 0xd4, 0xc9, 0x2a, - 0x11, 0xe6, 0xfe, 0x21, 0x94, 0x4f, 0x37, 0x82, 0xa7, 0x67, 0x80, 0xdf, 0x83, 0x7b, 0xcb, 0xdf, - 0x8d, 0x4f, 0xd6, 0xce, 0xf5, 0xcc, 0x0b, 0x94, 0xd3, 0x4d, 0xd0, 0xab, 0x0b, 0xc7, 0x33, 0x5b, - 0xbf, 0xf0, 0xb9, 0x35, 0xdc, 0xa0, 0xb0, 0x40, 0x53, 0xf8, 0x93, 0x04, 0x0e, 0xf2, 0x39, 0xfa, - 0x70, 0xed, 0x7c, 0x49, 0x84, 0xf2, 0xd9, 0xa6, 0x11, 0xe9, 0x29, 0xda, 0xcf, 0x5f, 0x5d, 0x37, - 0xa4, 0xd7, 0xd7, 0x0d, 0xe9, 0xcf, 0xeb, 0x86, 0xf4, 0xeb, 0x4d, 0xa3, 0xf0, 0xfa, 0xa6, 0x51, - 0xf8, 0xe3, 0xa6, 0x51, 0x78, 0xf1, 0x85, 0x8d, 0xfd, 0xab, 0x49, 0x5f, 0xb7, 0xc8, 0xd8, 0xb0, - 0x08, 0x1d, 0x13, 0x6a, 0xe0, 0xbe, 0x75, 0x62, 0x13, 0x63, 0x7a, 0x6a, 0x8c, 0xc9, 0x60, 0x32, - 0x42, 0x94, 0x7f, 0xd2, 0x1f, 0x3e, 0x3e, 0x11, 0xfe, 0xe9, 0x7e, 0xe0, 0x22, 0xda, 0xdf, 0x63, - 0x4f, 0xee, 0xe3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x12, 0x14, 0x2b, 0x56, 0x0c, 0x00, - 0x00, + // 965 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x31, 0x73, 0xe3, 0x44, + 0x14, 0xb6, 0x62, 0xc7, 0xb1, 0xd7, 0x3e, 0xee, 0x6e, 0x71, 0x12, 0x21, 0xee, 0x2c, 0x23, 0x60, + 0x48, 0x41, 0xa4, 0xf3, 0xdd, 0x31, 0x40, 0x80, 0x22, 0x76, 0x43, 0x8a, 0x83, 0x8c, 0xb8, 0xb9, + 0x19, 0xae, 0xf1, 0xd8, 0xf2, 0x46, 0xd9, 0xb1, 0xad, 0xf5, 0x68, 0x65, 0x83, 0x68, 0x69, 0x18, + 0x2a, 0x7e, 0x01, 0x73, 0xff, 0x81, 0x3f, 0x71, 0x65, 0x0a, 0x0a, 0x2a, 0x0d, 0x93, 0x34, 0xd4, + 0xee, 0xe8, 0x98, 0xdd, 0x95, 0xe4, 0xb5, 0x23, 0x0f, 0x31, 0x0e, 0x9d, 0x9e, 0xde, 0xf7, 0xde, + 0xdb, 0xf7, 0xf6, 0xfb, 0xde, 0x48, 0x40, 0xc7, 0x3d, 0xc7, 0x72, 0x88, 0x8f, 0x2c, 0x87, 0x78, + 0x1e, 0x72, 0x02, 0x4c, 0x3c, 0x6b, 0xda, 0xb4, 0x82, 0xef, 0xcd, 0xb1, 0x4f, 0x02, 0x02, 0xf7, + 0x70, 0xcf, 0x31, 0x19, 0xc0, 0x9c, 0x03, 0xcc, 0x69, 0x53, 0xab, 0xb9, 0xc4, 0x25, 0x1c, 0x62, + 0xb1, 0x27, 0x81, 0xd6, 0xde, 0x72, 0x09, 0x71, 0x87, 0xc8, 0xe2, 0x56, 0x6f, 0x72, 0x66, 0x75, + 0xbd, 0x30, 0x76, 0x49, 0x95, 0x86, 0x18, 0x79, 0x01, 0xab, 0x22, 0x9e, 0x62, 0xc0, 0x07, 0x2b, + 0x8e, 0x22, 0xd5, 0xe5, 0x40, 0xe3, 0xb7, 0x2d, 0xb0, 0xfb, 0x8c, 0xba, 0xed, 0xf4, 0xfd, 0xd7, + 0x63, 0xe4, 0x9d, 0x78, 0x38, 0x80, 0x4d, 0x50, 0x16, 0x29, 0x3b, 0xb8, 0xaf, 0x2a, 0x0d, 0xe5, + 0xa0, 0xdc, 0xaa, 0xcd, 0x22, 0xfd, 0x5e, 0xd8, 0x1d, 0x0d, 0x8f, 0x8c, 0xd4, 0x65, 0xd8, 0x25, + 0xf1, 0x7c, 0xd2, 0x87, 0x5f, 0x81, 0xaa, 0x43, 0x26, 0x5e, 0x80, 0xfc, 0x71, 0xd7, 0x0f, 0x42, + 0x75, 0xab, 0xa1, 0x1c, 0x54, 0x1e, 0xbf, 0x67, 0x66, 0xb7, 0x6d, 0xb6, 0x25, 0x6c, 0xab, 0xf0, + 0x3a, 0xd2, 0x73, 0xf6, 0x42, 0x3c, 0xfc, 0x14, 0xec, 0x4c, 0x91, 0x4f, 0x31, 0xf1, 0xd4, 0x3c, + 0x4f, 0xa5, 0xaf, 0x4a, 0xf5, 0x42, 0xc0, 0xec, 0x04, 0x0f, 0x8f, 0x40, 0xb5, 0x8f, 0x86, 0xdd, + 0xb0, 0x33, 0x46, 0x3e, 0x26, 0x7d, 0xb5, 0xd0, 0x50, 0x0e, 0x0a, 0xad, 0xfd, 0x59, 0xa4, 0xbf, + 0x29, 0x1a, 0x90, 0xbd, 0x86, 0x5d, 0xe1, 0xe6, 0x29, 0xb7, 0xe0, 0x1e, 0x28, 0x52, 0xec, 0x7a, + 0xc8, 0x57, 0xb7, 0x59, 0xdb, 0x76, 0x6c, 0x1d, 0x95, 0x7e, 0x7a, 0xa5, 0xe7, 0xfe, 0x7a, 0xa5, + 0xe7, 0x0c, 0x1d, 0x3c, 0xcc, 0x1c, 0x9a, 0x8d, 0xe8, 0x98, 0x78, 0x14, 0x19, 0xbf, 0xef, 0x80, + 0xda, 0x35, 0xc4, 0x73, 0x3f, 0xfc, 0x2f, 0x53, 0xfd, 0x16, 0xec, 0x8d, 0x7d, 0x34, 0xc5, 0x64, + 0x42, 0x3b, 0xf3, 0xae, 0x59, 0xfc, 0x16, 0x8f, 0x7f, 0x77, 0x16, 0xe9, 0x0f, 0x45, 0x7c, 0x36, + 0xce, 0x50, 0x15, 0xbb, 0x96, 0xb8, 0xe6, 0x47, 0x3a, 0xe9, 0xc3, 0x53, 0x50, 0x8d, 0x4b, 0xd2, + 0xa0, 0x1b, 0xa0, 0x78, 0xca, 0x35, 0x53, 0x30, 0xcf, 0x4c, 0x98, 0x67, 0x1e, 0x7b, 0xa1, 0x3c, + 0x3b, 0x39, 0xc6, 0xb0, 0x2b, 0xc2, 0xfc, 0x86, 0x59, 0xd7, 0x28, 0x50, 0xd8, 0x90, 0x02, 0xcb, + 0xf7, 0xb8, 0xbd, 0xc6, 0x3d, 0x4e, 0xc1, 0xae, 0x9c, 0xab, 0x13, 0x73, 0x83, 0xaa, 0xc5, 0x46, + 0xfe, 0x06, 0x64, 0x6a, 0x35, 0x66, 0x91, 0xfe, 0x20, 0xee, 0x38, 0x2b, 0x8f, 0x61, 0xd7, 0xe4, + 0xf7, 0x71, 0x18, 0x85, 0x2f, 0x41, 0x75, 0xec, 0x13, 0x72, 0xd6, 0x39, 0x47, 0xd8, 0x3d, 0x0f, + 0xd4, 0x1d, 0x3e, 0x03, 0x4d, 0x2a, 0x27, 0xa4, 0x3a, 0x6d, 0x9a, 0x5f, 0x72, 0x44, 0xeb, 0x6d, + 0xd6, 0xf9, 0xbc, 0x27, 0x39, 0xda, 0xb0, 0x2b, 0xdc, 0x14, 0x48, 0xf8, 0x14, 0x00, 0xe1, 0xc5, + 0x1e, 0x0e, 0xd4, 0x52, 0x43, 0x39, 0xa8, 0xb6, 0x76, 0x67, 0x91, 0x7e, 0x5f, 0x8e, 0x64, 0x3e, + 0xc3, 0x2e, 0x73, 0x83, 0x6b, 0xf9, 0x28, 0x39, 0x91, 0xa8, 0xac, 0x96, 0x79, 0xdc, 0xfe, 0x72, + 0x45, 0xe1, 0x4d, 0x2a, 0xb6, 0xb9, 0x05, 0xdb, 0xe0, 0x6e, 0xec, 0x65, 0xcc, 0xf6, 0xe8, 0x84, + 0xaa, 0x80, 0x87, 0x6b, 0xb3, 0x48, 0xdf, 0x5b, 0x08, 0x4f, 0x00, 0x86, 0xfd, 0x86, 0xc8, 0x90, + 0xbc, 0x80, 0x67, 0xe0, 0x5e, 0xea, 0x4d, 0xc6, 0x52, 0xf9, 0xd7, 0xb1, 0xe8, 0xf1, 0x58, 0xf6, + 0x93, 0x4b, 0x58, 0xcc, 0x60, 0xd8, 0x77, 0xd3, 0x57, 0xf1, 0x78, 0xe6, 0xd2, 0xad, 0xca, 0xd2, + 0x85, 0x9f, 0x01, 0xed, 0x9c, 0xd0, 0x60, 0x7e, 0x44, 0x41, 0xde, 0x0e, 0x3f, 0xa6, 0x7a, 0x87, + 0xf5, 0x63, 0xef, 0x33, 0x44, 0x7a, 0x64, 0x4e, 0xe7, 0x53, 0xe6, 0x96, 0x74, 0x5f, 0x07, 0x0f, + 0xb2, 0x54, 0x9d, 0xca, 0xfe, 0xd7, 0x62, 0x86, 0xec, 0x8f, 0x9d, 0x01, 0xfc, 0x02, 0xdc, 0x59, + 0x94, 0xae, 0x90, 0xbe, 0x3a, 0x8b, 0xf4, 0x5a, 0xda, 0x9c, 0xa4, 0x58, 0xa6, 0x02, 0x49, 0xa7, + 0x0e, 0xd0, 0x16, 0x18, 0x98, 0xb5, 0x06, 0xde, 0x9f, 0x45, 0xfa, 0x3b, 0x19, 0x6c, 0x5d, 0x4a, + 0xac, 0xca, 0xce, 0x85, 0x65, 0xb0, 0xc1, 0xb6, 0x5d, 0xde, 0x23, 0x85, 0x8d, 0xf7, 0xc8, 0xb2, + 0x86, 0xb6, 0x6f, 0x51, 0x43, 0x4d, 0x20, 0xa4, 0xd1, 0x09, 0xfc, 0x50, 0x2d, 0x72, 0x2e, 0x4b, + 0x3b, 0x38, 0x75, 0x19, 0x76, 0x89, 0x3f, 0xb3, 0xb5, 0xbd, 0x2c, 0xa0, 0x9d, 0xcd, 0x04, 0x54, + 0xba, 0x15, 0x01, 0x95, 0xff, 0x57, 0x01, 0x81, 0x35, 0x04, 0x54, 0xd9, 0x44, 0x40, 0xc7, 0xce, + 0x20, 0x15, 0xd0, 0xcf, 0x5b, 0x40, 0xbd, 0x06, 0x68, 0x13, 0xef, 0x0c, 0xfb, 0xa3, 0x4d, 0x45, + 0x94, 0x5e, 0x7b, 0xd7, 0x19, 0x70, 0xcd, 0x64, 0x5c, 0x7b, 0xd7, 0x19, 0x24, 0xd7, 0xce, 0x64, + 0xbb, 0xcc, 0xc2, 0xfc, 0x2d, 0xb2, 0x70, 0x3e, 0xe9, 0xc2, 0x8a, 0xaf, 0x0c, 0x03, 0x34, 0x56, + 0xcd, 0x22, 0x19, 0xd8, 0xe3, 0xbf, 0xf3, 0x20, 0xff, 0x8c, 0xba, 0xf0, 0x07, 0x00, 0x33, 0xbe, + 0xe1, 0x0e, 0x57, 0x29, 0x38, 0xf3, 0xeb, 0x45, 0xfb, 0x68, 0x2d, 0x78, 0x72, 0x06, 0xf8, 0x1d, + 0xb8, 0x7f, 0xfd, 0x43, 0xe7, 0xc3, 0x1b, 0xe7, 0x7a, 0xee, 0x87, 0xda, 0xd3, 0x75, 0xd0, 0xab, + 0x0b, 0xb3, 0x3b, 0xbb, 0x79, 0xe1, 0x63, 0x67, 0xb0, 0x46, 0x61, 0x89, 0xa6, 0xf0, 0x47, 0x05, + 0xec, 0x66, 0x73, 0xf4, 0xd1, 0x8d, 0xf3, 0xc5, 0x11, 0xda, 0x27, 0xeb, 0x46, 0x24, 0xa7, 0x68, + 0xbd, 0x78, 0x7d, 0x59, 0x57, 0x2e, 0x2e, 0xeb, 0xca, 0x9f, 0x97, 0x75, 0xe5, 0x97, 0xab, 0x7a, + 0xee, 0xe2, 0xaa, 0x9e, 0xfb, 0xe3, 0xaa, 0x9e, 0x7b, 0xf9, 0xb9, 0x8b, 0x83, 0xf3, 0x49, 0xcf, + 0x74, 0xc8, 0xc8, 0x72, 0x08, 0x1d, 0x11, 0x6a, 0xe1, 0x9e, 0x73, 0xe8, 0x12, 0x6b, 0xfa, 0xb1, + 0x35, 0x22, 0xfd, 0xc9, 0x10, 0x51, 0xf1, 0x7b, 0xf0, 0xe8, 0xc9, 0xa1, 0xf4, 0x87, 0x10, 0x84, + 0x63, 0x44, 0x7b, 0x45, 0xbe, 0xaf, 0x9f, 0xfc, 0x13, 0x00, 0x00, 0xff, 0xff, 0x40, 0xa4, 0x36, + 0x0d, 0xd0, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -754,6 +760,13 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.HostConsensusStateProof) > 0 { + i -= len(m.HostConsensusStateProof) + copy(dAtA[i:], m.HostConsensusStateProof) + i = encodeVarintTx(dAtA, i, uint64(len(m.HostConsensusStateProof))) + i-- + dAtA[i] = 0x6a + } if len(m.Signer) > 0 { i -= len(m.Signer) copy(dAtA[i:], m.Signer) @@ -903,6 +916,13 @@ func (m *MsgConnectionOpenAck) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.HostConsensusStateProof) > 0 { + i -= len(m.HostConsensusStateProof) + copy(dAtA[i:], m.HostConsensusStateProof) + i = encodeVarintTx(dAtA, i, uint64(len(m.HostConsensusStateProof))) + i-- + dAtA[i] = 0x5a + } if len(m.Signer) > 0 { i -= len(m.Signer) copy(dAtA[i:], m.Signer) @@ -1187,6 +1207,10 @@ func (m *MsgConnectionOpenTry) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.HostConsensusStateProof) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -1241,6 +1265,10 @@ func (m *MsgConnectionOpenAck) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.HostConsensusStateProof) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -1958,6 +1986,40 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { } m.Signer = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HostConsensusStateProof", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HostConsensusStateProof = append(m.HostConsensusStateProof[:0], dAtA[iNdEx:postIndex]...) + if m.HostConsensusStateProof == nil { + m.HostConsensusStateProof = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -2394,6 +2456,40 @@ func (m *MsgConnectionOpenAck) Unmarshal(dAtA []byte) error { } m.Signer = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HostConsensusStateProof", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HostConsensusStateProof = append(m.HostConsensusStateProof[:0], dAtA[iNdEx:postIndex]...) + if m.HostConsensusStateProof == nil { + m.HostConsensusStateProof = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/modules/core/03-connection/types/version.go b/modules/core/03-connection/types/version.go index 15ffc49d577..f986236dc53 100644 --- a/modules/core/03-connection/types/version.go +++ b/modules/core/03-connection/types/version.go @@ -3,9 +3,9 @@ package types import ( "strings" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( @@ -50,14 +50,14 @@ func (version Version) GetFeatures() []string { // features. It unmarshals the version string into a Version object. func ValidateVersion(version *Version) error { if version == nil { - return sdkerrors.Wrap(ErrInvalidVersion, "version cannot be nil") + return errorsmod.Wrap(ErrInvalidVersion, "version cannot be nil") } if strings.TrimSpace(version.Identifier) == "" { - return sdkerrors.Wrap(ErrInvalidVersion, "version identifier cannot be blank") + return errorsmod.Wrap(ErrInvalidVersion, "version identifier cannot be blank") } for i, feature := range version.Features { if strings.TrimSpace(feature) == "" { - return sdkerrors.Wrapf(ErrInvalidVersion, "feature cannot be blank, index %d", i) + return errorsmod.Wrapf(ErrInvalidVersion, "feature cannot be blank, index %d", i) } } @@ -70,14 +70,14 @@ func ValidateVersion(version *Version) error { // identifier. func (version Version) VerifyProposedVersion(proposedVersion exported.Version) error { if proposedVersion.GetIdentifier() != version.GetIdentifier() { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( ErrVersionNegotiationFailed, "proposed version identifier does not equal supported version identifier (%s != %s)", proposedVersion.GetIdentifier(), version.GetIdentifier(), ) } if len(proposedVersion.GetFeatures()) == 0 && !allowNilFeatureSet[proposedVersion.GetIdentifier()] { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( ErrVersionNegotiationFailed, "nil feature sets are not supported for version identifier (%s)", proposedVersion.GetIdentifier(), ) @@ -85,7 +85,7 @@ func (version Version) VerifyProposedVersion(proposedVersion exported.Version) e for _, proposedFeature := range proposedVersion.GetFeatures() { if !contains(proposedFeature, version.GetFeatures()) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( ErrVersionNegotiationFailed, "proposed feature (%s) is not a supported feature set (%s)", proposedFeature, version.GetFeatures(), ) @@ -166,7 +166,7 @@ func PickVersion(supportedVersions, counterpartyVersions []exported.Version) (*V } } - return nil, sdkerrors.Wrapf( + return nil, errorsmod.Wrapf( ErrVersionNegotiationFailed, "failed to find a matching counterparty version (%v) from the supported version list (%v)", counterpartyVersions, supportedVersions, ) diff --git a/modules/core/03-connection/types/version_test.go b/modules/core/03-connection/types/version_test.go index 2958c55fa38..9aa4abf9259 100644 --- a/modules/core/03-connection/types/version_test.go +++ b/modules/core/03-connection/types/version_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func TestValidateVersion(t *testing.T) { diff --git a/modules/core/04-channel/client/cli/cli.go b/modules/core/04-channel/client/cli/cli.go index 34259b09146..7d74011db41 100644 --- a/modules/core/04-channel/client/cli/cli.go +++ b/modules/core/04-channel/client/cli/cli.go @@ -4,7 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // GetQueryCmd returns the query commands for IBC channels diff --git a/modules/core/04-channel/client/cli/query.go b/modules/core/04-channel/client/cli/query.go index 8fe1937e055..b06b9655eb3 100644 --- a/modules/core/04-channel/client/cli/query.go +++ b/modules/core/04-channel/client/cli/query.go @@ -9,9 +9,9 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/client/utils" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/client/utils" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) const ( @@ -25,7 +25,7 @@ func GetCmdQueryChannels() *cobra.Command { Use: "channels", Short: "Query all channels", Long: "Query all channels from a chain", - Example: fmt.Sprintf("%s query %s %s channels", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s channels", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -65,7 +65,7 @@ func GetCmdQueryChannel() *cobra.Command { Short: "Query a channel end", Long: "Query an IBC channel end from a port and channel identifiers", Example: fmt.Sprintf( - "%s query %s %s end [port-id] [channel-id]", version.AppName, host.ModuleName, types.SubModuleName, + "%s query %s %s end [port-id] [channel-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName, ), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { @@ -99,7 +99,7 @@ func GetCmdQueryConnectionChannels() *cobra.Command { Use: "connections [connection-id]", Short: "Query all channels associated with a connection", Long: "Query all channels associated with a connection", - Example: fmt.Sprintf("%s query %s %s connections [connection-id]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s connections [connection-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -169,7 +169,7 @@ func GetCmdQueryPacketCommitments() *cobra.Command { Use: "packet-commitments [port-id] [channel-id]", Short: "Query all packet commitments associated with a channel", Long: "Query all packet commitments associated with a channel", - Example: fmt.Sprintf("%s query %s %s packet-commitments [port-id] [channel-id]", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s packet-commitments [port-id] [channel-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -210,7 +210,7 @@ func GetCmdQueryPacketCommitment() *cobra.Command { Short: "Query a packet commitment", Long: "Query a packet commitment", Example: fmt.Sprintf( - "%s query %s %s packet-commitment [port-id] [channel-id] [sequence]", version.AppName, host.ModuleName, types.SubModuleName, + "%s query %s %s packet-commitment [port-id] [channel-id] [sequence]", version.AppName, ibcexported.ModuleName, types.SubModuleName, ), Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { @@ -249,7 +249,7 @@ func GetCmdQueryPacketReceipt() *cobra.Command { Short: "Query a packet receipt", Long: "Query a packet receipt", Example: fmt.Sprintf( - "%s query %s %s packet-receipt [port-id] [channel-id] [sequence]", version.AppName, host.ModuleName, types.SubModuleName, + "%s query %s %s packet-receipt [port-id] [channel-id] [sequence]", version.AppName, ibcexported.ModuleName, types.SubModuleName, ), Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { @@ -288,7 +288,7 @@ func GetCmdQueryPacketAcknowledgement() *cobra.Command { Short: "Query a packet acknowledgement", Long: "Query a packet acknowledgement", Example: fmt.Sprintf( - "%s query %s %s packet-ack [port-id] [channel-id] [sequence]", version.AppName, host.ModuleName, types.SubModuleName, + "%s query %s %s packet-ack [port-id] [channel-id] [sequence]", version.AppName, ibcexported.ModuleName, types.SubModuleName, ), Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { @@ -331,7 +331,7 @@ func GetCmdQueryUnreceivedPackets() *cobra.Command { The return value represents: - Unreceived packet commitments: no acknowledgement exists on receiving chain for the given packet commitment sequence on sending chain. `, - Example: fmt.Sprintf("%s query %s %s unreceived-packets [port-id] [channel-id] --sequences=1,2,3", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s unreceived-packets [port-id] [channel-id] --sequences=1,2,3", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -381,7 +381,7 @@ func GetCmdQueryUnreceivedAcks() *cobra.Command { The return value represents: - Unreceived packet acknowledgement: packet commitment exists on original sending (executing) chain and ack exists on receiving chain. `, - Example: fmt.Sprintf("%s query %s %s unreceived-acks [port-id] [channel-id] --sequences=1,2,3", version.AppName, host.ModuleName, types.SubModuleName), + Example: fmt.Sprintf("%s query %s %s unreceived-acks [port-id] [channel-id] --sequences=1,2,3", version.AppName, ibcexported.ModuleName, types.SubModuleName), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) @@ -428,7 +428,7 @@ func GetCmdQueryNextSequenceReceive() *cobra.Command { Short: "Query a next receive sequence", Long: "Query the next receive sequence for a given channel", Example: fmt.Sprintf( - "%s query %s %s next-sequence-receive [port-id] [channel-id]", version.AppName, host.ModuleName, types.SubModuleName, + "%s query %s %s next-sequence-receive [port-id] [channel-id]", version.AppName, ibcexported.ModuleName, types.SubModuleName, ), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { diff --git a/modules/core/04-channel/client/utils/utils.go b/modules/core/04-channel/client/utils/utils.go index 577172b598c..be06badf011 100644 --- a/modules/core/04-channel/client/utils/utils.go +++ b/modules/core/04-channel/client/utils/utils.go @@ -4,16 +4,17 @@ import ( "context" "encoding/binary" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - clientutils "github.com/cosmos/ibc-go/v4/modules/core/02-client/client/utils" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/client" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clientutils "github.com/cosmos/ibc-go/v7/modules/core/02-client/client/utils" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/client" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // QueryChannel returns a channel end. @@ -45,7 +46,7 @@ func queryChannelABCI(clientCtx client.Context, portID, channelID string) (*type // check if channel exists if len(value) == 0 { - return nil, sdkerrors.Wrapf(types.ErrChannelNotFound, "portID (%s), channelID (%s)", portID, channelID) + return nil, errorsmod.Wrapf(types.ErrChannelNotFound, "portID (%s), channelID (%s)", portID, channelID) } cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) @@ -140,7 +141,7 @@ func QueryLatestConsensusState( clientHeight, ok := clientState.GetLatestHeight().(clienttypes.Height) if !ok { - return nil, clienttypes.Height{}, clienttypes.Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid height type. expected type: %T, got: %T", + return nil, clienttypes.Height{}, clienttypes.Height{}, errorsmod.Wrapf(ibcerrors.ErrInvalidHeight, "invalid height type. expected type: %T, got: %T", clienttypes.Height{}, clientHeight) } res, err := QueryChannelConsensusState(clientCtx, portID, channelID, clientHeight, false) @@ -185,7 +186,7 @@ func queryNextSequenceRecvABCI(clientCtx client.Context, portID, channelID strin // check if next sequence receive exists if len(value) == 0 { - return nil, sdkerrors.Wrapf(types.ErrChannelNotFound, "portID (%s), channelID (%s)", portID, channelID) + return nil, errorsmod.Wrapf(types.ErrChannelNotFound, "portID (%s), channelID (%s)", portID, channelID) } sequence := binary.BigEndian.Uint64(value) @@ -226,7 +227,7 @@ func queryPacketCommitmentABCI( // check if packet commitment exists if len(value) == 0 { - return nil, sdkerrors.Wrapf(types.ErrPacketCommitmentNotFound, "portID (%s), channelID (%s), sequence (%d)", portID, channelID, sequence) + return nil, errorsmod.Wrapf(types.ErrPacketCommitmentNotFound, "portID (%s), channelID (%s), sequence (%d)", portID, channelID, sequence) } return types.NewQueryPacketCommitmentResponse(value, proofBz, proofHeight), nil @@ -293,7 +294,7 @@ func queryPacketAcknowledgementABCI(clientCtx client.Context, portID, channelID } if len(value) == 0 { - return nil, sdkerrors.Wrapf(types.ErrInvalidAcknowledgement, "portID (%s), channelID (%s), sequence (%d)", portID, channelID, sequence) + return nil, errorsmod.Wrapf(types.ErrInvalidAcknowledgement, "portID (%s), channelID (%s), sequence (%d)", portID, channelID, sequence) } return types.NewQueryPacketAcknowledgementResponse(value, proofBz, proofHeight), nil diff --git a/modules/core/04-channel/doc.go b/modules/core/04-channel/doc.go new file mode 100644 index 00000000000..f5c537df089 --- /dev/null +++ b/modules/core/04-channel/doc.go @@ -0,0 +1,17 @@ +/* +Package channel implements the ICS 04 - Channel and Packet Semantics specification +(https://github.com/cosmos/ibc/tree/main/spec/core/ics-004-channel-and-packet-semantics). This +concrete implementation defines types and methods for safely creating two +stateful objects (channel ends) on two separate chains, each associated with a +particular connection. A channel serves as a conduit for packets passing between a +module on one chain and a module on another, ensuring that packets are executed +only once, delivered in the order in which they were sent (if necessary), +and delivered only to the corresponding module owning the other end of the +channel on the destination chain. + +The main types are Channel, which defines a stateful object on a +chain that allows for exactly-once packet delivery between specific modules +on separate blockchains, and Packet, which defines the data carried +across different chains through IBC. +*/ +package channel diff --git a/modules/core/04-channel/genesis.go b/modules/core/04-channel/genesis.go index 0d402fd8f39..91bd5b31767 100644 --- a/modules/core/04-channel/genesis.go +++ b/modules/core/04-channel/genesis.go @@ -3,8 +3,8 @@ package channel import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/keeper" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/keeper" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // InitGenesis initializes the ibc channel submodule's state from a provided genesis diff --git a/modules/core/04-channel/keeper/events.go b/modules/core/04-channel/keeper/events.go index bd014a67979..81304721b74 100644 --- a/modules/core/04-channel/keeper/events.go +++ b/modules/core/04-channel/keeper/events.go @@ -6,12 +6,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) -// EmitChannelOpenInitEvent emits a channel open init event -func EmitChannelOpenInitEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { +// emitChannelOpenInitEvent emits a channel open init event +func emitChannelOpenInitEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenInit, @@ -22,9 +22,6 @@ func EmitChannelOpenInitEvent(ctx sdk.Context, portID string, channelID string, sdk.NewAttribute(types.AttributeKeyConnectionID, channel.ConnectionHops[0]), sdk.NewAttribute(types.AttributeVersion, channel.Version), ), - }) - - ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), @@ -32,8 +29,8 @@ func EmitChannelOpenInitEvent(ctx sdk.Context, portID string, channelID string, }) } -// EmitChannelOpenTryEvent emits a channel open try event -func EmitChannelOpenTryEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { +// emitChannelOpenTryEvent emits a channel open try event +func emitChannelOpenTryEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenTry, @@ -44,8 +41,6 @@ func EmitChannelOpenTryEvent(ctx sdk.Context, portID string, channelID string, c sdk.NewAttribute(types.AttributeKeyConnectionID, channel.ConnectionHops[0]), sdk.NewAttribute(types.AttributeVersion, channel.Version), ), - }) - ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), @@ -53,8 +48,8 @@ func EmitChannelOpenTryEvent(ctx sdk.Context, portID string, channelID string, c }) } -// EmitChannelOpenAckEvent emits a channel open acknowledge event -func EmitChannelOpenAckEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { +// emitChannelOpenAckEvent emits a channel open acknowledge event +func emitChannelOpenAckEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenAck, @@ -71,8 +66,8 @@ func EmitChannelOpenAckEvent(ctx sdk.Context, portID string, channelID string, c }) } -// EmitChannelOpenConfirmEvent emits a channel open confirm event -func EmitChannelOpenConfirmEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { +// emitChannelOpenConfirmEvent emits a channel open confirm event +func emitChannelOpenConfirmEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenConfirm, @@ -89,8 +84,8 @@ func EmitChannelOpenConfirmEvent(ctx sdk.Context, portID string, channelID strin }) } -// EmitChannelCloseInitEvent emits a channel close init event -func EmitChannelCloseInitEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { +// emitChannelCloseInitEvent emits a channel close init event +func emitChannelCloseInitEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelCloseInit, @@ -107,8 +102,8 @@ func EmitChannelCloseInitEvent(ctx sdk.Context, portID string, channelID string, }) } -// EmitChannelCloseConfirmEvent emits a channel close confirm event -func EmitChannelCloseConfirmEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { +// emitChannelCloseConfirmEvent emits a channel close confirm event +func emitChannelCloseConfirmEvent(ctx sdk.Context, portID string, channelID string, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelCloseConfirm, @@ -125,13 +120,13 @@ func EmitChannelCloseConfirmEvent(ctx sdk.Context, portID string, channelID stri }) } -// EmitSendPacketEvent emits an event with packet data along with other packet information for relayer +// emitSendPacketEvent emits an event with packet data along with other packet information for relayer // to pick up and relay to other chain -func EmitSendPacketEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel, timeoutHeight exported.Height) { +func emitSendPacketEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel, timeoutHeight exported.Height) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeSendPacket, - sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData())), // DEPRECATED + sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData())), //nolint:staticcheck // DEPRECATED sdk.NewAttribute(types.AttributeKeyDataHex, hex.EncodeToString(packet.GetData())), sdk.NewAttribute(types.AttributeKeyTimeoutHeight, timeoutHeight.String()), sdk.NewAttribute(types.AttributeKeyTimeoutTimestamp, fmt.Sprintf("%d", packet.GetTimeoutTimestamp())), @@ -152,13 +147,13 @@ func EmitSendPacketEvent(ctx sdk.Context, packet exported.PacketI, channel types }) } -// EmitRecvPacketEvent emits a receive packet event. It will be emitted both the first time a packet +// emitRecvPacketEvent emits a receive packet event. It will be emitted both the first time a packet // is received for a certain sequence and for all duplicate receives. -func EmitRecvPacketEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel) { +func emitRecvPacketEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeRecvPacket, - sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData())), // DEPRECATED + sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData())), //nolint:staticcheck // DEPRECATED sdk.NewAttribute(types.AttributeKeyDataHex, hex.EncodeToString(packet.GetData())), sdk.NewAttribute(types.AttributeKeyTimeoutHeight, packet.GetTimeoutHeight().String()), sdk.NewAttribute(types.AttributeKeyTimeoutTimestamp, fmt.Sprintf("%d", packet.GetTimeoutTimestamp())), @@ -179,12 +174,12 @@ func EmitRecvPacketEvent(ctx sdk.Context, packet exported.PacketI, channel types }) } -// EmitWriteAcknowledgementEvent emits an event that the relayer can query for -func EmitWriteAcknowledgementEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel, acknowledgement []byte) { +// emitWriteAcknowledgementEvent emits an event that the relayer can query for +func emitWriteAcknowledgementEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel, acknowledgement []byte) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeWriteAck, - sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData())), // DEPRECATED + sdk.NewAttribute(types.AttributeKeyData, string(packet.GetData())), //nolint:staticcheck // DEPRECATED sdk.NewAttribute(types.AttributeKeyDataHex, hex.EncodeToString(packet.GetData())), sdk.NewAttribute(types.AttributeKeyTimeoutHeight, packet.GetTimeoutHeight().String()), sdk.NewAttribute(types.AttributeKeyTimeoutTimestamp, fmt.Sprintf("%d", packet.GetTimeoutTimestamp())), @@ -193,7 +188,7 @@ func EmitWriteAcknowledgementEvent(ctx sdk.Context, packet exported.PacketI, cha sdk.NewAttribute(types.AttributeKeySrcChannel, packet.GetSourceChannel()), sdk.NewAttribute(types.AttributeKeyDstPort, packet.GetDestPort()), sdk.NewAttribute(types.AttributeKeyDstChannel, packet.GetDestChannel()), - sdk.NewAttribute(types.AttributeKeyAck, string(acknowledgement)), + sdk.NewAttribute(types.AttributeKeyAck, string(acknowledgement)), //nolint:staticcheck // DEPRECATED sdk.NewAttribute(types.AttributeKeyAckHex, hex.EncodeToString(acknowledgement)), // we only support 1-hop packets now, and that is the most important hop for a relayer // (is it going to a chain I am connected to) @@ -206,9 +201,9 @@ func EmitWriteAcknowledgementEvent(ctx sdk.Context, packet exported.PacketI, cha }) } -// EmitAcknowledgePacketEvent emits an acknowledge packet event. It will be emitted both the first time +// emitAcknowledgePacketEvent emits an acknowledge packet event. It will be emitted both the first time // a packet is acknowledged for a certain sequence and for all duplicate acknowledgements. -func EmitAcknowledgePacketEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel) { +func emitAcknowledgePacketEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeAcknowledgePacket, @@ -231,9 +226,9 @@ func EmitAcknowledgePacketEvent(ctx sdk.Context, packet exported.PacketI, channe }) } -// EmitTimeoutPacketEvent emits a timeout packet event. It will be emitted both the first time a packet +// emitTimeoutPacketEvent emits a timeout packet event. It will be emitted both the first time a packet // is timed out for a certain sequence and for all duplicate timeouts. -func EmitTimeoutPacketEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel) { +func emitTimeoutPacketEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeTimeoutPacket, @@ -253,8 +248,8 @@ func EmitTimeoutPacketEvent(ctx sdk.Context, packet exported.PacketI, channel ty }) } -// EmitChannelClosedEvent emits a channel closed event. -func EmitChannelClosedEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel) { +// emitChannelClosedEvent emits a channel closed event. +func emitChannelClosedEvent(ctx sdk.Context, packet exported.PacketI, channel types.Channel) { ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelClosed, @@ -265,5 +260,9 @@ func EmitChannelClosedEvent(ctx sdk.Context, packet exported.PacketI, channel ty sdk.NewAttribute(types.AttributeKeyConnectionID, channel.ConnectionHops[0]), sdk.NewAttribute(types.AttributeKeyChannelOrdering, channel.Ordering.String()), ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), }) } diff --git a/modules/core/04-channel/keeper/grpc_query.go b/modules/core/04-channel/keeper/grpc_query.go index 6936fec0596..ee11b40251e 100644 --- a/modules/core/04-channel/keeper/grpc_query.go +++ b/modules/core/04-channel/keeper/grpc_query.go @@ -5,17 +5,17 @@ import ( "strconv" "strings" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) var _ types.QueryServer = (*Keeper)(nil) @@ -35,7 +35,7 @@ func (q Keeper) Channel(c context.Context, req *types.QueryChannelRequest) (*typ if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), + errorsmod.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), ) } @@ -96,26 +96,27 @@ func (q Keeper) ConnectionChannels(c context.Context, req *types.QueryConnection channels := []*types.IdentifiedChannel{} store := prefix.NewStore(ctx.KVStore(q.storeKey), []byte(host.KeyChannelEndPrefix)) - pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { + pageRes, err := query.FilteredPaginate(store, req.Pagination, func(key, value []byte, accumulate bool) (bool, error) { + // filter any metadata stored under channel key var result types.Channel if err := q.cdc.Unmarshal(value, &result); err != nil { - return err + return false, err } // ignore channel and continue to the next item if the connection is // different than the requested one if result.ConnectionHops[0] != req.Connection { - return nil + return false, nil } portID, channelID, err := host.ParseChannelPath(string(key)) if err != nil { - return err + return false, err } identifiedChannel := types.NewIdentifiedChannel(portID, channelID, result) channels = append(channels, &identifiedChannel) - return nil + return true, nil }) if err != nil { return nil, err @@ -168,7 +169,7 @@ func (q Keeper) ChannelConsensusState(c context.Context, req *types.QueryChannel if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), + errorsmod.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), ) } @@ -176,7 +177,7 @@ func (q Keeper) ChannelConsensusState(c context.Context, req *types.QueryChannel if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", channel.ConnectionHops[0]).Error(), + errorsmod.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", channel.ConnectionHops[0]).Error(), ) } @@ -185,7 +186,7 @@ func (q Keeper) ChannelConsensusState(c context.Context, req *types.QueryChannel if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(clienttypes.ErrConsensusStateNotFound, "client-id: %s", connection.ClientId).Error(), + errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "client-id: %s", connection.ClientId).Error(), ) } @@ -483,7 +484,7 @@ func (q Keeper) NextSequenceReceive(c context.Context, req *types.QueryNextSeque if !found { return nil, status.Error( codes.NotFound, - sdkerrors.Wrapf(types.ErrSequenceReceiveNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), + errorsmod.Wrapf(types.ErrSequenceReceiveNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), ) } diff --git a/modules/core/04-channel/keeper/grpc_query_test.go b/modules/core/04-channel/keeper/grpc_query_test.go index 8e7ac77a57a..0082663a243 100644 --- a/modules/core/04-channel/keeper/grpc_query_test.go +++ b/modules/core/04-channel/keeper/grpc_query_test.go @@ -6,13 +6,15 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) +const doesnotexist = "doesnotexist" + func (suite *KeeperTestSuite) TestQueryChannel() { var ( req *types.QueryChannelRequest @@ -372,7 +374,7 @@ func (suite *KeeperTestSuite) TestQueryChannelClientState() { channel := path.EndpointA.GetChannel() // update channel to reference a connection that does not exist - channel.ConnectionHops[0] = "doesnotexist" + channel.ConnectionHops[0] = doesnotexist // set connection hops to wrong connection ID suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) @@ -508,7 +510,7 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { channel := path.EndpointA.GetChannel() // update channel to reference a connection that does not exist - channel.ConnectionHops[0] = "doesnotexist" + channel.ConnectionHops[0] = doesnotexist // set connection hops to wrong connection ID suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) diff --git a/modules/core/04-channel/keeper/handshake.go b/modules/core/04-channel/keeper/handshake.go index 1d9cfd6382c..6419a8984bd 100644 --- a/modules/core/04-channel/keeper/handshake.go +++ b/modules/core/04-channel/keeper/handshake.go @@ -3,16 +3,16 @@ package keeper import ( "fmt" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "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" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // ChanOpenInit is called by a module to initiate a channel opening handshake with @@ -30,12 +30,12 @@ func (k Keeper) ChanOpenInit( // connection hop length checked on msg.ValidateBasic() connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return "", nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) + return "", nil, errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) } getVersions := connectionEnd.GetVersions() if len(getVersions) != 1 { - return "", nil, sdkerrors.Wrapf( + return "", nil, errorsmod.Wrapf( connectiontypes.ErrInvalidVersion, "single version must be negotiated on connection before opening channel, got: %v", getVersions, @@ -43,7 +43,7 @@ func (k Keeper) ChanOpenInit( } if !connectiontypes.VerifySupportedFeature(getVersions[0], order.String()) { - return "", nil, sdkerrors.Wrapf( + return "", nil, errorsmod.Wrapf( connectiontypes.ErrInvalidVersion, "connection version %s does not support channel ordering: %s", getVersions[0], order.String(), @@ -51,14 +51,14 @@ func (k Keeper) ChanOpenInit( } if !k.portKeeper.Authenticate(ctx, portCap, portID) { - return "", nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) + return "", nil, errorsmod.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) } channelID := k.GenerateChannelIdentifier(ctx) capKey, err := k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if err != nil { - return "", nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) + return "", nil, errorsmod.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) } return channelID, capKey, nil @@ -89,7 +89,7 @@ func (k Keeper) WriteOpenInitChannel( telemetry.IncrCounter(1, "ibc", "channel", "open-init") }() - EmitChannelOpenInitEvent(ctx, portID, channelID, channel) + emitChannelOpenInitEvent(ctx, portID, channelID, channel) } // ChanOpenTry is called by a module to accept the first step of a channel opening @@ -107,23 +107,23 @@ func (k Keeper) ChanOpenTry( ) (string, *capabilitytypes.Capability, error) { // connection hops only supports a single connection if len(connectionHops) != 1 { - return "", nil, sdkerrors.Wrapf(types.ErrTooManyConnectionHops, "expected 1, got %d", len(connectionHops)) + return "", nil, errorsmod.Wrapf(types.ErrTooManyConnectionHops, "expected 1, got %d", len(connectionHops)) } // generate a new channel channelID := k.GenerateChannelIdentifier(ctx) if !k.portKeeper.Authenticate(ctx, portCap, portID) { - return "", nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) + return "", nil, errorsmod.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return "", nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) + return "", nil, errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return "", nil, sdkerrors.Wrapf( + return "", nil, errorsmod.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) @@ -131,7 +131,7 @@ func (k Keeper) ChanOpenTry( getVersions := connectionEnd.GetVersions() if len(getVersions) != 1 { - return "", nil, sdkerrors.Wrapf( + return "", nil, errorsmod.Wrapf( connectiontypes.ErrInvalidVersion, "single version must be negotiated on connection before opening channel, got: %v", getVersions, @@ -139,7 +139,7 @@ func (k Keeper) ChanOpenTry( } if !connectiontypes.VerifySupportedFeature(getVersions[0], order.String()) { - return "", nil, sdkerrors.Wrapf( + return "", nil, errorsmod.Wrapf( connectiontypes.ErrInvalidVersion, "connection version %s does not support channel ordering: %s", getVersions[0], order.String(), @@ -170,7 +170,7 @@ func (k Keeper) ChanOpenTry( capKey, err = k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if err != nil { - return "", nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) + return "", nil, errorsmod.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) } return channelID, capKey, nil @@ -202,7 +202,7 @@ func (k Keeper) WriteOpenTryChannel( telemetry.IncrCounter(1, "ibc", "channel", "open-try") }() - EmitChannelOpenTryEvent(ctx, portID, channelID, channel) + emitChannelOpenTryEvent(ctx, portID, channelID, channel) } // ChanOpenAck is called by the handshake-originating module to acknowledge the @@ -219,24 +219,24 @@ func (k Keeper) ChanOpenAck( ) error { channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return sdkerrors.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) } if channel.State != types.INIT { - return sdkerrors.Wrapf(types.ErrInvalidChannelState, "channel state should be INIT (got %s)", channel.State.String()) + return errorsmod.Wrapf(types.ErrInvalidChannelState, "channel state should be INIT (got %s)", channel.State.String()) } if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) { - return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) + return errorsmod.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) @@ -287,11 +287,11 @@ func (k Keeper) WriteOpenAckChannel( telemetry.IncrCounter(1, "ibc", "channel", "open-ack") }() - EmitChannelOpenAckEvent(ctx, portID, channelID, channel) + emitChannelOpenAckEvent(ctx, portID, channelID, channel) } // ChanOpenConfirm is called by the counterparty module to close their end of the -// channel, since the other end has been closed. +// channel, since the other end has been closed. func (k Keeper) ChanOpenConfirm( ctx sdk.Context, portID, @@ -302,27 +302,27 @@ func (k Keeper) ChanOpenConfirm( ) error { channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return sdkerrors.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) } if channel.State != types.TRYOPEN { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelState, "channel state is not TRYOPEN (got %s)", channel.State.String(), ) } if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) { - return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) + return errorsmod.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) @@ -367,7 +367,7 @@ func (k Keeper) WriteOpenConfirmChannel( telemetry.IncrCounter(1, "ibc", "channel", "open-confirm") }() - EmitChannelOpenConfirmEvent(ctx, portID, channelID, channel) + emitChannelOpenConfirmEvent(ctx, portID, channelID, channel) } // Closing Handshake @@ -384,25 +384,25 @@ func (k Keeper) ChanCloseInit( chanCap *capabilitytypes.Capability, ) error { if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) { - return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) + return errorsmod.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) } channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return sdkerrors.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) } if channel.State == types.CLOSED { - return sdkerrors.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") + return errorsmod.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) @@ -417,7 +417,7 @@ func (k Keeper) ChanCloseInit( channel.State = types.CLOSED k.SetChannel(ctx, portID, channelID, channel) - EmitChannelCloseInitEvent(ctx, portID, channelID, channel) + emitChannelCloseInitEvent(ctx, portID, channelID, channel) return nil } @@ -433,25 +433,25 @@ func (k Keeper) ChanCloseConfirm( proofHeight exported.Height, ) error { if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) { - return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)") + return errorsmod.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)") } channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return sdkerrors.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) } if channel.State == types.CLOSED { - return sdkerrors.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") + return errorsmod.Wrap(types.ErrInvalidChannelState, "channel is already CLOSED") } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) @@ -482,7 +482,7 @@ func (k Keeper) ChanCloseConfirm( channel.State = types.CLOSED k.SetChannel(ctx, portID, channelID, channel) - EmitChannelCloseConfirmEvent(ctx, portID, channelID, channel) + emitChannelCloseConfirmEvent(ctx, portID, channelID, channel) return nil } diff --git a/modules/core/04-channel/keeper/handshake_test.go b/modules/core/04-channel/keeper/handshake_test.go index 88ca88887b4..bf77d7ed530 100644 --- a/modules/core/04-channel/keeper/handshake_test.go +++ b/modules/core/04-channel/keeper/handshake_test.go @@ -5,12 +5,12 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "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/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type testCase = struct { @@ -152,7 +152,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { {"success", func() { suite.coordinator.SetupConnections(path) path.SetChannelOrdered() - path.EndpointA.ChanOpenInit() + err := path.EndpointA.ChanOpenInit() + suite.Require().NoError(err) suite.chainB.CreatePortCapability(suite.chainB.GetSimApp().ScopedIBCMockKeeper, ibctesting.MockPort) portCap = suite.chainB.GetPortCapability(ibctesting.MockPort) @@ -177,7 +178,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { {"consensus state not found", func() { suite.coordinator.SetupConnections(path) path.SetChannelOrdered() - path.EndpointA.ChanOpenInit() + err := path.EndpointA.ChanOpenInit() + suite.Require().NoError(err) suite.chainB.CreatePortCapability(suite.chainB.GetSimApp().ScopedIBCMockKeeper, ibctesting.MockPort) portCap = suite.chainB.GetPortCapability(ibctesting.MockPort) @@ -192,14 +194,16 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { {"port capability not found", func() { suite.coordinator.SetupConnections(path) path.SetChannelOrdered() - path.EndpointA.ChanOpenInit() + err := path.EndpointA.ChanOpenInit() + suite.Require().NoError(err) portCap = capabilitytypes.NewCapability(3) }, false}, {"connection version not negotiated", func() { suite.coordinator.SetupConnections(path) path.SetChannelOrdered() - path.EndpointA.ChanOpenInit() + err := path.EndpointA.ChanOpenInit() + suite.Require().NoError(err) // modify connB versions conn := path.EndpointB.GetConnection() @@ -217,7 +221,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { {"connection does not support ORDERED channels", func() { suite.coordinator.SetupConnections(path) path.SetChannelOrdered() - path.EndpointA.ChanOpenInit() + err := path.EndpointA.ChanOpenInit() + suite.Require().NoError(err) // modify connA versions to only support UNORDERED channels conn := path.EndpointA.GetConnection() @@ -340,7 +345,7 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { // set the channel's connection hops to wrong connection ID channel := path.EndpointA.GetChannel() - channel.ConnectionHops[0] = "doesnotexist" + channel.ConnectionHops[0] = doesnotexist suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) }, false}, {"connection is not OPEN", func() { @@ -405,7 +410,8 @@ func (suite *KeeperTestSuite) TestChanOpenAck() { err := path.EndpointA.ChanOpenInit() suite.Require().NoError(err) - path.EndpointB.ChanOpenTry() + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) channelCap = capabilitytypes.NewCapability(6) }, false}, @@ -496,7 +502,7 @@ func (suite *KeeperTestSuite) TestChanOpenConfirm() { // set the channel's connection hops to wrong connection ID channel := path.EndpointB.GetChannel() - channel.ConnectionHops[0] = "doesnotexist" + channel.ConnectionHops[0] = doesnotexist suite.chainB.App.GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, channel) }, false}, {"connection is not OPEN", func() { @@ -618,7 +624,7 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) // close channel - err := path.EndpointA.SetChannelClosed() + err := path.EndpointA.SetChannelState(types.CLOSED) suite.Require().NoError(err) }, false}, {"connection not found", func() { @@ -627,7 +633,7 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { // set the channel's connection hops to wrong connection ID channel := path.EndpointA.GetChannel() - channel.ConnectionHops[0] = "doesnotexist" + channel.ConnectionHops[0] = doesnotexist suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) }, false}, {"connection is not OPEN", func() { @@ -639,6 +645,7 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { // create channel in init path.SetChannelOrdered() err = path.EndpointA.ChanOpenInit() + suite.Require().NoError(err) // ensure channel capability check passes suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) @@ -686,7 +693,7 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { suite.coordinator.Setup(path) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - err := path.EndpointA.SetChannelClosed() + err := path.EndpointA.SetChannelState(types.CLOSED) suite.Require().NoError(err) }, true}, {"channel doesn't exist", func() { @@ -702,7 +709,7 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { suite.coordinator.Setup(path) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - err := path.EndpointB.SetChannelClosed() + err := path.EndpointB.SetChannelState(types.CLOSED) suite.Require().NoError(err) }, false}, {"connection not found", func() { @@ -711,7 +718,7 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { // set the channel's connection hops to wrong connection ID channel := path.EndpointB.GetChannel() - channel.ConnectionHops[0] = "doesnotexist" + channel.ConnectionHops[0] = doesnotexist suite.chainB.App.GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, channel) }, false}, {"connection is not OPEN", func() { @@ -733,7 +740,7 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { suite.coordinator.Setup(path) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - err := path.EndpointA.SetChannelClosed() + err := path.EndpointA.SetChannelState(types.CLOSED) suite.Require().NoError(err) heightDiff = 3 @@ -747,7 +754,7 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { suite.coordinator.Setup(path) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - err := path.EndpointA.SetChannelClosed() + err := path.EndpointA.SetChannelState(types.CLOSED) suite.Require().NoError(err) channelCap = capabilitytypes.NewCapability(3) diff --git a/modules/core/04-channel/keeper/keeper.go b/modules/core/04-channel/keeper/keeper.go index 8d82129425f..3c800ad3795 100644 --- a/modules/core/04-channel/keeper/keeper.go +++ b/modules/core/04-channel/keeper/keeper.go @@ -5,19 +5,19 @@ import ( "strings" "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + errorsmod "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/tendermint/tendermint/libs/log" db "github.com/tendermint/tm-db" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "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" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var _ porttypes.ICS4Wrapper = Keeper{} @@ -27,19 +27,19 @@ type Keeper struct { // implements gRPC QueryServer interface types.QueryServer - storeKey sdk.StoreKey + storeKey storetypes.StoreKey cdc codec.BinaryCodec clientKeeper types.ClientKeeper connectionKeeper types.ConnectionKeeper portKeeper types.PortKeeper - scopedKeeper capabilitykeeper.ScopedKeeper + scopedKeeper exported.ScopedKeeper } // NewKeeper creates a new IBC channel Keeper instance func NewKeeper( - cdc codec.BinaryCodec, key sdk.StoreKey, + cdc codec.BinaryCodec, key storetypes.StoreKey, clientKeeper types.ClientKeeper, connectionKeeper types.ConnectionKeeper, - portKeeper types.PortKeeper, scopedKeeper capabilitykeeper.ScopedKeeper, + portKeeper types.PortKeeper, scopedKeeper exported.ScopedKeeper, ) Keeper { return Keeper{ storeKey: key, @@ -53,7 +53,7 @@ func NewKeeper( // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+host.ModuleName+"/"+types.SubModuleName) + return ctx.Logger().With("module", "x/"+exported.ModuleName+"/"+types.SubModuleName) } // GenerateChannelIdentifier returns the next channel identifier. @@ -66,11 +66,17 @@ func (k Keeper) GenerateChannelIdentifier(ctx sdk.Context) string { return channelID } +// HasChannel true if the channel with the given identifiers exists in state. +func (k Keeper) HasChannel(ctx sdk.Context, portID, channelID string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(host.ChannelKey(portID, channelID)) +} + // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(host.ChannelKey(portID, channelID)) - if bz == nil { + if len(bz) == 0 { return types.Channel{}, false } @@ -100,7 +106,7 @@ func (k Keeper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string func (k Keeper) GetNextChannelSequence(ctx sdk.Context) uint64 { store := ctx.KVStore(k.storeKey) bz := store.Get([]byte(types.KeyNextChannelSequence)) - if bz == nil { + if len(bz) == 0 { panic("next channel sequence is nil") } @@ -118,7 +124,7 @@ func (k Keeper) SetNextChannelSequence(ctx sdk.Context, sequence uint64) { func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(host.NextSequenceSendKey(portID, channelID)) - if bz == nil { + if len(bz) == 0 { return 0, false } @@ -136,7 +142,7 @@ func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, s func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(host.NextSequenceRecvKey(portID, channelID)) - if bz == nil { + if len(bz) == 0 { return 0, false } @@ -154,7 +160,7 @@ func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, s func (k Keeper) GetNextSequenceAck(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(host.NextSequenceAckKey(portID, channelID)) - if bz == nil { + if len(bz) == 0 { return 0, false } @@ -172,7 +178,7 @@ func (k Keeper) SetNextSequenceAck(ctx sdk.Context, portID, channelID string, se func (k Keeper) GetPacketReceipt(ctx sdk.Context, portID, channelID string, sequence uint64) (string, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(host.PacketReceiptKey(portID, channelID, sequence)) - if bz == nil { + if len(bz) == 0 { return "", false } @@ -219,7 +225,7 @@ func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID stri func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(host.PacketAcknowledgementKey(portID, channelID, sequence)) - if bz == nil { + if len(bz) == 0 { return nil, false } return bz, true @@ -235,7 +241,7 @@ func (k Keeper) HasPacketAcknowledgement(ctx sdk.Context, portID, channelID stri // For each sequence, cb will be called. If the cb returns true, the iterator // will close and stop. func (k Keeper) IteratePacketSequence(ctx sdk.Context, iterator db.Iterator, cb func(portID, channelID string, sequence uint64) bool) { - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { portID, channelID, err := host.ParseChannelPath(string(iterator.Key())) if err != nil { @@ -371,7 +377,7 @@ func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.IdentifiedChannel store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte(host.KeyChannelEndPrefix)) - defer iterator.Close() + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { var channel types.Channel k.cdc.MustUnmarshal(iterator.Value(), &channel) @@ -384,6 +390,28 @@ func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.IdentifiedChannel } } +// GetAllChannelsWithPortPrefix returns all channels with the specified port prefix. If an empty prefix is provided +// all channels will be returned. +func (k Keeper) GetAllChannelsWithPortPrefix(ctx sdk.Context, portPrefix string) []types.IdentifiedChannel { + if strings.TrimSpace(portPrefix) == "" { + return k.GetAllChannels(ctx) + } + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.FilteredPortPrefix(portPrefix)) + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) + + var filteredChannels []types.IdentifiedChannel + for ; iterator.Valid(); iterator.Next() { + var channel types.Channel + k.cdc.MustUnmarshal(iterator.Value(), &channel) + + portID, channelID := host.MustParseChannelPath(string(iterator.Key())) + identifiedChannel := types.NewIdentifiedChannel(portID, channelID, channel) + filteredChannels = append(filteredChannels, identifiedChannel) + } + return filteredChannels +} + // GetAllChannels returns all stored Channel objects. func (k Keeper) GetAllChannels(ctx sdk.Context) (channels []types.IdentifiedChannel) { k.IterateChannels(ctx, func(channel types.IdentifiedChannel) bool { @@ -397,17 +425,17 @@ func (k Keeper) GetAllChannels(ctx sdk.Context) (channels []types.IdentifiedChan func (k Keeper) GetChannelClientState(ctx sdk.Context, portID, channelID string) (string, exported.ClientState, error) { channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return "", nil, sdkerrors.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id: %s", portID, channelID) + return "", nil, errorsmod.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id: %s", portID, channelID) } connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return "", nil, sdkerrors.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", channel.ConnectionHops[0]) + return "", nil, errorsmod.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", channel.ConnectionHops[0]) } clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientId) if !found { - return "", nil, sdkerrors.Wrapf(clienttypes.ErrClientNotFound, "client-id: %s", connection.ClientId) + return "", nil, errorsmod.Wrapf(clienttypes.ErrClientNotFound, "client-id: %s", connection.ClientId) } return connection.ClientId, clientState, nil @@ -417,7 +445,7 @@ func (k Keeper) GetChannelClientState(ctx sdk.Context, portID, channelID string) func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (exported.ConnectionI, error) { connection, found := k.connectionKeeper.GetConnection(ctx, connectionID) if !found { - return nil, sdkerrors.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", connectionID) + return nil, errorsmod.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", connectionID) } return connection, nil @@ -427,14 +455,14 @@ func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (exported.Co func (k Keeper) GetChannelConnection(ctx sdk.Context, portID, channelID string) (string, exported.ConnectionI, error) { channel, found := k.GetChannel(ctx, portID, channelID) if !found { - return "", nil, sdkerrors.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id: %s", portID, channelID) + return "", nil, errorsmod.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id: %s", portID, channelID) } connectionID := channel.ConnectionHops[0] connection, found := k.connectionKeeper.GetConnection(ctx, connectionID) if !found { - return "", nil, sdkerrors.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", connectionID) + return "", nil, errorsmod.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", connectionID) } return connectionID, connection, nil @@ -451,8 +479,8 @@ func (k Keeper) LookupModuleByChannel(ctx sdk.Context, portID, channelID string) } // common functionality for IteratePacketCommitment and IteratePacketAcknowledgement -func (k Keeper) iterateHashes(_ sdk.Context, iterator db.Iterator, cb func(portID, channelID string, sequence uint64, hash []byte) bool) { - defer iterator.Close() +func (k Keeper) iterateHashes(ctx sdk.Context, iterator db.Iterator, cb func(portID, channelID string, sequence uint64, hash []byte) bool) { + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { keySplit := strings.Split(string(iterator.Key()), "/") diff --git a/modules/core/04-channel/keeper/keeper_test.go b/modules/core/04-channel/keeper/keeper_test.go index f202d8bce78..92afaba9135 100644 --- a/modules/core/04-channel/keeper/keeper_test.go +++ b/modules/core/04-channel/keeper/keeper_test.go @@ -1,13 +1,15 @@ package keeper_test import ( + "reflect" "testing" "github.com/stretchr/testify/suite" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) // KeeperTestSuite is a testing suite to test keeper functions. @@ -44,7 +46,7 @@ func (suite *KeeperTestSuite) TestSetChannel() { suite.coordinator.SetupConnections(path) // check for channel to be created on chainA - _, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.HasChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) suite.False(found) path.SetChannelOrdered() @@ -81,9 +83,89 @@ func (suite *KeeperTestSuite) TestGetAppVersion() { suite.Require().Equal(ibcmock.Version, channelVersion) } +// TestGetAllChannelsWithPortPrefix verifies ports are filtered correctly using a port prefix. +func (suite *KeeperTestSuite) TestGetAllChannelsWithPortPrefix() { + const ( + secondChannelID = "channel-1" + differentChannelPortID = "different-portid" + ) + + allChannels := []types.IdentifiedChannel{ + types.NewIdentifiedChannel(transfertypes.PortID, ibctesting.FirstChannelID, types.Channel{}), + types.NewIdentifiedChannel(differentChannelPortID, secondChannelID, types.Channel{}), + } + + tests := []struct { + name string + prefix string + allChannels []types.IdentifiedChannel + expectedChannels []types.IdentifiedChannel + }{ + { + name: "transfer channel is retrieved with prefix", + prefix: "tra", + allChannels: allChannels, + expectedChannels: []types.IdentifiedChannel{types.NewIdentifiedChannel(transfertypes.PortID, ibctesting.FirstChannelID, types.Channel{})}, + }, + { + name: "matches port with full name as prefix", + prefix: transfertypes.PortID, + allChannels: allChannels, + expectedChannels: []types.IdentifiedChannel{types.NewIdentifiedChannel(transfertypes.PortID, ibctesting.FirstChannelID, types.Channel{})}, + }, + { + name: "no ports match prefix", + prefix: "wont-match-anything", + allChannels: allChannels, + expectedChannels: nil, + }, + { + name: "empty prefix matches everything", + prefix: "", + allChannels: allChannels, + expectedChannels: allChannels, + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + for _, ch := range tc.allChannels { + suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), ch.PortId, ch.ChannelId, types.Channel{}) + } + + ctxA := suite.chainA.GetContext() + + actualChannels := suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.GetAllChannelsWithPortPrefix(ctxA, tc.prefix) + + suite.Require().True(containsAll(tc.expectedChannels, actualChannels)) + }) + } +} + +// containsAll verifies if all elements in the expected slice exist in the actual slice +// independent of order. +func containsAll(expected, actual []types.IdentifiedChannel) bool { + for _, expectedChannel := range expected { + foundMatch := false + for _, actualChannel := range actual { + if reflect.DeepEqual(actualChannel, expectedChannel) { + foundMatch = true + break + } + } + if !foundMatch { + return false + } + } + return true +} + // TestGetAllChannels creates multiple channels on chain A through various connections // and tests their retrieval. 2 channels are on connA0 and 1 channel is on connA1 -func (suite KeeperTestSuite) TestGetAllChannels() { +func (suite KeeperTestSuite) TestGetAllChannels() { //nolint:govet // this is a test, we are okay with copying locks path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.Setup(path) // channel0 on first connection on chainA @@ -147,7 +229,7 @@ func (suite KeeperTestSuite) TestGetAllChannels() { // TestGetAllSequences sets all packet sequences for two different channels on chain A and // tests their retrieval. -func (suite KeeperTestSuite) TestGetAllSequences() { +func (suite KeeperTestSuite) TestGetAllSequences() { //nolint:govet // this is a test, we are okay with copying locks path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.Setup(path) @@ -189,7 +271,7 @@ func (suite KeeperTestSuite) TestGetAllSequences() { // TestGetAllPacketState creates a set of acks, packet commitments, and receipts on two different // channels on chain A and tests their retrieval. -func (suite KeeperTestSuite) TestGetAllPacketState() { +func (suite KeeperTestSuite) TestGetAllPacketState() { //nolint:govet // this is a test, we are okay with copying locks path := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.Setup(path) diff --git a/modules/core/04-channel/keeper/packet.go b/modules/core/04-channel/keeper/packet.go index 551e02e8b78..c69cdfd6554 100644 --- a/modules/core/04-channel/keeper/packet.go +++ b/modules/core/04-channel/keeper/packet.go @@ -5,139 +5,115 @@ import ( "strconv" "time" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "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/ibc-go/v7/modules/core/exported" ) -// SendPacket is called by a module in order to send an IBC packet on a channel -// end owned by the calling module to the corresponding module on the counterparty -// chain. +// SendPacket is called by a module in order to send an IBC packet on a channel. +// The packet sequence generated for the packet to be sent is returned. An error +// is returned if one occurs. func (k Keeper) SendPacket( ctx sdk.Context, channelCap *capabilitytypes.Capability, - packet exported.PacketI, -) error { - if err := packet.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "packet failed basic validation") - } - - channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, +) (uint64, error) { + channel, found := k.GetChannel(ctx, sourcePort, sourceChannel) if !found { - return sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel()) + return 0, errorsmod.Wrap(types.ErrChannelNotFound, sourceChannel) } - if channel.State == types.CLOSED { - return sdkerrors.Wrapf( + if channel.State != types.OPEN { + return 0, errorsmod.Wrapf( types.ErrInvalidChannelState, - "channel is CLOSED (got %s)", channel.State.String(), + "channel is not OPEN (got %s)", channel.State.String(), ) } - if !k.scopedKeeper.AuthenticateCapability(ctx, channelCap, host.ChannelCapabilityPath(packet.GetSourcePort(), packet.GetSourceChannel())) { - return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel()) + if !k.scopedKeeper.AuthenticateCapability(ctx, channelCap, host.ChannelCapabilityPath(sourcePort, sourceChannel)) { + return 0, errorsmod.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", sourcePort, sourceChannel) } - if packet.GetDestPort() != channel.Counterparty.PortId { - return sdkerrors.Wrapf( - types.ErrInvalidPacket, - "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortId, + sequence, found := k.GetNextSequenceSend(ctx, sourcePort, sourceChannel) + if !found { + return 0, errorsmod.Wrapf( + types.ErrSequenceSendNotFound, + "source port: %s, source channel: %s", sourcePort, sourceChannel, ) } - if packet.GetDestChannel() != channel.Counterparty.ChannelId { - return sdkerrors.Wrapf( - types.ErrInvalidPacket, - "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelId, - ) + // construct packet from given fields and channel state + packet := types.NewPacket(data, sequence, sourcePort, sourceChannel, + channel.Counterparty.PortId, channel.Counterparty.ChannelId, timeoutHeight, timeoutTimestamp) + + if err := packet.ValidateBasic(); err != nil { + return 0, errorsmod.Wrap(err, "constructed packet failed basic validation") } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + return 0, errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } clientState, found := k.clientKeeper.GetClientState(ctx, connectionEnd.GetClientID()) if !found { - return clienttypes.ErrConsensusStateNotFound + return 0, clienttypes.ErrConsensusStateNotFound } // prevent accidental sends with clients that cannot be updated clientStore := k.clientKeeper.ClientStore(ctx, connectionEnd.GetClientID()) if status := clientState.Status(ctx, clientStore, k.cdc); status != exported.Active { - return sdkerrors.Wrapf(clienttypes.ErrClientNotActive, "cannot send packet using client (%s) with status %s", connectionEnd.GetClientID(), status) + return 0, errorsmod.Wrapf(clienttypes.ErrClientNotActive, "cannot send packet using client (%s) with status %s", connectionEnd.GetClientID(), status) } // check if packet is timed out on the receiving chain latestHeight := clientState.GetLatestHeight() - timeoutHeight := packet.GetTimeoutHeight() if !timeoutHeight.IsZero() && latestHeight.GTE(timeoutHeight) { - return sdkerrors.Wrapf( + return 0, errorsmod.Wrapf( types.ErrPacketTimeout, "receiving chain block height >= packet timeout height (%s >= %s)", latestHeight, timeoutHeight, ) } - clientType, _, err := clienttypes.ParseClientIdentifier(connectionEnd.GetClientID()) + latestTimestamp, err := k.connectionKeeper.GetTimestampAtHeight(ctx, connectionEnd, latestHeight) if err != nil { - return err - } - - // NOTE: this is a temporary fix. Solo machine does not support usage of 'GetTimestampAtHeight' - // A future change should move this function to be a ClientState callback. - if clientType != exported.Solomachine { - latestTimestamp, err := k.connectionKeeper.GetTimestampAtHeight(ctx, connectionEnd, latestHeight) - if err != nil { - return err - } - - if packet.GetTimeoutTimestamp() != 0 && latestTimestamp >= packet.GetTimeoutTimestamp() { - return sdkerrors.Wrapf( - types.ErrPacketTimeout, - "receiving chain block timestamp >= packet timeout timestamp (%s >= %s)", time.Unix(0, int64(latestTimestamp)), time.Unix(0, int64(packet.GetTimeoutTimestamp())), - ) - } - } - - nextSequenceSend, found := k.GetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) - if !found { - return sdkerrors.Wrapf( - types.ErrSequenceSendNotFound, - "source port: %s, source channel: %s", packet.GetSourcePort(), packet.GetSourceChannel(), - ) + return 0, err } - if packet.GetSequence() != nextSequenceSend { - return sdkerrors.Wrapf( - types.ErrInvalidPacket, - "packet sequence ≠ next send sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceSend, + if packet.GetTimeoutTimestamp() != 0 && latestTimestamp >= packet.GetTimeoutTimestamp() { + return 0, errorsmod.Wrapf( + types.ErrPacketTimeout, + "receiving chain block timestamp >= packet timeout timestamp (%s >= %s)", time.Unix(0, int64(latestTimestamp)), time.Unix(0, int64(packet.GetTimeoutTimestamp())), ) } commitment := types.CommitPacket(k.cdc, packet) - nextSequenceSend++ - k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) - k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment) + k.SetNextSequenceSend(ctx, sourcePort, sourceChannel, sequence+1) + k.SetPacketCommitment(ctx, sourcePort, sourceChannel, packet.GetSequence(), commitment) - EmitSendPacketEvent(ctx, packet, channel, timeoutHeight) + emitSendPacketEvent(ctx, packet, channel, timeoutHeight) k.Logger(ctx).Info( "packet sent", "sequence", strconv.FormatUint(packet.GetSequence(), 10), - "src_port", packet.GetSourcePort(), - "src_channel", packet.GetSourceChannel(), + "src_port", sourcePort, + "src_channel", sourceChannel, "dst_port", packet.GetDestPort(), "dst_channel", packet.GetDestChannel(), ) - return nil + return packet.GetSequence(), nil } // RecvPacket is called by a module in order to receive & process an IBC packet @@ -151,11 +127,11 @@ func (k Keeper) RecvPacket( ) error { channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetDestChannel()) + return errorsmod.Wrap(types.ErrChannelNotFound, packet.GetDestChannel()) } if channel.State != types.OPEN { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelState, "channel state is not OPEN (got %s)", channel.State.String(), ) @@ -164,7 +140,7 @@ func (k Keeper) RecvPacket( // Authenticate capability to ensure caller has authority to receive packet on this channel capName := host.ChannelCapabilityPath(packet.GetDestPort(), packet.GetDestChannel()) if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, capName) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelCapability, "channel capability failed authentication for capability name %s", capName, ) @@ -172,14 +148,14 @@ func (k Keeper) RecvPacket( // packet must come from the channel's counterparty if packet.GetSourcePort() != channel.Counterparty.PortId { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidPacket, "packet source port doesn't match the counterparty's port (%s ≠ %s)", packet.GetSourcePort(), channel.Counterparty.PortId, ) } if packet.GetSourceChannel() != channel.Counterparty.ChannelId { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidPacket, "packet source channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetSourceChannel(), channel.Counterparty.ChannelId, ) @@ -190,11 +166,11 @@ func (k Keeper) RecvPacket( // connection and channel must both be open connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) @@ -204,7 +180,7 @@ func (k Keeper) RecvPacket( selfHeight := clienttypes.GetSelfHeight(ctx) timeoutHeight := packet.GetTimeoutHeight() if !timeoutHeight.IsZero() && selfHeight.GTE(timeoutHeight) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrPacketTimeout, "block height >= packet timeout height (%s >= %s)", selfHeight, timeoutHeight, ) @@ -212,7 +188,7 @@ func (k Keeper) RecvPacket( // check if packet timeouted by comparing it with the latest timestamp of the chain if packet.GetTimeoutTimestamp() != 0 && uint64(ctx.BlockTime().UnixNano()) >= packet.GetTimeoutTimestamp() { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrPacketTimeout, "block timestamp >= packet timeout timestamp (%s >= %s)", ctx.BlockTime(), time.Unix(0, int64(packet.GetTimeoutTimestamp())), ) @@ -226,7 +202,7 @@ func (k Keeper) RecvPacket( packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment, ); err != nil { - return sdkerrors.Wrap(err, "couldn't verify counterparty packet commitment") + return errorsmod.Wrap(err, "couldn't verify counterparty packet commitment") } switch channel.Ordering { @@ -234,7 +210,7 @@ func (k Keeper) RecvPacket( // check if the packet receipt has been received already for unordered channels _, found := k.GetPacketReceipt(ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) if found { - EmitRecvPacketEvent(ctx, packet, channel) + emitRecvPacketEvent(ctx, packet, channel) // This error indicates that the packet has already been relayed. Core IBC will // treat this error as a no-op in order to prevent an entire relay transaction // from failing and consuming unnecessary fees. @@ -251,14 +227,14 @@ func (k Keeper) RecvPacket( // check if the packet is being received in order nextSequenceRecv, found := k.GetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrSequenceReceiveNotFound, "destination port: %s, destination channel: %s", packet.GetDestPort(), packet.GetDestChannel(), ) } if packet.GetSequence() < nextSequenceRecv { - EmitRecvPacketEvent(ctx, packet, channel) + emitRecvPacketEvent(ctx, packet, channel) // This error indicates that the packet has already been relayed. Core IBC will // treat this error as a no-op in order to prevent an entire relay transaction // from failing and consuming unnecessary fees. @@ -266,7 +242,7 @@ func (k Keeper) RecvPacket( } if packet.GetSequence() != nextSequenceRecv { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrPacketSequenceOutOfOrder, "packet sequence ≠ next receive sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceRecv, ) @@ -293,7 +269,7 @@ func (k Keeper) RecvPacket( ) // emit an event that the relayer can query for - EmitRecvPacketEvent(ctx, packet, channel) + emitRecvPacketEvent(ctx, packet, channel) return nil } @@ -317,11 +293,11 @@ func (k Keeper) WriteAcknowledgement( ) error { channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel()) if !found { - return sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetDestChannel()) + return errorsmod.Wrap(types.ErrChannelNotFound, packet.GetDestChannel()) } if channel.State != types.OPEN { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelState, "channel state is not OPEN (got %s)", channel.State.String(), ) @@ -330,7 +306,7 @@ func (k Keeper) WriteAcknowledgement( // Authenticate capability to ensure caller has authority to receive packet on this channel capName := host.ChannelCapabilityPath(packet.GetDestPort(), packet.GetDestChannel()) if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, capName) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelCapability, "channel capability failed authentication for capability name %s", capName, ) @@ -344,12 +320,12 @@ func (k Keeper) WriteAcknowledgement( } if acknowledgement == nil { - return sdkerrors.Wrap(types.ErrInvalidAcknowledgement, "acknowledgement cannot be nil") + return errorsmod.Wrap(types.ErrInvalidAcknowledgement, "acknowledgement cannot be nil") } bz := acknowledgement.Acknowledgement() if len(bz) == 0 { - return sdkerrors.Wrap(types.ErrInvalidAcknowledgement, "acknowledgement cannot be empty") + return errorsmod.Wrap(types.ErrInvalidAcknowledgement, "acknowledgement cannot be empty") } // set the acknowledgement so that it can be verified on the other side @@ -361,14 +337,14 @@ func (k Keeper) WriteAcknowledgement( // log that a packet acknowledgement has been written k.Logger(ctx).Info( "acknowledgement written", - "sequence", packet.GetSequence(), + "sequence", strconv.FormatUint(packet.GetSequence(), 10), "src_port", packet.GetSourcePort(), "src_channel", packet.GetSourceChannel(), "dst_port", packet.GetDestPort(), "dst_channel", packet.GetDestChannel(), ) - EmitWriteAcknowledgementEvent(ctx, packet, channel, bz) + emitWriteAcknowledgementEvent(ctx, packet, channel, bz) return nil } @@ -389,14 +365,14 @@ func (k Keeper) AcknowledgePacket( ) error { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel(), ) } if channel.State != types.OPEN { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelState, "channel state is not OPEN (got %s)", channel.State.String(), ) @@ -405,7 +381,7 @@ func (k Keeper) AcknowledgePacket( // Authenticate capability to ensure caller has authority to receive packet on this channel capName := host.ChannelCapabilityPath(packet.GetSourcePort(), packet.GetSourceChannel()) if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, capName) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelCapability, "channel capability failed authentication for capability name %s", capName, ) @@ -413,14 +389,14 @@ func (k Keeper) AcknowledgePacket( // packet must have been sent to the channel's counterparty if packet.GetDestPort() != channel.Counterparty.PortId { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidPacket, "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortId, ) } if packet.GetDestChannel() != channel.Counterparty.ChannelId { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidPacket, "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelId, ) @@ -428,11 +404,11 @@ func (k Keeper) AcknowledgePacket( connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) @@ -441,7 +417,7 @@ func (k Keeper) AcknowledgePacket( commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if len(commitment) == 0 { - EmitAcknowledgePacketEvent(ctx, packet, channel) + emitAcknowledgePacketEvent(ctx, packet, channel) // This error indicates that the acknowledgement has already been relayed // or there is a misconfigured relayer attempting to prove an acknowledgement // for a packet never sent. Core IBC will treat this error as a no-op in order to @@ -453,7 +429,7 @@ func (k Keeper) AcknowledgePacket( // verify we sent the packet and haven't cleared it out yet if !bytes.Equal(commitment, packetCommitment) { - return sdkerrors.Wrapf(types.ErrInvalidPacket, "commitment bytes are not equal: got (%v), expected (%v)", packetCommitment, commitment) + return errorsmod.Wrapf(types.ErrInvalidPacket, "commitment bytes are not equal: got (%v), expected (%v)", packetCommitment, commitment) } if err := k.connectionKeeper.VerifyPacketAcknowledgement( @@ -467,14 +443,14 @@ func (k Keeper) AcknowledgePacket( if channel.Ordering == types.ORDERED { nextSequenceAck, found := k.GetNextSequenceAck(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrSequenceAckNotFound, "source port: %s, source channel: %s", packet.GetSourcePort(), packet.GetSourceChannel(), ) } if packet.GetSequence() != nextSequenceAck { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrPacketSequenceOutOfOrder, "packet sequence ≠ next ack sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceAck, ) @@ -503,7 +479,7 @@ func (k Keeper) AcknowledgePacket( ) // emit an event marking that we have processed the acknowledgement - EmitAcknowledgePacketEvent(ctx, packet, channel) + emitAcknowledgePacketEvent(ctx, packet, channel) return nil } diff --git a/modules/core/04-channel/keeper/packet_test.go b/modules/core/04-channel/keeper/packet_test.go index 0000edda0e7..64a1154a2a2 100644 --- a/modules/core/04-channel/keeper/packet_test.go +++ b/modules/core/04-channel/keeper/packet_test.go @@ -4,56 +4,59 @@ import ( "errors" "fmt" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "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/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) var ( disabledTimeoutTimestamp = uint64(0) disabledTimeoutHeight = clienttypes.ZeroHeight() - timeoutHeight = clienttypes.NewHeight(0, 100) + defaultTimeoutHeight = clienttypes.NewHeight(1, 100) // for when the testing package cannot be used - clientIDA = "clientA" - clientIDB = "clientB" - connIDA = "connA" - connIDB = "connB" - portID = "portid" - channelIDA = "channelidA" - channelIDB = "channelidB" + connIDA = "connA" + connIDB = "connB" ) // TestSendPacket tests SendPacket from chainA to chainB func (suite *KeeperTestSuite) TestSendPacket() { var ( - path *ibctesting.Path - packet exported.PacketI - channelCap *capabilitytypes.Capability + path *ibctesting.Path + sourcePort string + sourceChannel string + packetData []byte + timeoutHeight clienttypes.Height + timeoutTimestamp uint64 + channelCap *capabilitytypes.Capability ) testCases := []testCase{ {"success: UNORDERED channel", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + sourceChannel = path.EndpointA.ChannelID + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, true}, {"success: ORDERED channel", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + sourceChannel = path.EndpointA.ChannelID + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, true}, {"success with solomachine: UNORDERED channel", func() { suite.coordinator.Setup(path) + sourceChannel = path.EndpointA.ChannelID + // swap client with solo machine solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinesingle", "testing", 1) path.EndpointA.ClientID = clienttypes.FormatClientIdentifier(exported.Solomachine, 10) @@ -62,12 +65,13 @@ func (suite *KeeperTestSuite) TestSendPacket() { connection.ClientId = path.EndpointA.ClientID path.EndpointA.SetConnection(connection) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, true}, {"success with solomachine: ORDERED channel", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) + sourceChannel = path.EndpointA.ChannelID + // swap client with solomachine solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinesingle", "testing", 1) path.EndpointA.ClientID = clienttypes.FormatClientIdentifier(exported.Solomachine, 10) @@ -76,111 +80,128 @@ func (suite *KeeperTestSuite) TestSendPacket() { connection.ClientId = path.EndpointA.ClientID path.EndpointA.SetConnection(connection) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, true}, - {"sending packet out of order on UNORDERED channel", func() { - // setup creates an unordered channel - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 5, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - }, false}, - {"sending packet out of order on ORDERED channel", func() { - path.SetChannelOrdered() - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 5, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - }, false}, {"packet basic validation failed, empty packet data", func() { suite.coordinator.Setup(path) - packet = types.NewPacket([]byte{}, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + sourceChannel = path.EndpointA.ChannelID + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + packetData = []byte{} }, false}, {"channel not found", func() { // use wrong channel naming suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + sourceChannel = ibctesting.InvalidID channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, - {"channel closed", func() { + {"channel is in CLOSED state", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + sourceChannel = path.EndpointA.ChannelID - err := path.EndpointA.SetChannelClosed() + err := path.EndpointA.SetChannelState(types.CLOSED) suite.Require().NoError(err) }, false}, - {"packet dest port ≠ channel counterparty port", func() { + {"channel is in INIT state", func() { suite.coordinator.Setup(path) - // use wrong port for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + sourceChannel = path.EndpointA.ChannelID + + err := path.EndpointA.SetChannelState(types.INIT) + suite.Require().NoError(err) }, false}, - {"packet dest channel ID ≠ channel counterparty channel ID", func() { + {"channel is in TRYOPEN stage", func() { suite.coordinator.Setup(path) - // use wrong channel for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) - channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + sourceChannel = path.EndpointA.ChannelID + + err := path.EndpointA.SetChannelState(types.TRYOPEN) + suite.Require().NoError(err) }, false}, {"connection not found", func() { // pass channel check - suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetChannel( - suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, - types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{connIDA}, path.EndpointA.ChannelConfig.Version), - ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.coordinator.Setup(path) + sourceChannel = path.EndpointA.ChannelID + + channel := path.EndpointA.GetChannel() + channel.ConnectionHops[0] = "invalid-connection" + path.EndpointA.SetChannel(channel) + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"client state not found", func() { suite.coordinator.Setup(path) + sourceChannel = path.EndpointA.ChannelID // change connection client ID connection := path.EndpointA.GetConnection() connection.ClientId = ibctesting.InvalidID suite.chainA.App.GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainA.GetContext(), path.EndpointA.ConnectionID, connection) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"client state is frozen", func() { suite.coordinator.Setup(path) + sourceChannel = path.EndpointA.ChannelID connection := path.EndpointA.GetConnection() clientState := path.EndpointA.GetClientState() - cs, ok := clientState.(*ibctmtypes.ClientState) + cs, ok := clientState.(*ibctm.ClientState) suite.Require().True(ok) // freeze client cs.FrozenHeight = clienttypes.NewHeight(0, 1) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), connection.ClientId, cs) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"timeout height passed", func() { suite.coordinator.Setup(path) + sourceChannel = path.EndpointA.ChannelID + // use client state latest height for timeout clientState := path.EndpointA.GetClientState() - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clientState.GetLatestHeight().(clienttypes.Height), disabledTimeoutTimestamp) + timeoutHeight = clientState.GetLatestHeight().(clienttypes.Height) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"timeout timestamp passed", func() { suite.coordinator.Setup(path) + sourceChannel = path.EndpointA.ChannelID + // use latest time on client state clientState := path.EndpointA.GetClientState() connection := path.EndpointA.GetConnection() timestamp, err := suite.chainA.App.GetIBCKeeper().ConnectionKeeper.GetTimestampAtHeight(suite.chainA.GetContext(), connection, clientState.GetLatestHeight()) suite.Require().NoError(err) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, disabledTimeoutHeight, timestamp) + timeoutHeight = disabledTimeoutHeight + timeoutTimestamp = timestamp + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + }, false}, + {"timeout timestamp passed with solomachine", func() { + suite.coordinator.Setup(path) + // swap client with solomachine + solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinesingle", "testing", 1) + path.EndpointA.ClientID = clienttypes.FormatClientIdentifier(exported.Solomachine, 10) + path.EndpointA.SetClientState(solomachine.ClientState()) + connection := path.EndpointA.GetConnection() + connection.ClientId = path.EndpointA.ClientID + path.EndpointA.SetConnection(connection) + + clientState := path.EndpointA.GetClientState() + timestamp, err := suite.chainA.App.GetIBCKeeper().ConnectionKeeper.GetTimestampAtHeight(suite.chainA.GetContext(), connection, clientState.GetLatestHeight()) + suite.Require().NoError(err) + + sourceChannel = path.EndpointA.ChannelID + timeoutHeight = disabledTimeoutHeight + timeoutTimestamp = timestamp + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"next sequence send not found", func() { path := ibctesting.NewPath(suite.chainA, suite.chainB) + sourceChannel = path.EndpointA.ChannelID + suite.coordinator.SetupConnections(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) // manually creating channel prevents next sequence from being set suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetChannel( suite.chainA.GetContext(), @@ -190,15 +211,10 @@ func (suite *KeeperTestSuite) TestSendPacket() { suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, - {"next sequence wrong", func() { - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 5) - channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) - }, false}, {"channel capability not found", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + sourceChannel = path.EndpointA.ChannelID + channelCap = capabilitytypes.NewCapability(5) }, false}, } @@ -209,12 +225,27 @@ func (suite *KeeperTestSuite) TestSendPacket() { suite.SetupTest() // reset path = ibctesting.NewPath(suite.chainA, suite.chainB) + // set default send packet arguments + // sourceChannel is set after path is setup + sourcePort = path.EndpointA.ChannelConfig.PortID + timeoutHeight = defaultTimeoutHeight + timeoutTimestamp = disabledTimeoutTimestamp + packetData = ibctesting.MockPacketData + + // malleate may modify send packet arguments above tc.malleate() - err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.SendPacket(suite.chainA.GetContext(), channelCap, packet) + // only check if nextSequenceSend exists in no error case since it is a tested error case above. + expectedSequence, ok := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetNextSequenceSend(suite.chainA.GetContext(), sourcePort, sourceChannel) + + sequence, err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.SendPacket(suite.chainA.GetContext(), channelCap, + sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, packetData) if tc.expPass { suite.Require().NoError(err) + // verify that the returned sequence matches expected value + suite.Require().True(ok) + suite.Require().Equal(expectedSequence, sequence, "send packet did not return the expected sequence of the outgoing packet") } else { suite.Require().Error(err) } @@ -230,7 +261,7 @@ func (suite *KeeperTestSuite) TestRecvPacket() { path *ibctesting.Path packet exported.PacketI channelCap *capabilitytypes.Capability - expError *sdkerrors.Error + expError *errorsmod.Error ) testCases := []testCase{ @@ -238,31 +269,28 @@ func (suite *KeeperTestSuite) TestRecvPacket() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, true}, {"success UNORDERED channel", func() { // setup uses an UNORDERED channel suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, true}, {"success with out of order packet: UNORDERED channel", func() { // setup uses an UNORDERED channel suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - // send 2 packets - err := path.EndpointA.SendPacket(packet) + _, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) - // set sequence to 2 - packet = types.NewPacket(ibctesting.MockPacketData, 2, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - err = path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) // attempts to receive packet 2 without receiving packet 1 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, true}, @@ -272,11 +300,11 @@ func (suite *KeeperTestSuite) TestRecvPacket() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet.(types.Packet)) suite.Require().NoError(err) }, false}, @@ -285,11 +313,11 @@ func (suite *KeeperTestSuite) TestRecvPacket() { // setup uses an UNORDERED channel suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet.(types.Packet)) suite.Require().NoError(err) }, false}, @@ -298,15 +326,14 @@ func (suite *KeeperTestSuite) TestRecvPacket() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) // send 2 packets - err := path.EndpointA.SendPacket(packet) + _, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) - // set sequence to 2 - packet = types.NewPacket(ibctesting.MockPacketData, 2, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - err = path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) // attempts to receive packet 2 without receiving packet 1 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, @@ -315,16 +342,16 @@ func (suite *KeeperTestSuite) TestRecvPacket() { // use wrong channel naming suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, ibctesting.InvalidID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, {"channel not open", func() { expError = types.ErrInvalidChannelState suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) - err := path.EndpointB.SetChannelClosed() + err := path.EndpointB.SetChannelState(types.CLOSED) suite.Require().NoError(err) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, @@ -334,9 +361,9 @@ func (suite *KeeperTestSuite) TestRecvPacket() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = capabilitytypes.NewCapability(3) }, false}, {"packet source port ≠ channel counterparty port", func() { @@ -344,7 +371,7 @@ func (suite *KeeperTestSuite) TestRecvPacket() { suite.coordinator.Setup(path) // use wrong port for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, {"packet source channel ID ≠ channel counterparty channel ID", func() { @@ -352,7 +379,7 @@ func (suite *KeeperTestSuite) TestRecvPacket() { suite.coordinator.Setup(path) // use wrong port for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, {"connection not found", func() { @@ -365,7 +392,7 @@ func (suite *KeeperTestSuite) TestRecvPacket() { path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{connIDB}, path.EndpointB.ChannelConfig.Version), ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) suite.chainB.CreateChannelCapability(suite.chainB.GetSimApp().ScopedIBCMockKeeper, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, @@ -383,7 +410,7 @@ func (suite *KeeperTestSuite) TestRecvPacket() { path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointB.ConnectionID}, path.EndpointB.ChannelConfig.Version), ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) suite.chainB.CreateChannelCapability(suite.chainB.GetSimApp().ScopedIBCMockKeeper, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, @@ -415,7 +442,7 @@ func (suite *KeeperTestSuite) TestRecvPacket() { types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointB.ConnectionID}, path.EndpointB.ChannelConfig.Version), ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) // manually set packet commitment suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, packet.GetSequence(), types.CommitPacket(suite.chainA.App.AppCodec(), packet)) @@ -423,16 +450,19 @@ func (suite *KeeperTestSuite) TestRecvPacket() { channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - path.EndpointA.UpdateClient() - path.EndpointB.UpdateClient() + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) }, false}, {"receipt already stored", func() { expError = types.ErrNoOpMsg suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - path.EndpointA.SendPacket(packet) - suite.chainB.App.GetIBCKeeper().ChannelKeeper.SetPacketReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, 1) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + suite.chainB.App.GetIBCKeeper().ChannelKeeper.SetPacketReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, sequence) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, {"validation failed", func() { @@ -440,7 +470,7 @@ func (suite *KeeperTestSuite) TestRecvPacket() { // packet commitment not set resulting in invalid proof suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, } @@ -501,7 +531,7 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgement() { "success", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) ack = ibcmock.MockAcknowledgement channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, @@ -510,16 +540,16 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgement() { {"channel not found", func() { // use wrong channel naming suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, ibctesting.InvalidID, defaultTimeoutHeight, disabledTimeoutTimestamp) ack = ibcmock.MockAcknowledgement channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, {"channel not open", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) ack = ibcmock.MockAcknowledgement - err := path.EndpointB.SetChannelClosed() + err := path.EndpointB.SetChannelState(types.CLOSED) suite.Require().NoError(err) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false}, @@ -527,7 +557,7 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgement() { "capability authentication failed", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) ack = ibcmock.MockAcknowledgement channelCap = capabilitytypes.NewCapability(3) }, @@ -537,7 +567,7 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgement() { "no-op, already acked", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) ack = ibcmock.MockAcknowledgement suite.chainB.App.GetIBCKeeper().ChannelKeeper.SetPacketAcknowledgement(suite.chainB.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ack.Acknowledgement()) channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) @@ -548,8 +578,8 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgement() { "empty acknowledgement", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - ack = ibcmock.NewMockEmptyAcknowledgement() + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) + ack = ibcmock.NewEmptyAcknowledgement() channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, false, @@ -558,7 +588,7 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgement() { "acknowledgement is nil", func() { suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) ack = nil channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) }, @@ -592,19 +622,20 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { ack = ibcmock.MockAcknowledgement channelCap *capabilitytypes.Capability - expError *sdkerrors.Error + expError *errorsmod.Error ) testCases := []testCase{ {"success on ordered channel", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // create packet receipt and acknowledgement + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -613,13 +644,13 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { {"success on unordered channel", func() { // setup uses an UNORDERED channel suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // create packet receipt and acknowledgement + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -630,12 +661,13 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // create packet receipt and acknowledgement + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -649,13 +681,13 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { // setup uses an UNORDERED channel suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // create packet receipt and acknowledgement + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -669,15 +701,15 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { // use wrong channel naming suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) }, false}, {"channel not open", func() { expError = types.ErrInvalidChannelState suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) - err := path.EndpointA.SetChannelClosed() + err := path.EndpointA.SetChannelState(types.CLOSED) suite.Require().NoError(err) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, @@ -687,12 +719,12 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // create packet receipt and acknowledgement + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -703,7 +735,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { suite.coordinator.Setup(path) // use wrong port for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"packet destination channel ID ≠ channel counterparty channel ID", func() { @@ -711,7 +743,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { suite.coordinator.Setup(path) // use wrong channel for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"connection not found", func() { @@ -724,7 +756,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{"connection-1000"}, path.EndpointA.ChannelConfig.Version), ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, @@ -741,7 +773,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{path.EndpointA.ConnectionID}, path.EndpointA.ChannelConfig.Version), ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, @@ -750,7 +782,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { // packet commitment never written suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"packet ack verification failed", func() { @@ -758,10 +790,11 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { // ack never written suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) // create packet commitment - path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"packet commitment bytes do not match", func() { @@ -769,13 +802,13 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { // setup uses an UNORDERED channel suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // create packet receipt and acknowledgement + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -797,7 +830,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{path.EndpointA.ConnectionID}, path.EndpointA.ChannelConfig.Version), ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) // manually set packet commitment suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, packet.GetSequence(), types.CommitPacket(suite.chainA.App.AppCodec(), packet)) @@ -809,19 +842,22 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { suite.coordinator.CommitBlock(path.EndpointA.Chain, path.EndpointB.Chain) - path.EndpointA.UpdateClient() - path.EndpointB.UpdateClient() + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) }, false}, {"next ack sequence mismatch ORDERED", func() { expError = types.ErrPacketSequenceOutOfOrder path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // create packet acknowledgement + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) diff --git a/modules/core/04-channel/keeper/timeout.go b/modules/core/04-channel/keeper/timeout.go index 1076f333185..a0151520cbf 100644 --- a/modules/core/04-channel/keeper/timeout.go +++ b/modules/core/04-channel/keeper/timeout.go @@ -4,14 +4,14 @@ import ( "bytes" "strconv" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "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/ibc-go/v7/modules/core/exported" ) // TimeoutPacket is called by a module which originally attempted to send a @@ -29,7 +29,7 @@ func (k Keeper) TimeoutPacket( ) error { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel(), ) @@ -39,14 +39,14 @@ func (k Keeper) TimeoutPacket( // so the capability authentication can be omitted here if packet.GetDestPort() != channel.Counterparty.PortId { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidPacket, "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortId, ) } if packet.GetDestChannel() != channel.Counterparty.ChannelId { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidPacket, "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelId, ) @@ -54,7 +54,7 @@ func (k Keeper) TimeoutPacket( connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap( + return errorsmod.Wrap( connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0], ) @@ -69,13 +69,13 @@ func (k Keeper) TimeoutPacket( timeoutHeight := packet.GetTimeoutHeight() if (timeoutHeight.IsZero() || proofHeight.LT(timeoutHeight)) && (packet.GetTimeoutTimestamp() == 0 || proofTimestamp < packet.GetTimeoutTimestamp()) { - return sdkerrors.Wrap(types.ErrPacketTimeout, "packet timeout has not been reached for height or timestamp") + return errorsmod.Wrap(types.ErrPacketTimeout, "packet timeout has not been reached for height or timestamp") } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if len(commitment) == 0 { - EmitTimeoutPacketEvent(ctx, packet, channel) + emitTimeoutPacketEvent(ctx, packet, channel) // This error indicates that the timeout has already been relayed // or there is a misconfigured relayer attempting to prove a timeout // for a packet never sent. Core IBC will treat this error as a no-op in order to @@ -84,7 +84,7 @@ func (k Keeper) TimeoutPacket( } if channel.State != types.OPEN { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelState, "channel state is not OPEN (got %s)", channel.State.String(), ) @@ -94,14 +94,14 @@ func (k Keeper) TimeoutPacket( // verify we sent the packet and haven't cleared it out yet if !bytes.Equal(commitment, packetCommitment) { - return sdkerrors.Wrapf(types.ErrInvalidPacket, "packet commitment bytes are not equal: got (%v), expected (%v)", commitment, packetCommitment) + return errorsmod.Wrapf(types.ErrInvalidPacket, "packet commitment bytes are not equal: got (%v), expected (%v)", commitment, packetCommitment) } switch channel.Ordering { case types.ORDERED: // check that packet has not been received if nextSequenceRecv > packet.GetSequence() { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrPacketReceived, "packet already received, next sequence receive > packet sequence (%d > %d)", nextSequenceRecv, packet.GetSequence(), ) @@ -118,7 +118,7 @@ func (k Keeper) TimeoutPacket( packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ) default: - panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) + panic(errorsmod.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) } if err != nil { @@ -140,12 +140,12 @@ func (k Keeper) TimeoutExecuted( ) error { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return sdkerrors.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel()) + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel()) } capName := host.ChannelCapabilityPath(packet.GetSourcePort(), packet.GetSourceChannel()) if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, capName) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrChannelCapabilityNotFound, "caller does not own capability for channel with capability name %s", capName, ) @@ -168,10 +168,10 @@ func (k Keeper) TimeoutExecuted( ) // emit an event marking that we have processed the timeout - EmitTimeoutPacketEvent(ctx, packet, channel) + emitTimeoutPacketEvent(ctx, packet, channel) if channel.Ordering == types.ORDERED && channel.State == types.CLOSED { - EmitChannelClosedEvent(ctx, packet, channel) + emitChannelClosedEvent(ctx, packet, channel) } return nil @@ -191,26 +191,26 @@ func (k Keeper) TimeoutOnClose( ) error { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { - return sdkerrors.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel()) + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel()) } capName := host.ChannelCapabilityPath(packet.GetSourcePort(), packet.GetSourceChannel()) if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, capName) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidChannelCapability, "channel capability failed authentication with capability name %s", capName, ) } if packet.GetDestPort() != channel.Counterparty.PortId { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidPacket, "packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortId, ) } if packet.GetDestChannel() != channel.Counterparty.ChannelId { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( types.ErrInvalidPacket, "packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelId, ) @@ -218,13 +218,13 @@ func (k Keeper) TimeoutOnClose( connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { - return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) } commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) if len(commitment) == 0 { - EmitTimeoutPacketEvent(ctx, packet, channel) + emitTimeoutPacketEvent(ctx, packet, channel) // This error indicates that the timeout has already been relayed // or there is a misconfigured relayer attempting to prove a timeout // for a packet never sent. Core IBC will treat this error as a no-op in order to @@ -236,7 +236,7 @@ func (k Keeper) TimeoutOnClose( // verify we sent the packet and haven't cleared it out yet if !bytes.Equal(commitment, packetCommitment) { - return sdkerrors.Wrapf(types.ErrInvalidPacket, "packet commitment bytes are not equal: got (%v), expected (%v)", commitment, packetCommitment) + return errorsmod.Wrapf(types.ErrInvalidPacket, "packet commitment bytes are not equal: got (%v), expected (%v)", commitment, packetCommitment) } counterpartyHops := []string{connectionEnd.GetCounterparty().GetConnectionID()} @@ -260,7 +260,7 @@ func (k Keeper) TimeoutOnClose( case types.ORDERED: // check that packet has not been received if nextSequenceRecv > packet.GetSequence() { - return sdkerrors.Wrapf(types.ErrInvalidPacket, "packet already received, next sequence receive > packet sequence (%d > %d", nextSequenceRecv, packet.GetSequence()) + return errorsmod.Wrapf(types.ErrInvalidPacket, "packet already received, next sequence receive > packet sequence (%d > %d", nextSequenceRecv, packet.GetSequence()) } // check that the recv sequence is as claimed @@ -274,7 +274,7 @@ func (k Keeper) TimeoutOnClose( packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ) default: - panic(sdkerrors.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) + panic(errorsmod.Wrapf(types.ErrInvalidChannelOrdering, channel.Ordering.String())) } if err != nil { diff --git a/modules/core/04-channel/keeper/timeout_test.go b/modules/core/04-channel/keeper/timeout_test.go index 5dab582e947..e2f8ebc9305 100644 --- a/modules/core/04-channel/keeper/timeout_test.go +++ b/modules/core/04-channel/keeper/timeout_test.go @@ -4,15 +4,15 @@ import ( "errors" "fmt" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "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/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) // TestTimeoutPacket test the TimeoutPacket call on chainA by ensuring the timeout has passed @@ -24,85 +24,107 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { packet types.Packet nextSeqRecv uint64 ordered bool - expError *sdkerrors.Error + expError *errorsmod.Error ) testCases := []testCase{ {"success: ORDERED", func() { ordered = true path.SetChannelOrdered() - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) }, true}, {"success: UNORDERED", func() { ordered = false - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp) - path.EndpointA.SendPacket(packet) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) }, true}, {"packet already timed out: ORDERED", func() { expError = types.ErrNoOpMsg ordered = true path.SetChannelOrdered() - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) - err := path.EndpointA.TimeoutPacket(packet) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) + err = path.EndpointA.TimeoutPacket(packet) suite.Require().NoError(err) }, false}, {"packet already timed out: UNORDERED", func() { expError = types.ErrNoOpMsg ordered = false - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp) - path.EndpointA.SendPacket(packet) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) - err := path.EndpointA.TimeoutPacket(packet) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + err = path.EndpointA.TimeoutPacket(packet) suite.Require().NoError(err) }, false}, {"channel not found", func() { expError = types.ErrChannelNotFound // use wrong channel naming suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) }, false}, {"channel not open", func() { expError = types.ErrInvalidChannelState suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.GetClientState().GetLatestHeight().Increment().(clienttypes.Height), disabledTimeoutTimestamp) - err := path.EndpointA.SendPacket(packet) + + timeoutHeight := path.EndpointA.GetClientState().GetLatestHeight().Increment().(clienttypes.Height) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) - err = path.EndpointA.SetChannelClosed() + err = path.EndpointA.SetChannelState(types.CLOSED) suite.Require().NoError(err) }, false}, {"packet destination port ≠ channel counterparty port", func() { expError = types.ErrInvalidPacket suite.coordinator.Setup(path) // use wrong port for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) }, false}, {"packet destination channel ID ≠ channel counterparty channel ID", func() { expError = types.ErrInvalidPacket suite.coordinator.Setup(path) // use wrong channel for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, defaultTimeoutHeight, disabledTimeoutTimestamp) }, false}, {"connection not found", func() { expError = connectiontypes.ErrConnectionNotFound @@ -112,26 +134,31 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{connIDA}, path.EndpointA.ChannelConfig.Version), ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) }, false}, {"timeout", func() { expError = types.ErrPacketTimeout suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) - path.EndpointA.SendPacket(packet) - path.EndpointA.UpdateClient() + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) }, false}, {"packet already received ", func() { expError = types.ErrPacketReceived ordered = true path.SetChannelOrdered() + suite.coordinator.Setup(path) nextSeqRecv = 2 + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) - path.EndpointA.UpdateClient() + sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, timeoutTimestamp) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) }, false}, {"packet hasn't been sent", func() { expError = types.ErrNoOpMsg @@ -139,8 +166,9 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.UpdateClient() + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, uint64(suite.chainB.GetContext().BlockTime().UnixNano())) + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) }, false}, {"next seq receive verification failed", func() { // skip error check, error occurs in light-clients @@ -149,11 +177,15 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { ordered = false path.SetChannelOrdered() - suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp) - path.EndpointA.SendPacket(packet) - path.EndpointA.UpdateClient() + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) }, false}, {"packet ack verification failed", func() { // skip error check, error occurs in light-clients @@ -162,9 +194,14 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { ordered = true suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp) - path.EndpointA.SendPacket(packet) - path.EndpointA.UpdateClient() + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) }, false}, } @@ -204,7 +241,6 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { if expError != nil { suite.Require().True(errors.Is(err, expError)) } - } }) } @@ -224,23 +260,31 @@ func (suite *KeeperTestSuite) TestTimeoutExecuted() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, true}, {"channel not found", func() { // use wrong channel naming suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) }, false}, {"incorrect capability ORDERED", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) chanCap = capabilitytypes.NewCapability(100) }, false}, } @@ -283,40 +327,52 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) - path.EndpointB.SetChannelClosed() + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + err = path.EndpointB.SetChannelState(types.CLOSED) + suite.Require().NoError(err) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, true}, {"success: UNORDERED", func() { ordered = false suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp) - path.EndpointA.SendPacket(packet) - path.EndpointB.SetChannelClosed() + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + err = path.EndpointB.SetChannelState(types.CLOSED) + suite.Require().NoError(err) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, true}, {"channel not found", func() { // use wrong channel naming suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) }, false}, {"packet dest port ≠ channel counterparty port", func() { suite.coordinator.Setup(path) // use wrong port for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"packet dest channel ID ≠ channel counterparty channel ID", func() { suite.coordinator.Setup(path) // use wrong channel for dest - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, defaultTimeoutHeight, disabledTimeoutTimestamp) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"connection not found", func() { @@ -326,7 +382,7 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{connIDA}, path.EndpointA.ChannelConfig.Version), ) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) + packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) // create chancap suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) @@ -345,42 +401,67 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { ordered = true suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) - path.EndpointB.SetChannelClosed() + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + err = path.EndpointB.SetChannelState(types.CLOSED) + suite.Require().NoError(err) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"channel verification failed ORDERED", func() { ordered = true path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"next seq receive verification failed ORDERED", func() { // set ordered to false providing the wrong proof for ORDERED case ordered = false - path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) - path.EndpointB.SetChannelClosed() - path.EndpointA.UpdateClient() + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + err = path.EndpointB.SetChannelState(types.CLOSED) + suite.Require().NoError(err) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"packet ack verification failed", func() { // set ordered to true providing the wrong proof for UNORDERED case ordered = true suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp) - path.EndpointA.SendPacket(packet) - path.EndpointB.SetChannelClosed() - path.EndpointA.UpdateClient() + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + err = path.EndpointB.SetChannelState(types.CLOSED) + suite.Require().NoError(err) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) }, false}, {"channel capability not found ORDERED", func() { @@ -388,12 +469,18 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) - path.EndpointA.SendPacket(packet) - path.EndpointB.SetChannelClosed() + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + err = path.EndpointB.SetChannelState(types.CLOSED) + suite.Require().NoError(err) // need to update chainA's client representing chainB to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) chanCap = capabilitytypes.NewCapability(100) }, false}, } diff --git a/modules/core/04-channel/module.go b/modules/core/04-channel/module.go index 867f8bd0351..5cc0f93b648 100644 --- a/modules/core/04-channel/module.go +++ b/modules/core/04-channel/module.go @@ -1,11 +1,11 @@ package channel import ( - "github.com/gogo/protobuf/grpc" + "github.com/cosmos/gogoproto/grpc" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/client/cli" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/client/cli" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // Name returns the IBC channel ICS name. diff --git a/modules/core/04-channel/simulation/decoder.go b/modules/core/04-channel/simulation/decoder.go index 5cec8179b84..7a66bc5b0c0 100644 --- a/modules/core/04-channel/simulation/decoder.go +++ b/modules/core/04-channel/simulation/decoder.go @@ -8,8 +8,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/kv" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // NewDecodeStore returns a decoder function closure that unmarshals the KVPair's diff --git a/modules/core/04-channel/simulation/decoder_test.go b/modules/core/04-channel/simulation/decoder_test.go index 4649df72b7f..64fd06d89f9 100644 --- a/modules/core/04-channel/simulation/decoder_test.go +++ b/modules/core/04-channel/simulation/decoder_test.go @@ -8,10 +8,10 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/simulation" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/simulation" + "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/ibc-go/v7/testing/simapp" ) func TestDecodeStore(t *testing.T) { diff --git a/modules/core/04-channel/simulation/genesis.go b/modules/core/04-channel/simulation/genesis.go index 7bc7ad6415d..8d30c5eb601 100644 --- a/modules/core/04-channel/simulation/genesis.go +++ b/modules/core/04-channel/simulation/genesis.go @@ -5,7 +5,7 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // GenChannelGenesis returns the default channel genesis state. diff --git a/modules/core/04-channel/types/acknowledgement.go b/modules/core/04-channel/types/acknowledgement.go index 49c795d0d55..3e4d02a1180 100644 --- a/modules/core/04-channel/types/acknowledgement.go +++ b/modules/core/04-channel/types/acknowledgement.go @@ -5,8 +5,8 @@ import ( "reflect" "strings" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) const ( @@ -32,7 +32,7 @@ func NewResultAcknowledgement(result []byte) Acknowledgement { func NewErrorAcknowledgement(err error) Acknowledgement { // the ABCI code is included in the abcitypes.ResponseDeliverTx hash // constructed in Tendermint and is therefore deterministic - _, code, _ := sdkerrors.ABCIInfo(err, false) // discard non-determinstic codespace and log values + _, code, _ := errorsmod.ABCIInfo(err, false) // discard non-determinstic codespace and log values return Acknowledgement{ Response: &Acknowledgement_Error{ @@ -46,15 +46,15 @@ func (ack Acknowledgement) ValidateBasic() error { switch resp := ack.Response.(type) { case *Acknowledgement_Result: if len(resp.Result) == 0 { - return sdkerrors.Wrap(ErrInvalidAcknowledgement, "acknowledgement result cannot be empty") + return errorsmod.Wrap(ErrInvalidAcknowledgement, "acknowledgement result cannot be empty") } case *Acknowledgement_Error: if strings.TrimSpace(resp.Error) == "" { - return sdkerrors.Wrap(ErrInvalidAcknowledgement, "acknowledgement error cannot be empty") + return errorsmod.Wrap(ErrInvalidAcknowledgement, "acknowledgement error cannot be empty") } default: - return sdkerrors.Wrapf(ErrInvalidAcknowledgement, "unsupported acknowledgement response field type %T", resp) + return errorsmod.Wrapf(ErrInvalidAcknowledgement, "unsupported acknowledgement response field type %T", resp) } return nil } diff --git a/modules/core/04-channel/types/acknowledgement_test.go b/modules/core/04-channel/types/acknowledgement_test.go index 9552fadf996..13ca093fa91 100644 --- a/modules/core/04-channel/types/acknowledgement_test.go +++ b/modules/core/04-channel/types/acknowledgement_test.go @@ -3,12 +3,14 @@ package types_test import ( "fmt" + errorsmod "cosmossdk.io/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" abcitypes "github.com/tendermint/tendermint/abci/types" tmprotostate "github.com/tendermint/tendermint/proto/tendermint/state" tmstate "github.com/tendermint/tendermint/state" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) const ( @@ -17,7 +19,7 @@ const ( ) // tests acknowledgement.ValidateBasic and acknowledgement.GetBytes -func (suite TypesTestSuite) TestAcknowledgement() { +func (suite TypesTestSuite) TestAcknowledgement() { //nolint:govet // this is a test, we are okay with copying locks testCases := []struct { name string ack types.Acknowledgement @@ -91,27 +93,27 @@ func (suite TypesTestSuite) TestAcknowledgement() { // This test acts as an indicator that the ABCI error codes may no longer be deterministic. func (suite *TypesTestSuite) TestABCICodeDeterminism() { // same ABCI error code used - err := sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "error string 1") - errSameABCICode := sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "error string 2") + err := errorsmod.Wrap(ibcerrors.ErrOutOfGas, "error string 1") + errSameABCICode := errorsmod.Wrap(ibcerrors.ErrOutOfGas, "error string 2") // different ABCI error code used - errDifferentABCICode := sdkerrors.ErrNotFound + errDifferentABCICode := ibcerrors.ErrNotFound - deliverTx := sdkerrors.ResponseDeliverTx(err, gasUsed, gasWanted, false) + deliverTx := sdkerrors.ResponseDeliverTxWithEvents(err, gasUsed, gasWanted, []abcitypes.Event{}, false) responses := tmprotostate.ABCIResponses{ DeliverTxs: []*abcitypes.ResponseDeliverTx{ &deliverTx, }, } - deliverTxSameABCICode := sdkerrors.ResponseDeliverTx(errSameABCICode, gasUsed, gasWanted, false) + deliverTxSameABCICode := sdkerrors.ResponseDeliverTxWithEvents(errSameABCICode, gasUsed, gasWanted, []abcitypes.Event{}, false) responsesSameABCICode := tmprotostate.ABCIResponses{ DeliverTxs: []*abcitypes.ResponseDeliverTx{ &deliverTxSameABCICode, }, } - deliverTxDifferentABCICode := sdkerrors.ResponseDeliverTx(errDifferentABCICode, gasUsed, gasWanted, false) + deliverTxDifferentABCICode := sdkerrors.ResponseDeliverTxWithEvents(errDifferentABCICode, gasUsed, gasWanted, []abcitypes.Event{}, false) responsesDifferentABCICode := tmprotostate.ABCIResponses{ DeliverTxs: []*abcitypes.ResponseDeliverTx{ &deliverTxDifferentABCICode, @@ -130,11 +132,11 @@ func (suite *TypesTestSuite) TestABCICodeDeterminism() { // ABCI error code are used in constructing the acknowledgement error string func (suite *TypesTestSuite) TestAcknowledgementError() { // same ABCI error code used - err := sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "error string 1") - errSameABCICode := sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "error string 2") + err := errorsmod.Wrap(ibcerrors.ErrOutOfGas, "error string 1") + errSameABCICode := errorsmod.Wrap(ibcerrors.ErrOutOfGas, "error string 2") // different ABCI error code used - errDifferentABCICode := sdkerrors.ErrNotFound + errDifferentABCICode := ibcerrors.ErrNotFound ack := types.NewErrorAcknowledgement(err) ackSameABCICode := types.NewErrorAcknowledgement(errSameABCICode) diff --git a/modules/core/04-channel/types/channel.go b/modules/core/04-channel/types/channel.go index 6b02b19f381..012b571fb07 100644 --- a/modules/core/04-channel/types/channel.go +++ b/modules/core/04-channel/types/channel.go @@ -1,10 +1,10 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( @@ -57,16 +57,16 @@ func (ch Channel) ValidateBasic() error { return ErrInvalidChannelState } if !(ch.Ordering == ORDERED || ch.Ordering == UNORDERED) { - return sdkerrors.Wrap(ErrInvalidChannelOrdering, ch.Ordering.String()) + return errorsmod.Wrap(ErrInvalidChannelOrdering, ch.Ordering.String()) } if len(ch.ConnectionHops) != 1 { - return sdkerrors.Wrap( + return errorsmod.Wrap( ErrTooManyConnectionHops, "current IBC version only supports one connection hop", ) } if err := host.ConnectionIdentifierValidator(ch.ConnectionHops[0]); err != nil { - return sdkerrors.Wrap(err, "invalid connection hop ID") + return errorsmod.Wrap(err, "invalid connection hop ID") } return ch.Counterparty.ValidateBasic() } @@ -92,11 +92,11 @@ func (c Counterparty) GetChannelID() string { // ValidateBasic performs a basic validation check of the identifiers func (c Counterparty) ValidateBasic() error { if err := host.PortIdentifierValidator(c.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty port ID") + return errorsmod.Wrap(err, "invalid counterparty port ID") } if c.ChannelId != "" { if err := host.ChannelIdentifierValidator(c.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty channel ID") + return errorsmod.Wrap(err, "invalid counterparty channel ID") } } return nil @@ -118,10 +118,10 @@ func NewIdentifiedChannel(portID, channelID string, ch Channel) IdentifiedChanne // ValidateBasic performs a basic validation of the identifiers and channel fields. func (ic IdentifiedChannel) ValidateBasic() error { if err := host.ChannelIdentifierValidator(ic.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + return errorsmod.Wrap(err, "invalid channel ID") } if err := host.PortIdentifierValidator(ic.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } channel := NewChannel(ic.State, ic.Ordering, ic.Counterparty, ic.ConnectionHops, ic.Version) return channel.ValidateBasic() diff --git a/modules/core/04-channel/types/channel.pb.go b/modules/core/04-channel/types/channel.pb.go index 3f52e4aa3dd..6d256367b07 100644 --- a/modules/core/04-channel/types/channel.pb.go +++ b/modules/core/04-channel/types/channel.pb.go @@ -5,9 +5,9 @@ package types import ( fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" io "io" math "math" math_bits "math/bits" @@ -511,68 +511,68 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/channel.proto", fileDescriptor_c3a07336710636a0) } var fileDescriptor_c3a07336710636a0 = []byte{ - // 962 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x56, 0xcf, 0x8e, 0xda, 0xd6, - 0x17, 0xc6, 0x8c, 0x61, 0xe0, 0x30, 0xc3, 0x9f, 0x9b, 0xdf, 0x10, 0xff, 0xdc, 0x04, 0x3b, 0x56, - 0x54, 0x8d, 0x52, 0x05, 0x32, 0xe9, 0xa8, 0x55, 0xb3, 0xea, 0x00, 0x4e, 0xc7, 0x6a, 0x04, 0xc8, - 0x30, 0x8b, 0x66, 0x43, 0xc1, 0xbe, 0x05, 0x2b, 0xe0, 0x4b, 0xed, 0x0b, 0xa3, 0x79, 0x80, 0x4a, - 0x11, 0x9b, 0xf6, 0x05, 0x90, 0x2a, 0x55, 0xed, 0xb3, 0x64, 0x99, 0x65, 0x57, 0xa8, 0x9a, 0x59, - 0x74, 0xcf, 0x0b, 0xb4, 0xf2, 0xbd, 0x36, 0x7f, 0x26, 0x51, 0x96, 0xed, 0xa6, 0x2b, 0xdf, 0xf3, - 0x9d, 0xef, 0x9c, 0xef, 0xdc, 0x73, 0x0e, 0xc6, 0xf0, 0xc0, 0xe9, 0x5b, 0x15, 0x8b, 0x78, 0xb8, - 0x62, 0x0d, 0x7b, 0xae, 0x8b, 0x47, 0x95, 0xd9, 0x49, 0x74, 0x2c, 0x4f, 0x3c, 0x42, 0x09, 0xba, - 0xe3, 0xf4, 0xad, 0x72, 0x40, 0x29, 0x47, 0xf8, 0xec, 0x44, 0xfe, 0xdf, 0x80, 0x0c, 0x08, 0xf3, - 0x57, 0x82, 0x13, 0xa7, 0xca, 0xca, 0x26, 0xdb, 0xc8, 0xc1, 0x2e, 0x65, 0xc9, 0xd8, 0x89, 0x13, - 0xb4, 0x5f, 0xe3, 0xb0, 0x5f, 0xe3, 0x59, 0xd0, 0x13, 0x48, 0xf8, 0xb4, 0x47, 0xb1, 0x24, 0xa8, - 0xc2, 0x71, 0xf6, 0xa9, 0x5c, 0x7e, 0x8f, 0x4e, 0xb9, 0x1d, 0x30, 0x4c, 0x4e, 0x44, 0x9f, 0x41, - 0x8a, 0x78, 0x36, 0xf6, 0x1c, 0x77, 0x20, 0xc5, 0x3f, 0x10, 0xd4, 0x0c, 0x48, 0xe6, 0x9a, 0x8b, - 0xbe, 0x86, 0x03, 0x8b, 0x4c, 0x5d, 0x8a, 0xbd, 0x49, 0xcf, 0xa3, 0x57, 0xd2, 0x9e, 0x2a, 0x1c, - 0x67, 0x9e, 0x3e, 0x78, 0x6f, 0x6c, 0x6d, 0x8b, 0x58, 0x15, 0xdf, 0x2c, 0x95, 0x98, 0xb9, 0x13, - 0x8c, 0x6a, 0x90, 0xb3, 0x88, 0xeb, 0x62, 0x8b, 0x3a, 0xc4, 0xed, 0x0e, 0xc9, 0xc4, 0x97, 0x44, - 0x75, 0xef, 0x38, 0x5d, 0x95, 0x57, 0x4b, 0xa5, 0x78, 0xd5, 0x1b, 0x8f, 0x9e, 0x69, 0xb7, 0x08, - 0x9a, 0x99, 0xdd, 0x20, 0xe7, 0x64, 0xe2, 0x23, 0x09, 0xf6, 0x67, 0xd8, 0xf3, 0x1d, 0xe2, 0x4a, - 0x09, 0x55, 0x38, 0x4e, 0x9b, 0x91, 0xf9, 0x4c, 0x7c, 0xfd, 0xb3, 0x12, 0xd3, 0xfe, 0x8c, 0x43, - 0xc1, 0xb0, 0xb1, 0x4b, 0x9d, 0xef, 0x1c, 0x6c, 0xff, 0xd7, 0xb1, 0x0f, 0x74, 0x0c, 0xdd, 0x85, - 0xfd, 0x09, 0xf1, 0x68, 0xd7, 0xb1, 0xa5, 0x24, 0xf3, 0x24, 0x03, 0xd3, 0xb0, 0xd1, 0x7d, 0x80, - 0xb0, 0xcc, 0xc0, 0xb7, 0xcf, 0x7c, 0xe9, 0x10, 0x31, 0xec, 0xb0, 0xd3, 0x97, 0x70, 0xb0, 0x7d, - 0x01, 0xf4, 0xc9, 0x26, 0x5b, 0xd0, 0xe5, 0x74, 0x15, 0xad, 0x96, 0x4a, 0x96, 0x17, 0x19, 0x3a, - 0xb4, 0xb5, 0xc2, 0xe9, 0x8e, 0x42, 0x9c, 0xf1, 0x8f, 0x56, 0x4b, 0xa5, 0x10, 0x5e, 0x6a, 0xed, - 0xd3, 0xde, 0x15, 0xfe, 0x6b, 0x0f, 0x92, 0xad, 0x9e, 0xf5, 0x0a, 0x53, 0x24, 0x43, 0xca, 0xc7, - 0xdf, 0x4f, 0xb1, 0x6b, 0xf1, 0xd1, 0x8a, 0xe6, 0xda, 0x46, 0x9f, 0x43, 0xc6, 0x27, 0x53, 0xcf, - 0xc2, 0xdd, 0x40, 0x33, 0xd4, 0x28, 0xae, 0x96, 0x0a, 0xe2, 0x1a, 0x5b, 0x4e, 0xcd, 0x04, 0x6e, - 0xb5, 0x88, 0x47, 0xd1, 0x97, 0x90, 0x0d, 0x7d, 0xa1, 0x32, 0x1b, 0x62, 0xba, 0xfa, 0xff, 0xd5, - 0x52, 0x39, 0xda, 0x89, 0x0d, 0xfd, 0x9a, 0x79, 0xc8, 0x81, 0x68, 0xdd, 0x9e, 0x43, 0xde, 0xc6, - 0x3e, 0x75, 0xdc, 0x1e, 0x9b, 0x0b, 0xd3, 0x17, 0x59, 0x8e, 0x8f, 0x56, 0x4b, 0xe5, 0x2e, 0xcf, - 0x71, 0x9b, 0xa1, 0x99, 0xb9, 0x2d, 0x88, 0x55, 0xd2, 0x84, 0x3b, 0xdb, 0xac, 0xa8, 0x1c, 0x36, - 0xc6, 0x6a, 0x69, 0xb5, 0x54, 0xe4, 0x77, 0x53, 0xad, 0x6b, 0x42, 0x5b, 0x68, 0x54, 0x18, 0x02, - 0xd1, 0xee, 0xd1, 0x1e, 0x1b, 0xf7, 0x81, 0xc9, 0xce, 0xe8, 0x5b, 0xc8, 0x52, 0x67, 0x8c, 0xc9, - 0x94, 0x76, 0x87, 0xd8, 0x19, 0x0c, 0x29, 0x1b, 0x78, 0x66, 0x67, 0xdf, 0xf9, 0x9b, 0x68, 0x76, - 0x52, 0x3e, 0x67, 0x8c, 0xea, 0xfd, 0x60, 0x59, 0x37, 0xed, 0xd8, 0x8d, 0xd7, 0xcc, 0xc3, 0x10, - 0xe0, 0x6c, 0x64, 0x40, 0x21, 0x62, 0x04, 0x4f, 0x9f, 0xf6, 0xc6, 0x13, 0x29, 0x15, 0x8c, 0xab, - 0x7a, 0x6f, 0xb5, 0x54, 0xa4, 0xdd, 0x24, 0x6b, 0x8a, 0x66, 0xe6, 0x43, 0xac, 0x13, 0x41, 0xe1, - 0x06, 0xfc, 0x26, 0x40, 0x86, 0x6f, 0x00, 0xfb, 0xcd, 0xfe, 0x03, 0xab, 0xb7, 0xb3, 0x69, 0x7b, - 0xb7, 0x36, 0x2d, 0xea, 0xaa, 0xb8, 0xe9, 0x6a, 0x58, 0xe8, 0x8f, 0x02, 0xa4, 0x78, 0xa1, 0x86, - 0xfd, 0x2f, 0x57, 0x19, 0x56, 0xd4, 0x84, 0xdc, 0x99, 0xf5, 0xca, 0x25, 0x97, 0x23, 0x6c, 0x0f, - 0xf0, 0x18, 0xbb, 0x14, 0x49, 0x90, 0xf4, 0xb0, 0x3f, 0x1d, 0x51, 0xe9, 0x28, 0xb8, 0xc0, 0x79, - 0xcc, 0x0c, 0x6d, 0x54, 0x84, 0x04, 0xf6, 0x3c, 0xe2, 0x49, 0xc5, 0x40, 0xff, 0x3c, 0x66, 0x72, - 0xb3, 0x0a, 0x90, 0xf2, 0xb0, 0x3f, 0x21, 0xae, 0x8f, 0x1f, 0xfd, 0x10, 0x87, 0x44, 0x3b, 0x7c, - 0x65, 0x2a, 0xed, 0xce, 0x59, 0x47, 0xef, 0x5e, 0x34, 0x8c, 0x86, 0xd1, 0x31, 0xce, 0x5e, 0x18, - 0x2f, 0xf5, 0x7a, 0xf7, 0xa2, 0xd1, 0x6e, 0xe9, 0x35, 0xe3, 0xb9, 0xa1, 0xd7, 0xf3, 0x31, 0xb9, - 0x30, 0x5f, 0xa8, 0x87, 0x3b, 0x04, 0x24, 0x01, 0xf0, 0xb8, 0x00, 0xcc, 0x0b, 0x72, 0x6a, 0xbe, - 0x50, 0xc5, 0xe0, 0x8c, 0x4a, 0x70, 0xc8, 0x3d, 0x1d, 0xf3, 0x9b, 0x66, 0x4b, 0x6f, 0xe4, 0xe3, - 0x72, 0x66, 0xbe, 0x50, 0xf7, 0x43, 0x73, 0x13, 0xc9, 0x9c, 0x7b, 0x3c, 0x92, 0x79, 0xee, 0xc1, - 0x01, 0xf7, 0xd4, 0x5e, 0x34, 0xdb, 0x7a, 0x3d, 0x2f, 0xca, 0x30, 0x5f, 0xa8, 0x49, 0x6e, 0xa1, - 0x8f, 0xa1, 0xb0, 0x51, 0xbc, 0x68, 0x7d, 0x65, 0x9e, 0xd5, 0xf5, 0x7c, 0x42, 0xce, 0xcd, 0x17, - 0x6a, 0x66, 0x0b, 0x42, 0x0f, 0x21, 0xbf, 0xd6, 0x8f, 0x68, 0x49, 0x39, 0x3b, 0x5f, 0xa8, 0xb0, - 0x41, 0x64, 0xf1, 0xf5, 0x2f, 0xa5, 0xd8, 0xa3, 0x4b, 0x48, 0xb0, 0xff, 0x02, 0xf4, 0x10, 0x8a, - 0x4d, 0xb3, 0xae, 0x9b, 0xdd, 0x46, 0xb3, 0xa1, 0xdf, 0xba, 0x3d, 0x2b, 0x30, 0xc0, 0x91, 0x06, - 0x39, 0xce, 0xba, 0x68, 0xb0, 0xa7, 0x5e, 0xcf, 0x0b, 0xf2, 0xe1, 0x7c, 0xa1, 0xa6, 0xd7, 0x40, - 0x70, 0x7d, 0xce, 0x89, 0x18, 0xe1, 0xf5, 0x43, 0x93, 0x0b, 0x57, 0xdb, 0x6f, 0xae, 0x4b, 0xc2, - 0xdb, 0xeb, 0x92, 0xf0, 0xc7, 0x75, 0x49, 0xf8, 0xe9, 0xa6, 0x14, 0x7b, 0x7b, 0x53, 0x8a, 0xfd, - 0x7e, 0x53, 0x8a, 0xbd, 0xfc, 0x62, 0xe0, 0xd0, 0xe1, 0xb4, 0x5f, 0xb6, 0xc8, 0xb8, 0x62, 0x11, - 0x7f, 0x4c, 0xfc, 0x8a, 0xd3, 0xb7, 0x1e, 0x0f, 0x48, 0x65, 0x76, 0x5a, 0x19, 0x13, 0x7b, 0x3a, - 0xc2, 0x3e, 0xff, 0xe8, 0x78, 0x72, 0xfa, 0x38, 0xfa, 0x8a, 0xa1, 0x57, 0x13, 0xec, 0xf7, 0x93, - 0xec, 0xab, 0xe3, 0xd3, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xee, 0x5e, 0xa5, 0xe6, 0x08, - 0x00, 0x00, + // 961 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x56, 0x4f, 0x8f, 0xda, 0x56, + 0x10, 0xc7, 0xac, 0x61, 0x61, 0xd8, 0xe5, 0xcf, 0x4b, 0x97, 0xb8, 0x6e, 0x82, 0x1d, 0x2b, 0xaa, + 0x56, 0xa9, 0x02, 0xd9, 0x34, 0x6a, 0xd4, 0x9c, 0xba, 0x80, 0xd3, 0xb5, 0x1a, 0x01, 0x32, 0xec, + 0xa1, 0xb9, 0x50, 0xb0, 0x5f, 0xc1, 0x0a, 0xf8, 0x51, 0xfb, 0xc1, 0x6a, 0x3f, 0x40, 0xa5, 0x88, + 0x4b, 0xfb, 0x05, 0x90, 0x2a, 0x55, 0xed, 0x67, 0xc9, 0x31, 0xc7, 0x9e, 0x50, 0xb5, 0x7b, 0xe8, + 0x9d, 0x2f, 0xd0, 0xca, 0xef, 0xd9, 0xfc, 0xd9, 0x44, 0x39, 0xb6, 0x97, 0x9e, 0xfc, 0xe6, 0x37, + 0xbf, 0x99, 0xdf, 0xbc, 0x99, 0xc1, 0x18, 0xee, 0x39, 0x7d, 0xab, 0x62, 0x11, 0x0f, 0x57, 0xac, + 0x61, 0xcf, 0x75, 0xf1, 0xa8, 0x32, 0x3b, 0x89, 0x8e, 0xe5, 0x89, 0x47, 0x28, 0x41, 0xb7, 0x9c, + 0xbe, 0x55, 0x0e, 0x28, 0xe5, 0x08, 0x9f, 0x9d, 0xc8, 0x1f, 0x0d, 0xc8, 0x80, 0x30, 0x7f, 0x25, + 0x38, 0x71, 0xaa, 0xac, 0x6c, 0xb2, 0x8d, 0x1c, 0xec, 0x52, 0x96, 0x8c, 0x9d, 0x38, 0x41, 0xfb, + 0x2d, 0x0e, 0xfb, 0x35, 0x9e, 0x05, 0x3d, 0x82, 0x84, 0x4f, 0x7b, 0x14, 0x4b, 0x82, 0x2a, 0x1c, + 0x67, 0x1f, 0xcb, 0xe5, 0xf7, 0xe8, 0x94, 0xdb, 0x01, 0xc3, 0xe4, 0x44, 0xf4, 0x05, 0xa4, 0x88, + 0x67, 0x63, 0xcf, 0x71, 0x07, 0x52, 0xfc, 0x03, 0x41, 0xcd, 0x80, 0x64, 0xae, 0xb9, 0xe8, 0x1b, + 0x38, 0xb0, 0xc8, 0xd4, 0xa5, 0xd8, 0x9b, 0xf4, 0x3c, 0x7a, 0x29, 0xed, 0xa9, 0xc2, 0x71, 0xe6, + 0xf1, 0xbd, 0xf7, 0xc6, 0xd6, 0xb6, 0x88, 0x55, 0xf1, 0xcd, 0x52, 0x89, 0x99, 0x3b, 0xc1, 0xa8, + 0x06, 0x39, 0x8b, 0xb8, 0x2e, 0xb6, 0xa8, 0x43, 0xdc, 0xee, 0x90, 0x4c, 0x7c, 0x49, 0x54, 0xf7, + 0x8e, 0xd3, 0x55, 0x79, 0xb5, 0x54, 0x8a, 0x97, 0xbd, 0xf1, 0xe8, 0x99, 0x76, 0x83, 0xa0, 0x99, + 0xd9, 0x0d, 0x72, 0x46, 0x26, 0x3e, 0x92, 0x60, 0x7f, 0x86, 0x3d, 0xdf, 0x21, 0xae, 0x94, 0x50, + 0x85, 0xe3, 0xb4, 0x19, 0x99, 0xcf, 0xc4, 0xd7, 0xbf, 0x28, 0x31, 0xed, 0xaf, 0x38, 0x14, 0x0c, + 0x1b, 0xbb, 0xd4, 0xf9, 0xde, 0xc1, 0xf6, 0xff, 0x1d, 0xfb, 0x40, 0xc7, 0xd0, 0x6d, 0xd8, 0x9f, + 0x10, 0x8f, 0x76, 0x1d, 0x5b, 0x4a, 0x32, 0x4f, 0x32, 0x30, 0x0d, 0x1b, 0xdd, 0x05, 0x08, 0xcb, + 0x0c, 0x7c, 0xfb, 0xcc, 0x97, 0x0e, 0x11, 0xc3, 0x0e, 0x3b, 0x7d, 0x01, 0x07, 0xdb, 0x17, 0x40, + 0x9f, 0x6d, 0xb2, 0x05, 0x5d, 0x4e, 0x57, 0xd1, 0x6a, 0xa9, 0x64, 0x79, 0x91, 0xa1, 0x43, 0x5b, + 0x2b, 0x3c, 0xd9, 0x51, 0x88, 0x33, 0xfe, 0xd1, 0x6a, 0xa9, 0x14, 0xc2, 0x4b, 0xad, 0x7d, 0xda, + 0xbb, 0xc2, 0x7f, 0xef, 0x41, 0xb2, 0xd5, 0xb3, 0x5e, 0x61, 0x8a, 0x64, 0x48, 0xf9, 0xf8, 0x87, + 0x29, 0x76, 0x2d, 0x3e, 0x5a, 0xd1, 0x5c, 0xdb, 0xe8, 0x29, 0x64, 0x7c, 0x32, 0xf5, 0x2c, 0xdc, + 0x0d, 0x34, 0x43, 0x8d, 0xe2, 0x6a, 0xa9, 0x20, 0xae, 0xb1, 0xe5, 0xd4, 0x4c, 0xe0, 0x56, 0x8b, + 0x78, 0x14, 0x7d, 0x05, 0xd9, 0xd0, 0x17, 0x2a, 0xb3, 0x21, 0xa6, 0xab, 0x1f, 0xaf, 0x96, 0xca, + 0xd1, 0x4e, 0x6c, 0xe8, 0xd7, 0xcc, 0x43, 0x0e, 0x44, 0xeb, 0xf6, 0x1c, 0xf2, 0x36, 0xf6, 0xa9, + 0xe3, 0xf6, 0xd8, 0x5c, 0x98, 0xbe, 0xc8, 0x72, 0x7c, 0xb2, 0x5a, 0x2a, 0xb7, 0x79, 0x8e, 0x9b, + 0x0c, 0xcd, 0xcc, 0x6d, 0x41, 0xac, 0x92, 0x26, 0xdc, 0xda, 0x66, 0x45, 0xe5, 0xb0, 0x31, 0x56, + 0x4b, 0xab, 0xa5, 0x22, 0xbf, 0x9b, 0x6a, 0x5d, 0x13, 0xda, 0x42, 0xa3, 0xc2, 0x10, 0x88, 0x76, + 0x8f, 0xf6, 0xd8, 0xb8, 0x0f, 0x4c, 0x76, 0x46, 0xdf, 0x41, 0x96, 0x3a, 0x63, 0x4c, 0xa6, 0xb4, + 0x3b, 0xc4, 0xce, 0x60, 0x48, 0xd9, 0xc0, 0x33, 0x3b, 0xfb, 0xce, 0xdf, 0x44, 0xb3, 0x93, 0xf2, + 0x19, 0x63, 0x54, 0xef, 0x06, 0xcb, 0xba, 0x69, 0xc7, 0x6e, 0xbc, 0x66, 0x1e, 0x86, 0x00, 0x67, + 0x23, 0x03, 0x0a, 0x11, 0x23, 0x78, 0xfa, 0xb4, 0x37, 0x9e, 0x48, 0xa9, 0x60, 0x5c, 0xd5, 0x3b, + 0xab, 0xa5, 0x22, 0xed, 0x26, 0x59, 0x53, 0x34, 0x33, 0x1f, 0x62, 0x9d, 0x08, 0x0a, 0x37, 0xe0, + 0x77, 0x01, 0x32, 0x7c, 0x03, 0xd8, 0x6f, 0xf6, 0x5f, 0x58, 0xbd, 0x9d, 0x4d, 0xdb, 0xbb, 0xb1, + 0x69, 0x51, 0x57, 0xc5, 0x4d, 0x57, 0xc3, 0x42, 0x7f, 0x12, 0x20, 0xc5, 0x0b, 0x35, 0xec, 0xff, + 0xb8, 0xca, 0xb0, 0xa2, 0x26, 0xe4, 0x4e, 0xad, 0x57, 0x2e, 0xb9, 0x18, 0x61, 0x7b, 0x80, 0xc7, + 0xd8, 0xa5, 0x48, 0x82, 0xa4, 0x87, 0xfd, 0xe9, 0x88, 0x4a, 0x47, 0xc1, 0x05, 0xce, 0x62, 0x66, + 0x68, 0xa3, 0x22, 0x24, 0xb0, 0xe7, 0x11, 0x4f, 0x2a, 0x06, 0xfa, 0x67, 0x31, 0x93, 0x9b, 0x55, + 0x80, 0x94, 0x87, 0xfd, 0x09, 0x71, 0x7d, 0xfc, 0xe0, 0xc7, 0x38, 0x24, 0xda, 0xe1, 0x2b, 0x53, + 0x69, 0x77, 0x4e, 0x3b, 0x7a, 0xf7, 0xbc, 0x61, 0x34, 0x8c, 0x8e, 0x71, 0xfa, 0xc2, 0x78, 0xa9, + 0xd7, 0xbb, 0xe7, 0x8d, 0x76, 0x4b, 0xaf, 0x19, 0xcf, 0x0d, 0xbd, 0x9e, 0x8f, 0xc9, 0x85, 0xf9, + 0x42, 0x3d, 0xdc, 0x21, 0x20, 0x09, 0x80, 0xc7, 0x05, 0x60, 0x5e, 0x90, 0x53, 0xf3, 0x85, 0x2a, + 0x06, 0x67, 0x54, 0x82, 0x43, 0xee, 0xe9, 0x98, 0xdf, 0x36, 0x5b, 0x7a, 0x23, 0x1f, 0x97, 0x33, + 0xf3, 0x85, 0xba, 0x1f, 0x9a, 0x9b, 0x48, 0xe6, 0xdc, 0xe3, 0x91, 0xcc, 0x73, 0x07, 0x0e, 0xb8, + 0xa7, 0xf6, 0xa2, 0xd9, 0xd6, 0xeb, 0x79, 0x51, 0x86, 0xf9, 0x42, 0x4d, 0x72, 0x0b, 0x7d, 0x0a, + 0x85, 0x8d, 0xe2, 0x79, 0xeb, 0x6b, 0xf3, 0xb4, 0xae, 0xe7, 0x13, 0x72, 0x6e, 0xbe, 0x50, 0x33, + 0x5b, 0x10, 0xba, 0x0f, 0xf9, 0xb5, 0x7e, 0x44, 0x4b, 0xca, 0xd9, 0xf9, 0x42, 0x85, 0x0d, 0x22, + 0x8b, 0xaf, 0x7f, 0x2d, 0xc5, 0x1e, 0x5c, 0x40, 0x82, 0xfd, 0x17, 0xa0, 0xfb, 0x50, 0x6c, 0x9a, + 0x75, 0xdd, 0xec, 0x36, 0x9a, 0x0d, 0xfd, 0xc6, 0xed, 0x59, 0x81, 0x01, 0x8e, 0x34, 0xc8, 0x71, + 0xd6, 0x79, 0x83, 0x3d, 0xf5, 0x7a, 0x5e, 0x90, 0x0f, 0xe7, 0x0b, 0x35, 0xbd, 0x06, 0x82, 0xeb, + 0x73, 0x4e, 0xc4, 0x08, 0xaf, 0x1f, 0x9a, 0x5c, 0xb8, 0xda, 0x7e, 0x73, 0x55, 0x12, 0xde, 0x5e, + 0x95, 0x84, 0x3f, 0xaf, 0x4a, 0xc2, 0xcf, 0xd7, 0xa5, 0xd8, 0xdb, 0xeb, 0x52, 0xec, 0x8f, 0xeb, + 0x52, 0xec, 0xe5, 0x97, 0x03, 0x87, 0x0e, 0xa7, 0xfd, 0xb2, 0x45, 0xc6, 0x15, 0x8b, 0xf8, 0x63, + 0xe2, 0x57, 0x9c, 0xbe, 0xf5, 0x70, 0x40, 0x2a, 0xb3, 0xa7, 0x95, 0x31, 0xb1, 0xa7, 0x23, 0xec, + 0xf3, 0x8f, 0x8e, 0x47, 0x4f, 0x1e, 0x46, 0x5f, 0x31, 0xf4, 0x72, 0x82, 0xfd, 0x7e, 0x92, 0x7d, + 0x75, 0x7c, 0xfe, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x04, 0xf2, 0xc5, 0x76, 0xe6, 0x08, 0x00, + 0x00, } func (m *Channel) Marshal() (dAtA []byte, err error) { diff --git a/modules/core/04-channel/types/channel_test.go b/modules/core/04-channel/types/channel_test.go index 95c4dea4d43..0817af7fc81 100644 --- a/modules/core/04-channel/types/channel_test.go +++ b/modules/core/04-channel/types/channel_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) func TestChannelValidateBasic(t *testing.T) { diff --git a/modules/core/04-channel/types/codec.go b/modules/core/04-channel/types/codec.go index 62114555778..78ec00e89bd 100644 --- a/modules/core/04-channel/types/codec.go +++ b/modules/core/04-channel/types/codec.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // RegisterInterfaces register the ibc channel submodule interfaces to protobuf diff --git a/modules/core/04-channel/types/errors.go b/modules/core/04-channel/types/errors.go index d557399a814..e8512831a77 100644 --- a/modules/core/04-channel/types/errors.go +++ b/modules/core/04-channel/types/errors.go @@ -1,43 +1,44 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // IBC channel sentinel errors var ( - ErrChannelExists = sdkerrors.Register(SubModuleName, 2, "channel already exists") - ErrChannelNotFound = sdkerrors.Register(SubModuleName, 3, "channel not found") - ErrInvalidChannel = sdkerrors.Register(SubModuleName, 4, "invalid channel") - ErrInvalidChannelState = sdkerrors.Register(SubModuleName, 5, "invalid channel state") - ErrInvalidChannelOrdering = sdkerrors.Register(SubModuleName, 6, "invalid channel ordering") - ErrInvalidCounterparty = sdkerrors.Register(SubModuleName, 7, "invalid counterparty channel") - ErrInvalidChannelCapability = sdkerrors.Register(SubModuleName, 8, "invalid channel capability") - ErrChannelCapabilityNotFound = sdkerrors.Register(SubModuleName, 9, "channel capability not found") - ErrSequenceSendNotFound = sdkerrors.Register(SubModuleName, 10, "sequence send not found") - ErrSequenceReceiveNotFound = sdkerrors.Register(SubModuleName, 11, "sequence receive not found") - ErrSequenceAckNotFound = sdkerrors.Register(SubModuleName, 12, "sequence acknowledgement not found") - ErrInvalidPacket = sdkerrors.Register(SubModuleName, 13, "invalid packet") - ErrPacketTimeout = sdkerrors.Register(SubModuleName, 14, "packet timeout") - ErrTooManyConnectionHops = sdkerrors.Register(SubModuleName, 15, "too many connection hops") - ErrInvalidAcknowledgement = sdkerrors.Register(SubModuleName, 16, "invalid acknowledgement") - ErrAcknowledgementExists = sdkerrors.Register(SubModuleName, 17, "acknowledgement for packet already exists") - ErrInvalidChannelIdentifier = sdkerrors.Register(SubModuleName, 18, "invalid channel identifier") + ErrChannelExists = errorsmod.Register(SubModuleName, 2, "channel already exists") + ErrChannelNotFound = errorsmod.Register(SubModuleName, 3, "channel not found") + ErrInvalidChannel = errorsmod.Register(SubModuleName, 4, "invalid channel") + ErrInvalidChannelState = errorsmod.Register(SubModuleName, 5, "invalid channel state") + ErrInvalidChannelOrdering = errorsmod.Register(SubModuleName, 6, "invalid channel ordering") + ErrInvalidCounterparty = errorsmod.Register(SubModuleName, 7, "invalid counterparty channel") + ErrInvalidChannelCapability = errorsmod.Register(SubModuleName, 8, "invalid channel capability") + ErrChannelCapabilityNotFound = errorsmod.Register(SubModuleName, 9, "channel capability not found") + ErrSequenceSendNotFound = errorsmod.Register(SubModuleName, 10, "sequence send not found") + ErrSequenceReceiveNotFound = errorsmod.Register(SubModuleName, 11, "sequence receive not found") + ErrSequenceAckNotFound = errorsmod.Register(SubModuleName, 12, "sequence acknowledgement not found") + ErrInvalidPacket = errorsmod.Register(SubModuleName, 13, "invalid packet") + ErrPacketTimeout = errorsmod.Register(SubModuleName, 14, "packet timeout") + ErrTooManyConnectionHops = errorsmod.Register(SubModuleName, 15, "too many connection hops") + ErrInvalidAcknowledgement = errorsmod.Register(SubModuleName, 16, "invalid acknowledgement") + ErrAcknowledgementExists = errorsmod.Register(SubModuleName, 17, "acknowledgement for packet already exists") + ErrInvalidChannelIdentifier = errorsmod.Register(SubModuleName, 18, "invalid channel identifier") // packets already relayed errors - ErrPacketReceived = sdkerrors.Register(SubModuleName, 19, "packet already received") - ErrPacketCommitmentNotFound = sdkerrors.Register(SubModuleName, 20, "packet commitment not found") // may occur for already received acknowledgements or timeouts and in rare cases for packets never sent + ErrPacketReceived = errorsmod.Register(SubModuleName, 19, "packet already received") + ErrPacketCommitmentNotFound = errorsmod.Register(SubModuleName, 20, "packet commitment not found") // may occur for already received acknowledgements or timeouts and in rare cases for packets never sent // ORDERED channel error - ErrPacketSequenceOutOfOrder = sdkerrors.Register(SubModuleName, 21, "packet sequence is out of order") + ErrPacketSequenceOutOfOrder = errorsmod.Register(SubModuleName, 21, "packet sequence is out of order") // Antehandler error - ErrRedundantTx = sdkerrors.Register(SubModuleName, 22, "packet messages are redundant") + ErrRedundantTx = errorsmod.Register(SubModuleName, 22, "packet messages are redundant") // Perform a no-op on the current Msg - ErrNoOpMsg = sdkerrors.Register(SubModuleName, 23, "message is redundant, no-op will be performed") + ErrNoOpMsg = errorsmod.Register(SubModuleName, 23, "message is redundant, no-op will be performed") - ErrInvalidChannelVersion = sdkerrors.Register(SubModuleName, 24, "invalid channel version") - ErrPacketNotSent = sdkerrors.Register(SubModuleName, 25, "packet has not been sent") - ErrInvalidUpgradeTimeout = sdkerrors.Register(SubModuleName, 26, "either timeout height or timeout timestamp must be non-zero") + ErrInvalidChannelVersion = errorsmod.Register(SubModuleName, 24, "invalid channel version") + ErrPacketNotSent = errorsmod.Register(SubModuleName, 25, "packet has not been sent") + ErrInvalidTimeout = errorsmod.Register(SubModuleName, 26, "invalid packet timeout") + ErrInvalidUpgradeTimeout = errorsmod.Register(SubModuleName, 27, "either timeout height or timeout timestamp must be non-zero") ) diff --git a/modules/core/04-channel/types/events.go b/modules/core/04-channel/types/events.go index ad9fcb922eb..3b58e1da8ae 100644 --- a/modules/core/04-channel/types/events.go +++ b/modules/core/04-channel/types/events.go @@ -3,7 +3,7 @@ package types import ( "fmt" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // IBC channel events @@ -22,9 +22,9 @@ const ( EventTypeTimeoutPacket = "timeout_packet" EventTypeTimeoutPacketOnClose = "timeout_on_close_packet" - // NOTE: DEPRECATED in favor of AttributeKeyDataHex + // Deprecated: in favor of AttributeKeyDataHex AttributeKeyData = "packet_data" - // NOTE: DEPRECATED in favor of AttributeKeyAckHex + // Deprecated: in favor of AttributeKeyAckHex AttributeKeyAck = "packet_ack" AttributeKeyDataHex = "packet_data_hex" @@ -50,5 +50,5 @@ var ( EventTypeChannelCloseConfirm = "channel_close_confirm" EventTypeChannelClosed = "channel_close" - AttributeValueCategory = fmt.Sprintf("%s_%s", host.ModuleName, SubModuleName) + AttributeValueCategory = fmt.Sprintf("%s_%s", ibcexported.ModuleName, SubModuleName) ) diff --git a/modules/core/04-channel/types/expected_keepers.go b/modules/core/04-channel/types/expected_keepers.go index 41be5a00e24..3a5460502c6 100644 --- a/modules/core/04-channel/types/expected_keepers.go +++ b/modules/core/04-channel/types/expected_keepers.go @@ -4,8 +4,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // ClientKeeper expected account IBC client keeper diff --git a/modules/core/04-channel/types/genesis.go b/modules/core/04-channel/types/genesis.go index 78d8ae2b04a..372fdcd4633 100644 --- a/modules/core/04-channel/types/genesis.go +++ b/modules/core/04-channel/types/genesis.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) // NewPacketState creates a new PacketState instance. @@ -76,7 +76,7 @@ func DefaultGenesisState() GenesisState { func (gs GenesisState) Validate() error { // keep track of the max sequence to ensure it is less than // the next sequence used in creating connection identifers. - var maxSequence uint64 = 0 + var maxSequence uint64 for i, channel := range gs.Channels { sequence, err := ParseChannelSequence(channel.ChannelId) diff --git a/modules/core/04-channel/types/genesis.pb.go b/modules/core/04-channel/types/genesis.pb.go index 6dc5f5b2f4c..4c6b61988f0 100644 --- a/modules/core/04-channel/types/genesis.pb.go +++ b/modules/core/04-channel/types/genesis.pb.go @@ -5,8 +5,8 @@ package types import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" @@ -195,39 +195,39 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/genesis.proto", fileDescriptor_cb06ec201f452595) } var fileDescriptor_cb06ec201f452595 = []byte{ - // 506 bytes of a gzipped FileDescriptorProto + // 507 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6e, 0xd3, 0x40, - 0x10, 0x87, 0xe3, 0x26, 0x4d, 0xd3, 0x6d, 0x13, 0xd1, 0x6d, 0x23, 0x99, 0xa8, 0xd8, 0xc1, 0x48, - 0x28, 0x12, 0xaa, 0x4d, 0x21, 0x17, 0x38, 0x9a, 0x03, 0xe4, 0x86, 0xb6, 0x9c, 0x90, 0x50, 0x64, - 0xaf, 0xa7, 0xee, 0x2a, 0xb1, 0x37, 0x78, 0x37, 0x81, 0x3e, 0x05, 0x3c, 0x56, 0x8f, 0x3d, 0x72, - 0xb2, 0x50, 0xf2, 0x06, 0x39, 0x72, 0x42, 0xfe, 0x9b, 0x44, 0x8d, 0x10, 0xed, 0xcd, 0x3b, 0xf3, - 0x9b, 0xef, 0x9b, 0x83, 0x07, 0x3d, 0x65, 0x2e, 0xb5, 0x28, 0x8f, 0xc0, 0xa2, 0x57, 0x4e, 0x18, - 0xc2, 0xd8, 0x9a, 0x9d, 0x5b, 0x3e, 0x84, 0x20, 0x98, 0x30, 0x27, 0x11, 0x97, 0x1c, 0x1f, 0x33, - 0x97, 0x9a, 0x49, 0xc4, 0xcc, 0x23, 0xe6, 0xec, 0xbc, 0x73, 0xe2, 0x73, 0x9f, 0xa7, 0x7d, 0x2b, - 0xf9, 0xca, 0xa2, 0x9d, 0xad, 0xb4, 0x62, 0x2a, 0x8d, 0x18, 0x8b, 0x5d, 0x74, 0xf8, 0x3e, 0xe3, - 0x5f, 0x48, 0x47, 0x02, 0xfe, 0x82, 0x1a, 0x79, 0x42, 0xa8, 0x4a, 0xb7, 0xda, 0x3b, 0x78, 0xf5, - 0xdc, 0xdc, 0x62, 0x34, 0x07, 0x1e, 0x84, 0x92, 0x5d, 0x32, 0xf0, 0xde, 0x65, 0x45, 0xfb, 0xf1, - 0x4d, 0xac, 0x57, 0xfe, 0xc4, 0xfa, 0xd1, 0x9d, 0x16, 0x29, 0x91, 0x98, 0xa0, 0x47, 0x0e, 0x1d, - 0x85, 0xfc, 0xdb, 0x18, 0x3c, 0x1f, 0x02, 0x08, 0xa5, 0x50, 0x77, 0x52, 0x4d, 0x77, 0xab, 0xe6, - 0xa3, 0x43, 0x47, 0x20, 0xd3, 0xd5, 0xec, 0x5a, 0x22, 0x20, 0x77, 0xe6, 0xf1, 0x07, 0x74, 0x40, - 0x79, 0x10, 0x30, 0x99, 0xe1, 0xaa, 0xf7, 0xc2, 0xad, 0x8f, 0x62, 0x1b, 0x35, 0x22, 0xa0, 0xc0, - 0x26, 0x52, 0xa8, 0xb5, 0x7b, 0x61, 0xca, 0x39, 0xcc, 0x50, 0x4b, 0x40, 0xe8, 0x0d, 0x05, 0x7c, - 0x9d, 0x42, 0x48, 0x41, 0xa8, 0xbb, 0x29, 0xe9, 0xd9, 0xbf, 0x48, 0x79, 0xd6, 0x7e, 0x92, 0xc0, - 0x96, 0xb1, 0xde, 0xbe, 0x76, 0x82, 0xf1, 0x5b, 0x63, 0x13, 0x64, 0x90, 0x66, 0x52, 0x28, 0xc2, - 0xa9, 0x2a, 0x02, 0x3a, 0x5b, 0x53, 0xd5, 0x1f, 0xac, 0xda, 0x04, 0x19, 0xa4, 0x99, 0x14, 0x56, - 0xaa, 0x4b, 0xd4, 0x74, 0xe8, 0x68, 0xcd, 0xb4, 0xf7, 0xff, 0xa6, 0xd3, 0xdc, 0x74, 0x92, 0x99, - 0x36, 0x38, 0x06, 0x39, 0x74, 0xe8, 0x68, 0xe5, 0xf9, 0x84, 0xda, 0x21, 0x7c, 0x97, 0xc3, 0x9c, - 0x56, 0x06, 0xd5, 0x46, 0x57, 0xe9, 0xd5, 0xec, 0xee, 0x32, 0xd6, 0x4f, 0x33, 0xcc, 0xd6, 0x98, - 0x41, 0x8e, 0x93, 0x7a, 0xfe, 0xdf, 0x15, 0x58, 0xe3, 0x87, 0x82, 0x5a, 0x9b, 0x4b, 0xe1, 0x17, - 0x68, 0x6f, 0xc2, 0x23, 0x39, 0x64, 0x9e, 0xaa, 0x74, 0x95, 0xde, 0xbe, 0x8d, 0x97, 0xb1, 0xde, - 0xca, 0xd0, 0x79, 0xc3, 0x20, 0xf5, 0xe4, 0x6b, 0xe0, 0xe1, 0x3e, 0x42, 0x85, 0x89, 0x79, 0xea, - 0x4e, 0x9a, 0x6f, 0x2f, 0x63, 0xfd, 0x28, 0xcb, 0xaf, 0x7a, 0x06, 0xd9, 0xcf, 0x1f, 0x03, 0x0f, - 0x77, 0x50, 0xa3, 0x5c, 0xbf, 0x9a, 0xac, 0x4f, 0xca, 0xb7, 0x7d, 0x71, 0x33, 0xd7, 0x94, 0xdb, - 0xb9, 0xa6, 0xfc, 0x9e, 0x6b, 0xca, 0xcf, 0x85, 0x56, 0xb9, 0x5d, 0x68, 0x95, 0x5f, 0x0b, 0xad, - 0xf2, 0xf9, 0x8d, 0xcf, 0xe4, 0xd5, 0xd4, 0x35, 0x29, 0x0f, 0x2c, 0xca, 0x45, 0xc0, 0x85, 0xc5, - 0x5c, 0x7a, 0xe6, 0x73, 0x6b, 0xd6, 0xb7, 0x02, 0xee, 0x4d, 0xc7, 0x20, 0xb2, 0xa3, 0x7e, 0xd9, - 0x3f, 0x2b, 0xee, 0x5a, 0x5e, 0x4f, 0x40, 0xb8, 0xf5, 0xf4, 0xa6, 0x5f, 0xff, 0x0d, 0x00, 0x00, - 0xff, 0xff, 0x37, 0x95, 0x0a, 0xe0, 0x46, 0x04, 0x00, 0x00, + 0x10, 0x87, 0xe3, 0x36, 0x4d, 0xd3, 0x6d, 0x13, 0xd1, 0x6d, 0x23, 0x99, 0xa8, 0xd8, 0xc6, 0x48, + 0x28, 0x12, 0xaa, 0x4d, 0xa1, 0x12, 0x82, 0xa3, 0x39, 0x40, 0x6e, 0x68, 0xcb, 0x09, 0x09, 0x45, + 0xf6, 0x7a, 0xea, 0xae, 0x12, 0x7b, 0x83, 0x77, 0x13, 0xe8, 0x53, 0xc0, 0x63, 0xf5, 0xd8, 0x23, + 0x27, 0x0b, 0x25, 0x6f, 0x90, 0x23, 0x27, 0xe4, 0xbf, 0x49, 0xd4, 0x08, 0x51, 0x6e, 0xde, 0x99, + 0xdf, 0x7c, 0xdf, 0x1c, 0x3c, 0xe8, 0x31, 0xf3, 0xa8, 0x4d, 0x79, 0x0c, 0x36, 0xbd, 0x72, 0xa3, + 0x08, 0x46, 0xf6, 0xf4, 0xcc, 0x0e, 0x20, 0x02, 0xc1, 0x84, 0x35, 0x8e, 0xb9, 0xe4, 0xf8, 0x88, + 0x79, 0xd4, 0x4a, 0x23, 0x56, 0x11, 0xb1, 0xa6, 0x67, 0xdd, 0xe3, 0x80, 0x07, 0x3c, 0xeb, 0xdb, + 0xe9, 0x57, 0x1e, 0xed, 0x6e, 0xa4, 0x95, 0x53, 0x59, 0xc4, 0x9c, 0xef, 0xa0, 0x83, 0x77, 0x39, + 0xff, 0x42, 0xba, 0x12, 0xf0, 0x67, 0xd4, 0x2c, 0x12, 0x42, 0x55, 0x8c, 0xed, 0xde, 0xfe, 0x8b, + 0xa7, 0xd6, 0x06, 0xa3, 0xd5, 0xf7, 0x21, 0x92, 0xec, 0x92, 0x81, 0xff, 0x36, 0x2f, 0x3a, 0x0f, + 0x6f, 0x12, 0xbd, 0xf6, 0x3b, 0xd1, 0x0f, 0xef, 0xb4, 0x48, 0x85, 0xc4, 0x04, 0x3d, 0x70, 0xe9, + 0x30, 0xe2, 0x5f, 0x47, 0xe0, 0x07, 0x10, 0x42, 0x24, 0x85, 0xba, 0x95, 0x69, 0x8c, 0x8d, 0x9a, + 0x0f, 0x2e, 0x1d, 0x82, 0xcc, 0x56, 0x73, 0xea, 0xa9, 0x80, 0xdc, 0x99, 0xc7, 0xef, 0xd1, 0x3e, + 0xe5, 0x61, 0xc8, 0x64, 0x8e, 0xdb, 0xbe, 0x17, 0x6e, 0x75, 0x14, 0x3b, 0xa8, 0x19, 0x03, 0x05, + 0x36, 0x96, 0x42, 0xad, 0xdf, 0x0b, 0x53, 0xcd, 0x61, 0x86, 0xda, 0x02, 0x22, 0x7f, 0x20, 0xe0, + 0xcb, 0x04, 0x22, 0x0a, 0x42, 0xdd, 0xc9, 0x48, 0x4f, 0xfe, 0x46, 0x2a, 0xb2, 0xce, 0xa3, 0x14, + 0xb6, 0x48, 0xf4, 0xce, 0xb5, 0x1b, 0x8e, 0xde, 0x98, 0xeb, 0x20, 0x93, 0xb4, 0xd2, 0x42, 0x19, + 0xce, 0x54, 0x31, 0xd0, 0xe9, 0x8a, 0xaa, 0xf1, 0xdf, 0xaa, 0x75, 0x90, 0x49, 0x5a, 0x69, 0x61, + 0xa9, 0xba, 0x44, 0x2d, 0x97, 0x0e, 0x57, 0x4c, 0xbb, 0xff, 0x6e, 0x3a, 0x29, 0x4c, 0xc7, 0xb9, + 0x69, 0x8d, 0x63, 0x92, 0x03, 0x97, 0x0e, 0x97, 0x9e, 0x8f, 0xa8, 0x13, 0xc1, 0x37, 0x39, 0x28, + 0x68, 0x55, 0x50, 0x6d, 0x1a, 0x4a, 0xaf, 0xee, 0x18, 0x8b, 0x44, 0x3f, 0xc9, 0x31, 0x1b, 0x63, + 0x26, 0x39, 0x4a, 0xeb, 0xc5, 0x7f, 0x57, 0x62, 0xcd, 0xef, 0x0a, 0x6a, 0xaf, 0x2f, 0x85, 0x9f, + 0xa1, 0xdd, 0x31, 0x8f, 0xe5, 0x80, 0xf9, 0xaa, 0x62, 0x28, 0xbd, 0x3d, 0x07, 0x2f, 0x12, 0xbd, + 0x9d, 0xa3, 0x8b, 0x86, 0x49, 0x1a, 0xe9, 0x57, 0xdf, 0xc7, 0xe7, 0x08, 0x95, 0x26, 0xe6, 0xab, + 0x5b, 0x59, 0xbe, 0xb3, 0x48, 0xf4, 0xc3, 0x3c, 0xbf, 0xec, 0x99, 0x64, 0xaf, 0x78, 0xf4, 0x7d, + 0xdc, 0x45, 0xcd, 0x6a, 0xfd, 0xed, 0x74, 0x7d, 0x52, 0xbd, 0x9d, 0x8b, 0x9b, 0x99, 0xa6, 0xdc, + 0xce, 0x34, 0xe5, 0xd7, 0x4c, 0x53, 0x7e, 0xcc, 0xb5, 0xda, 0xed, 0x5c, 0xab, 0xfd, 0x9c, 0x6b, + 0xb5, 0x4f, 0xaf, 0x03, 0x26, 0xaf, 0x26, 0x9e, 0x45, 0x79, 0x68, 0x53, 0x2e, 0x42, 0x2e, 0x6c, + 0xe6, 0xd1, 0xd3, 0x80, 0xdb, 0xd3, 0x57, 0x76, 0xc8, 0xfd, 0xc9, 0x08, 0x44, 0x7e, 0xd4, 0xcf, + 0xcf, 0x4f, 0xcb, 0xbb, 0x96, 0xd7, 0x63, 0x10, 0x5e, 0x23, 0xbb, 0xe9, 0x97, 0x7f, 0x02, 0x00, + 0x00, 0xff, 0xff, 0xcc, 0x89, 0x91, 0x33, 0x46, 0x04, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/modules/core/04-channel/types/genesis_test.go b/modules/core/04-channel/types/genesis_test.go index 0e1a64b02b6..10fd5248a59 100644 --- a/modules/core/04-channel/types/genesis_test.go +++ b/modules/core/04-channel/types/genesis_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) const ( diff --git a/modules/core/04-channel/types/keys.go b/modules/core/04-channel/types/keys.go index 347fd91a677..d961abe3dc0 100644 --- a/modules/core/04-channel/types/keys.go +++ b/modules/core/04-channel/types/keys.go @@ -4,9 +4,9 @@ import ( "fmt" "regexp" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) const ( @@ -50,13 +50,18 @@ func IsValidChannelID(channelID string) bool { // ParseChannelSequence parses the channel sequence from the channel identifier. func ParseChannelSequence(channelID string) (uint64, error) { if !IsChannelIDFormat(channelID) { - return 0, sdkerrors.Wrap(host.ErrInvalidID, "channel identifier is not in the format: `channel-{N}`") + return 0, errorsmod.Wrap(host.ErrInvalidID, "channel identifier is not in the format: `channel-{N}`") } sequence, err := host.ParseIdentifier(channelID, ChannelPrefix) if err != nil { - return 0, sdkerrors.Wrap(err, "invalid channel identifier") + return 0, errorsmod.Wrap(err, "invalid channel identifier") } return sequence, nil } + +// FilteredPortPrefix returns the prefix key for the given port prefix. +func FilteredPortPrefix(portPrefix string) []byte { + return []byte(fmt.Sprintf("%s/%s/%s", host.KeyChannelEndPrefix, host.KeyPortPrefix, portPrefix)) +} diff --git a/modules/core/04-channel/types/keys_test.go b/modules/core/04-channel/types/keys_test.go index c6c2e3fcec2..72bd91b5613 100644 --- a/modules/core/04-channel/types/keys_test.go +++ b/modules/core/04-channel/types/keys_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // tests ParseChannelSequence and IsValidChannelID diff --git a/modules/core/04-channel/types/msgs.go b/modules/core/04-channel/types/msgs.go index 205f8be5b4a..d96e8fdb85f 100644 --- a/modules/core/04-channel/types/msgs.go +++ b/modules/core/04-channel/types/msgs.go @@ -3,19 +3,21 @@ package types import ( "encoding/base64" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" ) var _ sdk.Msg = &MsgChannelOpenInit{} // NewMsgChannelOpenInit creates a new MsgChannelOpenInit. It sets the counterparty channel // identifier to be empty. -// nolint:interfacer +// +//nolint:interfacer func NewMsgChannelOpenInit( portID, version string, channelOrder Order, connectionHops []string, counterpartyPortID string, signer string, @@ -32,20 +34,20 @@ func NewMsgChannelOpenInit( // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if msg.Channel.State != INIT { - return sdkerrors.Wrapf(ErrInvalidChannelState, + return errorsmod.Wrapf(ErrInvalidChannelState, "channel state must be INIT in MsgChannelOpenInit. expected: %s, got: %s", INIT, msg.Channel.State, ) } if msg.Channel.Counterparty.ChannelId != "" { - return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty channel identifier must be empty") + return errorsmod.Wrap(ErrInvalidCounterparty, "counterparty channel identifier must be empty") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return msg.Channel.ValidateBasic() } @@ -64,9 +66,10 @@ var _ sdk.Msg = &MsgChannelOpenTry{} // NewMsgChannelOpenTry creates a new MsgChannelOpenTry instance // The version string is deprecated and will be ignored by core IBC. // It is left as an argument for go API backwards compatibility. -// nolint:interfacer +// +//nolint:interfacer func NewMsgChannelOpenTry( - portID, previousChannelID, version string, channelOrder Order, connectionHops []string, + portID, version string, channelOrder Order, connectionHops []string, counterpartyPortID, counterpartyChannelID, counterpartyVersion string, proofInit []byte, proofHeight clienttypes.Height, signer string, ) *MsgChannelOpenTry { @@ -74,7 +77,6 @@ func NewMsgChannelOpenTry( channel := NewChannel(TRYOPEN, channelOrder, counterparty, connectionHops, version) return &MsgChannelOpenTry{ PortId: portID, - PreviousChannelId: previousChannelID, Channel: channel, CounterpartyVersion: counterpartyVersion, ProofInit: proofInit, @@ -86,33 +88,28 @@ func NewMsgChannelOpenTry( // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenTry) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if msg.PreviousChannelId != "" { - if !IsValidChannelID(msg.PreviousChannelId) { - return sdkerrors.Wrap(ErrInvalidChannelIdentifier, "invalid previous channel ID") - } + return errorsmod.Wrap(ErrInvalidChannelIdentifier, "previous channel identifier must be empty, this field has been deprecated as crossing hellos are no longer supported") } if len(msg.ProofInit) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") } if msg.Channel.State != TRYOPEN { - return sdkerrors.Wrapf(ErrInvalidChannelState, + return errorsmod.Wrapf(ErrInvalidChannelState, "channel state must be TRYOPEN in MsgChannelOpenTry. expected: %s, got: %s", TRYOPEN, msg.Channel.State, ) } // counterparty validate basic allows empty counterparty channel identifiers if err := host.ChannelIdentifierValidator(msg.Channel.Counterparty.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty channel ID") + return errorsmod.Wrap(err, "invalid counterparty channel ID") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return msg.Channel.ValidateBasic() } @@ -129,7 +126,8 @@ func (msg MsgChannelOpenTry) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgChannelOpenAck{} // NewMsgChannelOpenAck creates a new MsgChannelOpenAck instance -// nolint:interfacer +// +//nolint:interfacer func NewMsgChannelOpenAck( portID, channelID, counterpartyChannelID string, cpv string, proofTry []byte, proofHeight clienttypes.Height, signer string, @@ -148,23 +146,20 @@ func NewMsgChannelOpenAck( // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenAck) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { return ErrInvalidChannelIdentifier } if err := host.ChannelIdentifierValidator(msg.CounterpartyChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid counterparty channel ID") + return errorsmod.Wrap(err, "invalid counterparty channel ID") } if len(msg.ProofTry) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof try") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof try") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil } @@ -181,7 +176,8 @@ func (msg MsgChannelOpenAck) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgChannelOpenConfirm{} // NewMsgChannelOpenConfirm creates a new MsgChannelOpenConfirm instance -// nolint:interfacer +// +//nolint:interfacer func NewMsgChannelOpenConfirm( portID, channelID string, proofAck []byte, proofHeight clienttypes.Height, signer string, @@ -198,20 +194,17 @@ func NewMsgChannelOpenConfirm( // ValidateBasic implements sdk.Msg func (msg MsgChannelOpenConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { return ErrInvalidChannelIdentifier } if len(msg.ProofAck) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil } @@ -228,7 +221,8 @@ func (msg MsgChannelOpenConfirm) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgChannelCloseInit{} // NewMsgChannelCloseInit creates a new MsgChannelCloseInit instance -// nolint:interfacer +// +//nolint:interfacer func NewMsgChannelCloseInit( portID string, channelID string, signer string, ) *MsgChannelCloseInit { @@ -242,14 +236,14 @@ func NewMsgChannelCloseInit( // ValidateBasic implements sdk.Msg func (msg MsgChannelCloseInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { return ErrInvalidChannelIdentifier } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil } @@ -266,7 +260,8 @@ func (msg MsgChannelCloseInit) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgChannelCloseConfirm{} // NewMsgChannelCloseConfirm creates a new MsgChannelCloseConfirm instance -// nolint:interfacer +// +//nolint:interfacer func NewMsgChannelCloseConfirm( portID, channelID string, proofInit []byte, proofHeight clienttypes.Height, signer string, @@ -283,20 +278,17 @@ func NewMsgChannelCloseConfirm( // ValidateBasic implements sdk.Msg func (msg MsgChannelCloseConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { return ErrInvalidChannelIdentifier } if len(msg.ProofInit) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil } @@ -313,7 +305,8 @@ func (msg MsgChannelCloseConfirm) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgRecvPacket{} // NewMsgRecvPacket constructs new MsgRecvPacket -// nolint:interfacer +// +//nolint:interfacer func NewMsgRecvPacket( packet Packet, proofCommitment []byte, proofHeight clienttypes.Height, signer string, @@ -329,14 +322,11 @@ func NewMsgRecvPacket( // ValidateBasic implements sdk.Msg func (msg MsgRecvPacket) ValidateBasic() error { if len(msg.ProofCommitment) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return msg.Packet.ValidateBasic() } @@ -360,7 +350,8 @@ func (msg MsgRecvPacket) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgTimeout{} // NewMsgTimeout constructs new MsgTimeout -// nolint:interfacer +// +//nolint:interfacer func NewMsgTimeout( packet Packet, nextSequenceRecv uint64, proofUnreceived []byte, proofHeight clienttypes.Height, signer string, @@ -377,17 +368,14 @@ func NewMsgTimeout( // ValidateBasic implements sdk.Msg func (msg MsgTimeout) ValidateBasic() error { if len(msg.ProofUnreceived) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty unreceived proof") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty unreceived proof") } if msg.NextSequenceRecv == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "next sequence receive cannot be 0") + return errorsmod.Wrap(ibcerrors.ErrInvalidSequence, "next sequence receive cannot be 0") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return msg.Packet.ValidateBasic() } @@ -402,7 +390,8 @@ func (msg MsgTimeout) GetSigners() []sdk.AccAddress { } // NewMsgTimeoutOnClose constructs new MsgTimeoutOnClose -// nolint:interfacer +// +//nolint:interfacer func NewMsgTimeoutOnClose( packet Packet, nextSequenceRecv uint64, proofUnreceived, proofClose []byte, @@ -421,20 +410,17 @@ func NewMsgTimeoutOnClose( // ValidateBasic implements sdk.Msg func (msg MsgTimeoutOnClose) ValidateBasic() error { if msg.NextSequenceRecv == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "next sequence receive cannot be 0") + return errorsmod.Wrap(ibcerrors.ErrInvalidSequence, "next sequence receive cannot be 0") } if len(msg.ProofUnreceived) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if len(msg.ProofClose) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof of closed counterparty channel end") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof of closed counterparty channel end") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return msg.Packet.ValidateBasic() } @@ -451,7 +437,8 @@ func (msg MsgTimeoutOnClose) GetSigners() []sdk.AccAddress { var _ sdk.Msg = &MsgAcknowledgement{} // NewMsgAcknowledgement constructs a new MsgAcknowledgement -// nolint:interfacer +// +//nolint:interfacer func NewMsgAcknowledgement( packet Packet, ack, proofAcked []byte, @@ -470,17 +457,14 @@ func NewMsgAcknowledgement( // ValidateBasic implements sdk.Msg func (msg MsgAcknowledgement) ValidateBasic() error { if len(msg.ProofAcked) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") - } - if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if len(msg.Acknowledgement) == 0 { - return sdkerrors.Wrap(ErrInvalidAcknowledgement, "ack bytes cannot be empty") + return errorsmod.Wrap(ErrInvalidAcknowledgement, "ack bytes cannot be empty") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return msg.Packet.ValidateBasic() } @@ -501,16 +485,16 @@ var _ sdk.Msg = &MsgChannelUpgradeInit{} func NewMsgChannelUpgradeInit( portID, channelID string, proposedUpgradeChannel Channel, - TimeoutHeight clienttypes.Height, - TimeoutTimestamp uint64, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, signer string, ) *MsgChannelUpgradeInit { return &MsgChannelUpgradeInit{ PortId: portID, ChannelId: channelID, ProposedUpgradeChannel: proposedUpgradeChannel, - TimeoutHeight: TimeoutHeight, - TimeoutTimestamp: TimeoutTimestamp, + TimeoutHeight: timeoutHeight, + TimeoutTimestamp: timeoutTimestamp, Signer: signer, } } @@ -518,20 +502,20 @@ func NewMsgChannelUpgradeInit( // ValidateBasic implements sdk.Msg func (msg MsgChannelUpgradeInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { return ErrInvalidChannelIdentifier } if msg.ProposedUpgradeChannel.State != INITUPGRADE { - return sdkerrors.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", INITUPGRADE, msg.ProposedUpgradeChannel.State) + return errorsmod.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", INITUPGRADE, msg.ProposedUpgradeChannel.State) } if msg.TimeoutHeight.IsZero() && msg.TimeoutTimestamp == 0 { - return sdkerrors.Wrap(ErrInvalidUpgradeTimeout, "timeout height and timeout timestamp cannot both be 0") + return errorsmod.Wrap(ErrInvalidUpgradeTimeout, "timeout height and timeout timestamp cannot both be 0") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil @@ -583,41 +567,41 @@ func NewMsgChannelUpgradeTry( // ValidateBasic implements sdk.Msg func (msg MsgChannelUpgradeTry) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { return ErrInvalidChannelIdentifier } if msg.CounterpartyChannel.State != INITUPGRADE { - return sdkerrors.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", INITUPGRADE, msg.CounterpartyChannel.State) + return errorsmod.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", INITUPGRADE, msg.CounterpartyChannel.State) } if msg.CounterpartySequence == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "counterparty sequence cannot be 0") + return errorsmod.Wrap(ibcerrors.ErrInvalidSequence, "counterparty sequence cannot be 0") } if msg.ProposedUpgradeChannel.State != TRYUPGRADE { - return sdkerrors.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", TRYUPGRADE, msg.CounterpartyChannel.State) + return errorsmod.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", TRYUPGRADE, msg.CounterpartyChannel.State) } if msg.TimeoutHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "timeout height must be non-zero") + return errorsmod.Wrap(ibcerrors.ErrInvalidHeight, "timeout height must be non-zero") } if msg.TimeoutTimestamp == 0 && msg.TimeoutHeight.IsZero() { - return sdkerrors.Wrap(ErrInvalidUpgradeTimeout, "invalid upgrade timeout timestamp or timeout height") + return errorsmod.Wrap(ErrInvalidUpgradeTimeout, "invalid upgrade timeout timestamp or timeout height") } if len(msg.ProofChannel) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") } if len(msg.ProofUpgradeTimeout) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade timeout proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade timeout proof") } if len(msg.ProofUpgradeSequence) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade sequence proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade sequence proof") } if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(ibcerrors.ErrInvalidHeight, "proof height must be non-zero") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil @@ -652,25 +636,25 @@ func NewMsgChannelUpgradeAck(portID, channelID string, counterpartyChannel Chann // ValidateBasic implements sdk.Msg func (msg MsgChannelUpgradeAck) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { return ErrInvalidChannelIdentifier } if len(msg.ProofChannel) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") } if len(msg.ProofUpgradeSequence) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade sequence proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade sequence proof") } if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(ibcerrors.ErrInvalidHeight, "proof height must be non-zero") } if msg.CounterpartyChannel.State != TRYUPGRADE { - return sdkerrors.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", "TRYUPGRADE", msg.CounterpartyChannel.State) + return errorsmod.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", "TRYUPGRADE", msg.CounterpartyChannel.State) } if _, err := sdk.AccAddressFromBech32(msg.Signer); err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil @@ -715,7 +699,7 @@ func NewMsgChannelUpgradeConfirm( // ValidateBasic implements sdk.Msg func (msg MsgChannelUpgradeConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { @@ -723,28 +707,28 @@ func (msg MsgChannelUpgradeConfirm) ValidateBasic() error { } if len(msg.ProofChannel) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") } if len(msg.ProofUpgradeError) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade error proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade error proof") } if len(msg.ProofUpgradeSequence) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade sequence proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade sequence proof") } if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(ibcerrors.ErrInvalidHeight, "proof height must be non-zero") } if msg.CounterpartyChannel.State != OPEN { - return sdkerrors.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", OPEN, msg.CounterpartyChannel.State) + return errorsmod.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", OPEN, msg.CounterpartyChannel.State) } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil @@ -786,7 +770,7 @@ func NewMsgChannelUpgradeTimeout( // ValidateBasic implements sdk.Msg func (msg MsgChannelUpgradeTimeout) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { @@ -794,20 +778,20 @@ func (msg MsgChannelUpgradeTimeout) ValidateBasic() error { } if len(msg.ProofChannel) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(ibcerrors.ErrInvalidHeight, "proof height must be non-zero") } if msg.CounterpartyChannel.State != OPEN { - return sdkerrors.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", OPEN, msg.CounterpartyChannel.State) + return errorsmod.Wrapf(ErrInvalidChannelState, "expected: %s, got: %s", OPEN, msg.CounterpartyChannel.State) } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil @@ -847,7 +831,7 @@ func NewMsgChannelUpgradeCancel( // ValidateBasic implements sdk.Msg func (msg MsgChannelUpgradeCancel) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid port ID") + return errorsmod.Wrap(err, "invalid port ID") } if !IsValidChannelID(msg.ChannelId) { @@ -855,20 +839,20 @@ func (msg MsgChannelUpgradeCancel) ValidateBasic() error { } if len(msg.ProofErrorReceipt) == 0 { - return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") } if msg.ProofHeight.IsZero() { - return sdkerrors.Wrap(sdkerrors.ErrInvalidHeight, "proof height must be non-zero") + return errorsmod.Wrap(ibcerrors.ErrInvalidHeight, "proof height must be non-zero") } if msg.ErrorReceipt.Sequence == 0 { - return sdkerrors.Wrap(sdkerrors.ErrInvalidSequence, "upgrade sequence cannot be 0") + return errorsmod.Wrap(ibcerrors.ErrInvalidSequence, "upgrade sequence cannot be 0") } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } return nil diff --git a/modules/core/04-channel/types/msgs_test.go b/modules/core/04-channel/types/msgs_test.go index 87a36a0fa7a..54893665aa2 100644 --- a/modules/core/04-channel/types/msgs_test.go +++ b/modules/core/04-channel/types/msgs_test.go @@ -10,13 +10,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" + log "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - "github.com/cosmos/ibc-go/v4/testing/simapp" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) const ( @@ -75,11 +76,13 @@ type TypesTestSuite struct { func (suite *TypesTestSuite) SetupTest() { app := simapp.Setup(false) db := dbm.NewMemDB() - store := rootmulti.NewStore(db) + dblog := log.TestingLogger() + store := rootmulti.NewStore(db, dblog) storeKey := storetypes.NewKVStoreKey("iavlStoreKey") store.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, nil) - store.LoadVersion(0) + err := store.LoadVersion(0) + suite.Require().NoError(err) iavlStore := store.GetCommitStore(storeKey).(*iavl.Store) iavlStore.Set([]byte("KEY"), []byte("VALUE")) @@ -149,25 +152,22 @@ func (suite *TypesTestSuite) TestMsgChannelOpenTryValidateBasic() { msg *types.MsgChannelOpenTry expPass bool }{ - {"", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"too short port id", types.NewMsgChannelOpenTry(invalidShortPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long port id", types.NewMsgChannelOpenTry(invalidLongPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"port id contains non-alpha", types.NewMsgChannelOpenTry(invalidPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too short channel id", types.NewMsgChannelOpenTry(portid, invalidShortChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long channel id", types.NewMsgChannelOpenTry(portid, invalidLongChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"channel id contains non-alpha", types.NewMsgChannelOpenTry(portid, invalidChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, "", suite.proof, height, addr), true}, - {"proof height is zero", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, clienttypes.ZeroHeight(), addr), false}, - {"invalid channel order", types.NewMsgChannelOpenTry(portid, chanid, version, types.Order(4), connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"connection hops more than 1 ", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too short connection id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long connection id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"connection id contains non-alpha", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"", types.NewMsgChannelOpenTry(portid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"invalid counterparty port id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, version, suite.proof, height, addr), false}, - {"invalid counterparty channel id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, version, suite.proof, height, addr), false}, - {"empty proof", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, cpportid, cpchanid, version, emptyProof, height, addr), false}, - {"channel not in TRYOPEN state", &types.MsgChannelOpenTry{portid, chanid, initChannel, version, suite.proof, height, addr}, false}, + {"", types.NewMsgChannelOpenTry(portid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, + {"too short port id", types.NewMsgChannelOpenTry(invalidShortPort, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long port id", types.NewMsgChannelOpenTry(invalidLongPort, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"port id contains non-alpha", types.NewMsgChannelOpenTry(invalidPort, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"", types.NewMsgChannelOpenTry(portid, version, types.ORDERED, connHops, cpportid, cpchanid, "", suite.proof, height, addr), true}, + {"invalid channel order", types.NewMsgChannelOpenTry(portid, version, types.Order(4), connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"connection hops more than 1 ", types.NewMsgChannelOpenTry(portid, version, types.UNORDERED, invalidConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too short connection id", types.NewMsgChannelOpenTry(portid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long connection id", types.NewMsgChannelOpenTry(portid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"connection id contains non-alpha", types.NewMsgChannelOpenTry(portid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"", types.NewMsgChannelOpenTry(portid, "", types.UNORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, + {"invalid counterparty port id", types.NewMsgChannelOpenTry(portid, version, types.UNORDERED, connHops, invalidPort, cpchanid, version, suite.proof, height, addr), false}, + {"invalid counterparty channel id", types.NewMsgChannelOpenTry(portid, version, types.UNORDERED, connHops, cpportid, invalidChannel, version, suite.proof, height, addr), false}, + {"empty proof", types.NewMsgChannelOpenTry(portid, version, types.UNORDERED, connHops, cpportid, cpchanid, version, emptyProof, height, addr), false}, + {"channel not in TRYOPEN state", &types.MsgChannelOpenTry{portid, "", initChannel, version, suite.proof, height, addr}, false}, + {"previous channel id is not empty", &types.MsgChannelOpenTry{portid, chanid, initChannel, version, suite.proof, height, addr}, false}, } for _, tc := range testCases { @@ -200,7 +200,6 @@ func (suite *TypesTestSuite) TestMsgChannelOpenAckValidateBasic() { {"channel id contains non-alpha", types.NewMsgChannelOpenAck(portid, invalidChannel, chanid, version, suite.proof, height, addr), false}, {"", types.NewMsgChannelOpenAck(portid, chanid, chanid, "", suite.proof, height, addr), true}, {"empty proof", types.NewMsgChannelOpenAck(portid, chanid, chanid, version, emptyProof, height, addr), false}, - {"proof height is zero", types.NewMsgChannelOpenAck(portid, chanid, chanid, version, suite.proof, clienttypes.ZeroHeight(), addr), false}, {"invalid counterparty channel id", types.NewMsgChannelOpenAck(portid, chanid, invalidShortChannel, version, suite.proof, height, addr), false}, } @@ -233,7 +232,6 @@ func (suite *TypesTestSuite) TestMsgChannelOpenConfirmValidateBasic() { {"too long channel id", types.NewMsgChannelOpenConfirm(portid, invalidLongChannel, suite.proof, height, addr), false}, {"channel id contains non-alpha", types.NewMsgChannelOpenConfirm(portid, invalidChannel, suite.proof, height, addr), false}, {"empty proof", types.NewMsgChannelOpenConfirm(portid, chanid, emptyProof, height, addr), false}, - {"proof height is zero", types.NewMsgChannelOpenConfirm(portid, chanid, suite.proof, clienttypes.ZeroHeight(), addr), false}, } for _, tc := range testCases { @@ -295,7 +293,6 @@ func (suite *TypesTestSuite) TestMsgChannelCloseConfirmValidateBasic() { {"too long channel id", types.NewMsgChannelCloseConfirm(portid, invalidLongChannel, suite.proof, height, addr), false}, {"channel id contains non-alpha", types.NewMsgChannelCloseConfirm(portid, invalidChannel, suite.proof, height, addr), false}, {"empty proof", types.NewMsgChannelCloseConfirm(portid, chanid, emptyProof, height, addr), false}, - {"proof height is zero", types.NewMsgChannelCloseConfirm(portid, chanid, suite.proof, clienttypes.ZeroHeight(), addr), false}, } for _, tc := range testCases { @@ -320,7 +317,6 @@ func (suite *TypesTestSuite) TestMsgRecvPacketValidateBasic() { expPass bool }{ {"success", types.NewMsgRecvPacket(packet, suite.proof, height, addr), true}, - {"proof height is zero", types.NewMsgRecvPacket(packet, suite.proof, clienttypes.ZeroHeight(), addr), false}, {"proof contain empty proof", types.NewMsgRecvPacket(packet, emptyProof, height, addr), false}, {"missing signer address", types.NewMsgRecvPacket(packet, suite.proof, height, emptyAddr), false}, {"invalid packet", types.NewMsgRecvPacket(invalidPacket, suite.proof, height, addr), false}, @@ -356,7 +352,6 @@ func (suite *TypesTestSuite) TestMsgTimeoutValidateBasic() { expPass bool }{ {"success", types.NewMsgTimeout(packet, 1, suite.proof, height, addr), true}, - {"proof height must be > 0", types.NewMsgTimeout(packet, 1, suite.proof, clienttypes.ZeroHeight(), addr), false}, {"seq 0", types.NewMsgTimeout(packet, 0, suite.proof, height, addr), false}, {"missing signer address", types.NewMsgTimeout(packet, 1, suite.proof, height, emptyAddr), false}, {"cannot submit an empty proof", types.NewMsgTimeout(packet, 1, emptyProof, height, addr), false}, @@ -388,7 +383,6 @@ func (suite *TypesTestSuite) TestMsgTimeoutOnCloseValidateBasic() { {"seq 0", types.NewMsgTimeoutOnClose(packet, 0, suite.proof, suite.proof, height, addr), false}, {"empty proof", types.NewMsgTimeoutOnClose(packet, 1, emptyProof, suite.proof, height, addr), false}, {"empty proof close", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, emptyProof, height, addr), false}, - {"proof height is zero", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, clienttypes.ZeroHeight(), addr), false}, {"signer address is empty", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, height, emptyAddr), false}, {"invalid packet", types.NewMsgTimeoutOnClose(invalidPacket, 1, suite.proof, suite.proof, height, addr), false}, } @@ -415,7 +409,6 @@ func (suite *TypesTestSuite) TestMsgAcknowledgementValidateBasic() { expPass bool }{ {"success", types.NewMsgAcknowledgement(packet, packet.GetData(), suite.proof, height, addr), true}, - {"proof height must be > 0", types.NewMsgAcknowledgement(packet, packet.GetData(), suite.proof, clienttypes.ZeroHeight(), addr), false}, {"empty ack", types.NewMsgAcknowledgement(packet, nil, suite.proof, height, addr), false}, {"missing signer address", types.NewMsgAcknowledgement(packet, packet.GetData(), suite.proof, height, emptyAddr), false}, {"cannot submit an empty proof", types.NewMsgAcknowledgement(packet, packet.GetData(), emptyProof, height, addr), false}, diff --git a/modules/core/04-channel/types/packet.go b/modules/core/04-channel/types/packet.go index caba2fc2591..c007f3af9b0 100644 --- a/modules/core/04-channel/types/packet.go +++ b/modules/core/04-channel/types/packet.go @@ -3,13 +3,13 @@ package types import ( "crypto/sha256" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // CommitPacket returns the packet commitment bytes. The commitment consists of: @@ -89,25 +89,25 @@ func (p Packet) GetTimeoutTimestamp() uint64 { return p.TimeoutTimestamp } // ValidateBasic implements PacketI interface func (p Packet) ValidateBasic() error { if err := host.PortIdentifierValidator(p.SourcePort); err != nil { - return sdkerrors.Wrap(err, "invalid source port ID") + return errorsmod.Wrap(err, "invalid source port ID") } if err := host.PortIdentifierValidator(p.DestinationPort); err != nil { - return sdkerrors.Wrap(err, "invalid destination port ID") + return errorsmod.Wrap(err, "invalid destination port ID") } if err := host.ChannelIdentifierValidator(p.SourceChannel); err != nil { - return sdkerrors.Wrap(err, "invalid source channel ID") + return errorsmod.Wrap(err, "invalid source channel ID") } if err := host.ChannelIdentifierValidator(p.DestinationChannel); err != nil { - return sdkerrors.Wrap(err, "invalid destination channel ID") + return errorsmod.Wrap(err, "invalid destination channel ID") } if p.Sequence == 0 { - return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") + return errorsmod.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") } if p.TimeoutHeight.IsZero() && p.TimeoutTimestamp == 0 { - return sdkerrors.Wrap(ErrInvalidPacket, "packet timeout height and packet timeout timestamp cannot both be 0") + return errorsmod.Wrap(ErrInvalidPacket, "packet timeout height and packet timeout timestamp cannot both be 0") } if len(p.Data) == 0 { - return sdkerrors.Wrap(ErrInvalidPacket, "packet data bytes cannot be empty") + return errorsmod.Wrap(ErrInvalidPacket, "packet data bytes cannot be empty") } return nil } @@ -115,21 +115,21 @@ func (p Packet) ValidateBasic() error { // Validates a PacketId func (p PacketId) Validate() error { if err := host.PortIdentifierValidator(p.PortId); err != nil { - return sdkerrors.Wrap(err, "invalid source port ID") + return errorsmod.Wrap(err, "invalid source port ID") } if err := host.ChannelIdentifierValidator(p.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid source channel ID") + return errorsmod.Wrap(err, "invalid source channel ID") } if p.Sequence == 0 { - return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") + return errorsmod.Wrap(ErrInvalidPacket, "packet sequence cannot be 0") } return nil } -// NewPacketId returns a new instance of PacketId -func NewPacketId(portId, channelId string, seq uint64) PacketId { - return PacketId{PortId: portId, ChannelId: channelId, Sequence: seq} +// NewPacketID returns a new instance of PacketId +func NewPacketID(portID, channelID string, seq uint64) PacketId { + return PacketId{PortId: portID, ChannelId: channelID, Sequence: seq} } diff --git a/modules/core/04-channel/types/packet_test.go b/modules/core/04-channel/types/packet_test.go index f1ed49b15a2..780844dbb54 100644 --- a/modules/core/04-channel/types/packet_test.go +++ b/modules/core/04-channel/types/packet_test.go @@ -7,8 +7,8 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/stretchr/testify/require" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) func TestCommitPacket(t *testing.T) { diff --git a/modules/core/04-channel/types/query.go b/modules/core/04-channel/types/query.go index 0a4662acc01..84c6fac61f2 100644 --- a/modules/core/04-channel/types/query.go +++ b/modules/core/04-channel/types/query.go @@ -3,8 +3,8 @@ package types import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var ( diff --git a/modules/core/04-channel/types/query.pb.go b/modules/core/04-channel/types/query.pb.go index 75970287318..ec6746d002c 100644 --- a/modules/core/04-channel/types/query.pb.go +++ b/modules/core/04-channel/types/query.pb.go @@ -8,10 +8,10 @@ import ( fmt "fmt" types1 "github.com/cosmos/cosmos-sdk/codec/types" query "github.com/cosmos/cosmos-sdk/types/query" - types "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -1708,101 +1708,101 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/query.proto", fileDescriptor_1034a1e9abc4cca1) } var fileDescriptor_1034a1e9abc4cca1 = []byte{ - // 1490 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xcf, 0x6f, 0x13, 0xc7, - 0x17, 0xcf, 0x38, 0x06, 0x92, 0x07, 0x5f, 0x7e, 0x4c, 0x12, 0x08, 0x4b, 0x70, 0x82, 0xbf, 0x6a, - 0x09, 0x48, 0xec, 0x90, 0x40, 0x29, 0xad, 0x5a, 0x24, 0x12, 0xa9, 0x90, 0xaa, 0xfc, 0xda, 0x14, - 0x15, 0x90, 0x5a, 0x77, 0xbd, 0x1e, 0x9c, 0x55, 0xe2, 0xdd, 0xc5, 0xbb, 0x36, 0xa0, 0xd4, 0x55, - 0xd5, 0x03, 0x45, 0xea, 0xa5, 0x2a, 0x87, 0x4a, 0xbd, 0x54, 0xea, 0x8d, 0x43, 0x0f, 0xfd, 0x0b, - 0x7a, 0xe5, 0x56, 0x24, 0x7a, 0xa8, 0x84, 0x44, 0x2b, 0x82, 0x44, 0xaf, 0xbd, 0xf4, 0x5c, 0xed, - 0xfc, 0x58, 0xef, 0xda, 0xbb, 0x1b, 0x3b, 0x8e, 0x25, 0xd4, 0xdb, 0xee, 0xec, 0xbc, 0x37, 0x9f, - 0xcf, 0xe7, 0xcd, 0x7b, 0x79, 0xcf, 0x81, 0x49, 0xb3, 0x68, 0x10, 0xc3, 0xae, 0x52, 0x62, 0x2c, - 0xe9, 0x96, 0x45, 0x57, 0x48, 0x7d, 0x86, 0xdc, 0xaa, 0xd1, 0xea, 0x5d, 0xd5, 0xa9, 0xda, 0x9e, - 0x8d, 0x47, 0xcc, 0xa2, 0xa1, 0xfa, 0x1b, 0x54, 0xb1, 0x41, 0xad, 0xcf, 0x28, 0x21, 0xab, 0x15, - 0x93, 0x5a, 0x9e, 0x6f, 0xc4, 0x9f, 0xb8, 0x95, 0x72, 0xd4, 0xb0, 0xdd, 0x8a, 0xed, 0x92, 0xa2, - 0xee, 0x52, 0xee, 0x8e, 0xd4, 0x67, 0x8a, 0xd4, 0xd3, 0x67, 0x88, 0xa3, 0x97, 0x4d, 0x4b, 0xf7, - 0x4c, 0xdb, 0x12, 0x7b, 0x0f, 0xc5, 0x41, 0x90, 0x87, 0xf1, 0x2d, 0x13, 0x65, 0xdb, 0x2e, 0xaf, - 0x50, 0xa2, 0x3b, 0x26, 0xd1, 0x2d, 0xcb, 0xf6, 0x98, 0xbd, 0x2b, 0xbe, 0xee, 0x17, 0x5f, 0xd9, - 0x5b, 0xb1, 0x76, 0x93, 0xe8, 0x96, 0x40, 0xaf, 0x8c, 0x96, 0xed, 0xb2, 0xcd, 0x1e, 0x89, 0xff, - 0xc4, 0x57, 0xf3, 0x17, 0x60, 0xe4, 0x8a, 0x8f, 0x69, 0x9e, 0x1f, 0xa2, 0xd1, 0x5b, 0x35, 0xea, - 0x7a, 0x78, 0x1f, 0x6c, 0x73, 0xec, 0xaa, 0x57, 0x30, 0x4b, 0xe3, 0x68, 0x0a, 0x4d, 0x0f, 0x6b, - 0x5b, 0xfd, 0xd7, 0x85, 0x12, 0x3e, 0x08, 0x20, 0xf0, 0xf8, 0xdf, 0x32, 0xec, 0xdb, 0xb0, 0x58, - 0x59, 0x28, 0xe5, 0x1f, 0x22, 0x18, 0x8d, 0xfa, 0x73, 0x1d, 0xdb, 0x72, 0x29, 0x3e, 0x05, 0xdb, - 0xc4, 0x2e, 0xe6, 0x70, 0xfb, 0xec, 0x84, 0x1a, 0xa3, 0xa6, 0x2a, 0xcd, 0xe4, 0x66, 0x3c, 0x0a, - 0x5b, 0x9c, 0xaa, 0x6d, 0xdf, 0x64, 0x47, 0xed, 0xd0, 0xf8, 0x0b, 0x9e, 0x87, 0x1d, 0xec, 0xa1, - 0xb0, 0x44, 0xcd, 0xf2, 0x92, 0x37, 0x3e, 0xc8, 0x5c, 0x2a, 0x21, 0x97, 0x3c, 0x02, 0xf5, 0x19, - 0xf5, 0x3c, 0xdb, 0x31, 0x97, 0x7d, 0xf4, 0x6c, 0x72, 0x40, 0xdb, 0xce, 0xac, 0xf8, 0x52, 0xfe, - 0x93, 0x28, 0x54, 0x57, 0x72, 0x7f, 0x0f, 0xa0, 0x19, 0x18, 0x81, 0xf6, 0x75, 0x95, 0x47, 0x51, - 0xf5, 0xa3, 0xa8, 0xf2, 0x4b, 0x21, 0xa2, 0xa8, 0x5e, 0xd6, 0xcb, 0x54, 0xd8, 0x6a, 0x21, 0xcb, - 0xfc, 0x33, 0x04, 0x63, 0x2d, 0x07, 0x08, 0x31, 0xe6, 0x60, 0x48, 0xf0, 0x73, 0xc7, 0xd1, 0xd4, - 0x20, 0xf3, 0x1f, 0xa7, 0xc6, 0x42, 0x89, 0x5a, 0x9e, 0x79, 0xd3, 0xa4, 0x25, 0xa9, 0x4b, 0x60, - 0x87, 0xcf, 0x45, 0x50, 0x66, 0x18, 0xca, 0xc3, 0xeb, 0xa2, 0xe4, 0x00, 0xc2, 0x30, 0xf1, 0x69, - 0xd8, 0xda, 0xa5, 0x8a, 0x62, 0x7f, 0xfe, 0x3e, 0x82, 0x1c, 0x27, 0x68, 0x5b, 0x16, 0x35, 0x7c, - 0x6f, 0xad, 0x5a, 0xe6, 0x00, 0x8c, 0xe0, 0xa3, 0xb8, 0x4a, 0xa1, 0x95, 0x16, 0xad, 0x33, 0x1b, - 0xd6, 0xfa, 0x2f, 0x04, 0x93, 0x89, 0x50, 0xfe, 0x5b, 0xaa, 0x5f, 0x93, 0xa2, 0x73, 0x4c, 0xf3, - 0x6c, 0xf7, 0xa2, 0xa7, 0x7b, 0xb4, 0xd7, 0xe4, 0xfd, 0x23, 0x10, 0x31, 0xc6, 0xb5, 0x10, 0x51, - 0x87, 0x7d, 0x66, 0xa0, 0x4f, 0x81, 0x43, 0x2d, 0xb8, 0xfe, 0x16, 0x91, 0x29, 0x47, 0xe2, 0x88, - 0x84, 0x24, 0x0d, 0xf9, 0x1c, 0x33, 0xe3, 0x96, 0xfb, 0x99, 0xf2, 0x3f, 0x21, 0x38, 0x14, 0x61, - 0xe8, 0x73, 0xb2, 0xdc, 0x9a, 0xbb, 0x19, 0xfa, 0xe1, 0xc3, 0xb0, 0xab, 0x4a, 0xeb, 0xa6, 0x6b, - 0xda, 0x56, 0xc1, 0xaa, 0x55, 0x8a, 0xb4, 0xca, 0x50, 0x66, 0xb5, 0x9d, 0x72, 0xf9, 0x22, 0x5b, - 0x8d, 0x6c, 0x14, 0x74, 0xb2, 0xd1, 0x8d, 0x02, 0xef, 0x53, 0x04, 0xf9, 0x34, 0xbc, 0x22, 0x28, - 0xef, 0xc2, 0x2e, 0x43, 0x7e, 0x89, 0x04, 0x63, 0x54, 0xe5, 0x7f, 0x0f, 0x54, 0xf9, 0xf7, 0x40, - 0x3d, 0x6b, 0xdd, 0xd5, 0x76, 0x1a, 0x11, 0x37, 0xf8, 0x00, 0x0c, 0x8b, 0x40, 0x06, 0xac, 0x86, - 0xf8, 0xc2, 0x42, 0xa9, 0x19, 0x8d, 0xc1, 0xb4, 0x68, 0x64, 0x37, 0x12, 0x8d, 0x2a, 0x4c, 0x30, - 0x72, 0x97, 0x75, 0x63, 0x99, 0x7a, 0xf3, 0x76, 0xa5, 0x62, 0x7a, 0x15, 0x6a, 0x79, 0xbd, 0xc6, - 0x41, 0x81, 0x21, 0xd7, 0x77, 0x61, 0x19, 0x54, 0x04, 0x20, 0x78, 0xcf, 0x7f, 0x8f, 0xe0, 0x60, - 0xc2, 0xa1, 0x42, 0x4c, 0x56, 0xb2, 0xe4, 0x2a, 0x3b, 0x78, 0x87, 0x16, 0x5a, 0xe9, 0xe7, 0xf5, - 0xfc, 0x21, 0x09, 0x9c, 0xdb, 0xab, 0x24, 0xd1, 0x3a, 0x3b, 0xb8, 0xe1, 0x3a, 0xfb, 0x52, 0x96, - 0xfc, 0x18, 0x84, 0x41, 0x99, 0xdd, 0xde, 0x54, 0x4b, 0x56, 0xda, 0xa9, 0xd8, 0x4a, 0xcb, 0x9d, - 0xf0, 0xbb, 0x1c, 0x36, 0x7a, 0x15, 0xca, 0xac, 0x0d, 0xfb, 0x43, 0x44, 0x35, 0x6a, 0x50, 0xd3, - 0xe9, 0xeb, 0xcd, 0x7c, 0x80, 0x40, 0x89, 0x3b, 0x51, 0xc8, 0xaa, 0xc0, 0x50, 0xd5, 0x5f, 0xaa, - 0x53, 0xee, 0x77, 0x48, 0x0b, 0xde, 0xfb, 0x99, 0xa3, 0xb7, 0x45, 0xc1, 0xe4, 0xa0, 0xce, 0x1a, - 0xcb, 0x96, 0x7d, 0x7b, 0x85, 0x96, 0xca, 0xb4, 0xdf, 0x89, 0xfa, 0x50, 0x96, 0xbe, 0x84, 0x93, - 0x85, 0x2c, 0xd3, 0xb0, 0x4b, 0x8f, 0x7e, 0x12, 0x29, 0xdb, 0xba, 0xdc, 0xcf, 0xbc, 0x7d, 0x91, - 0x8a, 0xf5, 0x55, 0x49, 0x5e, 0x7c, 0x06, 0x0e, 0x38, 0x0c, 0x60, 0xa1, 0x99, 0x6b, 0x05, 0x29, - 0xb8, 0x3b, 0x9e, 0x9d, 0x1a, 0x9c, 0xce, 0x6a, 0xfb, 0x9d, 0x96, 0xcc, 0x5e, 0x94, 0x1b, 0xf2, - 0xff, 0x20, 0xf8, 0x7f, 0x2a, 0x4d, 0x11, 0x93, 0x0f, 0x60, 0x77, 0x8b, 0xf8, 0x9d, 0x97, 0x81, - 0x36, 0xcb, 0x57, 0xa1, 0x16, 0x7c, 0x27, 0xeb, 0xf2, 0x55, 0x4b, 0xe6, 0x1c, 0xc7, 0xdc, 0x73, - 0x68, 0xd7, 0x09, 0xc9, 0xe0, 0x7a, 0x21, 0xb9, 0x23, 0xca, 0x71, 0x0c, 0x30, 0x11, 0x8c, 0x09, - 0x18, 0x6e, 0xfa, 0x43, 0xcc, 0x5f, 0x73, 0x21, 0xa4, 0x49, 0xa6, 0x4b, 0x4d, 0xee, 0xc9, 0x72, - 0xd5, 0x3c, 0xfa, 0xac, 0xb1, 0xdc, 0xb3, 0x20, 0xc7, 0x61, 0x54, 0x08, 0xa2, 0x1b, 0xcb, 0x6d, - 0x4a, 0x60, 0x47, 0xde, 0xbc, 0xa6, 0x04, 0x35, 0x38, 0x10, 0x8b, 0xa3, 0xcf, 0xfc, 0xaf, 0x8b, - 0x5e, 0xf9, 0x22, 0xbd, 0x13, 0xc4, 0x43, 0xe3, 0x00, 0x7a, 0xed, 0xc3, 0x7f, 0x46, 0x30, 0x95, - 0xec, 0x5b, 0xf0, 0x9a, 0x85, 0x31, 0x8b, 0xde, 0x69, 0x5e, 0x96, 0x82, 0x60, 0xcf, 0x8e, 0xca, - 0x6a, 0x23, 0x56, 0xbb, 0x6d, 0x1f, 0x4b, 0xe0, 0xec, 0xd7, 0x7b, 0x61, 0x0b, 0xc3, 0x8c, 0x7f, - 0x44, 0xb0, 0x4d, 0xb4, 0xab, 0x78, 0x3a, 0x36, 0xdf, 0x63, 0x7e, 0x70, 0x50, 0x8e, 0x74, 0xb0, - 0x93, 0x33, 0xcf, 0xcf, 0x7d, 0xf9, 0xe4, 0xc5, 0x83, 0xcc, 0x3b, 0xf8, 0x6d, 0x92, 0xf2, 0x6b, - 0x89, 0x4b, 0x56, 0x9b, 0x12, 0x37, 0x88, 0x2f, 0xbc, 0x4b, 0x56, 0x45, 0x38, 0x1a, 0xf8, 0x3e, - 0x82, 0x21, 0x39, 0x20, 0xe2, 0xf5, 0xcf, 0x96, 0xd7, 0x5a, 0x39, 0xda, 0xc9, 0x56, 0x81, 0xf3, - 0x35, 0x86, 0x73, 0x12, 0x1f, 0x4c, 0xc5, 0x89, 0x7f, 0x41, 0x80, 0xdb, 0xa7, 0x56, 0x7c, 0x22, - 0xe5, 0xa4, 0xa4, 0x71, 0x5b, 0x39, 0xd9, 0x9d, 0x91, 0x00, 0x7a, 0x86, 0x01, 0x3d, 0x8d, 0x4f, - 0xc5, 0x03, 0x0d, 0x0c, 0x7d, 0x4d, 0x83, 0x97, 0x46, 0x93, 0xc1, 0x63, 0x9f, 0x41, 0xdb, 0xc8, - 0x98, 0xca, 0x20, 0x69, 0x76, 0x4d, 0x65, 0x90, 0x38, 0x95, 0xe6, 0x2f, 0x31, 0x06, 0x0b, 0xf8, - 0xdc, 0xc6, 0xaf, 0x04, 0x09, 0xcf, 0xb2, 0xf8, 0xdb, 0x0c, 0x8c, 0xc5, 0xce, 0x5c, 0xf8, 0xd4, - 0xfa, 0x00, 0xe3, 0x86, 0x4a, 0xe5, 0xcd, 0xae, 0xed, 0x04, 0xb7, 0xaf, 0x10, 0x23, 0xf7, 0x05, - 0xc2, 0x9f, 0xf7, 0xc2, 0x2e, 0x3a, 0x1f, 0x12, 0x39, 0x68, 0x92, 0xd5, 0x96, 0x91, 0xb5, 0x41, - 0x78, 0x19, 0x08, 0x7d, 0xe0, 0x0b, 0x0d, 0xfc, 0x14, 0xc1, 0xee, 0xd6, 0xbe, 0x1f, 0xcf, 0x24, - 0xf3, 0x4a, 0x98, 0xeb, 0x94, 0xd9, 0x6e, 0x4c, 0x84, 0x0a, 0x9f, 0x32, 0x11, 0x6e, 0xe0, 0x6b, - 0x3d, 0x68, 0xd0, 0xf6, 0x97, 0xd6, 0x25, 0xab, 0xb2, 0x7c, 0x36, 0xf0, 0x13, 0x04, 0x7b, 0xda, - 0xa6, 0x1a, 0xdc, 0x05, 0xd6, 0x20, 0x0b, 0x4f, 0x74, 0x65, 0x23, 0x08, 0x5e, 0x65, 0x04, 0x2f, - 0xe1, 0x0b, 0x9b, 0x4a, 0x10, 0xff, 0x8a, 0xe0, 0x7f, 0x91, 0x81, 0x02, 0xab, 0xeb, 0xa1, 0x8b, - 0xce, 0x3a, 0x0a, 0xe9, 0x78, 0xbf, 0x60, 0xf2, 0x31, 0x63, 0xf2, 0x11, 0xbe, 0xda, 0x3b, 0x93, - 0x2a, 0x77, 0x1d, 0x89, 0xd3, 0x1a, 0x82, 0xb1, 0xd8, 0x06, 0x34, 0x2d, 0x35, 0xd3, 0xc6, 0x97, - 0xb4, 0xd4, 0x4c, 0x1d, 0x3e, 0xf2, 0xd7, 0x19, 0xd3, 0x45, 0x7c, 0xa5, 0x77, 0xa6, 0xba, 0xb1, - 0x1c, 0x61, 0xf9, 0x12, 0xc1, 0xde, 0xf8, 0x36, 0x1b, 0x77, 0x0b, 0x37, 0xb8, 0x97, 0xa7, 0xbb, - 0x37, 0x14, 0x44, 0x6f, 0x30, 0xa2, 0x1f, 0x62, 0x6d, 0x53, 0x88, 0x46, 0xe9, 0xdc, 0xcb, 0xc0, - 0x9e, 0xb6, 0xf6, 0x35, 0x2d, 0xef, 0x92, 0x9a, 0xf0, 0xb4, 0xbc, 0x4b, 0xec, 0x8f, 0x37, 0xa9, - 0xbc, 0xc6, 0x95, 0x96, 0x94, 0xc6, 0xbe, 0x41, 0x6a, 0x01, 0xa0, 0x82, 0x23, 0x28, 0xff, 0x8d, - 0x60, 0x67, 0xb4, 0x89, 0xc5, 0xa4, 0x13, 0x46, 0xa1, 0xb6, 0x5b, 0x39, 0xde, 0xb9, 0x81, 0xe0, - 0xff, 0x19, 0xa3, 0x5f, 0xc7, 0x5e, 0x7f, 0xd8, 0x47, 0xba, 0xf8, 0x08, 0x6d, 0xff, 0xc6, 0xe3, - 0xdf, 0x10, 0x8c, 0xc4, 0x74, 0xb9, 0x38, 0xa5, 0x0d, 0x48, 0x6e, 0xb8, 0x95, 0x37, 0xba, 0xb4, - 0x12, 0x12, 0x5c, 0x66, 0x12, 0xbc, 0x8f, 0xcf, 0xf7, 0x20, 0x41, 0xa4, 0x17, 0x9f, 0x5b, 0x7c, - 0xf4, 0x3c, 0x87, 0x1e, 0x3f, 0xcf, 0xa1, 0x3f, 0x9f, 0xe7, 0xd0, 0x37, 0x6b, 0xb9, 0x81, 0xc7, - 0x6b, 0xb9, 0x81, 0xdf, 0xd7, 0x72, 0x03, 0x37, 0xde, 0x2a, 0x9b, 0xde, 0x52, 0xad, 0xa8, 0x1a, - 0x76, 0x85, 0x88, 0x7f, 0x0c, 0x9a, 0x45, 0xe3, 0x58, 0xd9, 0x26, 0xf5, 0x93, 0xa4, 0x62, 0x97, - 0x6a, 0x2b, 0xd4, 0xe5, 0x10, 0x8e, 0x9f, 0x3c, 0x26, 0x51, 0x78, 0x77, 0x1d, 0xea, 0x16, 0xb7, - 0xb2, 0x1f, 0x71, 0x4f, 0xfc, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x44, 0xc0, 0x72, 0xa8, 0x1c, - 0x00, 0x00, + // 1489 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xcd, 0x6f, 0xd4, 0x46, + 0x14, 0xcf, 0x6c, 0x16, 0x48, 0x1e, 0x94, 0x8f, 0x49, 0x02, 0xc1, 0x84, 0x4d, 0xd8, 0xaa, 0x25, + 0x20, 0xe1, 0x21, 0x81, 0x02, 0xad, 0x5a, 0x24, 0x12, 0xa9, 0x90, 0xaa, 0x7c, 0x39, 0x45, 0x05, + 0xa4, 0x76, 0xeb, 0xf5, 0x0e, 0x1b, 0x2b, 0x59, 0xdb, 0xac, 0xbd, 0x0b, 0x28, 0xdd, 0xaa, 0xea, + 0x81, 0x22, 0xf5, 0x52, 0x95, 0x43, 0xa5, 0x5e, 0x2a, 0xf5, 0xc6, 0xa1, 0x87, 0xfe, 0x05, 0xbd, + 0x72, 0x2b, 0x12, 0x3d, 0x54, 0x42, 0xa2, 0x15, 0x41, 0xa2, 0xd7, 0x5e, 0x7a, 0xae, 0x3c, 0x1f, + 0x5e, 0x7b, 0xd7, 0x76, 0xb2, 0xd9, 0xac, 0x14, 0xf5, 0x66, 0x8f, 0xe7, 0xbd, 0xf9, 0xfd, 0x7e, + 0x6f, 0xde, 0xcb, 0x7b, 0x1b, 0x18, 0x37, 0x8b, 0x06, 0x31, 0xec, 0x2a, 0x25, 0xc6, 0x82, 0x6e, + 0x59, 0x74, 0x89, 0xd4, 0xa7, 0xc8, 0xed, 0x1a, 0xad, 0xde, 0x53, 0x9d, 0xaa, 0xed, 0xd9, 0x78, + 0xc8, 0x2c, 0x1a, 0xaa, 0xbf, 0x41, 0x15, 0x1b, 0xd4, 0xfa, 0x94, 0x12, 0xb2, 0x5a, 0x32, 0xa9, + 0xe5, 0xf9, 0x46, 0xfc, 0x89, 0x5b, 0x29, 0x47, 0x0d, 0xdb, 0xad, 0xd8, 0x2e, 0x29, 0xea, 0x2e, + 0xe5, 0xee, 0x48, 0x7d, 0xaa, 0x48, 0x3d, 0x7d, 0x8a, 0x38, 0x7a, 0xd9, 0xb4, 0x74, 0xcf, 0xb4, + 0x2d, 0xb1, 0xf7, 0x50, 0x1c, 0x04, 0x79, 0x18, 0xdf, 0x32, 0x56, 0xb6, 0xed, 0xf2, 0x12, 0x25, + 0xba, 0x63, 0x12, 0xdd, 0xb2, 0x6c, 0x8f, 0xd9, 0xbb, 0xe2, 0xeb, 0x7e, 0xf1, 0x95, 0xbd, 0x15, + 0x6b, 0xb7, 0x88, 0x6e, 0x09, 0xf4, 0xca, 0x70, 0xd9, 0x2e, 0xdb, 0xec, 0x91, 0xf8, 0x4f, 0x7c, + 0x35, 0x7f, 0x11, 0x86, 0xae, 0xfa, 0x98, 0x66, 0xf9, 0x21, 0x1a, 0xbd, 0x5d, 0xa3, 0xae, 0x87, + 0xf7, 0xc1, 0x36, 0xc7, 0xae, 0x7a, 0x05, 0xb3, 0x34, 0x8a, 0x26, 0xd0, 0xe4, 0xa0, 0xb6, 0xd5, + 0x7f, 0x9d, 0x2b, 0xe1, 0x83, 0x00, 0x02, 0x8f, 0xff, 0x2d, 0xc3, 0xbe, 0x0d, 0x8a, 0x95, 0xb9, + 0x52, 0xfe, 0x11, 0x82, 0xe1, 0xa8, 0x3f, 0xd7, 0xb1, 0x2d, 0x97, 0xe2, 0x53, 0xb0, 0x4d, 0xec, + 0x62, 0x0e, 0xb7, 0x4f, 0x8f, 0xa9, 0x31, 0x6a, 0xaa, 0xd2, 0x4c, 0x6e, 0xc6, 0xc3, 0xb0, 0xc5, + 0xa9, 0xda, 0xf6, 0x2d, 0x76, 0xd4, 0x0e, 0x8d, 0xbf, 0xe0, 0x59, 0xd8, 0xc1, 0x1e, 0x0a, 0x0b, + 0xd4, 0x2c, 0x2f, 0x78, 0xa3, 0xfd, 0xcc, 0xa5, 0x12, 0x72, 0xc9, 0x23, 0x50, 0x9f, 0x52, 0x2f, + 0xb0, 0x1d, 0x33, 0xd9, 0xc7, 0xcf, 0xc7, 0xfb, 0xb4, 0xed, 0xcc, 0x8a, 0x2f, 0xe5, 0x3f, 0x8d, + 0x42, 0x75, 0x25, 0xf7, 0xf7, 0x01, 0x9a, 0x81, 0x11, 0x68, 0xdf, 0x54, 0x79, 0x14, 0x55, 0x3f, + 0x8a, 0x2a, 0xbf, 0x14, 0x22, 0x8a, 0xea, 0x15, 0xbd, 0x4c, 0x85, 0xad, 0x16, 0xb2, 0xcc, 0x3f, + 0x47, 0x30, 0xd2, 0x72, 0x80, 0x10, 0x63, 0x06, 0x06, 0x04, 0x3f, 0x77, 0x14, 0x4d, 0xf4, 0x33, + 0xff, 0x71, 0x6a, 0xcc, 0x95, 0xa8, 0xe5, 0x99, 0xb7, 0x4c, 0x5a, 0x92, 0xba, 0x04, 0x76, 0xf8, + 0x7c, 0x04, 0x65, 0x86, 0xa1, 0x3c, 0xbc, 0x2a, 0x4a, 0x0e, 0x20, 0x0c, 0x13, 0x9f, 0x81, 0xad, + 0x1d, 0xaa, 0x28, 0xf6, 0xe7, 0x1f, 0x20, 0xc8, 0x71, 0x82, 0xb6, 0x65, 0x51, 0xc3, 0xf7, 0xd6, + 0xaa, 0x65, 0x0e, 0xc0, 0x08, 0x3e, 0x8a, 0xab, 0x14, 0x5a, 0x69, 0xd1, 0x3a, 0xb3, 0x6e, 0xad, + 0xff, 0x46, 0x30, 0x9e, 0x08, 0xe5, 0xff, 0xa5, 0xfa, 0x75, 0x29, 0x3a, 0xc7, 0x34, 0xcb, 0x76, + 0xcf, 0x7b, 0xba, 0x47, 0xbb, 0x4d, 0xde, 0x3f, 0x03, 0x11, 0x63, 0x5c, 0x0b, 0x11, 0x75, 0xd8, + 0x67, 0x06, 0xfa, 0x14, 0x38, 0xd4, 0x82, 0xeb, 0x6f, 0x11, 0x99, 0x72, 0x24, 0x8e, 0x48, 0x48, + 0xd2, 0x90, 0xcf, 0x11, 0x33, 0x6e, 0xb9, 0x97, 0x29, 0xff, 0x33, 0x82, 0x43, 0x11, 0x86, 0x3e, + 0x27, 0xcb, 0xad, 0xb9, 0x1b, 0xa1, 0x1f, 0x3e, 0x0c, 0xbb, 0xaa, 0xb4, 0x6e, 0xba, 0xa6, 0x6d, + 0x15, 0xac, 0x5a, 0xa5, 0x48, 0xab, 0x0c, 0x65, 0x56, 0xdb, 0x29, 0x97, 0x2f, 0xb1, 0xd5, 0xc8, + 0x46, 0x41, 0x27, 0x1b, 0xdd, 0x28, 0xf0, 0x3e, 0x43, 0x90, 0x4f, 0xc3, 0x2b, 0x82, 0xf2, 0x1e, + 0xec, 0x32, 0xe4, 0x97, 0x48, 0x30, 0x86, 0x55, 0xfe, 0xf7, 0x40, 0x95, 0x7f, 0x0f, 0xd4, 0x73, + 0xd6, 0x3d, 0x6d, 0xa7, 0x11, 0x71, 0x83, 0x0f, 0xc0, 0xa0, 0x08, 0x64, 0xc0, 0x6a, 0x80, 0x2f, + 0xcc, 0x95, 0x9a, 0xd1, 0xe8, 0x4f, 0x8b, 0x46, 0x76, 0x3d, 0xd1, 0xa8, 0xc2, 0x18, 0x23, 0x77, + 0x45, 0x37, 0x16, 0xa9, 0x37, 0x6b, 0x57, 0x2a, 0xa6, 0x57, 0xa1, 0x96, 0xd7, 0x6d, 0x1c, 0x14, + 0x18, 0x70, 0x7d, 0x17, 0x96, 0x41, 0x45, 0x00, 0x82, 0xf7, 0xfc, 0x0f, 0x08, 0x0e, 0x26, 0x1c, + 0x2a, 0xc4, 0x64, 0x25, 0x4b, 0xae, 0xb2, 0x83, 0x77, 0x68, 0xa1, 0x95, 0x5e, 0x5e, 0xcf, 0x1f, + 0x93, 0xc0, 0xb9, 0xdd, 0x4a, 0x12, 0xad, 0xb3, 0xfd, 0xeb, 0xae, 0xb3, 0xaf, 0x64, 0xc9, 0x8f, + 0x41, 0x18, 0x94, 0xd9, 0xed, 0x4d, 0xb5, 0x64, 0xa5, 0x9d, 0x88, 0xad, 0xb4, 0xdc, 0x09, 0xbf, + 0xcb, 0x61, 0xa3, 0xcd, 0x50, 0x66, 0x6d, 0xd8, 0x1f, 0x22, 0xaa, 0x51, 0x83, 0x9a, 0x4e, 0x4f, + 0x6f, 0xe6, 0x43, 0x04, 0x4a, 0xdc, 0x89, 0x42, 0x56, 0x05, 0x06, 0xaa, 0xfe, 0x52, 0x9d, 0x72, + 0xbf, 0x03, 0x5a, 0xf0, 0xde, 0xcb, 0x1c, 0xbd, 0x23, 0x0a, 0x26, 0x07, 0x75, 0xce, 0x58, 0xb4, + 0xec, 0x3b, 0x4b, 0xb4, 0x54, 0xa6, 0xbd, 0x4e, 0xd4, 0x47, 0xb2, 0xf4, 0x25, 0x9c, 0x2c, 0x64, + 0x99, 0x84, 0x5d, 0x7a, 0xf4, 0x93, 0x48, 0xd9, 0xd6, 0xe5, 0x5e, 0xe6, 0xed, 0xcb, 0x54, 0xac, + 0x9b, 0x25, 0x79, 0xf1, 0x59, 0x38, 0xe0, 0x30, 0x80, 0x85, 0x66, 0xae, 0x15, 0xa4, 0xe0, 0xee, + 0x68, 0x76, 0xa2, 0x7f, 0x32, 0xab, 0xed, 0x77, 0x5a, 0x32, 0x7b, 0x5e, 0x6e, 0xc8, 0xff, 0x8b, + 0xe0, 0xf5, 0x54, 0x9a, 0x22, 0x26, 0x1f, 0xc2, 0xee, 0x16, 0xf1, 0xd7, 0x5e, 0x06, 0xda, 0x2c, + 0x37, 0x43, 0x2d, 0xf8, 0x5e, 0xd6, 0xe5, 0x6b, 0x96, 0xcc, 0x39, 0x8e, 0xb9, 0xeb, 0xd0, 0xae, + 0x12, 0x92, 0xfe, 0xd5, 0x42, 0x72, 0x57, 0x94, 0xe3, 0x18, 0x60, 0x22, 0x18, 0x63, 0x30, 0xd8, + 0xf4, 0x87, 0x98, 0xbf, 0xe6, 0x42, 0x48, 0x93, 0x4c, 0x87, 0x9a, 0xdc, 0x97, 0xe5, 0xaa, 0x79, + 0xf4, 0x39, 0x63, 0xb1, 0x6b, 0x41, 0x8e, 0xc3, 0xb0, 0x10, 0x44, 0x37, 0x16, 0xdb, 0x94, 0xc0, + 0x8e, 0xbc, 0x79, 0x4d, 0x09, 0x6a, 0x70, 0x20, 0x16, 0x47, 0x8f, 0xf9, 0xdf, 0x10, 0xbd, 0xf2, + 0x25, 0x7a, 0x37, 0x88, 0x87, 0xc6, 0x01, 0x74, 0xdb, 0x87, 0xff, 0x82, 0x60, 0x22, 0xd9, 0xb7, + 0xe0, 0x35, 0x0d, 0x23, 0x16, 0xbd, 0xdb, 0xbc, 0x2c, 0x05, 0xc1, 0x9e, 0x1d, 0x95, 0xd5, 0x86, + 0xac, 0x76, 0xdb, 0x1e, 0x96, 0xc0, 0xe9, 0x6f, 0xf6, 0xc2, 0x16, 0x86, 0x19, 0xff, 0x84, 0x60, + 0x9b, 0x68, 0x57, 0xf1, 0x64, 0x6c, 0xbe, 0xc7, 0xfc, 0xe0, 0xa0, 0x1c, 0x59, 0xc3, 0x4e, 0xce, + 0x3c, 0x3f, 0xf3, 0xd5, 0xd3, 0x97, 0x0f, 0x33, 0xef, 0xe2, 0x77, 0x48, 0xca, 0xaf, 0x25, 0x2e, + 0x59, 0x6e, 0x4a, 0xdc, 0x20, 0xbe, 0xf0, 0x2e, 0x59, 0x16, 0xe1, 0x68, 0xe0, 0x07, 0x08, 0x06, + 0xe4, 0x80, 0x88, 0x57, 0x3f, 0x5b, 0x5e, 0x6b, 0xe5, 0xe8, 0x5a, 0xb6, 0x0a, 0x9c, 0x6f, 0x30, + 0x9c, 0xe3, 0xf8, 0x60, 0x2a, 0x4e, 0xfc, 0x2b, 0x02, 0xdc, 0x3e, 0xb5, 0xe2, 0x13, 0x29, 0x27, + 0x25, 0x8d, 0xdb, 0xca, 0xc9, 0xce, 0x8c, 0x04, 0xd0, 0xb3, 0x0c, 0xe8, 0x19, 0x7c, 0x2a, 0x1e, + 0x68, 0x60, 0xe8, 0x6b, 0x1a, 0xbc, 0x34, 0x9a, 0x0c, 0x9e, 0xf8, 0x0c, 0xda, 0x46, 0xc6, 0x54, + 0x06, 0x49, 0xb3, 0x6b, 0x2a, 0x83, 0xc4, 0xa9, 0x34, 0x7f, 0x99, 0x31, 0x98, 0xc3, 0xe7, 0xd7, + 0x7f, 0x25, 0x48, 0x78, 0x96, 0xc5, 0xdf, 0x65, 0x60, 0x24, 0x76, 0xe6, 0xc2, 0xa7, 0x56, 0x07, + 0x18, 0x37, 0x54, 0x2a, 0xa7, 0x3b, 0xb6, 0x13, 0xdc, 0xbe, 0x46, 0x8c, 0xdc, 0x97, 0x08, 0x7f, + 0xd1, 0x0d, 0xbb, 0xe8, 0x7c, 0x48, 0xe4, 0xa0, 0x49, 0x96, 0x5b, 0x46, 0xd6, 0x06, 0xe1, 0x65, + 0x20, 0xf4, 0x81, 0x2f, 0x34, 0xf0, 0x33, 0x04, 0xbb, 0x5b, 0xfb, 0x7e, 0x3c, 0x95, 0xcc, 0x2b, + 0x61, 0xae, 0x53, 0xa6, 0x3b, 0x31, 0x11, 0x2a, 0x7c, 0xc6, 0x44, 0xb8, 0x89, 0xaf, 0x77, 0xa1, + 0x41, 0xdb, 0x5f, 0x5a, 0x97, 0x2c, 0xcb, 0xf2, 0xd9, 0xc0, 0x4f, 0x11, 0xec, 0x69, 0x9b, 0x6a, + 0x70, 0x07, 0x58, 0x83, 0x2c, 0x3c, 0xd1, 0x91, 0x8d, 0x20, 0x78, 0x8d, 0x11, 0xbc, 0x8c, 0x2f, + 0x6e, 0x28, 0x41, 0xfc, 0x1b, 0x82, 0xd7, 0x22, 0x03, 0x05, 0x56, 0x57, 0x43, 0x17, 0x9d, 0x75, + 0x14, 0xb2, 0xe6, 0xfd, 0x82, 0xc9, 0x27, 0x8c, 0xc9, 0xc7, 0xf8, 0x5a, 0xf7, 0x4c, 0xaa, 0xdc, + 0x75, 0x24, 0x4e, 0x2b, 0x08, 0x46, 0x62, 0x1b, 0xd0, 0xb4, 0xd4, 0x4c, 0x1b, 0x5f, 0xd2, 0x52, + 0x33, 0x75, 0xf8, 0xc8, 0xdf, 0x60, 0x4c, 0xe7, 0xf1, 0xd5, 0xee, 0x99, 0xea, 0xc6, 0x62, 0x84, + 0xe5, 0x2b, 0x04, 0x7b, 0xe3, 0xdb, 0x6c, 0xdc, 0x29, 0xdc, 0xe0, 0x5e, 0x9e, 0xe9, 0xdc, 0x50, + 0x10, 0xbd, 0xc9, 0x88, 0x7e, 0x84, 0xb5, 0x0d, 0x21, 0x1a, 0xa5, 0x73, 0x3f, 0x03, 0x7b, 0xda, + 0xda, 0xd7, 0xb4, 0xbc, 0x4b, 0x6a, 0xc2, 0xd3, 0xf2, 0x2e, 0xb1, 0x3f, 0xde, 0xa0, 0xf2, 0x1a, + 0x57, 0x5a, 0x52, 0x1a, 0xfb, 0x06, 0xa9, 0x05, 0x80, 0x0a, 0x8e, 0xa0, 0xfc, 0x0f, 0x82, 0x9d, + 0xd1, 0x26, 0x16, 0x93, 0xb5, 0x30, 0x0a, 0xb5, 0xdd, 0xca, 0xf1, 0xb5, 0x1b, 0x08, 0xfe, 0x9f, + 0x33, 0xfa, 0x75, 0xec, 0xf5, 0x86, 0x7d, 0xa4, 0x8b, 0x8f, 0xd0, 0xf6, 0x6f, 0x3c, 0xfe, 0x1d, + 0xc1, 0x50, 0x4c, 0x97, 0x8b, 0x53, 0xda, 0x80, 0xe4, 0x86, 0x5b, 0x79, 0xab, 0x43, 0x2b, 0x21, + 0xc1, 0x15, 0x26, 0xc1, 0x07, 0xf8, 0x42, 0x17, 0x12, 0x44, 0x7a, 0xf1, 0x99, 0xf9, 0xc7, 0x2f, + 0x72, 0xe8, 0xc9, 0x8b, 0x1c, 0xfa, 0xeb, 0x45, 0x0e, 0x7d, 0xbb, 0x92, 0xeb, 0x7b, 0xb2, 0x92, + 0xeb, 0xfb, 0x63, 0x25, 0xd7, 0x77, 0xf3, 0xed, 0xb2, 0xe9, 0x2d, 0xd4, 0x8a, 0xaa, 0x61, 0x57, + 0x88, 0xf8, 0xc7, 0xa0, 0x59, 0x34, 0x8e, 0x95, 0x6d, 0x52, 0x3f, 0x4d, 0x2a, 0x76, 0xa9, 0xb6, + 0x44, 0x5d, 0x0e, 0xe1, 0xf8, 0xc9, 0x63, 0x12, 0x85, 0x77, 0xcf, 0xa1, 0x6e, 0x71, 0x2b, 0xfb, + 0x11, 0xf7, 0xc4, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x67, 0x58, 0x5b, 0xa1, 0xa8, 0x1c, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/core/04-channel/types/query.pb.gw.go b/modules/core/04-channel/types/query.pb.gw.go index 9e59c03b536..0f9ed6eaab3 100644 --- a/modules/core/04-channel/types/query.pb.gw.go +++ b/modules/core/04-channel/types/query.pb.gw.go @@ -20,6 +20,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -30,6 +31,7 @@ var _ status.Status var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var _ = metadata.Join func request_Query_Channel_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryChannelRequest @@ -1168,12 +1170,14 @@ func local_request_Query_NextSequenceReceive_0(ctx context.Context, marshaler ru // 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. -// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { mux.Handle("GET", pattern_Query_Channel_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 { @@ -1181,6 +1185,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Channel_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) @@ -1194,6 +1199,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_Channels_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 { @@ -1201,6 +1208,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_Channels_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) @@ -1214,6 +1222,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ConnectionChannels_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 { @@ -1221,6 +1231,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ConnectionChannels_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) @@ -1234,6 +1245,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ChannelClientState_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 { @@ -1241,6 +1254,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ChannelClientState_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) @@ -1254,6 +1268,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_ChannelConsensusState_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 { @@ -1261,6 +1277,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_ChannelConsensusState_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) @@ -1274,6 +1291,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_PacketCommitment_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 { @@ -1281,6 +1300,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_PacketCommitment_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) @@ -1294,6 +1314,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_PacketCommitments_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 { @@ -1301,6 +1323,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_PacketCommitments_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) @@ -1314,6 +1337,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_PacketReceipt_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 { @@ -1321,6 +1346,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_PacketReceipt_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) @@ -1334,6 +1360,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_PacketAcknowledgement_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 { @@ -1341,6 +1369,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_PacketAcknowledgement_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) @@ -1354,6 +1383,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_PacketAcknowledgements_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 { @@ -1361,6 +1392,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_PacketAcknowledgements_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) @@ -1374,6 +1406,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_UnreceivedPackets_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 { @@ -1381,6 +1415,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_UnreceivedPackets_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) @@ -1394,6 +1429,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_UnreceivedAcks_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 { @@ -1401,6 +1438,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_UnreceivedAcks_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) @@ -1414,6 +1452,8 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv mux.Handle("GET", pattern_Query_NextSequenceReceive_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 { @@ -1421,6 +1461,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } resp, md, err := local_request_Query_NextSequenceReceive_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) @@ -1736,31 +1777,31 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Channel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Channel_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Channels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "channel", "v1", "channels"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Channels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "channel", "v1", "channels"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ConnectionChannels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"ibc", "core", "channel", "v1", "connections", "connection", "channels"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConnectionChannels_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"ibc", "core", "channel", "v1", "connections", "connection", "channels"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ChannelClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "client_state"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ChannelClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "client_state"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ChannelConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 2, 9, 1, 0, 4, 1, 5, 10, 2, 11, 1, 0, 4, 1, 5, 12}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "consensus_state", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ChannelConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 2, 9, 1, 0, 4, 1, 5, 10, 2, 11, 1, 0, 4, 1, 5, 12}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "consensus_state", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_PacketCommitment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_commitments", "sequence"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_PacketCommitment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_commitments", "sequence"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_PacketCommitments_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_commitments"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_PacketCommitments_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_commitments"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_PacketReceipt_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_receipts", "sequence"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_PacketReceipt_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_receipts", "sequence"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_PacketAcknowledgement_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_acks", "sequence"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_PacketAcknowledgement_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_acks", "sequence"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_PacketAcknowledgements_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_acknowledgements"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_PacketAcknowledgements_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_acknowledgements"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_UnreceivedPackets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_commitments", "packet_commitment_sequences", "unreceived_packets"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UnreceivedPackets_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_commitments", "packet_commitment_sequences", "unreceived_packets"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_UnreceivedAcks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_commitments", "packet_ack_sequences", "unreceived_acks"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UnreceivedAcks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9, 2, 10}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "packet_commitments", "packet_ack_sequences", "unreceived_acks"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_NextSequenceReceive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "next_sequence"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_NextSequenceReceive_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1", "channels", "channel_id", "ports", "port_id", "next_sequence"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/modules/core/04-channel/types/tx.pb.go b/modules/core/04-channel/types/tx.pb.go index 359060b801f..47b4b3992f6 100644 --- a/modules/core/04-channel/types/tx.pb.go +++ b/modules/core/04-channel/types/tx.pb.go @@ -6,10 +6,10 @@ package types import ( context "context" fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - _ "github.com/gogo/protobuf/gogoproto" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -205,7 +205,8 @@ var xxx_messageInfo_MsgChannelOpenTry proto.InternalMessageInfo // MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. type MsgChannelOpenTryResponse struct { - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"` } func (m *MsgChannelOpenTryResponse) Reset() { *m = MsgChannelOpenTryResponse{} } @@ -248,6 +249,13 @@ func (m *MsgChannelOpenTryResponse) GetVersion() string { return "" } +func (m *MsgChannelOpenTryResponse) GetChannelId() string { + if m != nil { + return m.ChannelId + } + return "" +} + // MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge // the change of channel state to TRYOPEN on Chain B. type MsgChannelOpenAck struct { @@ -1420,125 +1428,126 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/tx.proto", fileDescriptor_bc4637e0ac3fc7b7) } var fileDescriptor_bc4637e0ac3fc7b7 = []byte{ - // 1886 bytes of a gzipped FileDescriptorProto + // 1891 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5a, 0xcb, 0x6f, 0xe3, 0xc6, 0x19, 0xd7, 0x5b, 0xf6, 0xe7, 0x97, 0x4c, 0xd9, 0x5e, 0x2d, 0x6d, 0x8b, 0x32, 0x8b, 0xc6, 0xee, - 0xb6, 0x96, 0x62, 0xc7, 0x46, 0x91, 0x45, 0x8b, 0xc2, 0x52, 0x15, 0xd4, 0x68, 0xfd, 0x00, 0x25, - 0xb7, 0xe8, 0xb6, 0xa8, 0x2a, 0x53, 0x13, 0x99, 0x90, 0x44, 0x2a, 0x24, 0xa5, 0x44, 0x05, 0xfa, - 0xb8, 0x04, 0x08, 0xf6, 0x94, 0x73, 0x80, 0x05, 0x52, 0xf4, 0x54, 0xf4, 0xd0, 0xfc, 0x19, 0x41, - 0x4f, 0xb9, 0x35, 0xed, 0x41, 0x08, 0x76, 0x2f, 0x3d, 0xeb, 0x2f, 0x28, 0x38, 0x1c, 0x52, 0x7c, - 0xae, 0x29, 0xc7, 0x92, 0xd3, 0x9e, 0x44, 0xce, 0xfc, 0xe6, 0xfb, 0x66, 0x7e, 0xdf, 0x6f, 0xbe, - 0x79, 0x50, 0xb0, 0x25, 0x5c, 0xf3, 0x05, 0x5e, 0x92, 0x51, 0x81, 0xbf, 0xa9, 0x8b, 0x22, 0x6a, - 0x17, 0xfa, 0x07, 0x05, 0xf5, 0x83, 0x7c, 0x57, 0x96, 0x54, 0x89, 0x4a, 0x0b, 0xd7, 0x7c, 0x5e, - 0xab, 0xcd, 0x93, 0xda, 0x7c, 0xff, 0x80, 0x5e, 0x6b, 0x4a, 0x4d, 0x09, 0xd7, 0x17, 0xb4, 0x27, - 0x1d, 0x4a, 0x33, 0x63, 0x43, 0x6d, 0x01, 0x89, 0xaa, 0x66, 0x47, 0x7f, 0x22, 0x80, 0x1d, 0x2f, - 0x4f, 0x86, 0xd9, 0xd7, 0x40, 0x7a, 0xdd, 0xa6, 0x5c, 0x6f, 0x20, 0x1d, 0xc2, 0xfe, 0x39, 0x0c, - 0xd4, 0x99, 0xd2, 0x2c, 0xe9, 0xf5, 0x17, 0x5d, 0x24, 0x9e, 0x8a, 0x82, 0x4a, 0x7d, 0x17, 0x92, - 0x5d, 0x49, 0x56, 0x6b, 0x42, 0x23, 0x13, 0xce, 0x85, 0xf7, 0xe6, 0x8b, 0xd4, 0x68, 0xc8, 0x2c, - 0x0f, 0xea, 0x9d, 0xf6, 0x53, 0x96, 0x54, 0xb0, 0x5c, 0x42, 0x7b, 0x3a, 0x6d, 0x50, 0x3f, 0x80, - 0x24, 0xb1, 0x9f, 0x89, 0xe4, 0xc2, 0x7b, 0x0b, 0x87, 0x5b, 0x79, 0x8f, 0x71, 0xe6, 0x89, 0x8f, - 0x62, 0xec, 0xf3, 0x21, 0x13, 0xe2, 0x8c, 0x26, 0xd4, 0x06, 0x24, 0x14, 0xa1, 0x29, 0x22, 0x39, - 0x13, 0xd5, 0x3c, 0x71, 0xe4, 0xed, 0xe9, 0xdc, 0x47, 0x9f, 0x32, 0xa1, 0xff, 0x7c, 0xca, 0x84, - 0xd8, 0x36, 0xd0, 0xee, 0x2e, 0x72, 0x48, 0xe9, 0x4a, 0xa2, 0x82, 0xa8, 0x23, 0x00, 0x62, 0x6a, - 0xdc, 0xdb, 0xf5, 0xd1, 0x90, 0x59, 0xd5, 0x7b, 0x3b, 0xae, 0x63, 0xb9, 0x79, 0xf2, 0x72, 0xda, - 0xa0, 0x32, 0x90, 0xec, 0x23, 0x59, 0x11, 0x24, 0x11, 0xf7, 0x79, 0x9e, 0x33, 0x5e, 0xd9, 0x2f, - 0xa3, 0xb0, 0x6a, 0x77, 0x57, 0x95, 0x07, 0x93, 0x11, 0x72, 0x09, 0xe9, 0xae, 0x8c, 0xfa, 0x82, - 0xd4, 0x53, 0x6a, 0x96, 0xbe, 0x61, 0x47, 0xc5, 0xdc, 0x68, 0xc8, 0xd0, 0xa4, 0xa1, 0x1b, 0xc4, - 0x66, 0xc2, 0xdc, 0xaa, 0x51, 0x5e, 0x32, 0xbb, 0x6b, 0xa1, 0x38, 0x3a, 0x39, 0xc5, 0x1c, 0xac, - 0xf1, 0x52, 0x4f, 0x54, 0x91, 0xdc, 0xad, 0xcb, 0xea, 0xa0, 0x66, 0x8c, 0x3c, 0x86, 0x3b, 0xc4, - 0x8c, 0x86, 0xcc, 0x26, 0x21, 0xcb, 0x03, 0xc5, 0x72, 0x69, 0x6b, 0xf1, 0xcf, 0xf5, 0x52, 0x8d, - 0xf6, 0xae, 0x2c, 0x49, 0xef, 0xd6, 0x04, 0x51, 0x50, 0x33, 0xf1, 0x5c, 0x78, 0x6f, 0xd1, 0x4a, - 0xfb, 0xb8, 0x8e, 0xe5, 0xe6, 0xf1, 0x0b, 0xd6, 0xd5, 0x33, 0x58, 0xd4, 0x6b, 0x6e, 0x90, 0xd0, - 0xbc, 0x51, 0x33, 0x09, 0x3c, 0x18, 0xda, 0x32, 0x18, 0x5d, 0xe2, 0xfd, 0x83, 0xfc, 0x4f, 0x30, - 0xa2, 0xb8, 0xa9, 0x0d, 0x65, 0x34, 0x64, 0xd2, 0x56, 0xbb, 0x7a, 0x6b, 0x96, 0x5b, 0xc0, 0xaf, - 0x3a, 0xd2, 0x22, 0xa4, 0xa4, 0x8f, 0x90, 0x8e, 0xe1, 0xb1, 0x2b, 0xb2, 0xa6, 0x8e, 0x2c, 0x8a, - 0x08, 0xdb, 0x15, 0xf1, 0x4f, 0x97, 0x22, 0x4e, 0xf8, 0xd6, 0x64, 0x8a, 0xb0, 0x8b, 0x34, 0x12, - 0x50, 0xa4, 0xcf, 0xe0, 0x91, 0x2d, 0x22, 0x16, 0x13, 0x78, 0xae, 0x14, 0xd9, 0xd1, 0x90, 0xc9, - 0x7a, 0x84, 0xce, 0x6a, 0x6f, 0xdd, 0x5a, 0x33, 0x56, 0xd4, 0x34, 0x34, 0x71, 0x00, 0x7a, 0xa8, - 0x6b, 0xaa, 0x3c, 0x20, 0x92, 0x58, 0x1b, 0x0d, 0x99, 0x94, 0x35, 0x74, 0xaa, 0x3c, 0x60, 0xb9, - 0x39, 0xfc, 0xac, 0xcd, 0xab, 0x87, 0x15, 0xc4, 0xa6, 0x53, 0x10, 0x27, 0x7c, 0xcb, 0x10, 0x04, - 0xfb, 0xb7, 0x08, 0xac, 0xdb, 0x6b, 0x4b, 0x92, 0xf8, 0xae, 0x20, 0x77, 0x66, 0x11, 0x7a, 0x93, - 0xca, 0x3a, 0xdf, 0xc2, 0xc1, 0xf6, 0xa0, 0xb2, 0xce, 0xb7, 0x0c, 0x2a, 0x35, 0x41, 0x3a, 0xa9, - 0x8c, 0x4d, 0x85, 0xca, 0xb8, 0x0f, 0x95, 0x0c, 0x6c, 0x7b, 0x92, 0x65, 0xd2, 0xf9, 0x49, 0x18, - 0xd2, 0x63, 0x44, 0xa9, 0x2d, 0x29, 0x68, 0xf2, 0xa5, 0xe6, 0x6e, 0x64, 0xde, 0xbe, 0xc4, 0x6c, - 0xc3, 0xa6, 0x47, 0xdf, 0xcc, 0xbe, 0xff, 0x3d, 0x02, 0x1b, 0x8e, 0xfa, 0x19, 0x6a, 0xc1, 0x9e, - 0x6a, 0xa3, 0x77, 0x4c, 0xb5, 0xb3, 0x95, 0x43, 0x0e, 0xb2, 0xde, 0x84, 0x99, 0x9c, 0x7e, 0x1c, - 0x81, 0xa5, 0x33, 0xa5, 0xc9, 0x21, 0xbe, 0x7f, 0x59, 0xe7, 0x5b, 0x48, 0xa5, 0xde, 0x86, 0x44, - 0x17, 0x3f, 0x61, 0x26, 0x17, 0x0e, 0x37, 0x3d, 0xd7, 0x38, 0x1d, 0x4c, 0x96, 0x38, 0xd2, 0x80, - 0x7a, 0x07, 0x52, 0x7a, 0x77, 0x79, 0xa9, 0xd3, 0x11, 0xd4, 0x0e, 0x12, 0x55, 0x4c, 0xef, 0x62, - 0x71, 0x73, 0x34, 0x64, 0x1e, 0x59, 0x07, 0x34, 0x46, 0xb0, 0xdc, 0x0a, 0x2e, 0x2a, 0x99, 0x25, - 0x2e, 0xd2, 0xa2, 0x53, 0x21, 0x2d, 0xe6, 0x43, 0xda, 0x6f, 0x70, 0xc2, 0x19, 0x33, 0x62, 0xae, - 0x4d, 0x3f, 0x82, 0x84, 0x8c, 0x94, 0x5e, 0x5b, 0x67, 0x66, 0xf9, 0x70, 0xd7, 0x93, 0x19, 0x03, - 0xce, 0x61, 0x68, 0x75, 0xd0, 0x45, 0x1c, 0x69, 0xf6, 0x34, 0xa6, 0xf9, 0x60, 0xff, 0x1d, 0x01, - 0x38, 0x53, 0x9a, 0x55, 0xa1, 0x83, 0xa4, 0xde, 0xfd, 0xf0, 0xdd, 0x13, 0x65, 0xc4, 0x23, 0xa1, - 0x8f, 0x1a, 0x7e, 0x7c, 0x8f, 0x11, 0x06, 0xdf, 0x57, 0x66, 0xc9, 0x54, 0xf9, 0xfe, 0x29, 0x50, - 0x22, 0xfa, 0x40, 0xad, 0x29, 0xe8, 0xbd, 0x1e, 0x12, 0x79, 0x54, 0x93, 0x11, 0xdf, 0xc7, 0xdc, - 0xc7, 0x8a, 0xdb, 0xa3, 0x21, 0xf3, 0x58, 0xb7, 0xe0, 0xc6, 0xb0, 0x5c, 0x4a, 0x2b, 0xac, 0x90, - 0x32, 0x2d, 0x1e, 0x01, 0x14, 0xff, 0x2b, 0xbc, 0x91, 0x26, 0xdc, 0xde, 0x77, 0xe4, 0x3e, 0xd1, - 0xb7, 0x20, 0xc4, 0xfa, 0x85, 0x88, 0x67, 0xd4, 0x37, 0x21, 0x80, 0xdf, 0x87, 0x05, 0x32, 0xad, - 0xb4, 0x1e, 0x91, 0xe4, 0xb4, 0x31, 0x1a, 0x32, 0x94, 0x6d, 0xce, 0x69, 0x95, 0x2c, 0xa7, 0xa7, - 0x31, 0xbd, 0xef, 0xd3, 0x4c, 0x4f, 0xde, 0x91, 0x8f, 0x7f, 0xdd, 0xc8, 0x27, 0x7c, 0x22, 0x7f, - 0x8d, 0x77, 0x11, 0xf6, 0xd8, 0xdc, 0xb7, 0x00, 0x3e, 0x8b, 0x60, 0x79, 0x9d, 0xf0, 0x2d, 0x51, - 0x7a, 0xbf, 0x8d, 0x1a, 0x4d, 0x84, 0xf3, 0xd5, 0xd7, 0x50, 0xc0, 0x1e, 0xac, 0xd4, 0xed, 0xd6, - 0x74, 0x01, 0x70, 0xce, 0xe2, 0x71, 0x8c, 0xb5, 0x86, 0x0d, 0xbf, 0x18, 0xe3, 0x4a, 0x23, 0xc6, - 0x27, 0xda, 0xcb, 0x03, 0x2f, 0x41, 0x3c, 0x3e, 0x36, 0x3a, 0x18, 0xbb, 0xef, 0xb8, 0xfc, 0x23, - 0x6a, 0xdd, 0x24, 0x5e, 0xe9, 0x67, 0xeb, 0x59, 0xed, 0x6b, 0xfe, 0x08, 0x99, 0xae, 0x2c, 0x75, - 0x25, 0x05, 0x35, 0x6a, 0xe4, 0x58, 0x5f, 0x9b, 0xe4, 0x98, 0xb8, 0x4b, 0xd8, 0x66, 0x4c, 0xb6, - 0x3d, 0x6d, 0xb1, 0xdc, 0x86, 0x51, 0x45, 0x06, 0x48, 0x0c, 0x50, 0xbf, 0x85, 0x65, 0x55, 0x97, - 0x7d, 0xf0, 0x10, 0x6f, 0x13, 0xa7, 0xeb, 0xba, 0x53, 0x7b, 0x7b, 0x96, 0x5b, 0x22, 0x05, 0x24, - 0xcc, 0xa7, 0xb0, 0x6a, 0x20, 0xb4, 0x5f, 0x45, 0xad, 0x77, 0xba, 0x64, 0x26, 0x6f, 0x8d, 0x86, - 0x4c, 0xc6, 0x6e, 0xc4, 0x84, 0xb0, 0x5c, 0x8a, 0x94, 0x55, 0x8d, 0xa2, 0x00, 0x13, 0xd9, 0xb6, - 0x87, 0xb5, 0xc4, 0xd2, 0xdc, 0xb3, 0x7c, 0x95, 0x84, 0x35, 0x17, 0x62, 0xe2, 0xeb, 0x81, 0xbb, - 0x05, 0x5b, 0x75, 0x1c, 0xd8, 0x26, 0x09, 0xf4, 0xb7, 0x08, 0xe7, 0x9b, 0xfe, 0x67, 0x45, 0xc7, - 0x91, 0xce, 0x88, 0xf0, 0x15, 0xd8, 0xce, 0x8f, 0x66, 0xba, 0x24, 0xeb, 0x68, 0x6e, 0x34, 0x64, - 0xb6, 0x3c, 0x8c, 0x1a, 0x30, 0x96, 0xb3, 0x75, 0xda, 0x48, 0xac, 0xaf, 0x55, 0x6e, 0xfc, 0x61, - 0x94, 0x9b, 0x98, 0x85, 0x72, 0x93, 0x77, 0x52, 0xee, 0x0f, 0x61, 0x89, 0xac, 0xa3, 0x84, 0xa2, - 0x39, 0x9c, 0x82, 0x33, 0xa3, 0x21, 0xb3, 0x66, 0x5b, 0x66, 0x8d, 0x51, 0xeb, 0x69, 0xd7, 0x18, - 0x6b, 0x15, 0xd6, 0xc9, 0x4a, 0x4e, 0xd8, 0x21, 0x0e, 0x32, 0xf3, 0xd8, 0x8c, 0x25, 0x86, 0x9e, - 0x30, 0x96, 0x4b, 0xeb, 0xab, 0x3e, 0x91, 0x3b, 0xd9, 0x3d, 0xfe, 0x02, 0x36, 0xec, 0x70, 0x53, - 0x1a, 0x80, 0xcd, 0xee, 0x8c, 0x86, 0xcc, 0xb6, 0x97, 0x59, 0x8b, 0x36, 0xac, 0x76, 0x4d, 0x6d, - 0x38, 0x57, 0x8d, 0x85, 0xa9, 0xac, 0x1a, 0x8b, 0x3e, 0x39, 0x20, 0x0b, 0x5b, 0x5e, 0x33, 0xdc, - 0x4c, 0x01, 0x1f, 0xc6, 0x3c, 0x52, 0xc0, 0x8c, 0xee, 0x83, 0x1e, 0x26, 0x05, 0xb8, 0xd4, 0x17, - 0x9b, 0x48, 0x7d, 0xfe, 0x3a, 0x89, 0xdf, 0xaf, 0x4e, 0x66, 0x7b, 0x75, 0xe4, 0xa5, 0x13, 0xeb, - 0xed, 0xd1, 0xbf, 0x62, 0x90, 0x71, 0x01, 0x66, 0x78, 0x69, 0xf0, 0x3f, 0xa9, 0x95, 0x73, 0x48, - 0xdb, 0x35, 0x80, 0x64, 0x59, 0x92, 0x89, 0x50, 0xb2, 0xd6, 0x8b, 0x73, 0x17, 0x88, 0xe5, 0x56, - 0xad, 0x2a, 0x29, 0x6b, 0x65, 0xaf, 0xd1, 0x5e, 0xe2, 0x7e, 0xb5, 0x97, 0x9c, 0x8a, 0xf6, 0xe6, - 0x7c, 0xb4, 0xc7, 0x42, 0xce, 0x4f, 0x5a, 0xa6, 0xfe, 0xfe, 0x14, 0xf7, 0xd0, 0x9f, 0x91, 0xbb, - 0xff, 0x6f, 0xf5, 0xf7, 0x07, 0x2d, 0xe0, 0xe4, 0xa3, 0x0a, 0x96, 0x45, 0x0d, 0x9f, 0x54, 0xbb, - 0xc6, 0xc6, 0x74, 0xc7, 0xd3, 0x2f, 0x16, 0x0b, 0xa7, 0x03, 0x8b, 0xdf, 0x26, 0xce, 0xb7, 0x1d, - 0xdf, 0x68, 0x6c, 0xe6, 0xb0, 0x2e, 0xf4, 0x0a, 0x6b, 0x63, 0xb7, 0xfe, 0xe3, 0x77, 0xd3, 0xbf, - 0xbd, 0xef, 0x09, 0x6f, 0xfd, 0x3b, 0x7a, 0xa4, 0xeb, 0xdf, 0xd6, 0x9d, 0x6f, 0x9e, 0x4c, 0x1d, - 0xf7, 0x23, 0xec, 0x67, 0x51, 0x78, 0xe4, 0xd6, 0x72, 0x5d, 0xe4, 0x51, 0x7b, 0x16, 0x2a, 0x6d, - 0xc0, 0x92, 0x9d, 0xea, 0x68, 0x50, 0x99, 0x6c, 0x11, 0xa2, 0x48, 0x58, 0x1d, 0xb1, 0x58, 0x44, - 0xd6, 0x30, 0xf8, 0x84, 0x35, 0x76, 0x5f, 0x61, 0x8d, 0x4f, 0x25, 0xac, 0x7e, 0xa7, 0xa4, 0x1d, - 0x60, 0x7c, 0x22, 0x66, 0x44, 0xf5, 0xc9, 0x5f, 0xc3, 0x40, 0xb9, 0x8f, 0xce, 0xd4, 0x31, 0xe4, - 0xb8, 0x72, 0xe5, 0xf2, 0xe2, 0xbc, 0x52, 0xae, 0x71, 0xe5, 0xca, 0xd5, 0xcf, 0xaa, 0xb5, 0xea, - 0x2f, 0x2f, 0xcb, 0xb5, 0xab, 0xf3, 0xca, 0x65, 0xb9, 0x74, 0xfa, 0xce, 0x69, 0xf9, 0xc7, 0xa9, - 0x10, 0xbd, 0xf2, 0xfc, 0x45, 0x6e, 0xc1, 0x52, 0x44, 0xed, 0xc2, 0x63, 0xcf, 0x66, 0xe7, 0x17, - 0x17, 0x97, 0xa9, 0x30, 0x3d, 0xf7, 0xfc, 0x45, 0x2e, 0xa6, 0x3d, 0x53, 0xfb, 0xb0, 0xe5, 0x09, - 0xac, 0x5c, 0x95, 0x4a, 0xe5, 0x4a, 0x25, 0x15, 0xa1, 0x17, 0x9e, 0xbf, 0xc8, 0x25, 0xc9, 0x2b, - 0x1d, 0xfb, 0xe8, 0x2f, 0xd9, 0xd0, 0xe1, 0x87, 0xcb, 0x10, 0x3d, 0x53, 0x9a, 0x54, 0x0b, 0x56, - 0x9c, 0x5f, 0xc1, 0xbd, 0xef, 0x04, 0xdc, 0xdf, 0xa2, 0xe9, 0x42, 0x40, 0xa0, 0x79, 0xfb, 0x70, - 0x03, 0xcb, 0x8e, 0x0f, 0xcc, 0x6f, 0x04, 0x30, 0x51, 0x95, 0x07, 0x74, 0x3e, 0x18, 0xce, 0xc7, - 0x93, 0xb6, 0x51, 0x0d, 0xe2, 0xe9, 0x84, 0x6f, 0x05, 0xf2, 0x64, 0xd9, 0xf1, 0x50, 0x2a, 0x50, - 0x1e, 0xdf, 0xca, 0x9e, 0x04, 0xb0, 0x42, 0xb0, 0xf4, 0x61, 0x70, 0xac, 0xe9, 0x55, 0x84, 0x94, - 0xeb, 0x93, 0xd2, 0xde, 0x2d, 0x76, 0x4c, 0x24, 0xfd, 0x66, 0x50, 0xa4, 0xe9, 0xef, 0x7d, 0x48, - 0x7b, 0x7e, 0x06, 0x0a, 0x62, 0xc8, 0x18, 0xe7, 0x5b, 0x13, 0x80, 0x4d, 0xc7, 0xbf, 0x06, 0xb0, - 0x7c, 0x2b, 0x61, 0xfd, 0x4c, 0x8c, 0x31, 0xf4, 0x93, 0xdb, 0x31, 0xa6, 0xf5, 0x0a, 0x24, 0x8d, - 0xcd, 0x01, 0xe3, 0xd7, 0x8c, 0x00, 0xe8, 0xdd, 0x5b, 0x00, 0x56, 0xed, 0x39, 0x6e, 0xac, 0xdf, - 0xb8, 0xa5, 0x29, 0xc1, 0xf9, 0x6b, 0xcf, 0xe7, 0x96, 0xb5, 0x05, 0x2b, 0xce, 0xab, 0x51, 0xdf, - 0x5e, 0x3a, 0x80, 0xfe, 0x93, 0xd7, 0xef, 0xea, 0x70, 0x2c, 0x74, 0xeb, 0x7d, 0xdf, 0x6d, 0x42, - 0xb7, 0x60, 0x6f, 0x15, 0xba, 0xc7, 0xdd, 0x13, 0xf5, 0x1e, 0xac, 0xba, 0xef, 0x9d, 0xbe, 0x13, - 0xcc, 0x90, 0x96, 0x38, 0x0e, 0x02, 0x43, 0xfd, 0x5d, 0x6a, 0xe9, 0x23, 0xa0, 0x4b, 0x2d, 0x83, - 0x1c, 0x04, 0x86, 0x9a, 0x2e, 0x7f, 0x0f, 0xeb, 0xde, 0x47, 0xa6, 0xfd, 0x60, 0xb6, 0x8c, 0x29, - 0x76, 0x3c, 0x11, 0xdc, 0xdf, 0xbd, 0x31, 0x29, 0x02, 0xba, 0x37, 0xa6, 0xc8, 0xf1, 0x44, 0x70, - 0xd3, 0xfd, 0xef, 0x60, 0xcd, 0x73, 0x27, 0xf4, 0xbd, 0x80, 0xa3, 0xc1, 0x68, 0xfa, 0x68, 0x12, - 0xb4, 0xe1, 0xbb, 0x58, 0xf9, 0xfc, 0x65, 0x36, 0xfc, 0xc5, 0xcb, 0x6c, 0xf8, 0xab, 0x97, 0xd9, - 0xf0, 0xc7, 0xaf, 0xb2, 0xa1, 0x2f, 0x5e, 0x65, 0x43, 0x5f, 0xbe, 0xca, 0x86, 0x9e, 0xbd, 0xdd, - 0x14, 0xd4, 0x9b, 0xde, 0x75, 0x9e, 0x97, 0x3a, 0x05, 0x5e, 0x52, 0x3a, 0x92, 0x52, 0x10, 0xae, - 0xf9, 0xfd, 0xa6, 0x54, 0xe8, 0x1f, 0x15, 0x3a, 0x52, 0xa3, 0xd7, 0x46, 0x8a, 0xfe, 0x37, 0xb3, - 0x37, 0x8f, 0xf6, 0x8d, 0x7f, 0x9a, 0xa9, 0x83, 0x2e, 0x52, 0xae, 0x13, 0xf8, 0x5f, 0x66, 0x6f, - 0xfd, 0x37, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xc0, 0xd1, 0x87, 0x17, 0x27, 0x00, 0x00, + 0xb6, 0x96, 0x62, 0x67, 0x17, 0x41, 0x16, 0x2d, 0x0a, 0x4b, 0x55, 0x50, 0xa3, 0xf5, 0x03, 0x94, + 0xdc, 0xa2, 0xdb, 0xa2, 0xaa, 0x4c, 0x4d, 0x64, 0x42, 0x12, 0xa9, 0x90, 0x94, 0x12, 0x15, 0xe8, + 0xe3, 0x12, 0x20, 0xd8, 0x53, 0xce, 0x01, 0x16, 0x48, 0xd1, 0x53, 0xd1, 0x43, 0xf3, 0x67, 0x04, + 0x3d, 0xe5, 0xd6, 0xb4, 0x07, 0x61, 0xb1, 0x7b, 0xe9, 0x59, 0x7f, 0x41, 0xc1, 0xe1, 0x90, 0xe2, + 0x73, 0x4d, 0x79, 0x2d, 0x79, 0x9b, 0x93, 0xc8, 0x99, 0xdf, 0x7c, 0xdf, 0xcc, 0xef, 0xfb, 0xcd, + 0x37, 0x0f, 0x0a, 0xb6, 0x84, 0x4b, 0xbe, 0xc0, 0x4b, 0x32, 0x2a, 0xf0, 0x57, 0x75, 0x51, 0x44, + 0xed, 0x42, 0xff, 0xa0, 0xa0, 0x7e, 0x9c, 0xef, 0xca, 0x92, 0x2a, 0x51, 0x69, 0xe1, 0x92, 0xcf, + 0x6b, 0xb5, 0x79, 0x52, 0x9b, 0xef, 0x1f, 0xd0, 0x6b, 0x4d, 0xa9, 0x29, 0xe1, 0xfa, 0x82, 0xf6, + 0xa4, 0x43, 0x69, 0x66, 0x6c, 0xa8, 0x2d, 0x20, 0x51, 0xd5, 0xec, 0xe8, 0x4f, 0x04, 0xb0, 0xe3, + 0xe5, 0xc9, 0x30, 0xfb, 0x0a, 0x48, 0xaf, 0xdb, 0x94, 0xeb, 0x0d, 0xa4, 0x43, 0xd8, 0xbf, 0x84, + 0x81, 0x3a, 0x51, 0x9a, 0x25, 0xbd, 0xfe, 0xac, 0x8b, 0xc4, 0x63, 0x51, 0x50, 0xa9, 0xef, 0x43, + 0xb2, 0x2b, 0xc9, 0x6a, 0x4d, 0x68, 0x64, 0xc2, 0xb9, 0xf0, 0xde, 0x7c, 0x91, 0x1a, 0x0d, 0x99, + 0xe5, 0x41, 0xbd, 0xd3, 0x7e, 0xcc, 0x92, 0x0a, 0x96, 0x4b, 0x68, 0x4f, 0xc7, 0x0d, 0xea, 0x87, + 0x90, 0x24, 0xf6, 0x33, 0x91, 0x5c, 0x78, 0x6f, 0xe1, 0x70, 0x2b, 0xef, 0x31, 0xce, 0x3c, 0xf1, + 0x51, 0x8c, 0x7d, 0x35, 0x64, 0x42, 0x9c, 0xd1, 0x84, 0xda, 0x80, 0x84, 0x22, 0x34, 0x45, 0x24, + 0x67, 0xa2, 0x9a, 0x27, 0x8e, 0xbc, 0x3d, 0x9e, 0xfb, 0xf4, 0x0b, 0x26, 0xf4, 0xdf, 0x2f, 0x98, + 0x10, 0xdb, 0x06, 0xda, 0xdd, 0x45, 0x0e, 0x29, 0x5d, 0x49, 0x54, 0x10, 0xf5, 0x10, 0x80, 0x98, + 0x1a, 0xf7, 0x76, 0x7d, 0x34, 0x64, 0x56, 0xf5, 0xde, 0x8e, 0xeb, 0x58, 0x6e, 0x9e, 0xbc, 0x1c, + 0x37, 0xa8, 0x0c, 0x24, 0xfb, 0x48, 0x56, 0x04, 0x49, 0xc4, 0x7d, 0x9e, 0xe7, 0x8c, 0x57, 0xf6, + 0x9b, 0x28, 0xac, 0xda, 0xdd, 0x55, 0xe5, 0xc1, 0x64, 0x84, 0x9c, 0x43, 0xba, 0x2b, 0xa3, 0xbe, + 0x20, 0xf5, 0x94, 0x9a, 0xa5, 0x6f, 0xd8, 0x51, 0x31, 0x37, 0x1a, 0x32, 0x34, 0x69, 0xe8, 0x06, + 0xb1, 0x99, 0x30, 0xb7, 0x6a, 0x94, 0x97, 0xcc, 0xee, 0x5a, 0x28, 0x8e, 0x4e, 0x4e, 0x31, 0x07, + 0x6b, 0xbc, 0xd4, 0x13, 0x55, 0x24, 0x77, 0xeb, 0xb2, 0x3a, 0xa8, 0x19, 0x23, 0x8f, 0xe1, 0x0e, + 0x31, 0xa3, 0x21, 0xb3, 0x49, 0xc8, 0xf2, 0x40, 0xb1, 0x5c, 0xda, 0x5a, 0xfc, 0x0b, 0xbd, 0x54, + 0xa3, 0xbd, 0x2b, 0x4b, 0xd2, 0x07, 0x35, 0x41, 0x14, 0xd4, 0x4c, 0x3c, 0x17, 0xde, 0x5b, 0xb4, + 0xd2, 0x3e, 0xae, 0x63, 0xb9, 0x79, 0xfc, 0x82, 0x75, 0xf5, 0x04, 0x16, 0xf5, 0x9a, 0x2b, 0x24, + 0x34, 0xaf, 0xd4, 0x4c, 0x02, 0x0f, 0x86, 0xb6, 0x0c, 0x46, 0x97, 0x78, 0xff, 0x20, 0xff, 0x53, + 0x8c, 0x28, 0x6e, 0x6a, 0x43, 0x19, 0x0d, 0x99, 0xb4, 0xd5, 0xae, 0xde, 0x9a, 0xe5, 0x16, 0xf0, + 0xab, 0x8e, 0xb4, 0x08, 0x29, 0xe9, 0x23, 0xa4, 0x16, 0xdc, 0x77, 0x45, 0xd6, 0xd4, 0x91, 0x45, + 0x11, 0x61, 0x9b, 0x22, 0x1c, 0x0a, 0x8b, 0x04, 0x53, 0x18, 0xfb, 0x2f, 0x97, 0x8e, 0x8e, 0xf8, + 0xd6, 0x64, 0x3a, 0xba, 0x91, 0x63, 0xea, 0x09, 0xdc, 0xb3, 0xc5, 0xd1, 0x62, 0x02, 0xcf, 0xb0, + 0x22, 0x3b, 0x1a, 0x32, 0x59, 0x8f, 0x80, 0x5b, 0xed, 0xad, 0x5b, 0x6b, 0xc6, 0x3a, 0x9c, 0x86, + 0x92, 0x0e, 0x40, 0x17, 0x48, 0x4d, 0x95, 0x07, 0x44, 0x48, 0x6b, 0xa3, 0x21, 0x93, 0xb2, 0x06, + 0x5c, 0x95, 0x07, 0x2c, 0x37, 0x87, 0x9f, 0xb5, 0xd9, 0x78, 0xb7, 0x32, 0xda, 0x74, 0xca, 0xe8, + 0x88, 0x6f, 0x19, 0x32, 0x62, 0xff, 0x1e, 0x81, 0x75, 0x7b, 0x6d, 0x49, 0x12, 0x3f, 0x10, 0xe4, + 0xce, 0x2c, 0x42, 0x6f, 0x52, 0x59, 0xe7, 0x5b, 0x38, 0xd8, 0x1e, 0x54, 0xd6, 0xf9, 0x96, 0x41, + 0xa5, 0x26, 0x48, 0x27, 0x95, 0xb1, 0xa9, 0x50, 0x19, 0xf7, 0xa1, 0x92, 0x81, 0x6d, 0x4f, 0xb2, + 0x4c, 0x3a, 0x3f, 0x0f, 0x43, 0x7a, 0x8c, 0x28, 0xb5, 0x25, 0x05, 0x4d, 0xbe, 0x40, 0xdd, 0x8c, + 0xcc, 0xeb, 0x17, 0xa6, 0x6d, 0xd8, 0xf4, 0xe8, 0x9b, 0xd9, 0xf7, 0x7f, 0x44, 0x60, 0xc3, 0x51, + 0x3f, 0x43, 0x2d, 0xd8, 0x13, 0x74, 0xf4, 0x86, 0x09, 0x7a, 0xb6, 0x72, 0xc8, 0x41, 0xd6, 0x9b, + 0x30, 0x93, 0xd3, 0xcf, 0x22, 0xb0, 0x74, 0xa2, 0x34, 0x39, 0xc4, 0xf7, 0xcf, 0xeb, 0x7c, 0x0b, + 0xa9, 0xd4, 0x7b, 0x90, 0xe8, 0xe2, 0x27, 0xcc, 0xe4, 0xc2, 0xe1, 0xa6, 0xe7, 0xca, 0xa8, 0x83, + 0xc9, 0xc2, 0x48, 0x1a, 0x50, 0xef, 0x43, 0x4a, 0xef, 0x2e, 0x2f, 0x75, 0x3a, 0x82, 0xda, 0x41, + 0xa2, 0x8a, 0xe9, 0x5d, 0x2c, 0x6e, 0x8e, 0x86, 0xcc, 0x3d, 0xeb, 0x80, 0xc6, 0x08, 0x96, 0x5b, + 0xc1, 0x45, 0x25, 0xb3, 0xc4, 0x45, 0x5a, 0x74, 0x2a, 0xa4, 0xc5, 0x7c, 0x48, 0xfb, 0x2d, 0x4e, + 0x38, 0x63, 0x46, 0xcc, 0x15, 0xed, 0xc7, 0x90, 0x90, 0x91, 0xd2, 0x6b, 0xeb, 0xcc, 0x2c, 0x1f, + 0xee, 0x7a, 0x32, 0x63, 0xc0, 0x39, 0x0c, 0xad, 0x0e, 0xba, 0x88, 0x23, 0xcd, 0x1e, 0xc7, 0x34, + 0x1f, 0xec, 0x7f, 0x22, 0x00, 0x27, 0x4a, 0xb3, 0x2a, 0x74, 0x90, 0xd4, 0xbb, 0x1d, 0xbe, 0x7b, + 0xa2, 0x8c, 0x78, 0x24, 0xf4, 0x51, 0xc3, 0x8f, 0xef, 0x31, 0xc2, 0xe0, 0xfb, 0xc2, 0x2c, 0x99, + 0x2a, 0xdf, 0x3f, 0x03, 0x4a, 0x44, 0x1f, 0xab, 0x35, 0x05, 0x7d, 0xd8, 0x43, 0x22, 0x8f, 0x6a, + 0x32, 0xe2, 0xfb, 0x98, 0xfb, 0x58, 0x71, 0x7b, 0x34, 0x64, 0xee, 0xeb, 0x16, 0xdc, 0x18, 0x96, + 0x4b, 0x69, 0x85, 0x15, 0x52, 0xa6, 0xc5, 0x23, 0x80, 0xe2, 0x7f, 0x8d, 0xb7, 0xdf, 0x84, 0xdb, + 0xdb, 0x8e, 0xdc, 0xe7, 0xfa, 0x16, 0x84, 0x58, 0x3f, 0x13, 0xf1, 0x8c, 0x7a, 0x13, 0x02, 0xf8, + 0x2e, 0x2c, 0x90, 0x69, 0xa5, 0xf5, 0x88, 0x24, 0xa7, 0x8d, 0xd1, 0x90, 0xa1, 0x6c, 0x73, 0x4e, + 0xab, 0x64, 0x39, 0x3d, 0x8d, 0xe9, 0x7d, 0x9f, 0x66, 0x7a, 0xf2, 0x8e, 0x7c, 0xfc, 0x75, 0x23, + 0x9f, 0xf0, 0x89, 0xfc, 0x25, 0xde, 0x45, 0xd8, 0x63, 0x73, 0xdb, 0x02, 0xf8, 0x32, 0x82, 0xe5, + 0x75, 0xc4, 0xb7, 0x44, 0xe9, 0xa3, 0x36, 0x6a, 0x34, 0x11, 0xce, 0x57, 0xaf, 0xa1, 0x80, 0x3d, + 0x58, 0xa9, 0xdb, 0xad, 0xe9, 0x02, 0xe0, 0x9c, 0xc5, 0xe3, 0x18, 0x6b, 0x0d, 0x1b, 0x7e, 0x31, + 0xc6, 0x95, 0x46, 0x8c, 0x8f, 0xb4, 0x97, 0x3b, 0x5e, 0x82, 0x78, 0x7c, 0xd8, 0x74, 0x30, 0x76, + 0xdb, 0x71, 0xf9, 0x67, 0xd4, 0xba, 0x49, 0xbc, 0xd0, 0x4f, 0xe4, 0xb3, 0xda, 0xd7, 0xfc, 0x09, + 0x32, 0x5d, 0x59, 0xea, 0x4a, 0x0a, 0x6a, 0xd4, 0xc8, 0x65, 0x40, 0x6d, 0x92, 0xc3, 0xe5, 0x2e, + 0x61, 0x9b, 0x31, 0xd9, 0xf6, 0xb4, 0xc5, 0x72, 0x1b, 0x46, 0x15, 0x19, 0x20, 0x31, 0x40, 0xfd, + 0x0e, 0x96, 0x55, 0x5d, 0xf6, 0xc1, 0x43, 0xbc, 0x4d, 0x9c, 0xae, 0xeb, 0x4e, 0xed, 0xed, 0x59, + 0x6e, 0x89, 0x14, 0x90, 0x30, 0x1f, 0xc3, 0xaa, 0x81, 0xd0, 0x7e, 0x15, 0xb5, 0xde, 0xe9, 0x92, + 0x99, 0xbc, 0x35, 0x1a, 0x32, 0x19, 0xbb, 0x11, 0x13, 0xc2, 0x72, 0x29, 0x52, 0x56, 0x35, 0x8a, + 0x02, 0x4c, 0x64, 0xdb, 0x1e, 0xd6, 0x12, 0x4b, 0x73, 0xcf, 0xf2, 0x3c, 0x09, 0x6b, 0x2e, 0xc4, + 0xc4, 0x97, 0x0a, 0x37, 0x0b, 0xb6, 0xea, 0x38, 0xb0, 0x4d, 0x12, 0xe8, 0xef, 0x10, 0xce, 0x37, + 0xfd, 0xcf, 0x8a, 0x8e, 0x23, 0x9d, 0x11, 0xe1, 0x0b, 0xb0, 0x9d, 0x1f, 0xcd, 0x74, 0x49, 0xd6, + 0xd1, 0xdc, 0x68, 0xc8, 0x6c, 0x79, 0x18, 0x35, 0x60, 0x2c, 0x67, 0xeb, 0xb4, 0x91, 0x58, 0x5f, + 0xa9, 0xdc, 0xf8, 0xdd, 0x28, 0x37, 0x31, 0x0b, 0xe5, 0x26, 0x6f, 0xa4, 0xdc, 0x1f, 0xc1, 0x12, + 0x59, 0x47, 0x09, 0x45, 0x73, 0x38, 0x05, 0x67, 0x46, 0x43, 0x66, 0xcd, 0xb6, 0xcc, 0x1a, 0xa3, + 0xd6, 0xd3, 0xae, 0x31, 0xd6, 0x2a, 0xac, 0x93, 0x95, 0x9c, 0xb0, 0x43, 0x1c, 0x64, 0xe6, 0xb1, + 0x19, 0x4b, 0x0c, 0x3d, 0x61, 0x2c, 0x97, 0xd6, 0x57, 0x7d, 0x22, 0x77, 0xb2, 0x7b, 0xfc, 0x25, + 0x6c, 0xd8, 0xe1, 0xa6, 0x34, 0x00, 0x9b, 0xdd, 0x19, 0x0d, 0x99, 0x6d, 0x2f, 0xb3, 0x16, 0x6d, + 0x58, 0xed, 0x9a, 0xda, 0x70, 0xae, 0x1a, 0x0b, 0x53, 0x59, 0x35, 0x16, 0x7d, 0x72, 0x40, 0x16, + 0xb6, 0xbc, 0x66, 0xb8, 0x99, 0x02, 0x3e, 0x89, 0x79, 0xa4, 0x80, 0x19, 0xdd, 0x07, 0xdd, 0x4d, + 0x0a, 0x70, 0xa9, 0x2f, 0x36, 0x91, 0xfa, 0xfc, 0x75, 0x12, 0xbf, 0x5d, 0x9d, 0xcc, 0xf6, 0xea, + 0xc8, 0x4b, 0x27, 0xd6, 0xdb, 0xa3, 0x7f, 0xc7, 0x20, 0xe3, 0x02, 0xcc, 0xf0, 0xd2, 0xe0, 0xff, + 0x52, 0x2b, 0xa7, 0x90, 0xb6, 0x6b, 0x00, 0xc9, 0xb2, 0x24, 0x13, 0xa1, 0x64, 0xad, 0xd7, 0xed, + 0x2e, 0x10, 0xcb, 0xad, 0x5a, 0x55, 0x52, 0xd6, 0xca, 0x5e, 0xa1, 0xbd, 0xc4, 0xed, 0x6a, 0x2f, + 0x39, 0x15, 0xed, 0xcd, 0xf9, 0x68, 0x8f, 0x85, 0x9c, 0x9f, 0xb4, 0x4c, 0xfd, 0xfd, 0x39, 0xee, + 0xa1, 0x3f, 0x23, 0x77, 0x7f, 0x6b, 0xf5, 0xf7, 0x47, 0x2d, 0xe0, 0xe4, 0x53, 0x0c, 0x96, 0x45, + 0x0d, 0x9f, 0x54, 0xbb, 0xc6, 0xc6, 0x74, 0xc7, 0xd3, 0x2f, 0x16, 0x0b, 0xa7, 0x03, 0x8b, 0xdf, + 0x25, 0xce, 0xb7, 0x1d, 0x5f, 0x76, 0x6c, 0xe6, 0xb0, 0x2e, 0xf4, 0x0a, 0x6b, 0x63, 0xb7, 0xfe, + 0xe3, 0x37, 0xd3, 0xbf, 0xbd, 0xef, 0x09, 0x6f, 0xfd, 0x3b, 0x7a, 0xa4, 0xeb, 0xdf, 0xd6, 0x9d, + 0x37, 0x4f, 0xa6, 0x8e, 0xfb, 0x11, 0xf6, 0xcb, 0x28, 0xdc, 0x73, 0x6b, 0xb9, 0x2e, 0xf2, 0xa8, + 0x3d, 0x0b, 0x95, 0x36, 0x60, 0xc9, 0x4e, 0x75, 0x34, 0xa8, 0x4c, 0xb6, 0x08, 0x51, 0x24, 0xac, + 0x8e, 0x58, 0x2c, 0x22, 0x6b, 0x18, 0x7c, 0xc2, 0x1a, 0xbb, 0xad, 0xb0, 0xc6, 0xa7, 0x12, 0x56, + 0xbf, 0x53, 0xd2, 0x0e, 0x30, 0x3e, 0x11, 0x33, 0xa2, 0xfa, 0xe0, 0x6f, 0x61, 0xa0, 0xdc, 0x47, + 0x67, 0xea, 0x11, 0xe4, 0xb8, 0x72, 0xe5, 0xfc, 0xec, 0xb4, 0x52, 0xae, 0x71, 0xe5, 0xca, 0xc5, + 0xcf, 0xab, 0xb5, 0xea, 0xaf, 0xce, 0xcb, 0xb5, 0x8b, 0xd3, 0xca, 0x79, 0xb9, 0x74, 0xfc, 0xfe, + 0x71, 0xf9, 0x27, 0xa9, 0x10, 0xbd, 0xf2, 0xf4, 0x59, 0x6e, 0xc1, 0x52, 0x44, 0xed, 0xc2, 0x7d, + 0xcf, 0x66, 0xa7, 0x67, 0x67, 0xe7, 0xa9, 0x30, 0x3d, 0xf7, 0xf4, 0x59, 0x2e, 0xa6, 0x3d, 0x53, + 0xfb, 0xb0, 0xe5, 0x09, 0xac, 0x5c, 0x94, 0x4a, 0xe5, 0x4a, 0x25, 0x15, 0xa1, 0x17, 0x9e, 0x3e, + 0xcb, 0x25, 0xc9, 0x2b, 0x1d, 0xfb, 0xf4, 0xaf, 0xd9, 0xd0, 0xe1, 0x27, 0xcb, 0x10, 0x3d, 0x51, + 0x9a, 0x54, 0x0b, 0x56, 0x9c, 0xdf, 0xce, 0xbd, 0xef, 0x04, 0xdc, 0x5f, 0xb0, 0xe9, 0x42, 0x40, + 0xa0, 0x79, 0xfb, 0x70, 0x05, 0xcb, 0x8e, 0xcf, 0xd2, 0x6f, 0x05, 0x30, 0x51, 0x95, 0x07, 0x74, + 0x3e, 0x18, 0xce, 0xc7, 0x93, 0xb6, 0x51, 0x0d, 0xe2, 0xe9, 0x88, 0x6f, 0x05, 0xf2, 0x64, 0xd9, + 0xf1, 0x50, 0x2a, 0x50, 0x1e, 0xdf, 0xca, 0x1e, 0x04, 0xb0, 0x42, 0xb0, 0xf4, 0x61, 0x70, 0xac, + 0xe9, 0x55, 0x84, 0x94, 0xeb, 0x93, 0xd2, 0xde, 0x35, 0x76, 0x4c, 0x24, 0xfd, 0x76, 0x50, 0xa4, + 0xe9, 0xef, 0x23, 0x48, 0x7b, 0x7e, 0x06, 0x0a, 0x62, 0xc8, 0x18, 0xe7, 0x3b, 0x13, 0x80, 0x4d, + 0xc7, 0xbf, 0x01, 0xb0, 0x7c, 0x2b, 0x61, 0xfd, 0x4c, 0x8c, 0x31, 0xf4, 0x83, 0xeb, 0x31, 0xa6, + 0xf5, 0x0a, 0x24, 0x8d, 0xcd, 0x01, 0xe3, 0xd7, 0x8c, 0x00, 0xe8, 0xdd, 0x6b, 0x00, 0x56, 0xed, + 0x39, 0x6e, 0xac, 0xdf, 0xba, 0xa6, 0x29, 0xc1, 0xf9, 0x6b, 0xcf, 0xe7, 0x96, 0xb5, 0x05, 0x2b, + 0xce, 0xab, 0x51, 0xdf, 0x5e, 0x3a, 0x80, 0xfe, 0x93, 0xd7, 0xef, 0xea, 0x70, 0x2c, 0x74, 0xeb, + 0x7d, 0xdf, 0x75, 0x42, 0xb7, 0x60, 0xaf, 0x15, 0xba, 0xc7, 0xdd, 0x13, 0xf5, 0x21, 0xac, 0xba, + 0xef, 0x9d, 0xbe, 0x17, 0xcc, 0x90, 0x96, 0x38, 0x0e, 0x02, 0x43, 0xfd, 0x5d, 0x6a, 0xe9, 0x23, + 0xa0, 0x4b, 0x2d, 0x83, 0x1c, 0x04, 0x86, 0x9a, 0x2e, 0xff, 0x00, 0xeb, 0xde, 0x47, 0xa6, 0xfd, + 0x60, 0xb6, 0x8c, 0x29, 0xf6, 0x68, 0x22, 0xb8, 0xbf, 0x7b, 0x63, 0x52, 0x04, 0x74, 0x6f, 0x4c, + 0x91, 0x47, 0x13, 0xc1, 0x4d, 0xf7, 0xbf, 0x87, 0x35, 0xcf, 0x9d, 0xd0, 0x0f, 0x02, 0x8e, 0x06, + 0xa3, 0xe9, 0x87, 0x93, 0xa0, 0x0d, 0xdf, 0xc5, 0xca, 0x57, 0x2f, 0xb2, 0xe1, 0xaf, 0x5f, 0x64, + 0xc3, 0xcf, 0x5f, 0x64, 0xc3, 0x9f, 0xbd, 0xcc, 0x86, 0xbe, 0x7e, 0x99, 0x0d, 0x7d, 0xf3, 0x32, + 0x1b, 0x7a, 0xf2, 0x5e, 0x53, 0x50, 0xaf, 0x7a, 0x97, 0x79, 0x5e, 0xea, 0x14, 0x78, 0x49, 0xe9, + 0x48, 0x4a, 0x41, 0xb8, 0xe4, 0xf7, 0x9b, 0x52, 0xa1, 0xff, 0x6e, 0xa1, 0x23, 0x35, 0x7a, 0x6d, + 0xa4, 0xe8, 0x7f, 0x4e, 0x7b, 0xfb, 0xe1, 0xbe, 0xf1, 0xff, 0x34, 0x75, 0xd0, 0x45, 0xca, 0x65, + 0x02, 0xff, 0x37, 0xed, 0x9d, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x39, 0xbb, 0x93, 0xd7, 0x4d, + 0x27, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2377,6 +2386,13 @@ func (m *MsgChannelOpenTryResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l + if len(m.ChannelId) > 0 { + i -= len(m.ChannelId) + copy(dAtA[i:], m.ChannelId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChannelId))) + i-- + dAtA[i] = 0x12 + } if len(m.Version) > 0 { i -= len(m.Version) copy(dAtA[i:], m.Version) @@ -3818,6 +3834,10 @@ func (m *MsgChannelOpenTryResponse) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -4982,6 +5002,38 @@ func (m *MsgChannelOpenTryResponse) Unmarshal(dAtA []byte) error { } m.Version = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", 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.ChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/modules/core/04-channel/types/upgrade.pb.go b/modules/core/04-channel/types/upgrade.pb.go index 7d4674d801e..9057d650154 100644 --- a/modules/core/04-channel/types/upgrade.pb.go +++ b/modules/core/04-channel/types/upgrade.pb.go @@ -5,9 +5,9 @@ package types import ( fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" io "io" math "math" math_bits "math/bits" @@ -145,28 +145,28 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/upgrade.proto", fileDescriptor_fb1cef68588848b2) } var fileDescriptor_fb1cef68588848b2 = []byte{ - // 334 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xb1, 0x4e, 0xf3, 0x30, - 0x14, 0x85, 0xe3, 0x5f, 0xfd, 0x11, 0x18, 0xa8, 0x20, 0x14, 0xa9, 0x8a, 0x20, 0x29, 0x99, 0xba, - 0xd4, 0xa6, 0xd0, 0x05, 0x26, 0x54, 0x09, 0x09, 0xd6, 0x50, 0x16, 0x16, 0x48, 0xdc, 0xab, 0xc4, - 0x52, 0x12, 0x87, 0xc4, 0x89, 0xd4, 0xb7, 0xe0, 0x85, 0xd8, 0x3b, 0x76, 0x64, 0xaa, 0x50, 0xfb, - 0x06, 0x7d, 0x02, 0x94, 0xb8, 0x4d, 0xd5, 0xc9, 0xe7, 0x1e, 0x7f, 0x3e, 0xd7, 0xba, 0x17, 0x5f, - 0x71, 0x8f, 0x51, 0x26, 0x52, 0xa0, 0x2c, 0x70, 0xe3, 0x18, 0x42, 0x5a, 0xf4, 0x69, 0x9e, 0xf8, - 0xa9, 0x3b, 0x06, 0x92, 0xa4, 0x42, 0x0a, 0xfd, 0x8c, 0x7b, 0x8c, 0x94, 0x08, 0x59, 0x23, 0xa4, - 0xe8, 0x1b, 0x2d, 0x5f, 0xf8, 0xa2, 0xba, 0xa7, 0xa5, 0x52, 0xa8, 0x61, 0x6d, 0xd3, 0x42, 0x0e, - 0xb1, 0x2c, 0xc3, 0x94, 0x52, 0x80, 0xfd, 0x8d, 0x70, 0xf3, 0x55, 0xa5, 0x8f, 0x78, 0x04, 0x22, - 0x97, 0xfa, 0x07, 0x6e, 0x4a, 0x25, 0xdf, 0x03, 0xe0, 0x7e, 0x20, 0xdb, 0xa8, 0x83, 0xba, 0x87, - 0x37, 0x06, 0xd9, 0xf6, 0x55, 0x11, 0x45, 0x9f, 0x3c, 0x55, 0xc4, 0xf0, 0x72, 0x3a, 0xb7, 0xb4, - 0xd5, 0xdc, 0x3a, 0x9f, 0xb8, 0x51, 0x78, 0x6f, 0xef, 0xbe, 0xb7, 0x9d, 0xe3, 0xb5, 0xa1, 0x68, - 0xfd, 0x19, 0x9f, 0x6e, 0x88, 0xf2, 0xcc, 0xa4, 0x1b, 0x25, 0xed, 0x7f, 0x1d, 0xd4, 0x6d, 0x0c, - 0x2f, 0x56, 0x73, 0xab, 0xbd, 0x1b, 0x52, 0x23, 0xb6, 0x73, 0xb2, 0xf6, 0x46, 0xb5, 0xf5, 0x80, - 0x8f, 0x1e, 0xd3, 0x54, 0xa4, 0x0e, 0x30, 0xe0, 0x89, 0xd4, 0x0d, 0xbc, 0x9f, 0xc1, 0x67, 0x0e, - 0x31, 0x83, 0xea, 0xdb, 0x0d, 0xa7, 0xae, 0xf5, 0x16, 0xfe, 0x0f, 0x25, 0x5b, 0xb5, 0x3a, 0x70, - 0x54, 0x31, 0x7c, 0x99, 0x2e, 0x4c, 0x34, 0x5b, 0x98, 0xe8, 0x77, 0x61, 0xa2, 0xaf, 0xa5, 0xa9, - 0xcd, 0x96, 0xa6, 0xf6, 0xb3, 0x34, 0xb5, 0xb7, 0x3b, 0x9f, 0xcb, 0x20, 0xf7, 0x08, 0x13, 0x11, - 0x65, 0x22, 0x8b, 0x44, 0x46, 0xb9, 0xc7, 0x7a, 0xbe, 0xa0, 0xc5, 0x80, 0x46, 0x62, 0x9c, 0x87, - 0x90, 0xa9, 0xe1, 0x5e, 0x0f, 0x7a, 0x9b, 0x6d, 0xc9, 0x49, 0x02, 0x99, 0xb7, 0x57, 0x4d, 0xf7, - 0xf6, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x94, 0x8d, 0xab, 0x07, 0xce, 0x01, 0x00, 0x00, + // 335 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xc1, 0x4a, 0xf3, 0x40, + 0x14, 0x85, 0x33, 0x3f, 0xfd, 0x45, 0x47, 0x2d, 0x1a, 0x2b, 0x94, 0xa0, 0x49, 0xcd, 0xaa, 0x9b, + 0xce, 0x58, 0x15, 0x44, 0x57, 0x52, 0x10, 0x74, 0x1b, 0xeb, 0xc6, 0x8d, 0x26, 0xd3, 0x4b, 0x32, + 0x90, 0x64, 0x62, 0x32, 0x09, 0xf4, 0x2d, 0x7c, 0x21, 0xf7, 0x5d, 0x76, 0xe9, 0xaa, 0x48, 0xfb, + 0x06, 0x7d, 0x02, 0x49, 0xa6, 0x4d, 0xe9, 0x6a, 0xce, 0x3d, 0xf3, 0xcd, 0xb9, 0xc3, 0xbd, 0xf8, + 0x82, 0x7b, 0x8c, 0x32, 0x91, 0x02, 0x65, 0x81, 0x1b, 0xc7, 0x10, 0xd2, 0xa2, 0x4f, 0xf3, 0xc4, + 0x4f, 0xdd, 0x11, 0x90, 0x24, 0x15, 0x52, 0xe8, 0x27, 0xdc, 0x63, 0xa4, 0x44, 0xc8, 0x0a, 0x21, + 0x45, 0xdf, 0x68, 0xf9, 0xc2, 0x17, 0xd5, 0x3d, 0x2d, 0x95, 0x42, 0x0d, 0x6b, 0x93, 0x16, 0x72, + 0x88, 0x65, 0x19, 0xa6, 0x94, 0x02, 0xec, 0x6f, 0x84, 0x9b, 0xaf, 0x2a, 0x7d, 0xc8, 0x23, 0x10, + 0xb9, 0xd4, 0x3f, 0x70, 0x53, 0x2a, 0xf9, 0x1e, 0x00, 0xf7, 0x03, 0xd9, 0x46, 0x1d, 0xd4, 0xdd, + 0xbf, 0x32, 0xc8, 0xa6, 0xaf, 0x8a, 0x28, 0xfa, 0xe4, 0xa9, 0x22, 0x06, 0xe7, 0x93, 0x99, 0xa5, + 0x2d, 0x67, 0xd6, 0xe9, 0xd8, 0x8d, 0xc2, 0x7b, 0x7b, 0xfb, 0xbd, 0xed, 0x1c, 0xae, 0x0c, 0x45, + 0xeb, 0xcf, 0xf8, 0x78, 0x4d, 0x94, 0x67, 0x26, 0xdd, 0x28, 0x69, 0xff, 0xeb, 0xa0, 0x6e, 0x63, + 0x70, 0xb6, 0x9c, 0x59, 0xed, 0xed, 0x90, 0x1a, 0xb1, 0x9d, 0xa3, 0x95, 0x37, 0xac, 0xad, 0x07, + 0x7c, 0xf0, 0x98, 0xa6, 0x22, 0x75, 0x80, 0x01, 0x4f, 0xa4, 0x6e, 0xe0, 0xdd, 0x0c, 0x3e, 0x73, + 0x88, 0x19, 0x54, 0xdf, 0x6e, 0x38, 0x75, 0xad, 0xb7, 0xf0, 0x7f, 0x28, 0xd9, 0xaa, 0xd5, 0x9e, + 0xa3, 0x8a, 0xc1, 0xcb, 0x64, 0x6e, 0xa2, 0xe9, 0xdc, 0x44, 0xbf, 0x73, 0x13, 0x7d, 0x2d, 0x4c, + 0x6d, 0xba, 0x30, 0xb5, 0x9f, 0x85, 0xa9, 0xbd, 0xdd, 0xf9, 0x5c, 0x06, 0xb9, 0x47, 0x98, 0x88, + 0x28, 0x13, 0x59, 0x24, 0x32, 0xca, 0x3d, 0xd6, 0xf3, 0x05, 0x2d, 0x6e, 0x69, 0x24, 0x46, 0x79, + 0x08, 0x99, 0x1a, 0xee, 0xe5, 0x4d, 0x6f, 0xbd, 0x2d, 0x39, 0x4e, 0x20, 0xf3, 0x76, 0xaa, 0xe9, + 0x5e, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x6f, 0x91, 0x30, 0xd4, 0xce, 0x01, 0x00, 0x00, } func (m *UpgradeTimeout) Marshal() (dAtA []byte, err error) { diff --git a/modules/core/05-port/doc.go b/modules/core/05-port/doc.go new file mode 100644 index 00000000000..0ff91c0fe47 --- /dev/null +++ b/modules/core/05-port/doc.go @@ -0,0 +1,7 @@ +/* +Package port implements the ICS 05 - Port Allocation specification +(https://github.com/cosmos/ibc/tree/main/spec/core/ics-005-port-allocation). This +concrete implementation defines types and methods with which modules can bind +to uniquely named ports allocated by the IBC handler. +*/ +package port diff --git a/modules/core/05-port/keeper/keeper.go b/modules/core/05-port/keeper/keeper.go index db65f384455..35b3f273af7 100644 --- a/modules/core/05-port/keeper/keeper.go +++ b/modules/core/05-port/keeper/keeper.go @@ -4,23 +4,23 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // Keeper defines the IBC connection keeper type Keeper struct { Router *types.Router - scopedKeeper capabilitykeeper.ScopedKeeper + scopedKeeper exported.ScopedKeeper } // NewKeeper creates a new IBC connection Keeper instance -func NewKeeper(sck capabilitykeeper.ScopedKeeper) Keeper { +func NewKeeper(sck exported.ScopedKeeper) Keeper { return Keeper{ scopedKeeper: sck, } @@ -28,7 +28,7 @@ func NewKeeper(sck capabilitykeeper.ScopedKeeper) Keeper { // Logger returns a module-specific logger. func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+host.ModuleName+"/"+types.SubModuleName) + return ctx.Logger().With("module", "x/"+exported.ModuleName+"/"+types.SubModuleName) } // IsBound checks a given port ID is already bounded. diff --git a/modules/core/05-port/keeper/keeper_test.go b/modules/core/05-port/keeper/keeper_test.go index fe2449b81be..c091a857474 100644 --- a/modules/core/05-port/keeper/keeper_test.go +++ b/modules/core/05-port/keeper/keeper_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - "github.com/cosmos/ibc-go/v4/modules/core/05-port/keeper" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/modules/core/05-port/keeper" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) var ( diff --git a/modules/core/05-port/module.go b/modules/core/05-port/module.go index dd13e8a1b1b..9c07da041c2 100644 --- a/modules/core/05-port/module.go +++ b/modules/core/05-port/module.go @@ -1,11 +1,10 @@ package port import ( - "github.com/gogo/protobuf/grpc" "github.com/spf13/cobra" - "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - "github.com/cosmos/ibc-go/v4/modules/core/client/cli" + "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + "github.com/cosmos/ibc-go/v7/modules/core/client/cli" ) // Name returns the IBC port ICS name. @@ -17,8 +16,3 @@ func Name() string { func GetQueryCmd() *cobra.Command { return cli.GetQueryCmd() } - -// RegisterQueryService registers the gRPC query service for IBC ports. -func RegisterQueryService(server grpc.Server, queryServer types.QueryServer) { - types.RegisterQueryServer(server, queryServer) -} diff --git a/modules/core/05-port/types/errors.go b/modules/core/05-port/types/errors.go index 23a2776f59d..1348dfc83b4 100644 --- a/modules/core/05-port/types/errors.go +++ b/modules/core/05-port/types/errors.go @@ -1,13 +1,13 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // IBC port sentinel errors var ( - ErrPortExists = sdkerrors.Register(SubModuleName, 2, "port is already binded") - ErrPortNotFound = sdkerrors.Register(SubModuleName, 3, "port not found") - ErrInvalidPort = sdkerrors.Register(SubModuleName, 4, "invalid port") - ErrInvalidRoute = sdkerrors.Register(SubModuleName, 5, "route not found") + ErrPortExists = errorsmod.Register(SubModuleName, 2, "port is already binded") + ErrPortNotFound = errorsmod.Register(SubModuleName, 3, "port not found") + ErrInvalidPort = errorsmod.Register(SubModuleName, 4, "invalid port") + ErrInvalidRoute = errorsmod.Register(SubModuleName, 5, "route not found") ) diff --git a/modules/core/05-port/types/module.go b/modules/core/05-port/types/module.go index 3f71e1d0339..9073a5778c1 100644 --- a/modules/core/05-port/types/module.go +++ b/modules/core/05-port/types/module.go @@ -4,8 +4,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + 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" ) // IBCModule defines an interface that implements all the callbacks @@ -110,8 +111,12 @@ type ICS4Wrapper interface { SendPacket( ctx sdk.Context, chanCap *capabilitytypes.Capability, - packet exported.PacketI, - ) error + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, + ) (sequence uint64, err error) WriteAcknowledgement( ctx sdk.Context, diff --git a/modules/core/05-port/types/query.go b/modules/core/05-port/types/query.go deleted file mode 100644 index 7da3fe678af..00000000000 --- a/modules/core/05-port/types/query.go +++ /dev/null @@ -1,9 +0,0 @@ -package types - -// NewQueryAppVersionResponse creates a new QueryAppVersionResponse instance -func NewQueryAppVersionResponse(portID, version string) *QueryAppVersionResponse { - return &QueryAppVersionResponse{ - PortId: portID, - Version: version, - } -} diff --git a/modules/core/05-port/types/query.pb.go b/modules/core/05-port/types/query.pb.go deleted file mode 100644 index 3d7b414c747..00000000000 --- a/modules/core/05-port/types/query.pb.go +++ /dev/null @@ -1,843 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: ibc/core/port/v1/query.proto - -package types - -import ( - context "context" - fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - grpc1 "github.com/gogo/protobuf/grpc" - proto "github.com/gogo/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// QueryAppVersionRequest is the request type for the Query/AppVersion RPC method -type QueryAppVersionRequest struct { - // port unique identifier - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` - // connection unique identifier - ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"` - // whether the channel is ordered or unordered - Ordering types.Order `protobuf:"varint,3,opt,name=ordering,proto3,enum=ibc.core.channel.v1.Order" json:"ordering,omitempty"` - // counterparty channel end - Counterparty *types.Counterparty `protobuf:"bytes,4,opt,name=counterparty,proto3" json:"counterparty,omitempty"` - // proposed version - ProposedVersion string `protobuf:"bytes,5,opt,name=proposed_version,json=proposedVersion,proto3" json:"proposed_version,omitempty"` -} - -func (m *QueryAppVersionRequest) Reset() { *m = QueryAppVersionRequest{} } -func (m *QueryAppVersionRequest) String() string { return proto.CompactTextString(m) } -func (*QueryAppVersionRequest) ProtoMessage() {} -func (*QueryAppVersionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9a256596009a8334, []int{0} -} -func (m *QueryAppVersionRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryAppVersionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryAppVersionRequest.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 *QueryAppVersionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryAppVersionRequest.Merge(m, src) -} -func (m *QueryAppVersionRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryAppVersionRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryAppVersionRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryAppVersionRequest proto.InternalMessageInfo - -func (m *QueryAppVersionRequest) GetPortId() string { - if m != nil { - return m.PortId - } - return "" -} - -func (m *QueryAppVersionRequest) GetConnectionId() string { - if m != nil { - return m.ConnectionId - } - return "" -} - -func (m *QueryAppVersionRequest) GetOrdering() types.Order { - if m != nil { - return m.Ordering - } - return types.NONE -} - -func (m *QueryAppVersionRequest) GetCounterparty() *types.Counterparty { - if m != nil { - return m.Counterparty - } - return nil -} - -func (m *QueryAppVersionRequest) GetProposedVersion() string { - if m != nil { - return m.ProposedVersion - } - return "" -} - -// QueryAppVersionResponse is the response type for the Query/AppVersion RPC method. -type QueryAppVersionResponse struct { - // port id associated with the request identifiers - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` - // supported app version - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` -} - -func (m *QueryAppVersionResponse) Reset() { *m = QueryAppVersionResponse{} } -func (m *QueryAppVersionResponse) String() string { return proto.CompactTextString(m) } -func (*QueryAppVersionResponse) ProtoMessage() {} -func (*QueryAppVersionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_9a256596009a8334, []int{1} -} -func (m *QueryAppVersionResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryAppVersionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryAppVersionResponse.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 *QueryAppVersionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryAppVersionResponse.Merge(m, src) -} -func (m *QueryAppVersionResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryAppVersionResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryAppVersionResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryAppVersionResponse proto.InternalMessageInfo - -func (m *QueryAppVersionResponse) GetPortId() string { - if m != nil { - return m.PortId - } - return "" -} - -func (m *QueryAppVersionResponse) GetVersion() string { - if m != nil { - return m.Version - } - return "" -} - -func init() { - proto.RegisterType((*QueryAppVersionRequest)(nil), "ibc.core.port.v1.QueryAppVersionRequest") - proto.RegisterType((*QueryAppVersionResponse)(nil), "ibc.core.port.v1.QueryAppVersionResponse") -} - -func init() { proto.RegisterFile("ibc/core/port/v1/query.proto", fileDescriptor_9a256596009a8334) } - -var fileDescriptor_9a256596009a8334 = []byte{ - // 371 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xcd, 0xee, 0x12, 0x31, - 0x10, 0xdf, 0x45, 0x01, 0xad, 0xa8, 0xa4, 0x07, 0xd9, 0x10, 0xb3, 0x01, 0xbc, 0x2c, 0x07, 0x5a, - 0x81, 0xc8, 0x5d, 0x8d, 0x07, 0x12, 0x13, 0x75, 0x0f, 0x1e, 0xbc, 0x10, 0xb6, 0xdb, 0x40, 0x13, - 0xe8, 0x94, 0xb6, 0xbb, 0x09, 0x37, 0x1f, 0xc1, 0xc7, 0xf2, 0xc8, 0xd1, 0xa3, 0x81, 0x17, 0x31, - 0xdd, 0x65, 0xc1, 0x0f, 0x4c, 0xfe, 0xb7, 0xce, 0xfc, 0x3e, 0xf2, 0x9b, 0xe9, 0xa0, 0xe7, 0x22, - 0x61, 0x94, 0x81, 0xe6, 0x54, 0x81, 0xb6, 0x34, 0x1f, 0xd3, 0x5d, 0xc6, 0xf5, 0x9e, 0x28, 0x0d, - 0x16, 0x70, 0x5b, 0x24, 0x8c, 0x38, 0x94, 0x38, 0x94, 0xe4, 0xe3, 0x6e, 0xff, 0xc2, 0x67, 0xeb, - 0xa5, 0x94, 0x7c, 0xe3, 0x24, 0xe7, 0x67, 0x29, 0x1a, 0x7c, 0xad, 0xa1, 0x67, 0x9f, 0x9c, 0xc9, - 0x6b, 0xa5, 0x3e, 0x73, 0x6d, 0x04, 0xc8, 0x98, 0xef, 0x32, 0x6e, 0x2c, 0xee, 0xa0, 0xa6, 0x33, - 0x5a, 0x88, 0x34, 0xf0, 0x7b, 0x7e, 0xf4, 0x30, 0x6e, 0xb8, 0x72, 0x9e, 0xe2, 0x17, 0xe8, 0x31, - 0x03, 0x29, 0x39, 0xb3, 0x02, 0xa4, 0x83, 0x6b, 0x05, 0xdc, 0xba, 0x36, 0xe7, 0x29, 0x9e, 0xa1, - 0x07, 0xa0, 0x53, 0xae, 0x85, 0x5c, 0x05, 0xf7, 0x7a, 0x7e, 0xf4, 0x64, 0xd2, 0x25, 0x97, 0x80, - 0x55, 0x86, 0x7c, 0x4c, 0x3e, 0x38, 0x52, 0x7c, 0xe1, 0xe2, 0x77, 0xa8, 0xc5, 0x20, 0x93, 0x96, - 0x6b, 0xb5, 0xd4, 0x76, 0x1f, 0xdc, 0xef, 0xf9, 0xd1, 0xa3, 0x49, 0xff, 0xa6, 0xf6, 0xed, 0x6f, - 0xc4, 0xf8, 0x0f, 0x19, 0x1e, 0xa2, 0xb6, 0xd2, 0xa0, 0xc0, 0xf0, 0x74, 0x91, 0x97, 0x73, 0x05, - 0xf5, 0x22, 0xe6, 0xd3, 0xaa, 0x7f, 0x1e, 0x77, 0xf0, 0x1e, 0x75, 0xfe, 0xd9, 0x80, 0x51, 0x20, - 0x0d, 0xff, 0xff, 0x0a, 0x02, 0xd4, 0xac, 0x5c, 0xcb, 0xe1, 0xab, 0x72, 0xb2, 0x41, 0xf5, 0xc2, - 0x0d, 0x33, 0x84, 0xae, 0x8e, 0x38, 0x22, 0x7f, 0xff, 0x0e, 0xb9, 0xbd, 0xf6, 0xee, 0xf0, 0x0e, - 0xcc, 0x32, 0xde, 0xc0, 0x7b, 0xf3, 0xf1, 0xfb, 0x31, 0xf4, 0x0f, 0xc7, 0xd0, 0xff, 0x79, 0x0c, - 0xfd, 0x6f, 0xa7, 0xd0, 0x3b, 0x9c, 0x42, 0xef, 0xc7, 0x29, 0xf4, 0xbe, 0xcc, 0x56, 0xc2, 0xae, - 0xb3, 0x84, 0x30, 0xd8, 0x52, 0x06, 0x66, 0x0b, 0x86, 0x8a, 0x84, 0x8d, 0x56, 0x40, 0xf3, 0x29, - 0xdd, 0x42, 0x9a, 0x6d, 0xb8, 0x29, 0x6f, 0xe3, 0xe5, 0xab, 0x51, 0x71, 0x4e, 0x76, 0xaf, 0xb8, - 0x49, 0x1a, 0xc5, 0x5d, 0x4c, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x19, 0x37, 0x7f, 0x1d, 0x6c, - 0x02, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// QueryClient is the client API for Query service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type QueryClient interface { - // AppVersion queries an IBC Port and determines the appropriate application version to be used - AppVersion(ctx context.Context, in *QueryAppVersionRequest, opts ...grpc.CallOption) (*QueryAppVersionResponse, error) -} - -type queryClient struct { - cc grpc1.ClientConn -} - -func NewQueryClient(cc grpc1.ClientConn) QueryClient { - return &queryClient{cc} -} - -func (c *queryClient) AppVersion(ctx context.Context, in *QueryAppVersionRequest, opts ...grpc.CallOption) (*QueryAppVersionResponse, error) { - out := new(QueryAppVersionResponse) - err := c.cc.Invoke(ctx, "/ibc.core.port.v1.Query/AppVersion", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// QueryServer is the server API for Query service. -type QueryServer interface { - // AppVersion queries an IBC Port and determines the appropriate application version to be used - AppVersion(context.Context, *QueryAppVersionRequest) (*QueryAppVersionResponse, error) -} - -// UnimplementedQueryServer can be embedded to have forward compatible implementations. -type UnimplementedQueryServer struct { -} - -func (*UnimplementedQueryServer) AppVersion(ctx context.Context, req *QueryAppVersionRequest) (*QueryAppVersionResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method AppVersion not implemented") -} - -func RegisterQueryServer(s grpc1.Server, srv QueryServer) { - s.RegisterService(&_Query_serviceDesc, srv) -} - -func _Query_AppVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryAppVersionRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).AppVersion(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.port.v1.Query/AppVersion", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).AppVersion(ctx, req.(*QueryAppVersionRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "ibc.core.port.v1.Query", - HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "AppVersion", - Handler: _Query_AppVersion_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "ibc/core/port/v1/query.proto", -} - -func (m *QueryAppVersionRequest) 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 *QueryAppVersionRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryAppVersionRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ProposedVersion) > 0 { - i -= len(m.ProposedVersion) - copy(dAtA[i:], m.ProposedVersion) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ProposedVersion))) - i-- - dAtA[i] = 0x2a - } - if m.Counterparty != nil { - { - size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.Ordering != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.Ordering)) - i-- - dAtA[i] = 0x18 - } - if len(m.ConnectionId) > 0 { - i -= len(m.ConnectionId) - copy(dAtA[i:], m.ConnectionId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ConnectionId))) - i-- - dAtA[i] = 0x12 - } - if len(m.PortId) > 0 { - i -= len(m.PortId) - copy(dAtA[i:], m.PortId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.PortId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *QueryAppVersionResponse) 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 *QueryAppVersionResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryAppVersionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Version) > 0 { - i -= len(m.Version) - copy(dAtA[i:], m.Version) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Version))) - i-- - dAtA[i] = 0x12 - } - if len(m.PortId) > 0 { - i -= len(m.PortId) - copy(dAtA[i:], m.PortId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.PortId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryAppVersionRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.PortId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - l = len(m.ConnectionId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if m.Ordering != 0 { - n += 1 + sovQuery(uint64(m.Ordering)) - } - if m.Counterparty != nil { - l = m.Counterparty.Size() - n += 1 + l + sovQuery(uint64(l)) - } - l = len(m.ProposedVersion) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - -func (m *QueryAppVersionResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.PortId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - l = len(m.Version) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - -func sovQuery(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozQuery(x uint64) (n int) { - return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *QueryAppVersionRequest) 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: QueryAppVersionRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAppVersionRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PortId", 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.PortId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", 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.ConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Ordering", wireType) - } - m.Ordering = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Ordering |= types.Order(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Counterparty", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Counterparty == nil { - m.Counterparty = &types.Counterparty{} - } - if err := m.Counterparty.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProposedVersion", 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.ProposedVersion = 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 (m *QueryAppVersionResponse) 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: QueryAppVersionResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAppVersionResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PortId", 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.PortId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", 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.Version = 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 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowQuery - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthQuery - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupQuery - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthQuery - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") -) diff --git a/modules/core/23-commitment/types/codec.go b/modules/core/23-commitment/types/codec.go index 5c1334cec6d..3ccf9164d60 100644 --- a/modules/core/23-commitment/types/codec.go +++ b/modules/core/23-commitment/types/codec.go @@ -3,7 +3,7 @@ package types import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // RegisterInterfaces registers the commitment interfaces to protobuf Any. diff --git a/modules/core/23-commitment/types/commitment.pb.go b/modules/core/23-commitment/types/commitment.pb.go index 8b77f6aa693..190710ffbe1 100644 --- a/modules/core/23-commitment/types/commitment.pb.go +++ b/modules/core/23-commitment/types/commitment.pb.go @@ -5,9 +5,9 @@ package types import ( fmt "fmt" - _go "github.com/confio/ics23/go" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + _go "github.com/cosmos/ics23/go" io "io" math "math" math_bits "math/bits" @@ -217,28 +217,29 @@ func init() { } var fileDescriptor_7921d88972a41469 = []byte{ - // 333 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x91, 0xbd, 0x4e, 0xc3, 0x30, - 0x10, 0xc7, 0x13, 0x51, 0x15, 0xea, 0x56, 0x42, 0x04, 0xa8, 0x50, 0x87, 0x14, 0x65, 0x80, 0x2e, - 0xb5, 0xd5, 0x8f, 0xa9, 0x82, 0x25, 0xb0, 0x22, 0x55, 0x19, 0x18, 0x58, 0x50, 0x62, 0xdc, 0xc4, - 0x6a, 0xc3, 0x45, 0xb1, 0x5b, 0x91, 0x37, 0x60, 0x64, 0x64, 0xe4, 0x71, 0x18, 0x3b, 0x32, 0x55, - 0xa8, 0x7d, 0x83, 0x3e, 0x01, 0xb2, 0x4d, 0x21, 0xdb, 0xfd, 0x75, 0xbf, 0xfb, 0xfa, 0x1f, 0xba, - 0xe4, 0x11, 0x25, 0x14, 0x72, 0x46, 0x28, 0xa4, 0x29, 0x97, 0x29, 0x7b, 0x96, 0x64, 0xd1, 0x2b, - 0x29, 0x9c, 0xe5, 0x20, 0xc1, 0x69, 0xf2, 0x88, 0x62, 0x05, 0xe2, 0x52, 0x6a, 0xd1, 0x6b, 0x9d, - 0xc4, 0x10, 0x83, 0x46, 0x88, 0x8a, 0x0c, 0xdd, 0x6a, 0x64, 0x39, 0xc0, 0x44, 0x18, 0xe5, 0x5d, - 0x20, 0x74, 0xc7, 0xf2, 0xe9, 0x8c, 0x05, 0x00, 0xd2, 0x71, 0x50, 0x25, 0x09, 0x45, 0x72, 0x66, - 0x9f, 0xdb, 0x9d, 0x46, 0xa0, 0xe3, 0x51, 0xe5, 0xf5, 0xa3, 0x6d, 0x79, 0xb7, 0xa8, 0x61, 0xb8, - 0x71, 0xce, 0x26, 0xfc, 0xc5, 0x19, 0x22, 0x34, 0x65, 0xc5, 0x63, 0xa6, 0x95, 0xe1, 0xfd, 0xd3, - 0xed, 0xaa, 0x7d, 0x54, 0x84, 0xe9, 0x6c, 0xe4, 0xfd, 0xe7, 0xbc, 0xa0, 0x36, 0x65, 0x85, 0xa9, - 0xf2, 0xfc, 0xdd, 0xb4, 0x71, 0x28, 0x13, 0x07, 0xa3, 0x03, 0xcd, 0x85, 0x52, 0x4d, 0xdc, 0xeb, - 0xd4, 0xfc, 0xe3, 0xed, 0xaa, 0x7d, 0x58, 0xea, 0x10, 0xca, 0xc4, 0x0b, 0xf6, 0x55, 0x7d, 0x28, - 0x93, 0x51, 0xe5, 0x5d, 0x6d, 0x72, 0x8d, 0xea, 0xbb, 0x4d, 0x00, 0x26, 0x0e, 0x46, 0x55, 0x73, - 0x90, 0x6e, 0x51, 0xef, 0x37, 0x31, 0xa7, 0xa2, 0x3f, 0xc0, 0x37, 0x7f, 0x56, 0x68, 0x2e, 0xf8, - 0xa5, 0xfc, 0xfb, 0xcf, 0xb5, 0x6b, 0x2f, 0xd7, 0xae, 0xfd, 0xbd, 0x76, 0xed, 0xb7, 0x8d, 0x6b, - 0x2d, 0x37, 0xae, 0xf5, 0xb5, 0x71, 0xad, 0x87, 0xab, 0x98, 0xcb, 0x64, 0x1e, 0x29, 0x13, 0x09, - 0x05, 0x91, 0x82, 0x20, 0x3c, 0xa2, 0xdd, 0x18, 0xc8, 0x62, 0x48, 0x52, 0x78, 0x9a, 0xcf, 0x98, - 0x30, 0xff, 0xe8, 0x0f, 0xba, 0xa5, 0x97, 0xc8, 0x22, 0x63, 0x22, 0xaa, 0x6a, 0x3f, 0x07, 0x3f, - 0x01, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x08, 0x76, 0x1b, 0xb6, 0x01, 0x00, 0x00, + // 346 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x91, 0xcd, 0x4a, 0xc3, 0x40, + 0x10, 0xc7, 0x13, 0x2c, 0xd5, 0x6e, 0x0b, 0x62, 0xfc, 0x40, 0x8a, 0xa4, 0x25, 0x07, 0xed, 0xa5, + 0xbb, 0xb4, 0x15, 0x94, 0xe2, 0x29, 0x0a, 0x9e, 0x84, 0x92, 0x83, 0x07, 0x2f, 0x92, 0xac, 0xdb, + 0x24, 0xb4, 0x71, 0x42, 0x76, 0x1b, 0xcc, 0x1b, 0x78, 0xf4, 0xe8, 0xd1, 0xc7, 0xf1, 0xd8, 0xa3, + 0xa7, 0x22, 0xed, 0x1b, 0xf4, 0x09, 0x64, 0x77, 0xad, 0xe6, 0x36, 0xc3, 0xfc, 0xe6, 0xe3, 0xff, + 0x1f, 0x74, 0x16, 0x07, 0x94, 0x50, 0xc8, 0x18, 0xa1, 0x90, 0x24, 0xb1, 0x48, 0xd8, 0xb3, 0x20, + 0x79, 0xaf, 0x94, 0xe1, 0x34, 0x03, 0x01, 0xd6, 0x51, 0x1c, 0x50, 0x2c, 0x41, 0x5c, 0x2a, 0xe5, + 0xbd, 0xe6, 0x41, 0x08, 0x21, 0x28, 0x84, 0xc8, 0x48, 0xd3, 0xcd, 0x13, 0x0a, 0x3c, 0x01, 0x4e, + 0x62, 0xca, 0xfb, 0x03, 0x39, 0x2f, 0xcd, 0x00, 0xc6, 0x5c, 0x57, 0x9d, 0x53, 0x84, 0xee, 0x58, + 0x36, 0x99, 0x32, 0x0f, 0x40, 0x58, 0x16, 0xaa, 0x44, 0x3e, 0x8f, 0x8e, 0xcd, 0xb6, 0xd9, 0x69, + 0x78, 0x2a, 0x1e, 0x56, 0x5e, 0x3f, 0x5a, 0x86, 0x73, 0x83, 0x1a, 0x9a, 0x1b, 0x65, 0x6c, 0x1c, + 0xbf, 0x58, 0xe7, 0x08, 0x4d, 0x58, 0xf1, 0x98, 0xaa, 0x4c, 0xf3, 0xee, 0xe1, 0x7a, 0xd1, 0xda, + 0x2b, 0xfc, 0x64, 0x3a, 0x74, 0xfe, 0x6b, 0x8e, 0x57, 0x9b, 0xb0, 0x42, 0x77, 0x39, 0xee, 0x66, + 0xdb, 0xc8, 0x17, 0x91, 0x85, 0xd1, 0x8e, 0xe2, 0x7c, 0x21, 0x37, 0x6e, 0x75, 0x6a, 0xee, 0xfe, + 0x7a, 0xd1, 0xda, 0x2d, 0x4d, 0xf0, 0x45, 0xe4, 0x78, 0xdb, 0xb2, 0xdf, 0x17, 0xd1, 0xb0, 0xf2, + 0x2e, 0x2f, 0xb9, 0x45, 0xf5, 0xcd, 0x25, 0x00, 0x63, 0xeb, 0x12, 0x55, 0xb5, 0x20, 0x35, 0xa2, + 0xde, 0x6f, 0x63, 0xad, 0x17, 0x2b, 0xbd, 0x38, 0xef, 0xe1, 0xeb, 0x3f, 0x93, 0x54, 0x87, 0xf7, + 0xcb, 0xbb, 0xf7, 0x9f, 0x4b, 0xdb, 0x9c, 0x2f, 0x6d, 0xf3, 0x7b, 0x69, 0x9b, 0x6f, 0x2b, 0xdb, + 0x98, 0xaf, 0x6c, 0xe3, 0x6b, 0x65, 0x1b, 0x0f, 0x57, 0x61, 0x2c, 0xa2, 0x59, 0x20, 0xed, 0x25, + 0x1b, 0xf7, 0x02, 0xda, 0x0d, 0x81, 0xe4, 0x17, 0x24, 0x81, 0xa7, 0xd9, 0x94, 0x71, 0xfd, 0xa9, + 0xfe, 0xa0, 0x5b, 0x7a, 0x96, 0x28, 0x52, 0xc6, 0x83, 0xaa, 0x72, 0x76, 0xf0, 0x13, 0x00, 0x00, + 0xff, 0xff, 0x90, 0xe5, 0x86, 0x50, 0xd0, 0x01, 0x00, 0x00, } func (m *MerkleRoot) Marshal() (dAtA []byte, err error) { diff --git a/modules/core/23-commitment/types/commitment_test.go b/modules/core/23-commitment/types/commitment_test.go index d1a32b9cae8..ccc794579f8 100644 --- a/modules/core/23-commitment/types/commitment_test.go +++ b/modules/core/23-commitment/types/commitment_test.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/rootmulti" storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/stretchr/testify/suite" + "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" ) @@ -20,12 +21,14 @@ type MerkleTestSuite struct { func (suite *MerkleTestSuite) SetupTest() { db := dbm.NewMemDB() - suite.store = rootmulti.NewStore(db) + dblog := log.TestingLogger() + suite.store = rootmulti.NewStore(db, dblog) suite.storeKey = storetypes.NewKVStoreKey("iavlStoreKey") suite.store.MountStoreWithDB(suite.storeKey, storetypes.StoreTypeIAVL, nil) - suite.store.LoadVersion(0) + err := suite.store.LoadVersion(0) + suite.Require().NoError(err) suite.iavlStore = suite.store.GetCommitStore(suite.storeKey).(*iavl.Store) } diff --git a/modules/core/23-commitment/types/errors.go b/modules/core/23-commitment/types/errors.go index 7191baef1cc..140ec912b00 100644 --- a/modules/core/23-commitment/types/errors.go +++ b/modules/core/23-commitment/types/errors.go @@ -1,7 +1,7 @@ package types import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // SubModuleName is the error codespace @@ -9,7 +9,7 @@ const SubModuleName string = "commitment" // IBC connection sentinel errors var ( - ErrInvalidProof = sdkerrors.Register(SubModuleName, 2, "invalid proof") - ErrInvalidPrefix = sdkerrors.Register(SubModuleName, 3, "invalid prefix") - ErrInvalidMerkleProof = sdkerrors.Register(SubModuleName, 4, "invalid merkle proof") + ErrInvalidProof = errorsmod.Register(SubModuleName, 2, "invalid proof") + ErrInvalidPrefix = errorsmod.Register(SubModuleName, 3, "invalid prefix") + ErrInvalidMerkleProof = errorsmod.Register(SubModuleName, 4, "invalid merkle proof") ) diff --git a/modules/core/23-commitment/types/merkle.go b/modules/core/23-commitment/types/merkle.go index b661855935f..7d15b00a318 100644 --- a/modules/core/23-commitment/types/merkle.go +++ b/modules/core/23-commitment/types/merkle.go @@ -5,12 +5,12 @@ import ( "fmt" "net/url" - ics23 "github.com/confio/ics23/go" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/gogo/protobuf/proto" + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/gogoproto/proto" + ics23 "github.com/cosmos/ics23/go" tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // var representing the proofspecs for a SDK chain @@ -121,7 +121,7 @@ func (mp MerklePath) Empty() bool { // with the given path. func ApplyPrefix(prefix exported.Prefix, path MerklePath) (MerklePath, error) { if prefix == nil || prefix.Empty() { - return MerklePath{}, sdkerrors.Wrap(ErrInvalidPrefix, "prefix can't be empty") + return MerklePath{}, errorsmod.Wrap(ErrInvalidPrefix, "prefix can't be empty") } return NewMerklePath(append([]string{string(prefix.Bytes())}, path.KeyPath...)...), nil } @@ -129,6 +129,7 @@ func ApplyPrefix(prefix exported.Prefix, path MerklePath) (MerklePath, error) { var _ exported.Proof = (*MerkleProof)(nil) // VerifyMembership verifies the membership of a merkle proof against the given root, path, and value. +// Note that the path is expected as []string{, }. func (proof MerkleProof) VerifyMembership(specs []*ics23.ProofSpec, root exported.Root, path exported.Path, value []byte) error { if err := proof.validateVerificationArgs(specs, root); err != nil { return err @@ -137,14 +138,14 @@ func (proof MerkleProof) VerifyMembership(specs []*ics23.ProofSpec, root exporte // VerifyMembership specific argument validation mpath, ok := path.(MerklePath) if !ok { - return sdkerrors.Wrapf(ErrInvalidProof, "path %v is not of type MerklePath", path) + return errorsmod.Wrapf(ErrInvalidProof, "path %v is not of type MerklePath", path) } if len(mpath.KeyPath) != len(specs) { - return sdkerrors.Wrapf(ErrInvalidProof, "path length %d not same as proof %d", + return errorsmod.Wrapf(ErrInvalidProof, "path length %d not same as proof %d", len(mpath.KeyPath), len(specs)) } if len(value) == 0 { - return sdkerrors.Wrap(ErrInvalidProof, "empty value in membership proof") + return errorsmod.Wrap(ErrInvalidProof, "empty value in membership proof") } // Since every proof in chain is a membership proof we can use verifyChainedMembershipProof from index 0 @@ -166,10 +167,10 @@ func (proof MerkleProof) VerifyNonMembership(specs []*ics23.ProofSpec, root expo // VerifyNonMembership specific argument validation mpath, ok := path.(MerklePath) if !ok { - return sdkerrors.Wrapf(ErrInvalidProof, "path %v is not of type MerkleProof", path) + return errorsmod.Wrapf(ErrInvalidProof, "path %v is not of type MerkleProof", path) } if len(mpath.KeyPath) != len(specs) { - return sdkerrors.Wrapf(ErrInvalidProof, "path length %d not same as proof %d", + return errorsmod.Wrapf(ErrInvalidProof, "path length %d not same as proof %d", len(mpath.KeyPath), len(specs)) } @@ -179,14 +180,14 @@ func (proof MerkleProof) VerifyNonMembership(specs []*ics23.ProofSpec, root expo // of all subroots up to final root subroot, err := proof.Proofs[0].Calculate() if err != nil { - return sdkerrors.Wrapf(ErrInvalidProof, "could not calculate root for proof index 0, merkle tree is likely empty. %v", err) + return errorsmod.Wrapf(ErrInvalidProof, "could not calculate root for proof index 0, merkle tree is likely empty. %v", err) } key, err := mpath.GetKey(uint64(len(mpath.KeyPath) - 1)) if err != nil { - return sdkerrors.Wrapf(ErrInvalidProof, "could not retrieve key bytes for key: %s", mpath.KeyPath[len(mpath.KeyPath)-1]) + return errorsmod.Wrapf(ErrInvalidProof, "could not retrieve key bytes for key: %s", mpath.KeyPath[len(mpath.KeyPath)-1]) } if ok := ics23.VerifyNonMembership(specs[0], subroot, proof.Proofs[0], key); !ok { - return sdkerrors.Wrapf(ErrInvalidProof, "could not verify absence of key %s. Please ensure that the path is correct.", string(key)) + return errorsmod.Wrapf(ErrInvalidProof, "could not verify absence of key %s. Please ensure that the path is correct.", string(key)) } // Verify chained membership proof starting from index 1 with value = subroot @@ -194,10 +195,10 @@ func (proof MerkleProof) VerifyNonMembership(specs []*ics23.ProofSpec, root expo return err } case *ics23.CommitmentProof_Exist: - return sdkerrors.Wrapf(ErrInvalidProof, + return errorsmod.Wrapf(ErrInvalidProof, "got ExistenceProof in VerifyNonMembership. If this is unexpected, please ensure that proof was queried with the correct key.") default: - return sdkerrors.Wrapf(ErrInvalidProof, + return errorsmod.Wrapf(ErrInvalidProof, "expected proof type: %T, got: %T", &ics23.CommitmentProof_Exist{}, proof.Proofs[0].Proof) } return nil @@ -206,13 +207,13 @@ func (proof MerkleProof) VerifyNonMembership(specs []*ics23.ProofSpec, root expo // BatchVerifyMembership verifies a group of key value pairs against the given root // NOTE: Currently left unimplemented as it is unused func (proof MerkleProof) BatchVerifyMembership(specs []*ics23.ProofSpec, root exported.Root, path exported.Path, items map[string][]byte) error { - return sdkerrors.Wrap(ErrInvalidProof, "batch proofs are currently unsupported") + return errorsmod.Wrap(ErrInvalidProof, "batch proofs are currently unsupported") } // BatchVerifyNonMembership verifies absence of a group of keys against the given root // NOTE: Currently left unimplemented as it is unused func (proof MerkleProof) BatchVerifyNonMembership(specs []*ics23.ProofSpec, root exported.Root, path exported.Path, items [][]byte) error { - return sdkerrors.Wrap(ErrInvalidProof, "batch proofs are currently unsupported") + return errorsmod.Wrap(ErrInvalidProof, "batch proofs are currently unsupported") } // verifyChainedMembershipProof takes a list of proofs and specs and verifies each proof sequentially ensuring that the value is committed to @@ -234,35 +235,35 @@ func verifyChainedMembershipProof(root []byte, specs []*ics23.ProofSpec, proofs case *ics23.CommitmentProof_Exist: subroot, err = proofs[i].Calculate() if err != nil { - return sdkerrors.Wrapf(ErrInvalidProof, "could not calculate proof root at index %d, merkle tree may be empty. %v", i, err) + return errorsmod.Wrapf(ErrInvalidProof, "could not calculate proof root at index %d, merkle tree may be empty. %v", i, err) } // Since keys are passed in from highest to lowest, we must grab their indices in reverse order // from the proofs and specs which are lowest to highest key, err := keys.GetKey(uint64(len(keys.KeyPath) - 1 - i)) if err != nil { - return sdkerrors.Wrapf(ErrInvalidProof, "could not retrieve key bytes for key %s: %v", keys.KeyPath[len(keys.KeyPath)-1-i], err) + return errorsmod.Wrapf(ErrInvalidProof, "could not retrieve key bytes for key %s: %v", keys.KeyPath[len(keys.KeyPath)-1-i], err) } // verify membership of the proof at this index with appropriate key and value if ok := ics23.VerifyMembership(specs[i], subroot, proofs[i], key, value); !ok { - return sdkerrors.Wrapf(ErrInvalidProof, + return errorsmod.Wrapf(ErrInvalidProof, "chained membership proof failed to verify membership of value: %X in subroot %X at index %d. Please ensure the path and value are both correct.", value, subroot, i) } // Set value to subroot so that we verify next proof in chain commits to this subroot value = subroot case *ics23.CommitmentProof_Nonexist: - return sdkerrors.Wrapf(ErrInvalidProof, + return errorsmod.Wrapf(ErrInvalidProof, "chained membership proof contains nonexistence proof at index %d. If this is unexpected, please ensure that proof was queried from a height that contained the value in store and was queried with the correct key. The key used: %s", i, keys) default: - return sdkerrors.Wrapf(ErrInvalidProof, + return errorsmod.Wrapf(ErrInvalidProof, "expected proof type: %T, got: %T", &ics23.CommitmentProof_Exist{}, proofs[i].Proof) } } // Check that chained proof root equals passed-in root if !bytes.Equal(root, subroot) { - return sdkerrors.Wrapf(ErrInvalidProof, + return errorsmod.Wrapf(ErrInvalidProof, "proof did not commit to expected root: %X, got: %X. Please ensure proof was submitted with correct proofHeight and to the correct chain.", root, subroot) } @@ -271,8 +272,10 @@ func verifyChainedMembershipProof(root []byte, specs []*ics23.ProofSpec, proofs // blankMerkleProof and blankProofOps will be used to compare against their zero values, // and are declared as globals to avoid having to unnecessarily re-allocate on every comparison. -var blankMerkleProof = &MerkleProof{} -var blankProofOps = &tmcrypto.ProofOps{} +var ( + blankMerkleProof = &MerkleProof{} + blankProofOps = &tmcrypto.ProofOps{} +) // Empty returns true if the root is empty func (proof *MerkleProof) Empty() bool { @@ -290,22 +293,22 @@ func (proof MerkleProof) ValidateBasic() error { // validateVerificationArgs verifies the proof arguments are valid func (proof MerkleProof) validateVerificationArgs(specs []*ics23.ProofSpec, root exported.Root) error { if proof.Empty() { - return sdkerrors.Wrap(ErrInvalidMerkleProof, "proof cannot be empty") + return errorsmod.Wrap(ErrInvalidMerkleProof, "proof cannot be empty") } if root == nil || root.Empty() { - return sdkerrors.Wrap(ErrInvalidMerkleProof, "root cannot be empty") + return errorsmod.Wrap(ErrInvalidMerkleProof, "root cannot be empty") } if len(specs) != len(proof.Proofs) { - return sdkerrors.Wrapf(ErrInvalidMerkleProof, + return errorsmod.Wrapf(ErrInvalidMerkleProof, "length of specs: %d not equal to length of proof: %d", len(specs), len(proof.Proofs)) } for i, spec := range specs { if spec == nil { - return sdkerrors.Wrapf(ErrInvalidProof, "spec at position %d is nil", i) + return errorsmod.Wrapf(ErrInvalidProof, "spec at position %d is nil", i) } } return nil diff --git a/modules/core/23-commitment/types/merkle_test.go b/modules/core/23-commitment/types/merkle_test.go index cf13348faf3..8086afd8c76 100644 --- a/modules/core/23-commitment/types/merkle_test.go +++ b/modules/core/23-commitment/types/merkle_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ) func (suite *MerkleTestSuite) TestVerifyMembership() { @@ -64,10 +64,10 @@ func (suite *MerkleTestSuite) TestVerifyMembership() { err := proof.VerifyMembership(types.GetSDKSpecs(), &root, path, tc.value) if tc.shouldPass { - // nolint: scopelint + //nolint: scopelint suite.Require().NoError(err, "test case %d should have passed", i) } else { - // nolint: scopelint + //nolint: scopelint suite.Require().Error(err, "test case %d should have failed", i) } }) @@ -127,10 +127,10 @@ func (suite *MerkleTestSuite) TestVerifyNonMembership() { err := proof.VerifyNonMembership(types.GetSDKSpecs(), &root, path) if tc.shouldPass { - // nolint: scopelint + //nolint: scopelint suite.Require().NoError(err, "test case %d should have passed", i) } else { - // nolint: scopelint + //nolint: scopelint suite.Require().Error(err, "test case %d should have failed", i) } }) diff --git a/modules/core/23-commitment/types/utils.go b/modules/core/23-commitment/types/utils.go index 7d2937f0fb5..2ad3bcf57dc 100644 --- a/modules/core/23-commitment/types/utils.go +++ b/modules/core/23-commitment/types/utils.go @@ -1,15 +1,15 @@ package types import ( - ics23 "github.com/confio/ics23/go" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" + ics23 "github.com/cosmos/ics23/go" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" ) // ConvertProofs converts crypto.ProofOps into MerkleProof func ConvertProofs(tmProof *crypto.ProofOps) (MerkleProof, error) { if tmProof == nil { - return MerkleProof{}, sdkerrors.Wrapf(ErrInvalidMerkleProof, "tendermint proof is nil") + return MerkleProof{}, errorsmod.Wrapf(ErrInvalidMerkleProof, "tendermint proof is nil") } // Unmarshal all proof ops to CommitmentProof proofs := make([]*ics23.CommitmentProof, len(tmProof.Ops)) @@ -17,7 +17,7 @@ func ConvertProofs(tmProof *crypto.ProofOps) (MerkleProof, error) { var p ics23.CommitmentProof err := p.Unmarshal(op.Data) if err != nil || p.Proof == nil { - return MerkleProof{}, sdkerrors.Wrapf(ErrInvalidMerkleProof, "could not unmarshal proof op into CommitmentProof at index %d: %v", i, err) + return MerkleProof{}, errorsmod.Wrapf(ErrInvalidMerkleProof, "could not unmarshal proof op into CommitmentProof at index %d: %v", i, err) } proofs[i] = &p } diff --git a/modules/core/23-commitment/types/utils_test.go b/modules/core/23-commitment/types/utils_test.go index 270d13cae5e..4a1c5d3e185 100644 --- a/modules/core/23-commitment/types/utils_test.go +++ b/modules/core/23-commitment/types/utils_test.go @@ -7,7 +7,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" - "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ) func (suite *MerkleTestSuite) TestConvertProofs() { diff --git a/modules/core/24-host/client_keys.go b/modules/core/24-host/client_keys.go index 3372da97689..575c363628f 100644 --- a/modules/core/24-host/client_keys.go +++ b/modules/core/24-host/client_keys.go @@ -3,7 +3,7 @@ package host import ( "fmt" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // KeyClientStorePrefix defines the KVStore key prefix for IBC clients @@ -26,6 +26,20 @@ func FullClientKey(clientID string, path []byte) []byte { return []byte(FullClientPath(clientID, string(path))) } +// PrefixedClientStorePath returns a key path which can be used for prefixed +// key store iteration. The prefix may be a clientType, clientID, or any +// valid key prefix which may be concatenated with the client store constant. +func PrefixedClientStorePath(prefix []byte) string { + return fmt.Sprintf("%s/%s", KeyClientStorePrefix, prefix) +} + +// PrefixedClientStoreKey returns a key which can be used for prefixed +// key store iteration. The prefix may be a clientType, clientID, or any +// valid key prefix which may be concatenated with the client store constant. +func PrefixedClientStoreKey(prefix []byte) []byte { + return []byte(PrefixedClientStorePath(prefix)) +} + // ICS02 // The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics#path-space diff --git a/modules/core/24-host/doc.go b/modules/core/24-host/doc.go index 0d73c4e7efe..c7bf710c597 100644 --- a/modules/core/24-host/doc.go +++ b/modules/core/24-host/doc.go @@ -1,9 +1,8 @@ /* -24-host is an implementation of ICS24. +24-host is an implementation of ICS 24. -The storage path supported are defined in [ICS24](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements#path-space). - -Hostname validation is implemented as defined in [ICS 24](https://github.com/cosmos/ibc/tree/master/spec/core/ics-024-host-requirements). +The storage path supported are defined in ICS 24 (https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements#path-space). +Hostname validation is implemented as defined in ICS 24 (https://github.com/cosmos/ibc/tree/master/spec/core/ics-024-host-requirements). */ package host diff --git a/modules/core/24-host/errors.go b/modules/core/24-host/errors.go index fe8129bde86..742f1779311 100644 --- a/modules/core/24-host/errors.go +++ b/modules/core/24-host/errors.go @@ -1,7 +1,7 @@ package host import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // SubModuleName defines the ICS 24 host @@ -9,7 +9,7 @@ const SubModuleName = "host" // IBC client sentinel errors var ( - ErrInvalidID = sdkerrors.Register(SubModuleName, 2, "invalid identifier") - ErrInvalidPath = sdkerrors.Register(SubModuleName, 3, "invalid path") - ErrInvalidPacket = sdkerrors.Register(SubModuleName, 4, "invalid packet") + ErrInvalidID = errorsmod.Register(SubModuleName, 2, "invalid identifier") + ErrInvalidPath = errorsmod.Register(SubModuleName, 3, "invalid path") + ErrInvalidPacket = errorsmod.Register(SubModuleName, 4, "invalid packet") ) diff --git a/modules/core/24-host/parse.go b/modules/core/24-host/parse.go index 8c3459500d9..81074bbfcca 100644 --- a/modules/core/24-host/parse.go +++ b/modules/core/24-host/parse.go @@ -4,7 +4,7 @@ import ( "strconv" "strings" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // ParseIdentifier parses the sequence from the identifier using the provided prefix. This function @@ -12,32 +12,66 @@ import ( // are required to use this format. func ParseIdentifier(identifier, prefix string) (uint64, error) { if !strings.HasPrefix(identifier, prefix) { - return 0, sdkerrors.Wrapf(ErrInvalidID, "identifier doesn't contain prefix `%s`", prefix) + return 0, errorsmod.Wrapf(ErrInvalidID, "identifier doesn't contain prefix `%s`", prefix) } splitStr := strings.Split(identifier, prefix) if len(splitStr) != 2 { - return 0, sdkerrors.Wrapf(ErrInvalidID, "identifier must be in format: `%s{N}`", prefix) + return 0, errorsmod.Wrapf(ErrInvalidID, "identifier must be in format: `%s{N}`", prefix) } // sanity check if splitStr[0] != "" { - return 0, sdkerrors.Wrapf(ErrInvalidID, "identifier must begin with prefix %s", prefix) + return 0, errorsmod.Wrapf(ErrInvalidID, "identifier must begin with prefix %s", prefix) } sequence, err := strconv.ParseUint(splitStr[1], 10, 64) if err != nil { - return 0, sdkerrors.Wrap(err, "failed to parse identifier sequence") + return 0, errorsmod.Wrap(err, "failed to parse identifier sequence") } return sequence, nil } +// MustParseClientStatePath returns the client ID from a client state path. It panics +// if the provided path is invalid or if the clientID is empty. +func MustParseClientStatePath(path string) string { + clientID, err := parseClientStatePath(path) + if err != nil { + panic(err.Error()) + } + + return clientID +} + +// parseClientStatePath returns the client ID from a client state path. It returns +// an error if the provided path is invalid. +func parseClientStatePath(path string) (string, error) { + split := strings.Split(path, "/") + if len(split) != 3 { + return "", errorsmod.Wrapf(ErrInvalidPath, "cannot parse client state path %s", path) + } + + if split[0] != string(KeyClientStorePrefix) { + return "", errorsmod.Wrapf(ErrInvalidPath, "path does not begin with client store prefix: expected %s, got %s", KeyClientStorePrefix, split[0]) + } + + if split[2] != KeyClientState { + return "", errorsmod.Wrapf(ErrInvalidPath, "path does not end with client state key: expected %s, got %s", KeyClientState, split[2]) + } + + if strings.TrimSpace(split[1]) == "" { + return "", errorsmod.Wrap(ErrInvalidPath, "clientID is empty") + } + + return split[1], nil +} + // ParseConnectionPath returns the connection ID from a full path. It returns // an error if the provided path is invalid. func ParseConnectionPath(path string) (string, error) { split := strings.Split(path, "/") if len(split) != 2 { - return "", sdkerrors.Wrapf(ErrInvalidPath, "cannot parse connection path %s", path) + return "", errorsmod.Wrapf(ErrInvalidPath, "cannot parse connection path %s", path) } return split[1], nil @@ -48,11 +82,11 @@ func ParseConnectionPath(path string) (string, error) { func ParseChannelPath(path string) (string, string, error) { split := strings.Split(path, "/") if len(split) < 5 { - return "", "", sdkerrors.Wrapf(ErrInvalidPath, "cannot parse channel path %s", path) + return "", "", errorsmod.Wrapf(ErrInvalidPath, "cannot parse channel path %s", path) } if split[1] != KeyPortPrefix || split[3] != KeyChannelPrefix { - return "", "", sdkerrors.Wrapf(ErrInvalidPath, "cannot parse channel path %s", path) + return "", "", errorsmod.Wrapf(ErrInvalidPath, "cannot parse channel path %s", path) } return split[2], split[4], nil diff --git a/modules/core/24-host/parse_test.go b/modules/core/24-host/parse_test.go index 18b9848e950..18c3ab2e832 100644 --- a/modules/core/24-host/parse_test.go +++ b/modules/core/24-host/parse_test.go @@ -1,13 +1,15 @@ package host_test import ( + "fmt" "math" "testing" "github.com/stretchr/testify/require" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func TestParseIdentifier(t *testing.T) { @@ -46,3 +48,32 @@ func TestParseIdentifier(t *testing.T) { } } } + +func TestMustParseClientStatePath(t *testing.T) { + testCases := []struct { + name string + path string + expPass bool + }{ + {"valid", host.FullClientStatePath(ibctesting.FirstClientID), true}, + {"path too large", fmt.Sprintf("clients/clients/%s/clientState", ibctesting.FirstClientID), false}, + {"path too small", fmt.Sprintf("clients/%s", ibctesting.FirstClientID), false}, + {"path does not begin with client store", fmt.Sprintf("cli/%s/%s", ibctesting.FirstClientID, host.KeyClientState), false}, + {"path does not end with client state key", fmt.Sprintf("%s/%s/consensus", string(host.KeyClientStorePrefix), ibctesting.FirstClientID), false}, + {"client ID is empty", host.FullClientStatePath(""), false}, + {"client ID is only spaces", host.FullClientStatePath(" "), false}, + } + + for _, tc := range testCases { + if tc.expPass { + require.NotPanics(t, func() { + clientID := host.MustParseClientStatePath(tc.path) + require.Equal(t, ibctesting.FirstClientID, clientID) + }) + } else { + require.Panics(t, func() { + host.MustParseClientStatePath(tc.path) + }) + } + } +} diff --git a/modules/core/24-host/validate.go b/modules/core/24-host/validate.go index 7102e66b455..e6219d99b40 100644 --- a/modules/core/24-host/validate.go +++ b/modules/core/24-host/validate.go @@ -4,7 +4,7 @@ import ( "regexp" "strings" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" ) // DefaultMaxCharacterLength defines the default maximum character length used @@ -36,21 +36,21 @@ var IsValidID = regexp.MustCompile(`^[a-zA-Z0-9\.\_\+\-\#\[\]\<\>]+$`).MatchStri // ValidateFn function type to validate path and identifier bytestrings type ValidateFn func(string) error -func defaultIdentifierValidator(id string, min, max int) error { //nolint:unparam +func defaultIdentifierValidator(id string, min, max int) error { if strings.TrimSpace(id) == "" { - return sdkerrors.Wrap(ErrInvalidID, "identifier cannot be blank") + return errorsmod.Wrap(ErrInvalidID, "identifier cannot be blank") } // valid id MUST NOT contain "/" separator if strings.Contains(id, "/") { - return sdkerrors.Wrapf(ErrInvalidID, "identifier %s cannot contain separator '/'", id) + return errorsmod.Wrapf(ErrInvalidID, "identifier %s cannot contain separator '/'", id) } // valid id must fit the length requirements if len(id) < min || len(id) > max { - return sdkerrors.Wrapf(ErrInvalidID, "identifier %s has invalid length: %d, must be between %d-%d characters", id, len(id), min, max) + return errorsmod.Wrapf(ErrInvalidID, "identifier %s has invalid length: %d, must be between %d-%d characters", id, len(id), min, max) } // valid id must contain only lower alphabetic characters if !IsValidID(id) { - return sdkerrors.Wrapf( + return errorsmod.Wrapf( ErrInvalidID, "identifier %s must contain only alphanumeric or the following characters: '.', '_', '+', '-', '#', '[', ']', '<', '>'", id, @@ -95,13 +95,13 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { return func(path string) error { pathArr := strings.Split(path, "/") if len(pathArr) > 0 && pathArr[0] == path { - return sdkerrors.Wrapf(ErrInvalidPath, "path %s doesn't contain any separator '/'", path) + return errorsmod.Wrapf(ErrInvalidPath, "path %s doesn't contain any separator '/'", path) } for _, p := range pathArr { // a path beginning or ending in a separator returns empty string elements. if p == "" { - return sdkerrors.Wrapf(ErrInvalidPath, "path %s cannot begin or end with '/'", path) + return errorsmod.Wrapf(ErrInvalidPath, "path %s cannot begin or end with '/'", path) } if err := idValidator(p); err != nil { @@ -109,7 +109,7 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { } // Each path element must either be a valid identifier or constant number if err := defaultIdentifierValidator(p, 1, DefaultMaxCharacterLength); err != nil { - return sdkerrors.Wrapf(err, "path %s contains an invalid identifier: '%s'", path, p) + return errorsmod.Wrapf(err, "path %s contains an invalid identifier: '%s'", path, p) } } diff --git a/modules/core/24-host/validate_test.go b/modules/core/24-host/validate_test.go index fe5c290ba40..e75ce9334bd 100644 --- a/modules/core/24-host/validate_test.go +++ b/modules/core/24-host/validate_test.go @@ -9,7 +9,7 @@ import ( ) // 195 characters -var longId = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eros neque, ultricies vel ligula ac, convallis porttitor elit. Maecenas tincidunt turpis elit, vel faucibus nisl pellentesque sodales" +var longID = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eros neque, ultricies vel ligula ac, convallis porttitor elit. Maecenas tincidunt turpis elit, vel faucibus nisl pellentesque sodales" type testCase struct { msg string @@ -63,7 +63,7 @@ func TestPortIdentifierValidator(t *testing.T) { {"numeric id", "1234567890", true}, {"blank id", " ", false}, {"id length out of range", "1", false}, - {"id is too long", longId, false}, + {"id is too long", longID, false}, {"path-like id", "lower/case/id", false}, {"invalid id", "(clientid)", false}, {"empty string", "", false}, diff --git a/modules/core/ante/ante.go b/modules/core/ante/ante.go index 1ad8d776b70..7b8cdb326de 100644 --- a/modules/core/ante/ante.go +++ b/modules/core/ante/ante.go @@ -3,25 +3,25 @@ package ante import ( sdk "github.com/cosmos/cosmos-sdk/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/modules/core/keeper" + 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/keeper" ) -type AnteDecorator struct { +type RedundantRelayDecorator struct { k *keeper.Keeper } -func NewAnteDecorator(k *keeper.Keeper) AnteDecorator { - return AnteDecorator{k: k} +func NewRedundantRelayDecorator(k *keeper.Keeper) RedundantRelayDecorator { + return RedundantRelayDecorator{k: k} } -// AnteDecorator returns an error if a multiMsg tx only contains packet messages (Recv, Ack, Timeout) and additional update messages +// RedundantRelayDecorator returns an error if a multiMsg tx only contains packet messages (Recv, Ack, Timeout) and additional update messages // and all packet messages are redundant. If the transaction is just a single UpdateClient message, or the multimsg transaction // contains some other message type, then the antedecorator returns no error and continues processing to ensure these transactions // are included. This will ensure that relayers do not waste fees on multiMsg transactions when another relayer has already submitted // all packets, by rejecting the tx at the mempool layer. -func (ad AnteDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { +func (rrd RedundantRelayDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { // do not run redundancy check on DeliverTx or simulate if (ctx.IsCheckTx() || ctx.IsReCheckTx()) && !simulate { // keep track of total packet messages and number of redundancies across `RecvPacket`, `AcknowledgePacket`, and `TimeoutPacket/OnClose` @@ -30,47 +30,47 @@ func (ad AnteDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne for _, m := range tx.GetMsgs() { switch msg := m.(type) { case *channeltypes.MsgRecvPacket: - response, err := ad.k.RecvPacket(sdk.WrapSDKContext(ctx), msg) + response, err := rrd.k.RecvPacket(sdk.WrapSDKContext(ctx), msg) if err != nil { return ctx, err } if response.Result == channeltypes.NOOP { - redundancies += 1 + redundancies++ } - packetMsgs += 1 + packetMsgs++ case *channeltypes.MsgAcknowledgement: - response, err := ad.k.Acknowledgement(sdk.WrapSDKContext(ctx), msg) + response, err := rrd.k.Acknowledgement(sdk.WrapSDKContext(ctx), msg) if err != nil { return ctx, err } if response.Result == channeltypes.NOOP { - redundancies += 1 + redundancies++ } - packetMsgs += 1 + packetMsgs++ case *channeltypes.MsgTimeout: - response, err := ad.k.Timeout(sdk.WrapSDKContext(ctx), msg) + response, err := rrd.k.Timeout(sdk.WrapSDKContext(ctx), msg) if err != nil { return ctx, err } if response.Result == channeltypes.NOOP { - redundancies += 1 + redundancies++ } - packetMsgs += 1 + packetMsgs++ case *channeltypes.MsgTimeoutOnClose: - response, err := ad.k.TimeoutOnClose(sdk.WrapSDKContext(ctx), msg) + response, err := rrd.k.TimeoutOnClose(sdk.WrapSDKContext(ctx), msg) if err != nil { return ctx, err } if response.Result == channeltypes.NOOP { - redundancies += 1 + redundancies++ } - packetMsgs += 1 + packetMsgs++ case *clienttypes.MsgUpdateClient: - _, err := ad.k.UpdateClient(sdk.WrapSDKContext(ctx), msg) + _, err := rrd.k.UpdateClient(sdk.WrapSDKContext(ctx), msg) if err != nil { return ctx, err } diff --git a/modules/core/ante/ante_test.go b/modules/core/ante/ante_test.go index fb71db32b0f..20ed350a053 100644 --- a/modules/core/ante/ante_test.go +++ b/modules/core/ante/ante_test.go @@ -7,12 +7,12 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/ante" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + 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/ibc-go/v7/modules/core/ante" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type AnteTestSuite struct { @@ -45,14 +45,14 @@ func TestAnteTestSuite(t *testing.T) { } // createRecvPacketMessage creates a RecvPacket message for a packet sent from chain A to chain B. -func (suite *AnteTestSuite) createRecvPacketMessage(sequenceNumber uint64, isRedundant bool) sdk.Msg { - packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequenceNumber, +func (suite *AnteTestSuite) createRecvPacketMessage(isRedundant bool) sdk.Msg { + sequence, err := suite.path.EndpointA.SendPacket(clienttypes.NewHeight(2, 0), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - err := suite.path.EndpointA.SendPacket(packet) - suite.Require().NoError(err) + clienttypes.NewHeight(2, 0), 0) if isRedundant { err = suite.path.EndpointB.RecvPacket(packet) @@ -69,14 +69,14 @@ func (suite *AnteTestSuite) createRecvPacketMessage(sequenceNumber uint64, isRed } // createAcknowledgementMessage creates an Acknowledgement message for a packet sent from chain B to chain A. -func (suite *AnteTestSuite) createAcknowledgementMessage(sequenceNumber uint64, isRedundant bool) sdk.Msg { - packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequenceNumber, +func (suite *AnteTestSuite) createAcknowledgementMessage(isRedundant bool) sdk.Msg { + sequence, err := suite.path.EndpointB.SendPacket(clienttypes.NewHeight(2, 0), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - clienttypes.NewHeight(1, 0), 0) - - err := suite.path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) + clienttypes.NewHeight(2, 0), 0) err = suite.path.EndpointA.RecvPacket(packet) suite.Require().NoError(err) @@ -92,15 +92,11 @@ func (suite *AnteTestSuite) createAcknowledgementMessage(sequenceNumber uint64, } // createTimeoutMessage creates an Timeout message for a packet sent from chain B to chain A. -func (suite *AnteTestSuite) createTimeoutMessage(sequenceNumber uint64, isRedundant bool) sdk.Msg { +func (suite *AnteTestSuite) createTimeoutMessage(isRedundant bool) sdk.Msg { height := suite.chainA.LastHeader.GetHeight() timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) - packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequenceNumber, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - timeoutHeight, 0) - err := suite.path.EndpointB.SendPacket(packet) + sequence, err := suite.path.EndpointB.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) suite.coordinator.CommitNBlocks(suite.chainA, 3) @@ -108,6 +104,11 @@ func (suite *AnteTestSuite) createTimeoutMessage(sequenceNumber uint64, isRedund err = suite.path.EndpointB.UpdateClient() suite.Require().NoError(err) + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, + suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, + timeoutHeight, 0) + if isRedundant { err = suite.path.EndpointB.TimeoutPacket(packet) suite.Require().NoError(err) @@ -116,23 +117,24 @@ func (suite *AnteTestSuite) createTimeoutMessage(sequenceNumber uint64, isRedund packetKey := host.PacketReceiptKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) proof, proofHeight := suite.chainA.QueryProof(packetKey) - return channeltypes.NewMsgTimeout(packet, sequenceNumber, proof, proofHeight, suite.path.EndpointA.Chain.SenderAccount.GetAddress().String()) + return channeltypes.NewMsgTimeout(packet, sequence, proof, proofHeight, suite.path.EndpointA.Chain.SenderAccount.GetAddress().String()) } // createTimeoutOnCloseMessage creates an TimeoutOnClose message for a packet sent from chain B to chain A. -func (suite *AnteTestSuite) createTimeoutOnCloseMessage(sequenceNumber uint64, isRedundant bool) sdk.Msg { +func (suite *AnteTestSuite) createTimeoutOnCloseMessage(isRedundant bool) sdk.Msg { height := suite.chainA.LastHeader.GetHeight() timeoutHeight := clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) - packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequenceNumber, - suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, - timeoutHeight, 0) - err := suite.path.EndpointB.SendPacket(packet) + sequence, err := suite.path.EndpointB.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) - err = suite.path.EndpointA.SetChannelClosed() + err = suite.path.EndpointA.SetChannelState(channeltypes.CLOSED) suite.Require().NoError(err) + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, + suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, + suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, + timeoutHeight, 0) + if isRedundant { err = suite.path.EndpointB.TimeoutOnClose(packet) suite.Require().NoError(err) @@ -153,7 +155,7 @@ func (suite *AnteTestSuite) createUpdateClientMessage() sdk.Msg { // ensure counterparty has committed state endpoint.Chain.Coordinator.CommitBlock(endpoint.Counterparty.Chain) - var header exported.Header + var header exported.ClientMessage switch endpoint.ClientConfig.GetClientType() { case exported.Tendermint: @@ -166,7 +168,7 @@ func (suite *AnteTestSuite) createUpdateClientMessage() sdk.Msg { endpoint.ClientID, header, endpoint.Chain.SenderAccount.GetAddress().String(), ) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) return msg } @@ -181,7 +183,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { "success on one new RecvPacket message", func(suite *AnteTestSuite) []sdk.Msg { // the RecvPacket message has not been submitted to the chain yet, so it will succeed - return []sdk.Msg{suite.createRecvPacketMessage(1, false)} + return []sdk.Msg{suite.createRecvPacketMessage(false)} }, true, }, @@ -189,7 +191,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { "success on one new Acknowledgement message", func(suite *AnteTestSuite) []sdk.Msg { // the Acknowledgement message has not been submitted to the chain yet, so it will succeed - return []sdk.Msg{suite.createAcknowledgementMessage(1, false)} + return []sdk.Msg{suite.createAcknowledgementMessage(false)} }, true, }, @@ -197,7 +199,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { "success on one new Timeout message", func(suite *AnteTestSuite) []sdk.Msg { // the Timeout message has not been submitted to the chain yet, so it will succeed - return []sdk.Msg{suite.createTimeoutMessage(1, false)} + return []sdk.Msg{suite.createTimeoutMessage(false)} }, true, }, @@ -205,7 +207,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { "success on one new TimeoutOnClose message", func(suite *AnteTestSuite) []sdk.Msg { // the TimeoutOnClose message has not been submitted to the chain yet, so it will succeed - return []sdk.Msg{suite.createTimeoutOnCloseMessage(uint64(1), false)} + return []sdk.Msg{suite.createTimeoutOnCloseMessage(false)} }, true, }, @@ -220,18 +222,18 @@ func (suite *AnteTestSuite) TestAnteDecorator() { // from A to B for i := 1; i <= 3; i++ { - msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), false)) + msgs = append(msgs, suite.createRecvPacketMessage(false)) } // from B to A for i := 1; i <= 9; i++ { switch { case i >= 1 && i <= 3: - msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), false)) + msgs = append(msgs, suite.createAcknowledgementMessage(false)) case i >= 4 && i <= 6: - msgs = append(msgs, suite.createTimeoutMessage(uint64(i), false)) + msgs = append(msgs, suite.createTimeoutMessage(false)) case i >= 7 && i <= 9: - msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), false)) + msgs = append(msgs, suite.createTimeoutOnCloseMessage(false)) } } return msgs @@ -250,18 +252,18 @@ func (suite *AnteTestSuite) TestAnteDecorator() { // from A to B for i := 1; i <= 3; i++ { - msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) + msgs = append(msgs, suite.createRecvPacketMessage(true)) } // from B to A for i := 1; i <= 7; i++ { switch { case i >= 1 && i <= 3: - msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), true)) + msgs = append(msgs, suite.createAcknowledgementMessage(true)) case i == 4: - msgs = append(msgs, suite.createTimeoutMessage(uint64(i), false)) + msgs = append(msgs, suite.createTimeoutMessage(false)) case i >= 5 && i <= 7: - msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), true)) + msgs = append(msgs, suite.createTimeoutOnCloseMessage(true)) } } return msgs @@ -280,18 +282,18 @@ func (suite *AnteTestSuite) TestAnteDecorator() { // from A to B for i := 1; i <= 3; i++ { - msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), i != 2)) + msgs = append(msgs, suite.createRecvPacketMessage(i != 2)) } // from B to A for i := 1; i <= 9; i++ { switch { case i >= 1 && i <= 3: - msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), i != 2)) + msgs = append(msgs, suite.createAcknowledgementMessage(i != 2)) case i >= 4 && i <= 6: - msgs = append(msgs, suite.createTimeoutMessage(uint64(i), i != 5)) + msgs = append(msgs, suite.createTimeoutMessage(i != 5)) case i >= 7 && i <= 9: - msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), i != 8)) + msgs = append(msgs, suite.createTimeoutOnCloseMessage(i != 8)) } } return msgs @@ -319,7 +321,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { suite.createUpdateClientMessage(), suite.createUpdateClientMessage(), suite.createUpdateClientMessage(), - suite.createRecvPacketMessage(uint64(1), false), + suite.createRecvPacketMessage(false), } }, true, @@ -330,7 +332,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { msgs := []sdk.Msg{suite.createUpdateClientMessage()} for i := 1; i <= 3; i++ { - msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) + msgs = append(msgs, suite.createRecvPacketMessage(true)) } // append non packet and update message to msgs to ensure multimsg tx should pass @@ -342,7 +344,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { { "no success on one redundant RecvPacket message", func(suite *AnteTestSuite) []sdk.Msg { - return []sdk.Msg{suite.createRecvPacketMessage(uint64(1), true)} + return []sdk.Msg{suite.createRecvPacketMessage(true)} }, false, }, @@ -353,18 +355,18 @@ func (suite *AnteTestSuite) TestAnteDecorator() { // from A to B for i := 1; i <= 3; i++ { - msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) + msgs = append(msgs, suite.createRecvPacketMessage(true)) } // from B to A for i := 1; i <= 9; i++ { switch { case i >= 1 && i <= 3: - msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), true)) + msgs = append(msgs, suite.createAcknowledgementMessage(true)) case i >= 4 && i <= 6: - msgs = append(msgs, suite.createTimeoutMessage(uint64(i), true)) + msgs = append(msgs, suite.createTimeoutMessage(true)) case i >= 7 && i <= 9: - msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), true)) + msgs = append(msgs, suite.createTimeoutOnCloseMessage(true)) } } return msgs @@ -377,7 +379,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { msgs := []sdk.Msg{&clienttypes.MsgUpdateClient{}} for i := 1; i <= 3; i++ { - msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) + msgs = append(msgs, suite.createRecvPacketMessage(true)) } return msgs @@ -391,18 +393,18 @@ func (suite *AnteTestSuite) TestAnteDecorator() { // from A to B for i := 1; i <= 3; i++ { - msgs = append(msgs, suite.createRecvPacketMessage(uint64(i), true)) + msgs = append(msgs, suite.createRecvPacketMessage(true)) } // from B to A for i := 1; i <= 9; i++ { switch { case i >= 1 && i <= 3: - msgs = append(msgs, suite.createAcknowledgementMessage(uint64(i), true)) + msgs = append(msgs, suite.createAcknowledgementMessage(true)) case i >= 4 && i <= 6: - msgs = append(msgs, suite.createTimeoutMessage(uint64(i), true)) + msgs = append(msgs, suite.createTimeoutMessage(true)) case i >= 7 && i <= 9: - msgs = append(msgs, suite.createTimeoutOnCloseMessage(uint64(i), true)) + msgs = append(msgs, suite.createTimeoutOnCloseMessage(true)) } } return msgs @@ -415,11 +417,11 @@ func (suite *AnteTestSuite) TestAnteDecorator() { packet := channeltypes.NewPacket(ibctesting.MockPacketData, 2, suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, - clienttypes.NewHeight(1, 0), 0) + clienttypes.NewHeight(2, 0), 0) return []sdk.Msg{ - suite.createRecvPacketMessage(uint64(1), false), - channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(0, 1), "signer"), + suite.createRecvPacketMessage(false), + channeltypes.NewMsgRecvPacket(packet, []byte("proof"), clienttypes.NewHeight(1, 1), "signer"), } }, false, @@ -427,13 +429,13 @@ func (suite *AnteTestSuite) TestAnteDecorator() { { "no success on one new message and one redundant message in the same block", func(suite *AnteTestSuite) []sdk.Msg { - msg := suite.createRecvPacketMessage(uint64(1), false) + msg := suite.createRecvPacketMessage(false) // We want to be able to run check tx with the non-redundant message without - // commiting it to a block, so that the when check tx runs with the redundant + // committing it to a block, so that the when check tx runs with the redundant // message they are both in the same block k := suite.chainB.App.GetIBCKeeper() - decorator := ante.NewAnteDecorator(k) + decorator := ante.NewRedundantRelayDecorator(k) checkCtx := suite.chainB.GetContext().WithIsCheckTx(true) next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { return ctx, nil } txBuilder := suite.chainB.TxConfig.NewTxBuilder() @@ -458,7 +460,7 @@ func (suite *AnteTestSuite) TestAnteDecorator() { suite.SetupTest() k := suite.chainB.App.GetIBCKeeper() - decorator := ante.NewAnteDecorator(k) + decorator := ante.NewRedundantRelayDecorator(k) msgs := tc.malleate(suite) diff --git a/modules/core/client/cli/cli.go b/modules/core/client/cli/cli.go index a16b1d17751..6d5da971264 100644 --- a/modules/core/client/cli/cli.go +++ b/modules/core/client/cli/cli.go @@ -1,20 +1,19 @@ package cli import ( - "github.com/spf13/cobra" - "github.com/cosmos/cosmos-sdk/client" + "github.com/spf13/cobra" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client" - connection "github.com/cosmos/ibc-go/v4/modules/core/03-connection" - channel "github.com/cosmos/ibc-go/v4/modules/core/04-channel" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" + connection "github.com/cosmos/ibc-go/v7/modules/core/03-connection" + channel "github.com/cosmos/ibc-go/v7/modules/core/04-channel" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // GetTxCmd returns the transaction commands for this module func GetTxCmd() *cobra.Command { ibcTxCmd := &cobra.Command{ - Use: host.ModuleName, + Use: ibcexported.ModuleName, Short: "IBC transaction subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, @@ -33,7 +32,7 @@ func GetTxCmd() *cobra.Command { func GetQueryCmd() *cobra.Command { // Group ibc queries under a subcommand ibcQueryCmd := &cobra.Command{ - Use: host.ModuleName, + Use: ibcexported.ModuleName, Short: "Querying commands for the IBC module", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, diff --git a/modules/core/client/query.go b/modules/core/client/query.go index 3dd56aa92cc..48a87b3fa17 100644 --- a/modules/core/client/query.go +++ b/modules/core/client/query.go @@ -7,9 +7,9 @@ import ( "github.com/cosmos/cosmos-sdk/codec" abci "github.com/tendermint/tendermint/abci/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // QueryTendermintProof performs an ABCI query with the given key and returns @@ -39,7 +39,7 @@ func QueryTendermintProof(clientCtx client.Context, key []byte) ([]byte, []byte, } req := abci.RequestQuery{ - Path: fmt.Sprintf("store/%s/key", host.StoreKey), + Path: fmt.Sprintf("store/%s/key", ibcexported.StoreKey), Height: height, Data: key, Prove: true, diff --git a/modules/core/exported/client.go b/modules/core/exported/client.go index 4dce203bea4..88273ecc860 100644 --- a/modules/core/exported/client.go +++ b/modules/core/exported/client.go @@ -3,7 +3,7 @@ package exported import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - proto "github.com/gogo/protobuf/proto" + proto "github.com/cosmos/gogoproto/proto" ) // Status represents the status of a client @@ -19,10 +19,6 @@ const ( // Tendermint is used to indicate that the client uses the Tendermint Consensus Algorithm. Tendermint string = "07-tendermint" - // Localhost is the client type for a localhost client. It is also used as the clientID - // for the localhost client. - Localhost string = "09-localhost" - // Active is a status type of a client. An active client is allowed to be used. Active Status = "Active" @@ -44,137 +40,92 @@ type ClientState interface { GetLatestHeight() Height Validate() error - // Initialization function - // Clients must validate the initial consensus state, and may store any client-specific metadata - // necessary for correct light client operation - Initialize(sdk.Context, codec.BinaryCodec, sdk.KVStore, ConsensusState) error - - // Status function - // Clients must return their status. Only Active clients are allowed to process packets. + // Status must return the status of the client. Only Active clients are allowed to process packets. Status(ctx sdk.Context, clientStore sdk.KVStore, cdc codec.BinaryCodec) Status - // Genesis function - ExportMetadata(sdk.KVStore) []GenesisMetadata - - // Update and Misbehaviour functions + // ExportMetadata must export metadata stored within the clientStore for genesis export + ExportMetadata(clientStore sdk.KVStore) []GenesisMetadata - CheckHeaderAndUpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, Header) (ClientState, ConsensusState, error) - CheckMisbehaviourAndUpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, Misbehaviour) (ClientState, error) - CheckSubstituteAndUpdateState(ctx sdk.Context, cdc codec.BinaryCodec, subjectClientStore, substituteClientStore sdk.KVStore, substituteClient ClientState) (ClientState, error) - - // Upgrade functions - // NOTE: proof heights are not included as upgrade to a new revision is expected to pass only on the last - // height committed by the current revision. Clients are responsible for ensuring that the planned last - // height of the current revision is somehow encoded in the proof verification process. - // This is to ensure that no premature upgrades occur, since upgrade plans committed to by the counterparty - // may be cancelled or modified before the last planned height. - VerifyUpgradeAndUpdateState( - ctx sdk.Context, - cdc codec.BinaryCodec, - store sdk.KVStore, - newClient ClientState, - newConsState ConsensusState, - proofUpgradeClient, - proofUpgradeConsState []byte, - ) (ClientState, ConsensusState, error) - // Utility function that zeroes out any client customizable fields in client state + // ZeroCustomFields zeroes out any client customizable fields in client state // Ledger enforced fields are maintained while all custom fields are zero values // Used to verify upgrades ZeroCustomFields() ClientState - // State verification functions - - VerifyClientState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height Height, - prefix Prefix, - counterpartyClientIdentifier string, - proof []byte, - clientState ClientState, - ) error - VerifyClientConsensusState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height Height, - counterpartyClientIdentifier string, - consensusHeight Height, - prefix Prefix, - proof []byte, - consensusState ConsensusState, - ) error - VerifyConnectionState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height Height, - prefix Prefix, - proof []byte, - connectionID string, - connectionEnd ConnectionI, - ) error - VerifyChannelState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height Height, - prefix Prefix, - proof []byte, - portID, - channelID string, - channel ChannelI, - ) error - VerifyPacketCommitment( + // GetTimestampAtHeight must return the timestamp for the consensus state associated with the provided height. + GetTimestampAtHeight( ctx sdk.Context, - store sdk.KVStore, + clientStore sdk.KVStore, cdc codec.BinaryCodec, height Height, - delayTimePeriod uint64, - delayBlockPeriod uint64, - prefix Prefix, - proof []byte, - portID, - channelID string, - sequence uint64, - commitmentBytes []byte, - ) error - VerifyPacketAcknowledgement( + ) (uint64, error) + + // Initialize is called upon client creation, it allows the client to perform validation on the initial consensus state and set the + // client state, consensus state and any client-specific metadata necessary for correct light client operation in the provided client store. + Initialize(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, consensusState ConsensusState) error + + // VerifyMembership is a generic proof verification method which verifies a proof of the existence of a value at a given CommitmentPath at the specified height. + // The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24). + VerifyMembership( ctx sdk.Context, - store sdk.KVStore, + clientStore sdk.KVStore, cdc codec.BinaryCodec, height Height, delayTimePeriod uint64, delayBlockPeriod uint64, - prefix Prefix, proof []byte, - portID, - channelID string, - sequence uint64, - acknowledgement []byte, + path Path, + value []byte, ) error - VerifyPacketReceiptAbsence( + + // VerifyNonMembership is a generic proof verification method which verifies the absence of a given CommitmentPath at a specified height. + // The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24). + VerifyNonMembership( ctx sdk.Context, - store sdk.KVStore, + clientStore sdk.KVStore, cdc codec.BinaryCodec, height Height, delayTimePeriod uint64, delayBlockPeriod uint64, - prefix Prefix, proof []byte, - portID, - channelID string, - sequence uint64, + path Path, ) error - VerifyNextSequenceRecv( + + // VerifyClientMessage must verify a ClientMessage. A ClientMessage could be a Header, Misbehaviour, or batch update. + // It must handle each type of ClientMessage appropriately. Calls to CheckForMisbehaviour, UpdateState, and UpdateStateOnMisbehaviour + // will assume that the content of the ClientMessage has been verified and can be trusted. An error should be returned + // if the ClientMessage fails to verify. + VerifyClientMessage(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) error + + // Checks for evidence of a misbehaviour in Header or Misbehaviour type. It assumes the ClientMessage + // has already been verified. + CheckForMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) bool + + // UpdateStateOnMisbehaviour should perform appropriate state changes on a client state given that misbehaviour has been detected and verified + UpdateStateOnMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) + + // UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. + // Upon successful update, a list of consensus heights is returned. It assumes the ClientMessage has already been verified. + UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) []Height + + // CheckSubstituteAndUpdateState must verify that the provided substitute may be used to update the subject client. + // The light client must set the updated client and consensus states within the clientStore for the subject client. + CheckSubstituteAndUpdateState(ctx sdk.Context, cdc codec.BinaryCodec, subjectClientStore, substituteClientStore sdk.KVStore, substituteClient ClientState) error + + // Upgrade functions + // NOTE: proof heights are not included as upgrade to a new revision is expected to pass only on the last + // height committed by the current revision. Clients are responsible for ensuring that the planned last + // height of the current revision is somehow encoded in the proof verification process. + // This is to ensure that no premature upgrades occur, since upgrade plans committed to by the counterparty + // may be cancelled or modified before the last planned height. + // If the upgrade is verified, the upgraded client and consensus states must be set in the client store. + VerifyUpgradeAndUpdateState( ctx sdk.Context, - store sdk.KVStore, cdc codec.BinaryCodec, - height Height, - delayTimePeriod uint64, - delayBlockPeriod uint64, - prefix Prefix, - proof []byte, - portID, - channelID string, - nextSequenceRecv uint64, + store sdk.KVStore, + newClient ClientState, + newConsState ConsensusState, + proofUpgradeClient, + proofUpgradeConsState []byte, ) error } @@ -184,31 +135,19 @@ type ConsensusState interface { ClientType() string // Consensus kind - // GetRoot returns the commitment root of the consensus state, - // which is used for key-value pair verification. - GetRoot() Root - // GetTimestamp returns the timestamp (in nanoseconds) of the consensus state GetTimestamp() uint64 ValidateBasic() error } -// Misbehaviour defines counterparty misbehaviour for a specific consensus type -type Misbehaviour interface { - proto.Message - - ClientType() string - GetClientID() string - ValidateBasic() error -} - -// Header is the consensus state update information -type Header interface { +// ClientMessage is an interface used to update an IBC client. +// The update may be done by a single header, a batch of headers, misbehaviour, or any type which when verified produces +// a change to state of the IBC client +type ClientMessage interface { proto.Message ClientType() string - GetHeight() Height ValidateBasic() error } diff --git a/modules/core/exported/commitment.go b/modules/core/exported/commitment.go index 99f304e2792..904910e44e9 100644 --- a/modules/core/exported/commitment.go +++ b/modules/core/exported/commitment.go @@ -1,6 +1,6 @@ package exported -import ics23 "github.com/confio/ics23/go" +import ics23 "github.com/cosmos/ics23/go" // ICS 023 Types Implementation // @@ -35,7 +35,7 @@ type Path interface { // Proof implements spec:CommitmentProof. // Proof can prove whether the key-value pair is a part of the Root or not. // Each proof has designated key-value pair it is able to prove. -// Proofs includes key but value is provided dynamically at the verification time. +// Proofs include key but value is provided dynamically at the verification time. type Proof interface { VerifyMembership([]*ics23.ProofSpec, Root, Path, []byte) error VerifyNonMembership([]*ics23.ProofSpec, Root, Path) error diff --git a/modules/core/exported/connection.go b/modules/core/exported/connection.go index 8f705daff1a..93129050db2 100644 --- a/modules/core/exported/connection.go +++ b/modules/core/exported/connection.go @@ -5,7 +5,6 @@ type ConnectionI interface { GetClientID() string GetState() int32 GetCounterparty() CounterpartyConnectionI - GetVersions() []Version GetDelayPeriod() uint64 ValidateBasic() error } diff --git a/modules/core/exported/expected_keepers.go b/modules/core/exported/expected_keepers.go new file mode 100644 index 00000000000..32bac1a00fb --- /dev/null +++ b/modules/core/exported/expected_keepers.go @@ -0,0 +1,15 @@ +package exported + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" +) + +// ScopedKeeper defines the expected x/capability scoped keeper interface +type ScopedKeeper interface { + NewCapability(ctx sdk.Context, name string) (*capabilitytypes.Capability, error) + GetCapability(ctx sdk.Context, name string) (*capabilitytypes.Capability, bool) + AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool + LookupModules(ctx sdk.Context, name string) ([]string, *capabilitytypes.Capability, error) + ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error +} diff --git a/modules/core/24-host/keys.go b/modules/core/exported/module.go similarity index 68% rename from modules/core/24-host/keys.go rename to modules/core/exported/module.go index 090030b6479..5af7d78b7a9 100644 --- a/modules/core/24-host/keys.go +++ b/modules/core/exported/module.go @@ -1,15 +1,12 @@ -package host +package exported const ( // ModuleName is the name of the IBC module ModuleName = "ibc" - // StoreKey is the string store representation - StoreKey string = ModuleName - + StoreKey = ModuleName // QuerierRoute is the querier route for the IBC module - QuerierRoute string = ModuleName - + QuerierRoute = ModuleName // RouterKey is the msg router key for the IBC module - RouterKey string = ModuleName + RouterKey = ModuleName ) diff --git a/modules/core/genesis.go b/modules/core/genesis.go index 7f9f65fa46f..42661193665 100644 --- a/modules/core/genesis.go +++ b/modules/core/genesis.go @@ -3,16 +3,16 @@ package ibc import ( sdk "github.com/cosmos/cosmos-sdk/types" - client "github.com/cosmos/ibc-go/v4/modules/core/02-client" - connection "github.com/cosmos/ibc-go/v4/modules/core/03-connection" - channel "github.com/cosmos/ibc-go/v4/modules/core/04-channel" - "github.com/cosmos/ibc-go/v4/modules/core/keeper" - "github.com/cosmos/ibc-go/v4/modules/core/types" + client "github.com/cosmos/ibc-go/v7/modules/core/02-client" + connection "github.com/cosmos/ibc-go/v7/modules/core/03-connection" + channel "github.com/cosmos/ibc-go/v7/modules/core/04-channel" + "github.com/cosmos/ibc-go/v7/modules/core/keeper" + "github.com/cosmos/ibc-go/v7/modules/core/types" ) // InitGenesis initializes the ibc state from a provided genesis // state. -func InitGenesis(ctx sdk.Context, k keeper.Keeper, createLocalhost bool, gs *types.GenesisState) { +func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs *types.GenesisState) { client.InitGenesis(ctx, k.ClientKeeper, gs.ClientGenesis) connection.InitGenesis(ctx, k.ConnectionKeeper, gs.ConnectionGenesis) channel.InitGenesis(ctx, k.ChannelKeeper, gs.ChannelGenesis) diff --git a/modules/core/genesis_test.go b/modules/core/genesis_test.go index cf0cf19efb0..215383fe09d 100644 --- a/modules/core/genesis_test.go +++ b/modules/core/genesis_test.go @@ -8,25 +8,23 @@ import ( "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - ibc "github.com/cosmos/ibc-go/v4/modules/core" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/core/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - localhosttypes "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - "github.com/cosmos/ibc-go/v4/testing/simapp" + ibc "github.com/cosmos/ibc-go/v7/modules/core" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) const ( connectionID = "connection-0" clientID = "07-tendermint-0" connectionID2 = "connection-1" - clientID2 = "07-tendermin-1" - localhostID = exported.Localhost + "-1" + clientID2 = "07-tendermint-1" port1 = "firstport" port2 = "secondport" @@ -35,7 +33,7 @@ const ( channel2 = "channel-1" ) -var clientHeight = clienttypes.NewHeight(0, 10) +var clientHeight = clienttypes.NewHeight(1, 10) type IBCTestSuite struct { suite.Suite @@ -77,10 +75,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - clienttypes.NewIdentifiedClientState( - localhostID, localhosttypes.NewClientState("chaindID", clientHeight), + clientID, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []clienttypes.ClientConsensusStates{ @@ -89,7 +84,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []clienttypes.ConsensusStateWithHeight{ clienttypes.NewConsensusStateWithHeight( header.GetHeight().(clienttypes.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.AppHash), header.Header.NextValidatorsHash, ), ), @@ -105,8 +100,8 @@ func (suite *IBCTestSuite) TestValidateGenesis() { }, ), }, - clienttypes.NewParams(exported.Tendermint, exported.Localhost), - true, + clienttypes.NewParams(exported.Tendermint), + false, 2, ), ConnectionGenesis: connectiontypes.NewGenesisState( @@ -157,10 +152,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - clienttypes.NewIdentifiedClientState( - localhostID, localhosttypes.NewClientState("(chaindID)", clienttypes.ZeroHeight()), + clientID, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, nil, @@ -241,10 +233,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), - ), - clienttypes.NewIdentifiedClientState( - exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight), + clientID, ibctm.NewClientState(suite.chainA.ChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath), ), }, []clienttypes.ClientConsensusStates{ @@ -253,7 +242,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { []clienttypes.ConsensusStateWithHeight{ clienttypes.NewConsensusStateWithHeight( header.GetHeight().(clienttypes.Height), - ibctmtypes.NewConsensusState( + ibctm.NewConsensusState( header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.AppHash), header.Header.NextValidatorsHash, ), ), @@ -269,8 +258,8 @@ func (suite *IBCTestSuite) TestInitGenesis() { }, ), }, - clienttypes.NewParams(exported.Tendermint, exported.Localhost), - true, + clienttypes.NewParams(exported.Tendermint), + false, 0, ), ConnectionGenesis: connectiontypes.NewGenesisState( @@ -320,7 +309,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { app := simapp.Setup(false) suite.NotPanics(func() { - ibc.InitGenesis(app.BaseApp.NewContext(false, tmproto.Header{Height: 1}), *app.IBCKeeper, true, tc.genState) + ibc.InitGenesis(app.BaseApp.NewContext(false, tmproto.Header{Height: 1}), *app.IBCKeeper, tc.genState) }) } } @@ -355,7 +344,7 @@ func (suite *IBCTestSuite) TestExportGenesis() { // init genesis based on export suite.NotPanics(func() { - ibc.InitGenesis(suite.chainA.GetContext(), *suite.chainA.App.GetIBCKeeper(), true, gs) + ibc.InitGenesis(suite.chainA.GetContext(), *suite.chainA.App.GetIBCKeeper(), gs) }) suite.NotPanics(func() { @@ -366,7 +355,7 @@ func (suite *IBCTestSuite) TestExportGenesis() { // init genesis based on marshal and unmarshal suite.NotPanics(func() { - ibc.InitGenesis(suite.chainA.GetContext(), *suite.chainA.App.GetIBCKeeper(), true, gs) + ibc.InitGenesis(suite.chainA.GetContext(), *suite.chainA.App.GetIBCKeeper(), gs) }) }) } diff --git a/modules/core/keeper/grpc_query.go b/modules/core/keeper/grpc_query.go index c42d7857616..a0d57ad36ac 100644 --- a/modules/core/keeper/grpc_query.go +++ b/modules/core/keeper/grpc_query.go @@ -3,9 +3,9 @@ package keeper import ( "context" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // ClientState implements the IBC QueryServer interface @@ -48,6 +48,11 @@ func (q Keeper) UpgradedClientState(c context.Context, req *clienttypes.QueryUpg return q.ClientKeeper.UpgradedClientState(c, req) } +// UpgradedConsensusState implements the IBC QueryServer interface +func (q Keeper) UpgradedConsensusState(c context.Context, req *clienttypes.QueryUpgradedConsensusStateRequest) (*clienttypes.QueryUpgradedConsensusStateResponse, error) { + return q.ClientKeeper.UpgradedConsensusState(c, req) +} + // Connection implements the IBC QueryServer interface func (q Keeper) Connection(c context.Context, req *connectiontypes.QueryConnectionRequest) (*connectiontypes.QueryConnectionResponse, error) { return q.ConnectionKeeper.Connection(c, req) @@ -73,6 +78,11 @@ func (q Keeper) ConnectionConsensusState(c context.Context, req *connectiontypes return q.ConnectionKeeper.ConnectionConsensusState(c, req) } +// ConnectionParams implements the IBC QueryServer interface +func (q Keeper) ConnectionParams(c context.Context, req *connectiontypes.QueryConnectionParamsRequest) (*connectiontypes.QueryConnectionParamsResponse, error) { + return q.ConnectionKeeper.ConnectionParams(c, req) +} + // Channel implements the IBC QueryServer interface func (q Keeper) Channel(c context.Context, req *channeltypes.QueryChannelRequest) (*channeltypes.QueryChannelResponse, error) { return q.ChannelKeeper.Channel(c, req) diff --git a/modules/core/keeper/keeper.go b/modules/core/keeper/keeper.go index 5ae7f4e40e7..a887b845bf4 100644 --- a/modules/core/keeper/keeper.go +++ b/modules/core/keeper/keeper.go @@ -5,18 +5,18 @@ import ( "reflect" "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - clientkeeper "github.com/cosmos/ibc-go/v4/modules/core/02-client/keeper" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectionkeeper "github.com/cosmos/ibc-go/v4/modules/core/03-connection/keeper" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channelkeeper "github.com/cosmos/ibc-go/v4/modules/core/04-channel/keeper" - portkeeper "github.com/cosmos/ibc-go/v4/modules/core/05-port/keeper" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - "github.com/cosmos/ibc-go/v4/modules/core/types" + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectionkeeper "github.com/cosmos/ibc-go/v7/modules/core/03-connection/keeper" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channelkeeper "github.com/cosmos/ibc-go/v7/modules/core/04-channel/keeper" + portkeeper "github.com/cosmos/ibc-go/v7/modules/core/05-port/keeper" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + "github.com/cosmos/ibc-go/v7/modules/core/types" ) var _ types.QueryServer = (*Keeper)(nil) @@ -37,7 +37,7 @@ type Keeper struct { // NewKeeper creates a new ibc Keeper func NewKeeper( - cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace paramtypes.Subspace, + cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, stakingKeeper clienttypes.StakingKeeper, upgradeKeeper clienttypes.UpgradeKeeper, scopedKeeper capabilitykeeper.ScopedKeeper, ) *Keeper { @@ -50,11 +50,10 @@ func NewKeeper( } // panic if any of the keepers passed in is empty - if reflect.ValueOf(stakingKeeper).IsZero() { + if isEmpty(stakingKeeper) { panic(fmt.Errorf("cannot initialize IBC keeper: empty staking keeper")) } - - if reflect.ValueOf(upgradeKeeper).IsZero() { + if isEmpty(upgradeKeeper) { panic(fmt.Errorf("cannot initialize IBC keeper: empty upgrade keeper")) } @@ -92,3 +91,19 @@ func (k *Keeper) SetRouter(rtr *porttypes.Router) { k.Router = rtr k.Router.Seal() } + +// isEmpty checks if the interface is an empty struct or a pointer pointing +// to an empty struct +func isEmpty(keeper interface{}) bool { + switch reflect.TypeOf(keeper).Kind() { + case reflect.Ptr: + if reflect.ValueOf(keeper).Elem().IsZero() { + return true + } + default: + if reflect.ValueOf(keeper).IsZero() { + return true + } + } + return false +} diff --git a/modules/core/keeper/keeper_test.go b/modules/core/keeper/keeper_test.go index ec808bdc0e0..60dd960ccba 100644 --- a/modules/core/keeper/keeper_test.go +++ b/modules/core/keeper/keeper_test.go @@ -6,16 +6,15 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - "github.com/stretchr/testify/suite" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" + "github.com/stretchr/testify/suite" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) type KeeperTestSuite struct { @@ -60,14 +59,14 @@ func (d MockStakingKeeper) UnbondingTime(ctx sdk.Context) time.Duration { // It verifies if ibckeeper.NewKeeper panic when any of the keepers passed in is empty. func (suite *KeeperTestSuite) TestNewKeeper() { var ( - stakingKeeper clienttypes.StakingKeeper - upgradeKeeper clienttypes.UpgradeKeeper - scopedKeeper capabilitykeeper.ScopedKeeper - newIBCKeeper = func() { + stakingKeeper clienttypes.StakingKeeper + upgradeKeeper clienttypes.UpgradeKeeper + scopedKeeper capabilitykeeper.ScopedKeeper + newIBCKeeperFn = func() { ibckeeper.NewKeeper( suite.chainA.GetSimApp().AppCodec(), - suite.chainA.GetSimApp().GetKey(ibchost.StoreKey), - suite.chainA.GetSimApp().GetSubspace(ibchost.ModuleName), + suite.chainA.GetSimApp().GetKey(ibcexported.StoreKey), + suite.chainA.GetSimApp().GetSubspace(ibcexported.ModuleName), stakingKeeper, upgradeKeeper, scopedKeeper, @@ -80,10 +79,15 @@ func (suite *KeeperTestSuite) TestNewKeeper() { malleate func() expPass bool }{ - {"failure: empty staking keeper", func() { - emptyStakingKeeper := stakingkeeper.Keeper{} + {"failure: empty staking keeper value", func() { + emptyStakingKeeperValue := stakingkeeper.Keeper{} - stakingKeeper = emptyStakingKeeper + stakingKeeper = emptyStakingKeeperValue + }, false}, + {"failure: empty staking keeper pointer", func() { + emptyStakingKeeperPointer := &stakingkeeper.Keeper{} + + stakingKeeper = emptyStakingKeeperPointer }, false}, {"failure: empty mock staking keeper", func() { // use a different implementation of clienttypes.StakingKeeper @@ -91,10 +95,15 @@ func (suite *KeeperTestSuite) TestNewKeeper() { stakingKeeper = emptyMockStakingKeeper }, false}, - {"failure: empty upgrade keeper", func() { - emptyUpgradeKeeper := upgradekeeper.Keeper{} + {"failure: empty upgrade keeper value", func() { + emptyUpgradeKeeperValue := upgradekeeper.Keeper{} + + upgradeKeeper = emptyUpgradeKeeperValue + }, false}, + {"failure: empty upgrade keeper pointer", func() { + emptyUpgradeKeeperPointer := &upgradekeeper.Keeper{} - upgradeKeeper = emptyUpgradeKeeper + upgradeKeeper = emptyUpgradeKeeperPointer }, false}, {"failure: empty scoped keeper", func() { emptyScopedKeeper := capabilitykeeper.ScopedKeeper{} @@ -122,11 +131,11 @@ func (suite *KeeperTestSuite) TestNewKeeper() { if tc.expPass { suite.Require().NotPanics( - newIBCKeeper, + newIBCKeeperFn, ) } else { suite.Require().Panics( - newIBCKeeper, + newIBCKeeperFn, ) } }) diff --git a/modules/core/keeper/migrations.go b/modules/core/keeper/migrations.go index 5a79c8399ec..423429092c7 100644 --- a/modules/core/keeper/migrations.go +++ b/modules/core/keeper/migrations.go @@ -3,7 +3,7 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - clientkeeper "github.com/cosmos/ibc-go/v4/modules/core/02-client/keeper" + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" ) // Migrator is a struct for handling in-place store migrations. @@ -16,15 +16,10 @@ func NewMigrator(keeper Keeper) Migrator { return Migrator{keeper: keeper} } -// Migrate1to2 migrates from version 1 to 2. -// This migration prunes: -// - migrates solo machine client state from protobuf definition v1 to v2 -// - prunes solo machine consensus states -// - prunes expired tendermint consensus states -// - adds ProcessedHeight and Iteration keys for unexpired tendermint consensus states -func (m Migrator) Migrate1to2(ctx sdk.Context) error { +// Migrate2to3 migrates from version 2 to 3. See 02-client keeper function Migrate2to3. +func (m Migrator) Migrate2to3(ctx sdk.Context) error { clientMigrator := clientkeeper.NewMigrator(m.keeper.ClientKeeper) - if err := clientMigrator.Migrate1to2(ctx); err != nil { + if err := clientMigrator.Migrate2to3(ctx); err != nil { return err } diff --git a/modules/core/keeper/msg_server.go b/modules/core/keeper/msg_server.go index b08edaf41a2..01d93e17f03 100644 --- a/modules/core/keeper/msg_server.go +++ b/modules/core/keeper/msg_server.go @@ -3,17 +3,16 @@ package keeper import ( "context" + errorsmod "cosmossdk.io/errors" metrics "github.com/armon/go-metrics" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - coretypes "github.com/cosmos/ibc-go/v4/modules/core/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/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" + coretypes "github.com/cosmos/ibc-go/v7/modules/core/types" ) var ( @@ -47,12 +46,12 @@ func (k Keeper) CreateClient(goCtx context.Context, msg *clienttypes.MsgCreateCl func (k Keeper) UpdateClient(goCtx context.Context, msg *clienttypes.MsgUpdateClient) (*clienttypes.MsgUpdateClientResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - header, err := clienttypes.UnpackHeader(msg.Header) + clientMsg, err := clienttypes.UnpackClientMessage(msg.ClientMessage) if err != nil { return nil, err } - if err = k.ClientKeeper.UpdateClient(ctx, msg.ClientId, header); err != nil { + if err = k.ClientKeeper.UpdateClient(ctx, msg.ClientId, clientMsg); err != nil { return nil, err } @@ -81,16 +80,18 @@ func (k Keeper) UpgradeClient(goCtx context.Context, msg *clienttypes.MsgUpgrade } // SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. +// Warning: DEPRECATED +// This handler is redudant as `MsgUpdateClient` is now capable of handling both a Header and a Misbehaviour func (k Keeper) SubmitMisbehaviour(goCtx context.Context, msg *clienttypes.MsgSubmitMisbehaviour) (*clienttypes.MsgSubmitMisbehaviourResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - misbehaviour, err := clienttypes.UnpackMisbehaviour(msg.Misbehaviour) + misbehaviour, err := clienttypes.UnpackClientMessage(msg.Misbehaviour) if err != nil { return nil, err } - if err := k.ClientKeeper.CheckMisbehaviourAndUpdateState(ctx, misbehaviour); err != nil { - return nil, sdkerrors.Wrap(err, "failed to process misbehaviour for IBC client") + if err = k.ClientKeeper.UpdateClient(ctx, msg.ClientId, misbehaviour); err != nil { + return nil, err } return &clienttypes.MsgSubmitMisbehaviourResponse{}, nil @@ -101,7 +102,7 @@ func (k Keeper) ConnectionOpenInit(goCtx context.Context, msg *connectiontypes.M ctx := sdk.UnwrapSDKContext(goCtx) if _, err := k.ConnectionKeeper.ConnOpenInit(ctx, msg.ClientId, msg.Counterparty, msg.Version, msg.DelayPeriod); err != nil { - return nil, sdkerrors.Wrap(err, "connection handshake open init failed") + return nil, errorsmod.Wrap(err, "connection handshake open init failed") } return &connectiontypes.MsgConnectionOpenInitResponse{}, nil @@ -121,7 +122,7 @@ func (k Keeper) ConnectionOpenTry(goCtx context.Context, msg *connectiontypes.Ms connectiontypes.ProtoVersionsToExported(msg.CounterpartyVersions), msg.ProofInit, msg.ProofClient, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, ); err != nil { - return nil, sdkerrors.Wrap(err, "connection handshake open try failed") + return nil, errorsmod.Wrap(err, "connection handshake open try failed") } return &connectiontypes.MsgConnectionOpenTryResponse{}, nil @@ -140,7 +141,7 @@ func (k Keeper) ConnectionOpenAck(goCtx context.Context, msg *connectiontypes.Ms msg.ProofTry, msg.ProofClient, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, ); err != nil { - return nil, sdkerrors.Wrap(err, "connection handshake open ack failed") + return nil, errorsmod.Wrap(err, "connection handshake open ack failed") } return &connectiontypes.MsgConnectionOpenAckResponse{}, nil @@ -153,7 +154,7 @@ func (k Keeper) ConnectionOpenConfirm(goCtx context.Context, msg *connectiontype if err := k.ConnectionKeeper.ConnOpenConfirm( ctx, msg.ConnectionId, msg.ProofAck, msg.ProofHeight, ); err != nil { - return nil, sdkerrors.Wrap(err, "connection handshake open confirm failed") + return nil, errorsmod.Wrap(err, "connection handshake open confirm failed") } return &connectiontypes.MsgConnectionOpenConfirmResponse{}, nil @@ -168,13 +169,15 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan // Lookup module by port capability module, portCap, err := k.PortKeeper.LookupModuleByPort(ctx, msg.PortId) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("channel open init callback failed", "port-id", msg.PortId, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve application callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("channel open init callback failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } // Perform 04-channel verification @@ -183,18 +186,22 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan portCap, msg.Channel.Counterparty, msg.Channel.Version, ) if err != nil { - return nil, sdkerrors.Wrap(err, "channel handshake open init failed") + ctx.Logger().Error("channel open init callback failed", "error", errorsmod.Wrap(err, "channel handshake open init failed")) + return nil, errorsmod.Wrap(err, "channel handshake open init failed") } // Perform application logic callback version, err := cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version) if err != nil { - return nil, sdkerrors.Wrap(err, "channel open init callback failed") + ctx.Logger().Error("channel open init callback failed", "port-id", msg.PortId, "channel-id", channelID, "error", err.Error()) + return nil, errorsmod.Wrapf(err, "channel open init callback failed for port ID: %s, channel ID: %s", msg.PortId, channelID) } // Write channel into state k.ChannelKeeper.WriteOpenInitChannel(ctx, msg.PortId, channelID, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.Channel.Counterparty, version) + ctx.Logger().Info("channel open init callback succeeded", "channel-id", channelID, "version", version) + return &channeltypes.MsgChannelOpenInitResponse{ ChannelId: channelID, Version: version, @@ -210,13 +217,15 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann // Lookup module by port capability module, portCap, err := k.PortKeeper.LookupModuleByPort(ctx, msg.PortId) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("channel open try callback failed", "port-id", msg.PortId, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve application callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("channel open try callback failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } // Perform 04-channel verification @@ -224,20 +233,25 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann portCap, msg.Channel.Counterparty, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, ) if err != nil { - return nil, sdkerrors.Wrap(err, "channel handshake open try failed") + ctx.Logger().Error("channel open try callback failed", "error", errorsmod.Wrap(err, "channel handshake open try failed")) + return nil, errorsmod.Wrap(err, "channel handshake open try failed") } // Perform application logic callback version, err := cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.CounterpartyVersion) if err != nil { - return nil, sdkerrors.Wrap(err, "channel open try callback failed") + ctx.Logger().Error("channel open try callback failed", "port-id", msg.PortId, "channel-id", channelID, "error", err.Error()) + return nil, errorsmod.Wrapf(err, "channel open try callback failed for port ID: %s, channel ID: %s", msg.PortId, channelID) } // Write channel into state k.ChannelKeeper.WriteOpenTryChannel(ctx, msg.PortId, channelID, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.Channel.Counterparty, version) + ctx.Logger().Info("channel open try callback succeeded", "channel-id", channelID, "port-id", msg.PortId, "version", version) + return &channeltypes.MsgChannelOpenTryResponse{ - Version: version, + ChannelId: channelID, + Version: version, }, nil } @@ -250,29 +264,35 @@ func (k Keeper) ChannelOpenAck(goCtx context.Context, msg *channeltypes.MsgChann // Lookup module by channel capability module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("channel open ack callback failed", "port-id", msg.PortId, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve application callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("channel open ack callback failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } // Perform 04-channel verification if err = k.ChannelKeeper.ChanOpenAck( ctx, msg.PortId, msg.ChannelId, cap, msg.CounterpartyVersion, msg.CounterpartyChannelId, msg.ProofTry, msg.ProofHeight, ); err != nil { - return nil, sdkerrors.Wrap(err, "channel handshake open ack failed") + ctx.Logger().Error("channel open ack callback failed", "error", err.Error()) + return nil, errorsmod.Wrap(err, "channel handshake open ack failed") } + // Write channel into state + k.ChannelKeeper.WriteOpenAckChannel(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyVersion, msg.CounterpartyChannelId) + // Perform application logic callback if err = cbs.OnChanOpenAck(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyChannelId, msg.CounterpartyVersion); err != nil { - return nil, sdkerrors.Wrap(err, "channel open ack callback failed") + ctx.Logger().Error("channel handshake open ack callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + return nil, errorsmod.Wrapf(err, "channel open ack callback failed for port ID: %s, channel ID: %s", msg.PortId, msg.ChannelId) } - // Write channel into state - k.ChannelKeeper.WriteOpenAckChannel(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyVersion, msg.CounterpartyChannelId) + ctx.Logger().Info("channel open ack callback succeeded", "channel-id", msg.ChannelId, "port-id", msg.PortId) return &channeltypes.MsgChannelOpenAckResponse{}, nil } @@ -286,27 +306,33 @@ func (k Keeper) ChannelOpenConfirm(goCtx context.Context, msg *channeltypes.MsgC // Lookup module by channel capability module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("channel open confirm callback failed", "port-id", msg.PortId, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve application callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("channel open confirm callback failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } // Perform 04-channel verification if err = k.ChannelKeeper.ChanOpenConfirm(ctx, msg.PortId, msg.ChannelId, cap, msg.ProofAck, msg.ProofHeight); err != nil { - return nil, sdkerrors.Wrap(err, "channel handshake open confirm failed") + ctx.Logger().Error("channel open confirm callback failed", "error", errorsmod.Wrap(err, "channel handshake open confirm failed")) + return nil, errorsmod.Wrap(err, "channel handshake open confirm failed") } + // Write channel into state + k.ChannelKeeper.WriteOpenConfirmChannel(ctx, msg.PortId, msg.ChannelId) + // Perform application logic callback if err = cbs.OnChanOpenConfirm(ctx, msg.PortId, msg.ChannelId); err != nil { - return nil, sdkerrors.Wrap(err, "channel open confirm callback failed") + ctx.Logger().Error("channel handshake open confirm callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + return nil, errorsmod.Wrapf(err, "channel open confirm callback failed for port ID: %s, channel ID: %s", msg.PortId, msg.ChannelId) } - // Write channel into state - k.ChannelKeeper.WriteOpenConfirmChannel(ctx, msg.PortId, msg.ChannelId) + ctx.Logger().Info("channel open confirm callback succeeded", "channel-id", msg.ChannelId, "port-id", msg.PortId) return &channeltypes.MsgChannelOpenConfirmResponse{}, nil } @@ -317,24 +343,30 @@ func (k Keeper) ChannelCloseInit(goCtx context.Context, msg *channeltypes.MsgCha // Lookup module by channel capability module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("channel close init callback failed", "port-id", msg.PortId, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("channel close init callback failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } if err = cbs.OnChanCloseInit(ctx, msg.PortId, msg.ChannelId); err != nil { - return nil, sdkerrors.Wrap(err, "channel close init callback failed") + ctx.Logger().Error("channel close init callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + return nil, errorsmod.Wrapf(err, "channel close init callback failed for port ID: %s, channel ID: %s", msg.PortId, msg.ChannelId) } err = k.ChannelKeeper.ChanCloseInit(ctx, msg.PortId, msg.ChannelId, cap) if err != nil { - return nil, sdkerrors.Wrap(err, "channel handshake close init failed") + ctx.Logger().Error("channel handshake close init callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + return nil, errorsmod.Wrap(err, "channel handshake close init failed") } + ctx.Logger().Info("channel close init callback succeeded", "channel-id", msg.ChannelId, "port-id", msg.PortId) + return &channeltypes.MsgChannelCloseInitResponse{}, nil } @@ -345,24 +377,30 @@ func (k Keeper) ChannelCloseConfirm(goCtx context.Context, msg *channeltypes.Msg // Lookup module by channel capability module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("channel close confirm callback failed", "port-id", msg.PortId, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("channel close confirm callback failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } if err = cbs.OnChanCloseConfirm(ctx, msg.PortId, msg.ChannelId); err != nil { - return nil, sdkerrors.Wrap(err, "channel close confirm callback failed") + ctx.Logger().Error("channel close confirm callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + return nil, errorsmod.Wrapf(err, "channel close confirm callback failed for port ID: %s, channel ID: %s", msg.PortId, msg.ChannelId) } err = k.ChannelKeeper.ChanCloseConfirm(ctx, msg.PortId, msg.ChannelId, cap, msg.ProofInit, msg.ProofHeight) if err != nil { - return nil, sdkerrors.Wrap(err, "channel handshake close confirm failed") + ctx.Logger().Error("channel handshake close confirm callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + return nil, errorsmod.Wrap(err, "channel handshake close confirm failed") } + ctx.Logger().Info("channel close confirm callback succeeded", "channel-id", msg.ChannelId, "port-id", msg.PortId) + return &channeltypes.MsgChannelCloseConfirmResponse{}, nil } @@ -372,19 +410,22 @@ func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacke relayer, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return nil, sdkerrors.Wrap(err, "Invalid address for msg Signer") + ctx.Logger().Error("receive packet failed", "error", errorsmod.Wrap(err, "Invalid address for msg Signer")) + return nil, errorsmod.Wrap(err, "Invalid address for msg Signer") } // Lookup module by channel capability module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("receive packet failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("receive packet failed", "port-id", msg.Packet.SourcePort, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } // Perform TAO verification @@ -394,16 +435,15 @@ func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacke cacheCtx, writeFn := ctx.CacheContext() err = k.ChannelKeeper.RecvPacket(cacheCtx, cap, msg.Packet, msg.ProofCommitment, msg.ProofHeight) - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - switch err { case nil: writeFn() case channeltypes.ErrNoOpMsg: + // no-ops do not need event emission as they will be ignored return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.NOOP}, nil default: - return nil, sdkerrors.Wrap(err, "receive packet verification failed") + ctx.Logger().Error("receive packet failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "receive packet verification failed")) + return nil, errorsmod.Wrap(err, "receive packet verification failed") } // Perform application logic callback @@ -411,12 +451,13 @@ func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacke // Cache context so that we may discard state changes from callback if the acknowledgement is unsuccessful. cacheCtx, writeFn = ctx.CacheContext() ack := cbs.OnRecvPacket(cacheCtx, msg.Packet, relayer) - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - // Events from callback are emitted regardless of acknowledgement success - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) if ack == nil || ack.Success() { // write application state changes for asynchronous and successful acknowledgements writeFn() + } else { + // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. + // Events should still be emitted from failed acks and asynchronous acks + ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) } // Set packet acknowledgement only if the acknowledgement is not nil. @@ -441,6 +482,8 @@ func (k Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacke ) }() + ctx.Logger().Info("receive packet callback succeeded", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "result", channeltypes.SUCCESS.String()) + return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.SUCCESS}, nil } @@ -450,19 +493,22 @@ func (k Keeper) Timeout(goCtx context.Context, msg *channeltypes.MsgTimeout) (*c relayer, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return nil, sdkerrors.Wrap(err, "Invalid address for msg Signer") + ctx.Logger().Error("timeout failed", "error", errorsmod.Wrap(err, "Invalid address for msg Signer")) + return nil, errorsmod.Wrap(err, "Invalid address for msg Signer") } // Lookup module by channel capability module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.SourcePort, msg.Packet.SourceChannel) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("timeout failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("timeout failed", "port-id", msg.Packet.SourcePort, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } // Perform TAO verification @@ -472,22 +518,22 @@ func (k Keeper) Timeout(goCtx context.Context, msg *channeltypes.MsgTimeout) (*c cacheCtx, writeFn := ctx.CacheContext() err = k.ChannelKeeper.TimeoutPacket(cacheCtx, msg.Packet, msg.ProofUnreceived, msg.ProofHeight, msg.NextSequenceRecv) - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - switch err { case nil: writeFn() case channeltypes.ErrNoOpMsg: + // no-ops do not need event emission as they will be ignored return &channeltypes.MsgTimeoutResponse{Result: channeltypes.NOOP}, nil default: - return nil, sdkerrors.Wrap(err, "timeout packet verification failed") + ctx.Logger().Error("timeout failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "timeout packet verification failed")) + return nil, errorsmod.Wrap(err, "timeout packet verification failed") } // Perform application logic callback err = cbs.OnTimeoutPacket(ctx, msg.Packet, relayer) if err != nil { - return nil, sdkerrors.Wrap(err, "timeout packet callback failed") + ctx.Logger().Error("timeout failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "timeout packet callback failed")) + return nil, errorsmod.Wrap(err, "timeout packet callback failed") } // Delete packet commitment @@ -509,6 +555,8 @@ func (k Keeper) Timeout(goCtx context.Context, msg *channeltypes.MsgTimeout) (*c ) }() + ctx.Logger().Info("timeout packet callback succeeded", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "result", channeltypes.SUCCESS.String()) + return &channeltypes.MsgTimeoutResponse{Result: channeltypes.SUCCESS}, nil } @@ -518,19 +566,22 @@ func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeo relayer, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return nil, sdkerrors.Wrap(err, "Invalid address for msg Signer") + ctx.Logger().Error("timeout on close failed", "error", errorsmod.Wrap(err, "Invalid address for msg Signer")) + return nil, errorsmod.Wrap(err, "Invalid address for msg Signer") } // Lookup module by channel capability module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.SourcePort, msg.Packet.SourceChannel) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("timeout on close failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("timeout on close failed", "port-id", msg.Packet.SourcePort, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } // Perform TAO verification @@ -540,16 +591,15 @@ func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeo cacheCtx, writeFn := ctx.CacheContext() err = k.ChannelKeeper.TimeoutOnClose(cacheCtx, cap, msg.Packet, msg.ProofUnreceived, msg.ProofClose, msg.ProofHeight, msg.NextSequenceRecv) - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - switch err { case nil: writeFn() case channeltypes.ErrNoOpMsg: + // no-ops do not need event emission as they will be ignored return &channeltypes.MsgTimeoutOnCloseResponse{Result: channeltypes.NOOP}, nil default: - return nil, sdkerrors.Wrap(err, "timeout on close packet verification failed") + ctx.Logger().Error("timeout on close failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "timeout on close packet verification failed")) + return nil, errorsmod.Wrap(err, "timeout on close packet verification failed") } // Perform application logic callback @@ -558,7 +608,8 @@ func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeo // application logic callback. err = cbs.OnTimeoutPacket(ctx, msg.Packet, relayer) if err != nil { - return nil, sdkerrors.Wrap(err, "timeout packet callback failed") + ctx.Logger().Error("timeout on close failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "timeout packet callback failed")) + return nil, errorsmod.Wrap(err, "timeout packet callback failed") } // Delete packet commitment @@ -580,6 +631,8 @@ func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeo ) }() + ctx.Logger().Info("timeout on close callback succeeded", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "result", channeltypes.SUCCESS.String()) + return &channeltypes.MsgTimeoutOnCloseResponse{Result: channeltypes.SUCCESS}, nil } @@ -589,19 +642,22 @@ func (k Keeper) Acknowledgement(goCtx context.Context, msg *channeltypes.MsgAckn relayer, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { - return nil, sdkerrors.Wrap(err, "Invalid address for msg Signer") + ctx.Logger().Error("acknowledgement failed", "error", errorsmod.Wrap(err, "Invalid address for msg Signer")) + return nil, errorsmod.Wrap(err, "Invalid address for msg Signer") } // Lookup module by channel capability module, cap, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.SourcePort, msg.Packet.SourceChannel) if err != nil { - return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + ctx.Logger().Error("acknowledgement failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "could not retrieve module from port-id")) + return nil, errorsmod.Wrap(err, "could not retrieve module from port-id") } // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) + ctx.Logger().Error("acknowledgement failed", "port-id", msg.Packet.SourcePort, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } // Perform TAO verification @@ -611,22 +667,22 @@ func (k Keeper) Acknowledgement(goCtx context.Context, msg *channeltypes.MsgAckn cacheCtx, writeFn := ctx.CacheContext() err = k.ChannelKeeper.AcknowledgePacket(cacheCtx, cap, msg.Packet, msg.Acknowledgement, msg.ProofAcked, msg.ProofHeight) - // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - switch err { case nil: writeFn() case channeltypes.ErrNoOpMsg: + // no-ops do not need event emission as they will be ignored return &channeltypes.MsgAcknowledgementResponse{Result: channeltypes.NOOP}, nil default: - return nil, sdkerrors.Wrap(err, "acknowledge packet verification failed") + ctx.Logger().Error("acknowledgement failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "acknowledge packet verification failed")) + return nil, errorsmod.Wrap(err, "acknowledge packet verification failed") } // Perform application logic callback err = cbs.OnAcknowledgementPacket(ctx, msg.Packet, msg.Acknowledgement, relayer) if err != nil { - return nil, sdkerrors.Wrap(err, "acknowledge packet callback failed") + ctx.Logger().Error("acknowledgement failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "acknowledge packet callback failed")) + return nil, errorsmod.Wrap(err, "acknowledge packet callback failed") } defer func() { @@ -642,6 +698,8 @@ func (k Keeper) Acknowledgement(goCtx context.Context, msg *channeltypes.MsgAckn ) }() + ctx.Logger().Info("acknowledgement succeeded", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "result", channeltypes.SUCCESS.String()) + return &channeltypes.MsgAcknowledgementResponse{Result: channeltypes.SUCCESS}, nil } diff --git a/modules/core/keeper/msg_server_test.go b/modules/core/keeper/msg_server_test.go index 3205c218bc7..b46dbcff4c8 100644 --- a/modules/core/keeper/msg_server_test.go +++ b/modules/core/keeper/msg_server_test.go @@ -4,19 +4,19 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/core/keeper" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/keeper" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" ) var ( - timeoutHeight = clienttypes.NewHeight(0, 10000) + timeoutHeight = clienttypes.NewHeight(1, 10000) maxSequence = uint64(10) ) @@ -41,17 +41,19 @@ func (suite *KeeperTestSuite) TestHandleRecvPacket() { {"success: ORDERED", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) }, true, false}, {"success: UNORDERED", func() { suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) }, true, false}, {"success: UNORDERED out of order packet", func() { // setup uses an UNORDERED channel @@ -59,35 +61,38 @@ func (suite *KeeperTestSuite) TestHandleRecvPacket() { // attempts to receive packet with sequence 10 without receiving packet with sequence 1 for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.MockPacketData, i, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) } }, true, false}, {"success: OnRecvPacket callback returns revert=true", func() { suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockFailPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockFailPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockFailPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) }, true, true}, {"success: ORDERED - async acknowledgement", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) async = true - packet = channeltypes.NewPacket(ibcmock.MockAsyncPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibcmock.MockAsyncPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibcmock.MockAsyncPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) }, true, false}, {"success: UNORDERED - async acknowledgement", func() { suite.coordinator.Setup(path) async = true - packet = channeltypes.NewPacket(ibcmock.MockAsyncPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibcmock.MockAsyncPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibcmock.MockAsyncPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) }, true, false}, {"failure: ORDERED out of order packet", func() { path.SetChannelOrdered() @@ -95,10 +100,10 @@ func (suite *KeeperTestSuite) TestHandleRecvPacket() { // attempts to receive packet with sequence 10 without receiving packet with sequence 1 for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.MockPacketData, i, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) } }, false, false}, {"channel does not exist", func() { @@ -113,22 +118,22 @@ func (suite *KeeperTestSuite) TestHandleRecvPacket() { // mock will panic if application callback is called twice on the same packet path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) }, true, false}, {"successful no-op: UNORDERED - packet already received (replay)", func() { // mock will panic if application callback is called twice on the same packet suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) }, true, false}, @@ -211,21 +216,21 @@ func (suite *KeeperTestSuite) TestHandleAcknowledgePacket() { {"success: ORDERED", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) }, true}, {"success: UNORDERED", func() { suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) }, true}, @@ -235,11 +240,10 @@ func (suite *KeeperTestSuite) TestHandleAcknowledgePacket() { // attempts to acknowledge ack with sequence 10 without acknowledging ack with sequence 1 (removing packet commitment) for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.MockPacketData, i, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) } @@ -250,11 +254,10 @@ func (suite *KeeperTestSuite) TestHandleAcknowledgePacket() { // attempts to acknowledge ack with sequence 10 without acknowledging ack with sequence 1 (removing packet commitment for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.MockPacketData, i, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) } @@ -265,18 +268,19 @@ func (suite *KeeperTestSuite) TestHandleAcknowledgePacket() { }, false}, {"packet not received", func() { suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) }, false}, {"successful no-op: ORDERED - packet already acknowledged (replay)", func() { suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -286,11 +290,10 @@ func (suite *KeeperTestSuite) TestHandleAcknowledgePacket() { {"successful no-op: UNORDERED - packet already acknowledged (replay)", func() { suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) err = path.EndpointB.RecvPacket(packet) suite.Require().NoError(err) @@ -358,28 +361,36 @@ func (suite *KeeperTestSuite) TestHandleTimeoutPacket() { {"success: ORDERED", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // need to update chainA client to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) packetKey = host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) }, true}, {"success: UNORDERED", func() { suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) suite.Require().NoError(err) // need to update chainA client to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, timeoutTimestamp) packetKey = host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) }, true}, {"success: UNORDERED timeout out of order packet", func() { @@ -389,14 +400,18 @@ func (suite *KeeperTestSuite) TestHandleTimeoutPacket() { // attempts to timeout the last packet sent without timing out the first packet // packet sequences begin at 1 for i := uint64(1); i < maxSequence; i++ { - packet = channeltypes.NewPacket(ibctesting.MockPacketData, i, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), 0) + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) } - path.EndpointA.UpdateClient() + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packetKey = host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) }, true}, {"success: ORDERED timeout out of order packet", func() { @@ -406,14 +421,18 @@ func (suite *KeeperTestSuite) TestHandleTimeoutPacket() { // attempts to timeout the last packet sent without timing out the first packet // packet sequences begin at 1 for i := uint64(1); i < maxSequence; i++ { - packet = channeltypes.NewPacket(ibctesting.MockPacketData, i, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), 0) + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) } - path.EndpointA.UpdateClient() + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packetKey = host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) }, true}, {"channel does not exist", func() { @@ -472,7 +491,7 @@ func (suite *KeeperTestSuite) TestHandleTimeoutPacket() { // and unordered channels. It verifies that the deletion of a packet // commitment occurs. It tests high level properties like ordering and basic // sanity checks. More rigorous testing of 'TimeoutOnClose' and -//'TimeoutExecuted' can be found in the 04-channel/keeper/timeout_test.go. +// 'TimeoutExecuted' can be found in the 04-channel/keeper/timeout_test.go. func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { var ( packet channeltypes.Packet @@ -488,35 +507,39 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { {"success: ORDERED", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) // need to update chainA client to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) packetKey = host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) // close counterparty channel - path.EndpointB.SetChannelClosed() + err = path.EndpointB.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) }, true}, {"success: UNORDERED", func() { suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) // need to update chainA client to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) packetKey = host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) // close counterparty channel - path.EndpointB.SetChannelClosed() + err = path.EndpointB.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) }, true}, {"success: UNORDERED timeout out of order packet", func() { // setup uses an UNORDERED channel @@ -525,18 +548,21 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { // attempts to timeout the last packet sent without timing out the first packet // packet sequences begin at 1 for i := uint64(1); i < maxSequence; i++ { - packet = channeltypes.NewPacket(ibctesting.MockPacketData, i, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) } - path.EndpointA.UpdateClient() + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packetKey = host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) // close counterparty channel - path.EndpointB.SetChannelClosed() + err = path.EndpointB.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) }, true}, {"success: ORDERED timeout out of order packet", func() { path.SetChannelOrdered() @@ -545,18 +571,21 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { // attempts to timeout the last packet sent without timing out the first packet // packet sequences begin at 1 for i := uint64(1); i < maxSequence; i++ { - packet = channeltypes.NewPacket(ibctesting.MockPacketData, i, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) - // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) + + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) } - path.EndpointA.UpdateClient() + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packetKey = host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) // close counterparty channel - path.EndpointB.SetChannelClosed() + err = path.EndpointB.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) }, true}, {"channel does not exist", func() { // any non-nil value of packet is valid @@ -570,20 +599,22 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { packetKey = host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) // close counterparty channel - path.EndpointB.SetChannelClosed() + err := path.EndpointB.SetChannelState(channeltypes.CLOSED) + suite.Require().NoError(err) }, true}, {"ORDERED: channel not closed", func() { path.SetChannelOrdered() suite.coordinator.Setup(path) - packet = channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) // create packet commitment - err := path.EndpointA.SendPacket(packet) + sequence, err := path.EndpointA.SendPacket(timeoutHeight, 0, ibctesting.MockPacketData) suite.Require().NoError(err) // need to update chainA client to prove missing ack - path.EndpointA.UpdateClient() + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + packet = channeltypes.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0) packetKey = host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) }, false}, } @@ -627,15 +658,13 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { func (suite *KeeperTestSuite) TestUpgradeClient() { var ( path *ibctesting.Path + newChainID string + newClientHeight clienttypes.Height upgradedClient exported.ClientState upgradedConsState exported.ConsensusState lastHeight exported.Height msg *clienttypes.MsgUpgradeClient ) - - newClientHeight := clienttypes.NewHeight(1, 1) - newChainId := "newChainId-1" - cases := []struct { name string setup func() @@ -644,11 +673,11 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { { name: "successful upgrade", setup: func() { - upgradedClient = ibctmtypes.NewClientState(newChainId, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedClient = ibctm.NewClientState(newChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient upgradedClient = upgradedClient.ZeroCustomFields() - upgradedConsState = &ibctmtypes.ConsensusState{ + upgradedConsState = &ibctm.ConsensusState{ NextValidatorsHash: []byte("nextValsHash"), } @@ -661,8 +690,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { suite.Require().NoError(err) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for testing + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for testing // commit upgrade store changes and update clients suite.coordinator.CommitBlock(suite.chainB) @@ -684,11 +713,11 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { { name: "VerifyUpgrade fails", setup: func() { - upgradedClient = ibctmtypes.NewClientState(newChainId, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedClient = ibctm.NewClientState(newChainID, ibctm.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath) // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient upgradedClient = upgradedClient.ZeroCustomFields() - upgradedConsState = &ibctmtypes.ConsensusState{ + upgradedConsState = &ibctm.ConsensusState{ NextValidatorsHash: []byte("nextValsHash"), } @@ -701,8 +730,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { suite.Require().NoError(err) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for testing + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for testing // commit upgrade store changes and update clients suite.coordinator.CommitBlock(suite.chainB) @@ -721,9 +750,18 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { path = ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(path) + var err error + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) + revisionNumber := clienttypes.ParseChainID(clientState.ChainId) + + newChainID, err = clienttypes.SetRevisionNumber(clientState.ChainId, revisionNumber+1) + suite.Require().NoError(err) + + newClientHeight = clienttypes.NewHeight(revisionNumber+1, clientState.GetLatestHeight().GetRevisionHeight()+1) + tc.setup() - _, err := keeper.Keeper.UpgradeClient(*suite.chainA.App.GetIBCKeeper(), sdk.WrapSDKContext(suite.chainA.GetContext()), msg) + _, err = keeper.Keeper.UpgradeClient(*suite.chainA.App.GetIBCKeeper(), sdk.WrapSDKContext(suite.chainA.GetContext()), msg) if tc.expPass { suite.Require().NoError(err, "upgrade handler failed on valid case: %s", tc.name) diff --git a/modules/core/legacy/v100/genesis.go b/modules/core/legacy/v100/genesis.go deleted file mode 100644 index 78e8f0d6065..00000000000 --- a/modules/core/legacy/v100/genesis.go +++ /dev/null @@ -1,54 +0,0 @@ -package v100 - -import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - tmtypes "github.com/tendermint/tendermint/types" - - clientv100 "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/types" -) - -// MigrateGenesis accepts exported v1.0.0 IBC client genesis file and migrates it to: -// -// - Update solo machine client state protobuf definition (v1 to v2) -// - Remove all solo machine consensus states -// - Remove all expired tendermint consensus states -func MigrateGenesis(appState genutiltypes.AppMap, clientCtx client.Context, genDoc tmtypes.GenesisDoc, maxExpectedTimePerBlock uint64) (genutiltypes.AppMap, error) { - if appState[host.ModuleName] != nil { - // ensure legacy solo machines are registered - clientv100.RegisterInterfaces(clientCtx.InterfaceRegistry) - - // unmarshal relative source genesis application state - ibcGenState := &types.GenesisState{} - clientCtx.JSONCodec.MustUnmarshalJSON(appState[host.ModuleName], ibcGenState) - - clientGenState, err := clientv100.MigrateGenesis(codec.NewProtoCodec(clientCtx.InterfaceRegistry), &ibcGenState.ClientGenesis, genDoc.GenesisTime, clienttypes.NewHeight(clienttypes.ParseChainID(genDoc.ChainID), uint64(genDoc.InitialHeight))) - if err != nil { - return nil, err - } - - ibcGenState.ClientGenesis = *clientGenState - - // set max expected time per block - connectionGenesis := connectiontypes.GenesisState{ - Connections: ibcGenState.ConnectionGenesis.Connections, - ClientConnectionPaths: ibcGenState.ConnectionGenesis.ClientConnectionPaths, - NextConnectionSequence: ibcGenState.ConnectionGenesis.NextConnectionSequence, - Params: connectiontypes.NewParams(maxExpectedTimePerBlock), - } - - ibcGenState.ConnectionGenesis = connectionGenesis - - // delete old genesis state - delete(appState, host.ModuleName) - - // set new ibc genesis state - appState[host.ModuleName] = clientCtx.JSONCodec.MustMarshalJSON(ibcGenState) - } - return appState, nil -} diff --git a/modules/core/legacy/v100/genesis_test.go b/modules/core/legacy/v100/genesis_test.go deleted file mode 100644 index 85e239862d9..00000000000 --- a/modules/core/legacy/v100/genesis_test.go +++ /dev/null @@ -1,178 +0,0 @@ -package v100_test - -import ( - "testing" - - "github.com/cosmos/cosmos-sdk/client" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - "github.com/stretchr/testify/suite" - tmtypes "github.com/tendermint/tendermint/types" - - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client" - clientv100 "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - v100 "github.com/cosmos/ibc-go/v4/modules/core/legacy/v100" - "github.com/cosmos/ibc-go/v4/modules/core/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - "github.com/cosmos/ibc-go/v4/testing/simapp" -) - -type LegacyTestSuite struct { - suite.Suite - - coordinator *ibctesting.Coordinator - - // testing chains used for convenience and readability - chainA *ibctesting.TestChain - chainB *ibctesting.TestChain -} - -// TestLegacyTestSuite runs all the tests within this package. -func TestLegacyTestSuite(t *testing.T) { - suite.Run(t, new(LegacyTestSuite)) -} - -// SetupTest creates a coordinator with 2 test chains. -func (suite *LegacyTestSuite) SetupTest() { - suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) - suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) - suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) - // commit some blocks so that QueryProof returns valid proof (cannot return valid query if height <= 1) - suite.coordinator.CommitNBlocks(suite.chainA, 2) - suite.coordinator.CommitNBlocks(suite.chainB, 2) -} - -// NOTE: this test is mainly copied from 02-client/legacy/v100 -func (suite *LegacyTestSuite) TestMigrateGenesisSolomachine() { - path := ibctesting.NewPath(suite.chainA, suite.chainB) - encodingConfig := simapp.MakeTestEncodingConfig() - clientCtx := client.Context{}. - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithJSONCodec(encodingConfig.Marshaler) - - // create multiple legacy solo machine clients - solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1) - solomachineMulti := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4) - - // create tendermint clients - // NOTE: only 1 set of metadata is created, we aren't testing ordering - // The purpose of this test is to ensure the genesis states can be marshalled/unmarshalled - suite.coordinator.SetupClients(path) - clientGenState := ibcclient.ExportGenesis(path.EndpointA.Chain.GetContext(), path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper) - - // manually generate old proto buf definitions and set in genesis - // NOTE: we cannot use 'ExportGenesis' for the solo machines since we are - // using client states and consensus states which do not implement the exported.ClientState - // and exported.ConsensusState interface - var clients []clienttypes.IdentifiedClientState - for _, sm := range []*ibctesting.Solomachine{solomachine, solomachineMulti} { - clientState := sm.ClientState() - - var seq uint64 - if clientState.IsFrozen { - seq = 1 - } - - // generate old client state proto defintion - legacyClientState := &clientv100.ClientState{ - Sequence: clientState.Sequence, - FrozenSequence: seq, - ConsensusState: &clientv100.ConsensusState{ - PublicKey: clientState.ConsensusState.PublicKey, - Diversifier: clientState.ConsensusState.Diversifier, - Timestamp: clientState.ConsensusState.Timestamp, - }, - AllowUpdateAfterProposal: clientState.AllowUpdateAfterProposal, - } - - // set client state - any, err := codectypes.NewAnyWithValue(legacyClientState) - suite.Require().NoError(err) - suite.Require().NotNil(any) - client := clienttypes.IdentifiedClientState{ - ClientId: sm.ClientID, - ClientState: any, - } - clients = append(clients, client) - - // set in store for ease of determining expected genesis - clientStore := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(path.EndpointA.Chain.GetContext(), sm.ClientID) - bz, err := path.EndpointA.Chain.App.AppCodec().MarshalInterface(legacyClientState) - suite.Require().NoError(err) - clientStore.Set(host.ClientStateKey(), bz) - - // set some consensus states - height1 := clienttypes.NewHeight(0, 1) - height2 := clienttypes.NewHeight(1, 2) - height3 := clienttypes.NewHeight(0, 123) - - any, err = codectypes.NewAnyWithValue(legacyClientState.ConsensusState) - suite.Require().NoError(err) - suite.Require().NotNil(any) - consensusState1 := clienttypes.ConsensusStateWithHeight{ - Height: height1, - ConsensusState: any, - } - consensusState2 := clienttypes.ConsensusStateWithHeight{ - Height: height2, - ConsensusState: any, - } - consensusState3 := clienttypes.ConsensusStateWithHeight{ - Height: height3, - ConsensusState: any, - } - - clientConsensusState := clienttypes.ClientConsensusStates{ - ClientId: sm.ClientID, - ConsensusStates: []clienttypes.ConsensusStateWithHeight{consensusState1, consensusState2, consensusState3}, - } - - clientGenState.ClientsConsensus = append(clientGenState.ClientsConsensus, clientConsensusState) - - // set in store for ease of determining expected genesis - bz, err = path.EndpointA.Chain.App.AppCodec().MarshalInterface(legacyClientState.ConsensusState) - suite.Require().NoError(err) - clientStore.Set(host.ConsensusStateKey(height1), bz) - clientStore.Set(host.ConsensusStateKey(height2), bz) - clientStore.Set(host.ConsensusStateKey(height3), bz) - } - // solo machine clients must come before tendermint in expected - clientGenState.Clients = append(clients, clientGenState.Clients...) - - // migrate store get expected genesis - // store migration and genesis migration should produce identical results - err := clientv100.MigrateStore(path.EndpointA.Chain.GetContext(), path.EndpointA.Chain.GetSimApp().GetKey(host.StoreKey), path.EndpointA.Chain.App.AppCodec()) - suite.Require().NoError(err) - expectedClientGenState := ibcclient.ExportGenesis(path.EndpointA.Chain.GetContext(), path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper) - - // NOTE: these lines are added in comparison to 02-client/legacy/v100 - // generate appState with old ibc genesis state - appState := genutiltypes.AppMap{} - ibcGenState := types.DefaultGenesisState() - ibcGenState.ClientGenesis = clientGenState - clientv100.RegisterInterfaces(clientCtx.InterfaceRegistry) - appState[host.ModuleName] = clientCtx.JSONCodec.MustMarshalJSON(ibcGenState) - genDoc := tmtypes.GenesisDoc{ - ChainID: suite.chainA.ChainID, - GenesisTime: suite.coordinator.CurrentTime, - InitialHeight: suite.chainA.GetContext().BlockHeight(), - } - - // NOTE: genesis time isn't updated since we aren't testing for tendermint consensus state pruning - migrated, err := v100.MigrateGenesis(appState, clientCtx, genDoc, uint64(connectiontypes.DefaultTimePerBlock)) - suite.Require().NoError(err) - - expectedAppState := genutiltypes.AppMap{} - expectedIBCGenState := types.DefaultGenesisState() - expectedIBCGenState.ClientGenesis = expectedClientGenState - - bz, err := clientCtx.JSONCodec.MarshalJSON(expectedIBCGenState) - suite.Require().NoError(err) - expectedAppState[host.ModuleName] = bz - - suite.Require().Equal(expectedAppState, migrated) -} diff --git a/modules/core/migrations/v7/genesis.go b/modules/core/migrations/v7/genesis.go new file mode 100644 index 00000000000..8647c4c77a7 --- /dev/null +++ b/modules/core/migrations/v7/genesis.go @@ -0,0 +1,42 @@ +package v7 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + + clientv7 "github.com/cosmos/ibc-go/v7/modules/core/02-client/migrations/v7" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/types" +) + +// MigrateGenesis accepts an exported IBC client genesis file and migrates it to: +// +// - Update solo machine client state protobuf definition (v2 to v3) +// - Remove all solo machine consensus states +// - Remove any localhost clients +func MigrateGenesis(appState genutiltypes.AppMap, cdc codec.ProtoCodecMarshaler) (genutiltypes.AppMap, error) { + if appState[ibcexported.ModuleName] == nil { + return appState, nil + } + + // ensure legacy solo machines types are registered + clientv7.RegisterInterfaces(cdc.InterfaceRegistry()) + + // unmarshal old ibc genesis state + ibcGenState := &types.GenesisState{} + cdc.MustUnmarshalJSON(appState[ibcexported.ModuleName], ibcGenState) + + clientGenState, err := clientv7.MigrateGenesis(&ibcGenState.ClientGenesis, cdc) + if err != nil { + return nil, err + } + + ibcGenState.ClientGenesis = *clientGenState + + // delete old genesis state + delete(appState, ibcexported.ModuleName) + + // set new ibc genesis state + appState[ibcexported.ModuleName] = cdc.MustMarshalJSON(ibcGenState) + return appState, nil +} diff --git a/modules/core/migrations/v7/genesis_test.go b/modules/core/migrations/v7/genesis_test.go new file mode 100644 index 00000000000..1a040534ff8 --- /dev/null +++ b/modules/core/migrations/v7/genesis_test.go @@ -0,0 +1,164 @@ +package v7_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/stretchr/testify/suite" + + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" + clientv7 "github.com/cosmos/ibc-go/v7/modules/core/02-client/migrations/v7" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + v7 "github.com/cosmos/ibc-go/v7/modules/core/migrations/v7" + "github.com/cosmos/ibc-go/v7/modules/core/types" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +type MigrationsV7TestSuite struct { + suite.Suite + + coordinator *ibctesting.Coordinator + + // testing chains used for convenience and readability + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain +} + +// TestMigrationsV7TestSuite runs all the tests within this package. +func TestMigrationsV7TestSuite(t *testing.T) { + suite.Run(t, new(MigrationsV7TestSuite)) +} + +// SetupTest creates a coordinator with 2 test chains. +func (suite *MigrationsV7TestSuite) SetupTest() { + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) + suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) + suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) +} + +// NOTE: this test is mainly copied from 02-client/migrations/v7/genesis_test.go +func (suite *MigrationsV7TestSuite) TestMigrateGenesisSolomachine() { + // create tendermint clients + for i := 0; i < 3; i++ { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + + suite.coordinator.SetupClients(path) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // update a second time to add more state + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + } + + // create multiple legacy solo machine clients + solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1) + solomachineMulti := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4) + + clientGenState := ibcclient.ExportGenesis(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper) + + // manually generate old proto buf definitions and set in genesis + // NOTE: we cannot use 'ExportGenesis' for the solo machines since we are + // using client states and consensus states which do not implement the exported.ClientState + // and exported.ConsensusState interface + var clients []clienttypes.IdentifiedClientState + for _, sm := range []*ibctesting.Solomachine{solomachine, solomachineMulti} { + clientState := sm.ClientState() + + // generate old client state proto definition + legacyClientState := &clientv7.ClientState{ + Sequence: clientState.Sequence, + ConsensusState: &clientv7.ConsensusState{ + PublicKey: clientState.ConsensusState.PublicKey, + Diversifier: clientState.ConsensusState.Diversifier, + Timestamp: clientState.ConsensusState.Timestamp, + }, + AllowUpdateAfterProposal: true, + } + + // set client state + protoAny, err := codectypes.NewAnyWithValue(legacyClientState) + suite.Require().NoError(err) + suite.Require().NotNil(protoAny) + + clients = append(clients, clienttypes.IdentifiedClientState{ + ClientId: sm.ClientID, + ClientState: protoAny, + }) + + // set in store for ease of determining expected genesis + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), sm.ClientID) + cdc := suite.chainA.App.AppCodec().(*codec.ProtoCodec) + clientv7.RegisterInterfaces(cdc.InterfaceRegistry()) + + bz, err := cdc.MarshalInterface(legacyClientState) + suite.Require().NoError(err) + clientStore.Set(host.ClientStateKey(), bz) + + protoAny, err = codectypes.NewAnyWithValue(legacyClientState.ConsensusState) + suite.Require().NoError(err) + suite.Require().NotNil(protoAny) + + // obtain marshalled bytes to set in client store + bz, err = cdc.MarshalInterface(legacyClientState.ConsensusState) + suite.Require().NoError(err) + + var consensusStates []clienttypes.ConsensusStateWithHeight + + // set consensus states in store and genesis + for i := uint64(0); i < 10; i++ { + height := clienttypes.NewHeight(1, i) + clientStore.Set(host.ConsensusStateKey(height), bz) + consensusStates = append(consensusStates, clienttypes.ConsensusStateWithHeight{ + Height: height, + ConsensusState: protoAny, + }) + } + + clientGenState.ClientsConsensus = append(clientGenState.ClientsConsensus, clienttypes.ClientConsensusStates{ + ClientId: sm.ClientID, + ConsensusStates: consensusStates, + }) + } + + // solo machine clients must come before tendermint in expected + clientGenState.Clients = append(clients, clientGenState.Clients...) + + // migrate store get expected genesis + // store migration and genesis migration should produce identical results + // NOTE: tendermint clients are not pruned in genesis so the test should not have expired tendermint clients + err := clientv7.MigrateStore(suite.chainA.GetContext(), suite.chainA.GetSimApp().GetKey(ibcexported.StoreKey), suite.chainA.App.AppCodec(), suite.chainA.GetSimApp().IBCKeeper.ClientKeeper) + suite.Require().NoError(err) + expectedClientGenState := ibcclient.ExportGenesis(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper) + + cdc := suite.chainA.App.AppCodec().(*codec.ProtoCodec) + + // NOTE: these lines are added in comparison to 02-client/migrations/v7/genesis_test.go + // generate appState with old ibc genesis state + appState := genutiltypes.AppMap{} + ibcGenState := types.DefaultGenesisState() + ibcGenState.ClientGenesis = clientGenState + + // ensure tests pass even if the legacy solo machine is already registered + clientv7.RegisterInterfaces(cdc.InterfaceRegistry()) + appState[ibcexported.ModuleName] = cdc.MustMarshalJSON(ibcGenState) + + // NOTE: genesis time isn't updated since we aren't testing for tendermint consensus state pruning + migrated, err := v7.MigrateGenesis(appState, cdc) + suite.Require().NoError(err) + + expectedAppState := genutiltypes.AppMap{} + expectedIBCGenState := types.DefaultGenesisState() + expectedIBCGenState.ClientGenesis = expectedClientGenState + + bz, err := cdc.MarshalJSON(expectedIBCGenState) + suite.Require().NoError(err) + expectedAppState[ibcexported.ModuleName] = bz + + suite.Require().Equal(expectedAppState, migrated) +} diff --git a/modules/core/module.go b/modules/core/module.go index b6285997652..4d55b6b2e3d 100644 --- a/modules/core/module.go +++ b/modules/core/module.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "math/rand" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -12,21 +11,20 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client" - clientkeeper "github.com/cosmos/ibc-go/v4/modules/core/02-client/keeper" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/client/cli" - "github.com/cosmos/ibc-go/v4/modules/core/keeper" - "github.com/cosmos/ibc-go/v4/modules/core/simulation" - "github.com/cosmos/ibc-go/v4/modules/core/types" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/client/cli" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/keeper" + "github.com/cosmos/ibc-go/v7/modules/core/simulation" + "github.com/cosmos/ibc-go/v7/modules/core/types" ) var ( @@ -42,7 +40,7 @@ var _ module.AppModuleBasic = AppModuleBasic{} // Name returns the ibc module's name. func (AppModuleBasic) Name() string { - return host.ModuleName + return exported.ModuleName } // RegisterLegacyAminoCodec does nothing. IBC does not support amino. @@ -58,20 +56,26 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { var gs types.GenesisState if err := cdc.UnmarshalJSON(bz, &gs); err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %w", host.ModuleName, err) + return fmt.Errorf("failed to unmarshal %s genesis state: %w", exported.ModuleName, err) } return gs.Validate() } -// RegisterRESTRoutes does nothing. IBC does not support legacy REST routes. -func (AppModuleBasic) RegisterRESTRoutes(client.Context, *mux.Router) {} - // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - clienttypes.RegisterQueryHandlerClient(context.Background(), mux, clienttypes.NewQueryClient(clientCtx)) - connectiontypes.RegisterQueryHandlerClient(context.Background(), mux, connectiontypes.NewQueryClient(clientCtx)) - channeltypes.RegisterQueryHandlerClient(context.Background(), mux, channeltypes.NewQueryClient(clientCtx)) + err := clienttypes.RegisterQueryHandlerClient(context.Background(), mux, clienttypes.NewQueryClient(clientCtx)) + if err != nil { + panic(err) + } + err = connectiontypes.RegisterQueryHandlerClient(context.Background(), mux, connectiontypes.NewQueryClient(clientCtx)) + if err != nil { + panic(err) + } + err = channeltypes.RegisterQueryHandlerClient(context.Background(), mux, channeltypes.NewQueryClient(clientCtx)) + if err != nil { + panic(err) + } } // GetTxCmd returns the root tx command for the ibc module. @@ -93,9 +97,6 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) type AppModule struct { AppModuleBasic keeper *keeper.Keeper - - // create localhost by default - createLocalhost bool } // NewAppModule creates a new AppModule object @@ -107,7 +108,7 @@ func NewAppModule(k *keeper.Keeper) AppModule { // Name returns the ibc module's name. func (AppModule) Name() string { - return host.ModuleName + return exported.ModuleName } // RegisterInvariants registers the ibc module invariants. @@ -115,21 +116,6 @@ func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { // TODO: } -// Route returns the message routing key for the ibc module. -func (am AppModule) Route() sdk.Route { - return sdk.Route{} -} - -// QuerierRoute returns the ibc module's querier route name. -func (AppModule) QuerierRoute() string { - return host.QuerierRoute -} - -// LegacyQuerierHandler returns nil. IBC does not support the legacy querier. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { - return nil -} - // RegisterServices registers module services. func (am AppModule) RegisterServices(cfg module.Configurator) { clienttypes.RegisterMsgServer(cfg.MsgServer(), am.keeper) @@ -138,7 +124,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryService(cfg.QueryServer(), am.keeper) m := clientkeeper.NewMigrator(am.keeper.ClientKeeper) - cfg.RegisterMigration(host.ModuleName, 1, m.Migrate1to2) + err := cfg.RegisterMigration(exported.ModuleName, 2, m.Migrate2to3) + if err != nil { + panic(err) + } } // InitGenesis performs genesis initialization for the ibc module. It returns @@ -147,9 +136,9 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, bz json.Ra var gs types.GenesisState err := cdc.UnmarshalJSON(bz, &gs) if err != nil { - panic(fmt.Sprintf("failed to unmarshal %s genesis state: %s", host.ModuleName, err)) + panic(fmt.Sprintf("failed to unmarshal %s genesis state: %s", exported.ModuleName, err)) } - InitGenesis(ctx, *am.keeper, am.createLocalhost, &gs) + InitGenesis(ctx, *am.keeper, &gs) return []abci.ValidatorUpdate{} } @@ -160,7 +149,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 2 } +func (AppModule) ConsensusVersion() uint64 { return 3 } // BeginBlock returns the begin blocker for the ibc module. func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { @@ -180,19 +169,9 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { simulation.RandomizedGenState(simState) } -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { - return nil -} - -// RandomizedParams returns nil since IBC doesn't register parameter changes. -func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { - return nil -} - // RegisterStoreDecoder registers a decoder for ibc module's types func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - sdr[host.StoreKey] = simulation.NewDecodeStore(*am.keeper) + sdr[exported.StoreKey] = simulation.NewDecodeStore(*am.keeper) } // WeightedOperations returns the all the ibc module operations with their respective weights. diff --git a/modules/core/simulation/decoder.go b/modules/core/simulation/decoder.go index fc2cc40bf00..1ed5bf72ad8 100644 --- a/modules/core/simulation/decoder.go +++ b/modules/core/simulation/decoder.go @@ -5,11 +5,11 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" - clientsim "github.com/cosmos/ibc-go/v4/modules/core/02-client/simulation" - connectionsim "github.com/cosmos/ibc-go/v4/modules/core/03-connection/simulation" - channelsim "github.com/cosmos/ibc-go/v4/modules/core/04-channel/simulation" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/keeper" + clientsim "github.com/cosmos/ibc-go/v7/modules/core/02-client/simulation" + connectionsim "github.com/cosmos/ibc-go/v7/modules/core/03-connection/simulation" + channelsim "github.com/cosmos/ibc-go/v7/modules/core/04-channel/simulation" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/keeper" ) // NewDecodeStore returns a decoder function closure that unmarshals the KVPair's @@ -28,6 +28,6 @@ func NewDecodeStore(k keeper.Keeper) func(kvA, kvB kv.Pair) string { return res } - panic(fmt.Sprintf("invalid %s key prefix: %s", host.ModuleName, string(kvA.Key))) + panic(fmt.Sprintf("invalid %s key prefix: %s", ibcexported.ModuleName, string(kvA.Key))) } } diff --git a/modules/core/simulation/decoder_test.go b/modules/core/simulation/decoder_test.go index f16d824c579..bf0388ccd69 100644 --- a/modules/core/simulation/decoder_test.go +++ b/modules/core/simulation/decoder_test.go @@ -7,13 +7,13 @@ import ( "github.com/cosmos/cosmos-sdk/types/kv" "github.com/stretchr/testify/require" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/simulation" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - "github.com/cosmos/ibc-go/v4/testing/simapp" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "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" + "github.com/cosmos/ibc-go/v7/modules/core/simulation" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) func TestDecodeStore(t *testing.T) { @@ -25,7 +25,7 @@ func TestDecodeStore(t *testing.T) { channelID := "channelidone" portID := "portidone" - clientState := &ibctmtypes.ClientState{ + clientState := &ibctm.ClientState{ FrozenHeight: clienttypes.NewHeight(0, 10), } connection := connectiontypes.ConnectionEnd{ diff --git a/modules/core/simulation/genesis.go b/modules/core/simulation/genesis.go index 9f5e0bc7f8d..187d986fd5f 100644 --- a/modules/core/simulation/genesis.go +++ b/modules/core/simulation/genesis.go @@ -9,14 +9,14 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" - clientsims "github.com/cosmos/ibc-go/v4/modules/core/02-client/simulation" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectionsims "github.com/cosmos/ibc-go/v4/modules/core/03-connection/simulation" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channelsims "github.com/cosmos/ibc-go/v4/modules/core/04-channel/simulation" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/types" + clientsims "github.com/cosmos/ibc-go/v7/modules/core/02-client/simulation" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectionsims "github.com/cosmos/ibc-go/v7/modules/core/03-connection/simulation" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channelsims "github.com/cosmos/ibc-go/v7/modules/core/04-channel/simulation" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/types" ) // Simulation parameter constants @@ -59,6 +59,6 @@ func RandomizedGenState(simState *module.SimulationState) { if err != nil { panic(err) } - fmt.Printf("Selected randomly generated %s parameters:\n%s\n", host.ModuleName, bz) - simState.GenState[host.ModuleName] = simState.Cdc.MustMarshalJSON(&ibcGenesis) + fmt.Printf("Selected randomly generated %s parameters:\n%s\n", ibcexported.ModuleName, bz) + simState.GenState[ibcexported.ModuleName] = simState.Cdc.MustMarshalJSON(&ibcGenesis) } diff --git a/modules/core/simulation/genesis_test.go b/modules/core/simulation/genesis_test.go index 20946fd5fd3..55dde9df7a9 100644 --- a/modules/core/simulation/genesis_test.go +++ b/modules/core/simulation/genesis_test.go @@ -5,21 +5,24 @@ import ( "math/rand" "testing" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/stretchr/testify/require" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/simulation" - "github.com/cosmos/ibc-go/v4/modules/core/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/simulation" + "github.com/cosmos/ibc-go/v7/modules/core/types" ) // TestRandomizedGenState tests the normal scenario of applying RandomizedGenState. // Abonormal scenarios are not tested here. func TestRandomizedGenState(t *testing.T) { interfaceRegistry := codectypes.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(interfaceRegistry) cdc := codec.NewProtoCodec(interfaceRegistry) s := rand.NewSource(1) @@ -31,7 +34,7 @@ func TestRandomizedGenState(t *testing.T) { Rand: r, NumBonded: 3, Accounts: simtypes.RandomAccounts(r, 3), - InitialStake: 1000, + InitialStake: math.NewInt(1000), GenState: make(map[string]json.RawMessage), } @@ -41,7 +44,7 @@ func TestRandomizedGenState(t *testing.T) { simulation.RandomizedGenState(&simState) var ibcGenesis types.GenesisState - simState.Cdc.MustUnmarshalJSON(simState.GenState[host.ModuleName], &ibcGenesis) + simState.Cdc.MustUnmarshalJSON(simState.GenState[ibcexported.ModuleName], &ibcGenesis) require.NotNil(t, ibcGenesis.ClientGenesis) require.NotNil(t, ibcGenesis.ConnectionGenesis) diff --git a/modules/core/spec/01_concepts.md b/modules/core/spec/01_concepts.md index 0ab6fa70710..3a06684f655 100644 --- a/modules/core/spec/01_concepts.md +++ b/modules/core/spec/01_concepts.md @@ -6,58 +6,58 @@ order: 1 ## Client Misbehaviour -IBC clients must freeze when the counterparty chain becomes byzantine and -takes actions that could fool the light client into accepting invalid state -transitions. Thus, relayers are able to submit Misbehaviour proofs that prove -that a counterparty chain has signed two Headers for the same height. This -constitutes misbehaviour as the IBC client could have accepted either header -as valid. Upon verifying the misbehaviour the IBC client must freeze at that +IBC clients must freeze when the counterparty chain becomes byzantine and +takes actions that could fool the light client into accepting invalid state +transitions. Thus, relayers are able to submit Misbehaviour proofs that prove +that a counterparty chain has signed two Headers for the same height. This +constitutes misbehaviour as the IBC client could have accepted either header +as valid. Upon verifying the misbehaviour the IBC client must freeze at that height so that any proof verifications for the frozen height or later fail. -Note, there is a difference between the chain-level Misbehaviour that IBC is -concerned with and the validator-level Evidence that Tendermint is concerned -with. Tendermint must be able to detect, submit, and punish any evidence of -individual validators breaking the Tendermint consensus protocol and attempting -to mount an attack. IBC clients must only act when an attack is successful -and the chain has successfully forked. In this case, valid Headers submitted +Note, there is a difference between the chain-level Misbehaviour that IBC is +concerned with and the validator-level Evidence that Tendermint is concerned +with. Tendermint must be able to detect, submit, and punish any evidence of +individual validators breaking the Tendermint consensus protocol and attempting +to mount an attack. IBC clients must only act when an attack is successful +and the chain has successfully forked. In this case, valid Headers submitted to the IBC client can no longer be trusted and the client must freeze. -Governance may then choose to override a frozen client and provide the correct, -canonical Header so that the client can continue operating after the Misbehaviour +Governance may then choose to override a frozen client and provide the correct, +canonical Header so that the client can continue operating after the Misbehaviour submission. ## Connection Handshake The connection handshake occurs in 4 steps as defined in [ICS 03](https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics). -`ConnOpenInit` is the first attempt to initialize a connection on the executing chain. -The handshake is expected to succeed if the version selected is supported. The connection +`ConnOpenInit` is the first attempt to initialize a connection on the executing chain. +The handshake is expected to succeed if the version selected is supported. The connection identifier for the counterparty connection must be left empty indicating that the counterparty -must select its own identifier. The connection identifier is auto derived in the format: +must select its own identifier. The connection identifier is auto derived in the format: `connection{N}` where N is the next sequence to be used. The counter begins at 0 and increments by 1. The connection is set and stored in the INIT state upon success. `ConnOpenTry` is a response to a chain executing `ConnOpenInit`. The executing chain will validate -the chain level parameters the counterparty has stored such as its chainID. The executing chain -will also verify that if a previous connection exists for the specified connection identifier -that all the parameters match and its previous state was in INIT. This may occur when both +the chain level parameters the counterparty has stored such as its chainID. The executing chain +will also verify that if a previous connection exists for the specified connection identifier +that all the parameters match and its previous state was in INIT. This may occur when both chains execute `ConnOpenInit` simultaneously. If the connection does not exist then a connection identifier is generated in the same format done in `ConnOpenInit`. The executing chain will verify -that the counterparty created a connection in INIT state. The executing chain will also verify -The `ClientState` and `ConsensusState` the counterparty stores for the executing chain. The -executing chain will select a version from the intersection of its supported versions and the -versions set by the counterparty. The connection is set and stored in the TRYOPEN state upon -success. +that the counterparty created a connection in INIT state. The executing chain will also verify +The `ClientState` and `ConsensusState` the counterparty stores for the executing chain. The +executing chain will select a version from the intersection of its supported versions and the +versions set by the counterparty. The connection is set and stored in the TRYOPEN state upon +success. `ConnOpenAck` may be called on a chain when the counterparty connection has entered TRYOPEN. A previous connection on the executing chain must exist in either INIT or TRYOPEN. The executing -chain will verify the version the counterparty selected. If the counterparty selected its own -connection identifier, it will be validated in the basic validation of a `MsgConnOpenAck`. +chain will verify the version the counterparty selected. If the counterparty selected its own +connection identifier, it will be validated in the basic validation of a `MsgConnOpenAck`. The counterparty connection state is verified along with the `ClientState` and `ConsensusState` stored for the executing chain. The connection is set and stored in the OPEN state upon success. `ConnOpenConfirm` is a response to a chain executing `ConnOpenAck`. The executing chain's connection -must be in TRYOPEN. The counterparty connection state is verified to be in the OPEN state. The +must be in TRYOPEN. The counterparty connection state is verified to be in the OPEN state. The connection is set and stored in the OPEN state upon success. ## Connection Version Negotiation @@ -72,7 +72,7 @@ versions is from most preferred to least preferred. This is not a strict requirement for the SDK implementation of IBC because the party calling `ConnOpenTry` will greedily select the latest version it supports that the counterparty supports as well. A specific version can optionally be passed -as `Version` to ensure that the handshake will either complete with that +as `Version` to ensure that the handshake will either complete with that version or fail. During `ConnOpenTry`, party B will select a version from the counterparty's @@ -83,19 +83,18 @@ During `ConnOpenAck`, party A will verify that they can support the version party B selected. If they do not support the selected version an error is returned. After this step, the connection version is considered agreed upon. - A `Version` is defined as follows: ```go type Version struct { - // unique version identifier - Identifier string - // list of features compatible with the specified identifier - Features []string + // unique version identifier + Identifier string + // list of features compatible with the specified identifier + Features []string } ``` -A version must contain a non empty identifier. Empty feature sets are allowed, but each +A version must contain a non empty identifier. Empty feature sets are allowed, but each feature must be a non empty string. ::: warning @@ -105,7 +104,6 @@ with regards to version selection in `ConnOpenTry`. Each version in a set of versions should have a unique version identifier. ::: - ## Channel Version Negotiation During the channel handshake procedure a version must be agreed upon between @@ -128,7 +126,7 @@ the version proposed by party B using the `MsgChanOpenAck` `CounterpartyVersion` field. The application module should throw an error if the version string is not valid. -In general empty version strings are to be considered valid options for an +In general empty version strings are to be considered valid options for an application module. Application modules may implement their own versioning system, such as semantic @@ -145,70 +143,69 @@ basic string matching using a single compatible version. Terminology: **Packet Commitment** A hash of the packet stored on the sending chain. -**Packet Receipt** A single bit indicating that a packet has been received. -Used for timeouts. +**Packet Receipt** A single bit indicating that a packet has been received. +Used for timeouts. **Acknowledgement** Data written to indicate the result of receiving a packet. Typically conveying either success or failure of the receive. A packet may be associated with one of the following states: + - the packet does not exist (ie it has not been sent) -- the packet has been sent but not received (the packet commitment exists on the +- the packet has been sent but not received (the packet commitment exists on the sending chain, but no receipt exists on the receiving chain) -- the packet has been received but not acknowledged (packet commitment exists +- the packet has been received but not acknowledged (packet commitment exists on the sending chain, a receipt exists on the receiving chain, but no acknowledgement exists on the receiving chain) -- the packet has been acknowledgement but the acknowledgement has not been relayed +- the packet has been acknowledgement but the acknowledgement has not been relayed (the packet commitment exists on the sending chain, the receipt and acknowledgement exist on the receiving chain) - the packet has completed its life cycle (the packet commitment does not exist on the sending chain, but a receipt and acknowledgement exist on the receiving chain) -Sending of a packet is initiated by a call to the `ChannelKeeper.SendPacket` +Sending of a packet is initiated by a call to the `ChannelKeeper.SendPacket` function by an application module. Packets being sent will be verified for correctness (core logic only). If the packet is valid, a hash of the packet will be stored as a packet commitment using the packet sequence in the key. Packet commitments are stored on the sending chain. A message should be sent to the receving chain indicating that the packet -has been committed on the sending chain and should be received on the +has been committed on the sending chain and should be received on the receiving chain. The light client on the receiving chain, which verifies the sending chain's state, should be updated to the lastest sending chain state if possible. The verification will fail if the latest state of the light client does not include the packet commitment. The receiving chain -is responsible for verifying that the counterparty set the hash of the +is responsible for verifying that the counterparty set the hash of the packet. If verification of the packet to be received is successful, the receiving chain should store a receipt of the packet and call application logic if necessary. An acknowledgement may be processed and stored at this time (synchronously) -or at another point in the future (asynchronously). +or at another point in the future (asynchronously). -Acknowledgements written on the receiving chain may be verified on the +Acknowledgements written on the receiving chain may be verified on the sending chain. If the sending chain successfully verifies the acknowledgement then it may delete the packet commitment stored at that sequence. There is no requirement for acknowledgements to be written. Only the hash of the acknowledgement is stored on the chain. Application logic may be executed in conjunction with verifying an acknowledgement. For example, in fungible cross-chain token transfer, a failed acknowledgement results in locked or -burned funds being refunded. +burned funds being refunded. -Relayers are responsible for reconstructing packets between the sending, -receiving, and acknowledging of packets. +Relayers are responsible for reconstructing packets between the sending, +receiving, and acknowledging of packets. IBC applications sending and receiving packets are expected to appropriately -handle data contained within a packet. For example, cross-chain token +handle data contained within a packet. For example, cross-chain token transfers will unmarshal the data into proto definitions representing -a token transfer. +a token transfer. -Future optimizations may allow for storage cleanup. Stored packet +Future optimizations may allow for storage cleanup. Stored packet commitments could be removed from channels which do not write packet acknowledgements and acknowledgements could be removed when a packet has completed its life cycle. -on channel closure will additionally verify that the counterparty channel has +on channel closure will additionally verify that the counterparty channel has been closed. A successful timeout may execute application logic as appropriate. -Both the packet's timeout timestamp and the timeout height must have been -surpassed on the receiving chain for a timeout to be valid. A timeout timestamp -or timeout height with a 0 value indicates the timeout field may be ignored. -Each packet is required to have at least one valid timeout field. - - +Both the packet's timeout timestamp and the timeout height must have been +surpassed on the receiving chain for a timeout to be valid. A timeout timestamp +or timeout height with a 0 value indicates the timeout field may be ignored. +Each packet is required to have at least one valid timeout field. diff --git a/modules/core/types/codec.go b/modules/core/types/codec.go index c879aa3234e..447b05c849b 100644 --- a/modules/core/types/codec.go +++ b/modules/core/types/codec.go @@ -3,13 +3,10 @@ package types import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - solomachinetypes "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - localhosttypes "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" ) // RegisterInterfaces registers x/ibc interfaces into protobuf Any. @@ -17,8 +14,5 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { clienttypes.RegisterInterfaces(registry) connectiontypes.RegisterInterfaces(registry) channeltypes.RegisterInterfaces(registry) - solomachinetypes.RegisterInterfaces(registry) - ibctmtypes.RegisterInterfaces(registry) - localhosttypes.RegisterInterfaces(registry) commitmenttypes.RegisterInterfaces(registry) } diff --git a/modules/core/types/genesis.go b/modules/core/types/genesis.go index 36a346cafff..bc14953cb0d 100644 --- a/modules/core/types/genesis.go +++ b/modules/core/types/genesis.go @@ -3,9 +3,9 @@ package types import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) var _ codectypes.UnpackInterfacesMessage = GenesisState{} diff --git a/modules/core/types/genesis.pb.go b/modules/core/types/genesis.pb.go index 6072e44d1bd..05dea516395 100644 --- a/modules/core/types/genesis.pb.go +++ b/modules/core/types/genesis.pb.go @@ -5,11 +5,11 @@ package types import ( fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - types1 "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - types2 "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + types1 "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + types2 "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" io "io" math "math" math_bits "math/bits" @@ -100,24 +100,24 @@ var fileDescriptor_b9a49c5663e6fc59 = []byte{ // 324 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0xb1, 0x4e, 0xeb, 0x30, 0x14, 0x86, 0x93, 0x5e, 0xe9, 0x0e, 0x01, 0x8a, 0x1a, 0x01, 0x82, 0x4a, 0xb8, 0x6d, 0xd4, 0x81, - 0x05, 0x5b, 0x05, 0x26, 0xc6, 0x2e, 0x30, 0x87, 0x8d, 0x05, 0x25, 0xc6, 0xa4, 0x46, 0x89, 0x4f, - 0x55, 0xbb, 0x91, 0xfa, 0x16, 0x3c, 0x56, 0xc7, 0x8e, 0x88, 0xa1, 0x42, 0xc9, 0x1b, 0xf0, 0x04, - 0xa8, 0xb1, 0x49, 0x52, 0x79, 0x8b, 0xfe, 0xf3, 0x9d, 0xff, 0x3b, 0x4a, 0xe2, 0x0d, 0x78, 0x4c, - 0x09, 0x85, 0x05, 0x23, 0x6a, 0x35, 0x67, 0x92, 0xe4, 0x13, 0x92, 0x30, 0xc1, 0x24, 0x97, 0x78, - 0xbe, 0x00, 0x05, 0x7e, 0x8f, 0xc7, 0x14, 0xef, 0x00, 0x5c, 0x01, 0x38, 0x9f, 0xf4, 0x4f, 0x12, - 0x48, 0xa0, 0x9a, 0x92, 0xdd, 0x93, 0x06, 0xfb, 0xc3, 0xba, 0x89, 0xa6, 0x9c, 0x09, 0x65, 0x55, - 0xf5, 0xc7, 0x0d, 0x01, 0x42, 0x30, 0xaa, 0x38, 0x08, 0x9b, 0x1a, 0x35, 0xd4, 0x2c, 0x12, 0x82, - 0xa5, 0x16, 0x12, 0x7c, 0x75, 0xbc, 0xc3, 0x07, 0x9d, 0x3c, 0xa9, 0x48, 0x31, 0xff, 0xcd, 0xeb, - 0x6a, 0xe9, 0x8b, 0x01, 0xcf, 0xdd, 0xa1, 0x7b, 0x75, 0x70, 0x33, 0xc4, 0xf5, 0xf5, 0x7a, 0x8e, - 0xf3, 0x09, 0x6e, 0x6f, 0x4e, 0x2f, 0xd7, 0xdb, 0x81, 0xf3, 0xb3, 0x1d, 0x9c, 0xae, 0xa2, 0x2c, - 0xbd, 0x0f, 0xf6, 0x5b, 0x82, 0xf0, 0x48, 0x07, 0x66, 0xc5, 0xcf, 0x3d, 0xbf, 0x39, 0xbd, 0x76, - 0x75, 0x2a, 0xd7, 0xb8, 0xe5, 0xaa, 0x19, 0xcb, 0x37, 0x32, 0xbe, 0x0b, 0xe3, 0xb3, 0xda, 0x82, - 0xb0, 0xd7, 0x84, 0x7f, 0xde, 0x77, 0xef, 0xd8, 0xbc, 0x8c, 0x5a, 0xfa, 0xaf, 0x92, 0x8e, 0x5a, - 0x52, 0x0d, 0x58, 0x46, 0x64, 0x8c, 0x67, 0xc6, 0xb8, 0xdf, 0x13, 0x84, 0x5d, 0x93, 0x98, 0xa5, - 0xe9, 0xe3, 0xba, 0x40, 0xee, 0xa6, 0x40, 0xee, 0x77, 0x81, 0xdc, 0x8f, 0x12, 0x39, 0x9b, 0x12, - 0x39, 0x9f, 0x25, 0x72, 0x9e, 0x71, 0xc2, 0xd5, 0x6c, 0x19, 0x63, 0x0a, 0x19, 0xa1, 0x20, 0x33, - 0x90, 0x84, 0xc7, 0xf4, 0x3a, 0x01, 0x92, 0xdf, 0x91, 0x0c, 0x5e, 0x97, 0x29, 0x93, 0xad, 0x7f, - 0x29, 0xfe, 0x5f, 0x7d, 0xad, 0xdb, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd2, 0xbe, 0x54, 0x19, + 0x05, 0x5b, 0x85, 0x01, 0x89, 0xb1, 0x0b, 0xcc, 0x61, 0x63, 0x41, 0x89, 0x31, 0xa9, 0x51, 0xe2, + 0x53, 0xd5, 0x6e, 0xa4, 0xbe, 0x05, 0x8f, 0xd5, 0xb1, 0x23, 0x62, 0xa8, 0x50, 0xf2, 0x06, 0x3c, + 0x01, 0x6a, 0x6c, 0x92, 0x54, 0xde, 0xa2, 0xff, 0x7c, 0xe7, 0xff, 0x8e, 0x92, 0x78, 0x03, 0x1e, + 0x53, 0x42, 0x61, 0xc1, 0x88, 0x5a, 0xcd, 0x99, 0x24, 0xf9, 0x84, 0x24, 0x4c, 0x30, 0xc9, 0x25, + 0x9e, 0x2f, 0x40, 0x81, 0xdf, 0xe3, 0x31, 0xc5, 0x3b, 0x00, 0x57, 0x00, 0xce, 0x27, 0xfd, 0x93, + 0x04, 0x12, 0xa8, 0xa6, 0x64, 0xf7, 0xa4, 0xc1, 0xfe, 0xb0, 0x6e, 0xa2, 0x29, 0x67, 0x42, 0x59, + 0x55, 0xfd, 0x71, 0x43, 0x80, 0x10, 0x8c, 0x2a, 0x0e, 0xc2, 0xa6, 0x46, 0x0d, 0x35, 0x8b, 0x84, + 0x60, 0xa9, 0x85, 0x04, 0x5f, 0x1d, 0xef, 0xf0, 0x41, 0x27, 0x4f, 0x2a, 0x52, 0xcc, 0x7f, 0xf3, + 0xba, 0x5a, 0xfa, 0x62, 0xc0, 0x73, 0x77, 0xe8, 0x5e, 0x1d, 0xdc, 0x0c, 0x71, 0x7d, 0xbd, 0x9e, + 0xe3, 0x7c, 0x82, 0xdb, 0x9b, 0xd3, 0xcb, 0xf5, 0x76, 0xe0, 0xfc, 0x6c, 0x07, 0xa7, 0xab, 0x28, + 0x4b, 0xef, 0x83, 0xfd, 0x96, 0x20, 0x3c, 0xd2, 0x81, 0x59, 0xf1, 0x73, 0xcf, 0x6f, 0x4e, 0xaf, + 0x5d, 0x9d, 0xca, 0x35, 0x6e, 0xb9, 0x6a, 0xc6, 0xf2, 0x8d, 0x8c, 0xef, 0xc2, 0xf8, 0xac, 0xb6, + 0x20, 0xec, 0x35, 0xe1, 0x9f, 0xf7, 0xdd, 0x3b, 0x36, 0x2f, 0xa3, 0x96, 0xfe, 0xab, 0xa4, 0xa3, + 0x96, 0x54, 0x03, 0x96, 0x11, 0x19, 0xe3, 0x99, 0x31, 0xee, 0xf7, 0x04, 0x61, 0xd7, 0x24, 0x66, + 0x69, 0xfa, 0xb8, 0x2e, 0x90, 0xbb, 0x29, 0x90, 0xfb, 0x5d, 0x20, 0xf7, 0xa3, 0x44, 0xce, 0xa6, + 0x44, 0xce, 0x67, 0x89, 0x9c, 0x67, 0x9c, 0x70, 0x35, 0x5b, 0xc6, 0x98, 0x42, 0x46, 0x28, 0xc8, + 0x0c, 0x24, 0xe1, 0x31, 0xbd, 0x4e, 0x80, 0xe4, 0x77, 0x24, 0x83, 0xd7, 0x65, 0xca, 0x64, 0xeb, + 0x5f, 0x8a, 0xff, 0x57, 0x5f, 0xeb, 0xf6, 0x37, 0x00, 0x00, 0xff, 0xff, 0xf5, 0xb9, 0x8a, 0x1b, 0x64, 0x02, 0x00, 0x00, } diff --git a/modules/core/types/query.go b/modules/core/types/query.go index 6ebeb77ba5e..c79190a84c6 100644 --- a/modules/core/types/query.go +++ b/modules/core/types/query.go @@ -1,14 +1,14 @@ package types import ( - "github.com/gogo/protobuf/grpc" + "github.com/cosmos/gogoproto/grpc" - client "github.com/cosmos/ibc-go/v4/modules/core/02-client" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connection "github.com/cosmos/ibc-go/v4/modules/core/03-connection" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channel "github.com/cosmos/ibc-go/v4/modules/core/04-channel" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + client "github.com/cosmos/ibc-go/v7/modules/core/02-client" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connection "github.com/cosmos/ibc-go/v7/modules/core/03-connection" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channel "github.com/cosmos/ibc-go/v7/modules/core/04-channel" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // QueryServer defines the IBC interfaces that the gRPC query server must implement diff --git a/modules/light-clients/06-solomachine/client_state.go b/modules/light-clients/06-solomachine/client_state.go new file mode 100644 index 00000000000..2c316dacaec --- /dev/null +++ b/modules/light-clients/06-solomachine/client_state.go @@ -0,0 +1,247 @@ +package solomachine + +import ( + "reflect" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +var _ exported.ClientState = (*ClientState)(nil) + +// NewClientState creates a new ClientState instance. +func NewClientState(latestSequence uint64, consensusState *ConsensusState) *ClientState { + return &ClientState{ + Sequence: latestSequence, + IsFrozen: false, + ConsensusState: consensusState, + } +} + +// ClientType is Solo Machine. +func (cs ClientState) ClientType() string { + return exported.Solomachine +} + +// GetLatestHeight returns the latest sequence number. +// Return exported.Height to satisfy ClientState interface +// Revision number is always 0 for a solo-machine. +func (cs ClientState) GetLatestHeight() exported.Height { + return clienttypes.NewHeight(0, cs.Sequence) +} + +// GetTimestampAtHeight returns the timestamp in nanoseconds of the consensus state at the given height. +func (cs ClientState) GetTimestampAtHeight( + _ sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height exported.Height, +) (uint64, error) { + return cs.ConsensusState.Timestamp, nil +} + +// Status returns the status of the solo machine client. +// The client may be: +// - Active: if frozen sequence is 0 +// - Frozen: otherwise solo machine is frozen +func (cs ClientState) Status(_ sdk.Context, _ sdk.KVStore, _ codec.BinaryCodec) exported.Status { + if cs.IsFrozen { + return exported.Frozen + } + + return exported.Active +} + +// Validate performs basic validation of the client state fields. +func (cs ClientState) Validate() error { + if cs.Sequence == 0 { + return errorsmod.Wrap(clienttypes.ErrInvalidClient, "sequence cannot be 0") + } + if cs.ConsensusState == nil { + return errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "consensus state cannot be nil") + } + return cs.ConsensusState.ValidateBasic() +} + +// ZeroCustomFields is not implemented for solo machine +func (cs ClientState) ZeroCustomFields() exported.ClientState { + panic("ZeroCustomFields is not implemented as the solo machine implementation does not support upgrades.") +} + +// Initialize checks that the initial consensus state is equal to the latest consensus state of the initial client and +// sets the client state in the provided client store. +func (cs ClientState) Initialize(_ sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, consState exported.ConsensusState) error { + if !reflect.DeepEqual(cs.ConsensusState, consState) { + return errorsmod.Wrapf(clienttypes.ErrInvalidConsensus, "consensus state in initial client does not equal initial consensus state. expected: %s, got: %s", + cs.ConsensusState, consState) + } + + setClientState(clientStore, cdc, &cs) + + return nil +} + +// ExportMetadata is a no-op since solomachine does not store any metadata in client store +func (cs ClientState) ExportMetadata(_ sdk.KVStore) []exported.GenesisMetadata { + return nil +} + +// VerifyUpgradeAndUpdateState returns an error since solomachine client does not support upgrades +func (cs ClientState) VerifyUpgradeAndUpdateState( + _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, + _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, +) error { + return errorsmod.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade solomachine client") +} + +// VerifyMembership is a generic proof verification method which verifies a proof of the existence of a value at a given CommitmentPath at the latest sequence. +// The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24). +func (cs *ClientState) VerifyMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + _ exported.Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path exported.Path, + value []byte, +) error { + publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, proof) + if err != nil { + return err + } + + merklePath, ok := path.(commitmenttypes.MerklePath) + if !ok { + return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "expected %T, got %T", commitmenttypes.MerklePath{}, path) + } + + if merklePath.Empty() { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "path is empty") + } + + signBytes := &SignBytes{ + Sequence: sequence, + Timestamp: timestamp, + Diversifier: cs.ConsensusState.Diversifier, + Path: []byte(merklePath.String()), + Data: value, + } + + signBz, err := cdc.Marshal(signBytes) + if err != nil { + return err + } + + if err := VerifySignature(publicKey, signBz, sigData); err != nil { + return err + } + + cs.Sequence++ + cs.ConsensusState.Timestamp = timestamp + setClientState(clientStore, cdc, cs) + + return nil +} + +// VerifyNonMembership is a generic proof verification method which verifies the absence of a given CommitmentPath at the latest sequence. +// The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24). +func (cs *ClientState) VerifyNonMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + _ exported.Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path exported.Path, +) error { + publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, proof) + if err != nil { + return err + } + + merklePath, ok := path.(commitmenttypes.MerklePath) + if !ok { + return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "expected %T, got %T", commitmenttypes.MerklePath{}, path) + } + + signBytes := &SignBytes{ + Sequence: sequence, + Timestamp: timestamp, + Diversifier: cs.ConsensusState.Diversifier, + Path: []byte(merklePath.String()), + Data: nil, + } + + signBz, err := cdc.Marshal(signBytes) + if err != nil { + return err + } + + if err := VerifySignature(publicKey, signBz, sigData); err != nil { + return err + } + + cs.Sequence++ + cs.ConsensusState.Timestamp = timestamp + setClientState(clientStore, cdc, cs) + + return nil +} + +// produceVerificationArgs perfoms the basic checks on the arguments that are +// shared between the verification functions and returns the public key of the +// consensus state, the unmarshalled proof representing the signature and timestamp. +func produceVerificationArgs( + cdc codec.BinaryCodec, + cs *ClientState, + proof []byte, +) (cryptotypes.PubKey, signing.SignatureData, uint64, uint64, error) { + if proof == nil { + return nil, nil, 0, 0, errorsmod.Wrap(ErrInvalidProof, "proof cannot be empty") + } + + var timestampedSigData TimestampedSignatureData + if err := cdc.Unmarshal(proof, ×tampedSigData); err != nil { + return nil, nil, 0, 0, errorsmod.Wrapf(err, "failed to unmarshal proof into type %T", timestampedSigData) + } + + timestamp := timestampedSigData.Timestamp + if len(timestampedSigData.SignatureData) == 0 { + return nil, nil, 0, 0, errorsmod.Wrap(ErrInvalidProof, "signature data cannot be empty") + } + + sigData, err := UnmarshalSignatureData(cdc, timestampedSigData.SignatureData) + if err != nil { + return nil, nil, 0, 0, err + } + + if cs.ConsensusState.GetTimestamp() > timestamp { + return nil, nil, 0, 0, errorsmod.Wrapf(ErrInvalidProof, "the consensus state timestamp is greater than the signature timestamp (%d >= %d)", cs.ConsensusState.GetTimestamp(), timestamp) + } + + sequence := cs.GetLatestHeight().GetRevisionHeight() + publicKey, err := cs.ConsensusState.GetPubKey() + if err != nil { + return nil, nil, 0, 0, err + } + + return publicKey, sigData, timestamp, sequence, nil +} + +// sets the client state to the store +func setClientState(store sdk.KVStore, cdc codec.BinaryCodec, clientState exported.ClientState) { + bz := clienttypes.MustMarshalClientState(cdc, clientState) + store.Set([]byte(host.KeyClientState), bz) +} diff --git a/modules/light-clients/06-solomachine/client_state_test.go b/modules/light-clients/06-solomachine/client_state_test.go new file mode 100644 index 00000000000..33888252e4e --- /dev/null +++ b/modules/light-clients/06-solomachine/client_state_test.go @@ -0,0 +1,830 @@ +package solomachine_test + +import ( + "bytes" + + 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" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" +) + +const ( + counterpartyClientIdentifier = "chainA" + testConnectionID = "connectionid" + testChannelID = "testchannelid" + testPortID = "testportid" +) + +func (suite *SoloMachineTestSuite) TestStatus() { + clientState := suite.solomachine.ClientState() + // solo machine discards arguments + status := clientState.Status(suite.chainA.GetContext(), nil, nil) + suite.Require().Equal(exported.Active, status) + + // freeze solo machine + clientState.IsFrozen = true + status = clientState.Status(suite.chainA.GetContext(), nil, nil) + suite.Require().Equal(exported.Frozen, status) +} + +func (suite *SoloMachineTestSuite) TestClientStateValidateBasic() { + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + + testCases := []struct { + name string + clientState *solomachine.ClientState + expPass bool + }{ + { + "valid client state", + sm.ClientState(), + true, + }, + { + "empty ClientState", + &solomachine.ClientState{}, + false, + }, + { + "sequence is zero", + solomachine.NewClientState(0, &solomachine.ConsensusState{sm.ConsensusState().PublicKey, sm.Diversifier, sm.Time}), + false, + }, + { + "timestamp is zero", + solomachine.NewClientState(1, &solomachine.ConsensusState{sm.ConsensusState().PublicKey, sm.Diversifier, 0}), + false, + }, + { + "diversifier is blank", + solomachine.NewClientState(1, &solomachine.ConsensusState{sm.ConsensusState().PublicKey, " ", 1}), + false, + }, + { + "pubkey is empty", + solomachine.NewClientState(1, &solomachine.ConsensusState{nil, sm.Diversifier, sm.Time}), + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + err := tc.clientState.Validate() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } + } +} + +func (suite *SoloMachineTestSuite) TestInitialize() { + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + malleatedConsensus := sm.ClientState().ConsensusState + malleatedConsensus.Timestamp += 10 + + testCases := []struct { + name string + consState exported.ConsensusState + expPass bool + }{ + { + "valid consensus state", + sm.ConsensusState(), + true, + }, + { + "nil consensus state", + nil, + false, + }, + { + "invalid consensus state: Tendermint consensus state", + &ibctm.ConsensusState{}, + false, + }, + { + "invalid consensus state: consensus state does not match consensus state in client", + malleatedConsensus, + false, + }, + } + + for _, tc := range testCases { + suite.SetupTest() + + store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "solomachine") + err := sm.ClientState().Initialize( + suite.chainA.GetContext(), suite.chainA.Codec, + store, tc.consState, + ) + + if tc.expPass { + suite.Require().NoError(err, "valid testcase: %s failed", tc.name) + suite.Require().True(store.Has(host.ClientStateKey())) + } else { + suite.Require().Error(err, "invalid testcase: %s passed", tc.name) + suite.Require().False(store.Has(host.ClientStateKey())) + } + } + } +} + +func (suite *SoloMachineTestSuite) TestVerifyMembership() { + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + + var ( + clientState *solomachine.ClientState + path exported.Path + proof []byte + testingPath *ibctesting.Path + signBytes solomachine.SignBytes + err error + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "success: client state verification", + func() { + clientState = sm.ClientState() + clientStateBz, err := suite.chainA.Codec.Marshal(clientState) + suite.Require().NoError(err) + + path = suite.solomachine.GetClientStatePath(counterpartyClientIdentifier) + signBytes = solomachine.SignBytes{ + Sequence: sm.GetHeight().GetRevisionHeight(), + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: clientStateBz, + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "success: consensus state verification", + func() { + clientState = sm.ClientState() + consensusState := clientState.ConsensusState + consensusStateBz, err := suite.chainA.Codec.Marshal(consensusState) + suite.Require().NoError(err) + + path = sm.GetConsensusStatePath(counterpartyClientIdentifier, clienttypes.NewHeight(0, 1)) + signBytes = solomachine.SignBytes{ + Sequence: sm.Sequence, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: consensusStateBz, + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "success: connection state verification", + func() { + suite.coordinator.SetupConnections(testingPath) + + connectionEnd, found := suite.chainA.GetSimApp().IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), ibctesting.FirstConnectionID) + suite.Require().True(found) + + connectionEndBz, err := suite.chainA.Codec.Marshal(&connectionEnd) + suite.Require().NoError(err) + + path = sm.GetConnectionStatePath(ibctesting.FirstConnectionID) + signBytes = solomachine.SignBytes{ + Sequence: sm.Sequence, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: connectionEndBz, + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "success: channel state verification", + func() { + suite.coordinator.SetupConnections(testingPath) + suite.coordinator.CreateMockChannels(testingPath) + + channelEnd, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), ibctesting.MockPort, ibctesting.FirstChannelID) + suite.Require().True(found) + + channelEndBz, err := suite.chainA.Codec.Marshal(&channelEnd) + suite.Require().NoError(err) + + path = sm.GetChannelStatePath(ibctesting.MockPort, ibctesting.FirstChannelID) + signBytes = solomachine.SignBytes{ + Sequence: sm.Sequence, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: channelEndBz, + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "success: next sequence recv verification", + func() { + suite.coordinator.SetupConnections(testingPath) + suite.coordinator.CreateMockChannels(testingPath) + + nextSeqRecv, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceRecv(suite.chainA.GetContext(), ibctesting.MockPort, ibctesting.FirstChannelID) + suite.Require().True(found) + + path = sm.GetNextSequenceRecvPath(ibctesting.MockPort, ibctesting.FirstChannelID) + signBytes = solomachine.SignBytes{ + Sequence: sm.Sequence, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: sdk.Uint64ToBigEndian(nextSeqRecv), + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "success: packet commitment verification", + func() { + packet := channeltypes.NewPacket( + ibctesting.MockPacketData, + 1, + ibctesting.MockPort, + ibctesting.FirstChannelID, + ibctesting.MockPort, + ibctesting.FirstChannelID, + clienttypes.NewHeight(0, 10), + 0, + ) + + commitmentBz := channeltypes.CommitPacket(suite.chainA.Codec, packet) + path = sm.GetPacketCommitmentPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + signBytes = solomachine.SignBytes{ + Sequence: sm.Sequence, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: commitmentBz, + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "success: packet acknowledgement verification", + func() { + path = sm.GetPacketAcknowledgementPath(ibctesting.MockPort, ibctesting.FirstChannelID, 1) + signBytes = solomachine.SignBytes{ + Sequence: sm.Sequence, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: ibctesting.MockAcknowledgement, + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "success: packet receipt verification", + func() { + path = sm.GetPacketReceiptPath(ibctesting.MockPort, ibctesting.FirstChannelID, 1) + signBytes = solomachine.SignBytes{ + Sequence: sm.Sequence, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: []byte{byte(1)}, // packet receipt is stored as a single byte + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "invalid path type", + func() { + path = ibcmock.KeyPath{} + }, + false, + }, + { + "malformed proof fails to unmarshal", + func() { + path = suite.solomachine.GetClientStatePath(counterpartyClientIdentifier) + proof = []byte("invalid proof") + }, + false, + }, + { + "consensus state timestamp is greater than signature", + func() { + consensusState := &solomachine.ConsensusState{ + Timestamp: sm.Time + 1, + PublicKey: sm.ConsensusState().PublicKey, + } + + clientState = solomachine.NewClientState(sm.Sequence, consensusState) + }, + false, + }, + { + "signature data is nil", + func() { + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: nil, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + false, + }, + { + "consensus state public key is nil", + func() { + clientState.ConsensusState.PublicKey = nil + }, + false, + }, + { + "malformed signature data fails to unmarshal", + func() { + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: []byte("invalid signature data"), + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + false, + }, + { + "proof is nil", + func() { + proof = nil + }, + false, + }, + { + "proof verification failed", + func() { + signBytes.Data = []byte("invalid membership data value") + }, + false, + }, + { + "empty path", + func() { + path = commitmenttypes.MerklePath{} + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() + testingPath = ibctesting.NewPath(suite.chainA, suite.chainB) + + clientState = sm.ClientState() + + path = commitmenttypes.NewMerklePath("ibc", "solomachine") + signBytes = solomachine.SignBytes{ + Sequence: sm.GetHeight().GetRevisionHeight(), + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: []byte("solomachine"), + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + + tc.malleate() + + var expSeq uint64 + if clientState.ConsensusState != nil { + expSeq = clientState.Sequence + 1 + } + + err = clientState.VerifyMembership( + suite.chainA.GetContext(), suite.store, suite.chainA.Codec, + clienttypes.ZeroHeight(), 0, 0, // solomachine does not check delay periods + proof, path, signBytes.Data, + ) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().Equal(expSeq, clientState.Sequence) + suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %s", suite.GetSequenceFromStore(), tc.name) + } else { + suite.Require().Error(err) + } + }) + } + } +} + +func (suite *SoloMachineTestSuite) TestSignBytesMarshalling() { + sm := suite.solomachine + merklePath := commitmenttypes.NewMerklePath("ibc", "solomachine") + signBytesNilData := solomachine.SignBytes{ + Sequence: sm.GetHeight().GetRevisionHeight(), + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(merklePath.String()), + Data: nil, + } + + signBytesEmptyArray := solomachine.SignBytes{ + Sequence: sm.GetHeight().GetRevisionHeight(), + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(merklePath.String()), + Data: []byte{}, + } + + signBzNil, err := suite.chainA.Codec.Marshal(&signBytesNilData) + suite.Require().NoError(err) + + signBzEmptyArray, err := suite.chainA.Codec.Marshal(&signBytesEmptyArray) + suite.Require().NoError(err) + + suite.Require().True(bytes.Equal(signBzNil, signBzEmptyArray)) +} + +func (suite *SoloMachineTestSuite) TestVerifyNonMembership() { + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + + var ( + clientState *solomachine.ClientState + path exported.Path + proof []byte + signBytes solomachine.SignBytes + err error + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "success: packet receipt absence verification", + func() { + path = suite.solomachine.GetPacketReceiptPath(ibctesting.MockPort, ibctesting.FirstChannelID, 1) + signBytes = solomachine.SignBytes{ + Sequence: sm.GetHeight().GetRevisionHeight(), + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: nil, + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + true, + }, + { + "invalid path type", + func() { + path = ibcmock.KeyPath{} + }, + false, + }, + { + "malformed proof fails to unmarshal", + func() { + path = suite.solomachine.GetClientStatePath(counterpartyClientIdentifier) + proof = []byte("invalid proof") + }, + false, + }, + { + "consensus state timestamp is greater than signature", + func() { + consensusState := &solomachine.ConsensusState{ + Timestamp: sm.Time + 1, + PublicKey: sm.ConsensusState().PublicKey, + } + + clientState = solomachine.NewClientState(sm.Sequence, consensusState) + }, + false, + }, + { + "signature data is nil", + func() { + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: nil, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + false, + }, + { + "consensus state public key is nil", + func() { + clientState.ConsensusState.PublicKey = nil + }, + false, + }, + { + "malformed signature data fails to unmarshal", + func() { + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: []byte("invalid signature data"), + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + false, + }, + { + "proof is nil", + func() { + proof = nil + }, + false, + }, + { + "proof verification failed", + func() { + signBytes.Data = []byte("invalid non-membership data value") + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + clientState = sm.ClientState() + + path = commitmenttypes.NewMerklePath("ibc", "solomachine") + signBytes = solomachine.SignBytes{ + Sequence: sm.GetHeight().GetRevisionHeight(), + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte(path.String()), + Data: nil, + } + + signBz, err := suite.chainA.Codec.Marshal(&signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: sm.Time, + } + + proof, err = suite.chainA.Codec.Marshal(signatureDoc) + suite.Require().NoError(err) + + tc.malleate() + + var expSeq uint64 + if clientState.ConsensusState != nil { + expSeq = clientState.Sequence + 1 + } + + err = clientState.VerifyNonMembership( + suite.chainA.GetContext(), suite.store, suite.chainA.Codec, + clienttypes.ZeroHeight(), 0, 0, // solomachine does not check delay periods + proof, path, + ) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().Equal(expSeq, clientState.Sequence) + suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %s", suite.GetSequenceFromStore(), tc.name) + } else { + suite.Require().Error(err) + } + }) + } + } +} + +func (suite *SoloMachineTestSuite) TestGetTimestampAtHeight() { + tmPath := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupClients(tmPath) + // Single setup for all test cases. + suite.SetupTest() + + testCases := []struct { + name string + clientState *solomachine.ClientState + height exported.Height + expValue uint64 + expPass bool + }{ + { + name: "get timestamp at height exists", + clientState: suite.solomachine.ClientState(), + height: suite.solomachine.ClientState().GetLatestHeight(), + expValue: suite.solomachine.ClientState().ConsensusState.Timestamp, + expPass: true, + }, + } + + for i, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + ctx := suite.chainA.GetContext() + + ts, err := tc.clientState.GetTimestampAtHeight( + ctx, suite.store, suite.chainA.Codec, tc.height, + ) + + suite.Require().Equal(tc.expValue, ts) + + if tc.expPass { + suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) + } else { + suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) + } + }) + } +} diff --git a/modules/light-clients/06-solomachine/codec.go b/modules/light-clients/06-solomachine/codec.go new file mode 100644 index 00000000000..e18cd8b563c --- /dev/null +++ b/modules/light-clients/06-solomachine/codec.go @@ -0,0 +1,42 @@ +package solomachine + +import ( + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// RegisterInterfaces register the ibc channel submodule interfaces to protobuf +// Any. +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations( + (*exported.ClientState)(nil), + &ClientState{}, + ) + registry.RegisterImplementations( + (*exported.ConsensusState)(nil), + &ConsensusState{}, + ) + registry.RegisterImplementations( + (*exported.ClientMessage)(nil), + &Header{}, + ) + registry.RegisterImplementations( + (*exported.ClientMessage)(nil), + &Misbehaviour{}, + ) +} + +func UnmarshalSignatureData(cdc codec.BinaryCodec, data []byte) (signing.SignatureData, error) { + protoSigData := &signing.SignatureDescriptor_Data{} + if err := cdc.Unmarshal(data, protoSigData); err != nil { + return nil, errorsmod.Wrapf(err, "failed to unmarshal proof into type %T", protoSigData) + } + + sigData := signing.SignatureDataFromProto(protoSigData) + + return sigData, nil +} diff --git a/modules/light-clients/06-solomachine/types/consensus_state.go b/modules/light-clients/06-solomachine/consensus_state.go similarity index 66% rename from modules/light-clients/06-solomachine/types/consensus_state.go rename to modules/light-clients/06-solomachine/consensus_state.go index e6b53fced72..ed3bfa55d37 100644 --- a/modules/light-clients/06-solomachine/types/consensus_state.go +++ b/modules/light-clients/06-solomachine/consensus_state.go @@ -1,13 +1,13 @@ -package types +package solomachine import ( "strings" + errorsmod "cosmossdk.io/errors" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) var _ exported.ConsensusState = &ConsensusState{} @@ -22,22 +22,17 @@ func (cs ConsensusState) GetTimestamp() uint64 { return cs.Timestamp } -// GetRoot returns nil since solo machines do not have roots. -func (cs ConsensusState) GetRoot() exported.Root { - return nil -} - // GetPubKey unmarshals the public key into a cryptotypes.PubKey type. // An error is returned if the public key is nil or the cached value // is not a PubKey. func (cs ConsensusState) GetPubKey() (cryptotypes.PubKey, error) { if cs.PublicKey == nil { - return nil, sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "consensus state PublicKey cannot be nil") + return nil, errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "consensus state PublicKey cannot be nil") } publicKey, ok := cs.PublicKey.GetCachedValue().(cryptotypes.PubKey) if !ok { - return nil, sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "consensus state PublicKey is not cryptotypes.PubKey") + return nil, errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "consensus state PublicKey is not cryptotypes.PubKey") } return publicKey, nil @@ -46,15 +41,15 @@ func (cs ConsensusState) GetPubKey() (cryptotypes.PubKey, error) { // ValidateBasic defines basic validation for the solo machine consensus state. func (cs ConsensusState) ValidateBasic() error { if cs.Timestamp == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "timestamp cannot be 0") + return errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "timestamp cannot be 0") } if cs.Diversifier != "" && strings.TrimSpace(cs.Diversifier) == "" { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "diversifier cannot contain only spaces") + return errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "diversifier cannot contain only spaces") } publicKey, err := cs.GetPubKey() if err != nil || publicKey == nil || len(publicKey.Bytes()) == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "public key cannot be empty") + return errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "public key cannot be empty") } return nil diff --git a/modules/light-clients/06-solomachine/types/consensus_state_test.go b/modules/light-clients/06-solomachine/consensus_state_test.go similarity index 56% rename from modules/light-clients/06-solomachine/types/consensus_state_test.go rename to modules/light-clients/06-solomachine/consensus_state_test.go index 29ea918a00b..4585ae533de 100644 --- a/modules/light-clients/06-solomachine/types/consensus_state_test.go +++ b/modules/light-clients/06-solomachine/consensus_state_test.go @@ -1,9 +1,9 @@ -package types_test +package solomachine_test import ( - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *SoloMachineTestSuite) TestConsensusState() { @@ -11,46 +11,45 @@ func (suite *SoloMachineTestSuite) TestConsensusState() { suite.Require().Equal(exported.Solomachine, consensusState.ClientType()) suite.Require().Equal(suite.solomachine.Time, consensusState.GetTimestamp()) - suite.Require().Nil(consensusState.GetRoot()) } func (suite *SoloMachineTestSuite) TestConsensusStateValidateBasic() { // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { testCases := []struct { name string - consensusState *types.ConsensusState + consensusState *solomachine.ConsensusState expPass bool }{ { "valid consensus state", - solomachine.ConsensusState(), + sm.ConsensusState(), true, }, { "timestamp is zero", - &types.ConsensusState{ - PublicKey: solomachine.ConsensusState().PublicKey, + &solomachine.ConsensusState{ + PublicKey: sm.ConsensusState().PublicKey, Timestamp: 0, - Diversifier: solomachine.Diversifier, + Diversifier: sm.Diversifier, }, false, }, { "diversifier is blank", - &types.ConsensusState{ - PublicKey: solomachine.ConsensusState().PublicKey, - Timestamp: solomachine.Time, + &solomachine.ConsensusState{ + PublicKey: sm.ConsensusState().PublicKey, + Timestamp: sm.Time, Diversifier: " ", }, false, }, { "pubkey is nil", - &types.ConsensusState{ - Timestamp: solomachine.Time, - Diversifier: solomachine.Diversifier, + &solomachine.ConsensusState{ + Timestamp: sm.Time, + Diversifier: sm.Diversifier, PublicKey: nil, }, false, diff --git a/modules/light-clients/06-solomachine/doc.go b/modules/light-clients/06-solomachine/doc.go index bbd5fb48493..c4d15dfdc76 100644 --- a/modules/light-clients/06-solomachine/doc.go +++ b/modules/light-clients/06-solomachine/doc.go @@ -1,7 +1,7 @@ /* -Package solomachine implements a concrete `ConsensusState`, `Header`, -`Misbehaviour` and `Equivocation` types for the Solo Machine light client. -This implementation is based off the ICS 06 specification: -https://github.com/cosmos/ibc/tree/master/spec/client/ics-006-solo-machine-client +Package solomachine implements a concrete ClientState, ConsensusState, +Header and Misbehaviour types for the Solo Machine light client. +This implementation is based off the ICS 06 specification +(https://github.com/cosmos/ibc/tree/master/spec/client/ics-006-solo-machine-client) */ package solomachine diff --git a/modules/light-clients/06-solomachine/errors.go b/modules/light-clients/06-solomachine/errors.go new file mode 100644 index 00000000000..91c22286241 --- /dev/null +++ b/modules/light-clients/06-solomachine/errors.go @@ -0,0 +1,13 @@ +package solomachine + +import ( + errorsmod "cosmossdk.io/errors" +) + +var ( + ErrInvalidHeader = errorsmod.Register(ModuleName, 2, "invalid header") + ErrInvalidSequence = errorsmod.Register(ModuleName, 3, "invalid sequence") + ErrInvalidSignatureAndData = errorsmod.Register(ModuleName, 4, "invalid signature and data") + ErrSignatureVerificationFailed = errorsmod.Register(ModuleName, 5, "signature verification failed") + ErrInvalidProof = errorsmod.Register(ModuleName, 6, "invalid solo machine proof") +) diff --git a/modules/light-clients/06-solomachine/types/header.go b/modules/light-clients/06-solomachine/header.go similarity index 50% rename from modules/light-clients/06-solomachine/types/header.go rename to modules/light-clients/06-solomachine/header.go index 2f9ab4147fb..e9dd883f2fd 100644 --- a/modules/light-clients/06-solomachine/types/header.go +++ b/modules/light-clients/06-solomachine/header.go @@ -1,67 +1,59 @@ -package types +package solomachine import ( "strings" + errorsmod "cosmossdk.io/errors" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) -var _ exported.Header = &Header{} +// SentinelHeaderPath defines a placeholder path value used for headers in solomachine client updates +const SentinelHeaderPath = "solomachine:header" + +var _ exported.ClientMessage = &Header{} // ClientType defines that the Header is a Solo Machine. func (Header) ClientType() string { return exported.Solomachine } -// GetHeight returns the current sequence number as the height. -// Return clientexported.Height to satisfy interface -// Revision number is always 0 for a solo-machine -func (h Header) GetHeight() exported.Height { - return clienttypes.NewHeight(0, h.Sequence) -} - // GetPubKey unmarshals the new public key into a cryptotypes.PubKey type. // An error is returned if the new public key is nil or the cached value // is not a PubKey. func (h Header) GetPubKey() (cryptotypes.PubKey, error) { if h.NewPublicKey == nil { - return nil, sdkerrors.Wrap(ErrInvalidHeader, "header NewPublicKey cannot be nil") + return nil, errorsmod.Wrap(ErrInvalidHeader, "header NewPublicKey cannot be nil") } publicKey, ok := h.NewPublicKey.GetCachedValue().(cryptotypes.PubKey) if !ok { - return nil, sdkerrors.Wrap(ErrInvalidHeader, "header NewPublicKey is not cryptotypes.PubKey") + return nil, errorsmod.Wrap(ErrInvalidHeader, "header NewPublicKey is not cryptotypes.PubKey") } return publicKey, nil } -// ValidateBasic ensures that the sequence, signature and public key have all +// ValidateBasic ensures that the timestamp, signature and public key have all // been initialized. func (h Header) ValidateBasic() error { - if h.Sequence == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "sequence number cannot be zero") - } - if h.Timestamp == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "timestamp cannot be zero") + return errorsmod.Wrap(clienttypes.ErrInvalidHeader, "timestamp cannot be zero") } if h.NewDiversifier != "" && strings.TrimSpace(h.NewDiversifier) == "" { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "diversifier cannot contain only spaces") + return errorsmod.Wrap(clienttypes.ErrInvalidHeader, "diversifier cannot contain only spaces") } if len(h.Signature) == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "signature cannot be empty") + return errorsmod.Wrap(clienttypes.ErrInvalidHeader, "signature cannot be empty") } newPublicKey, err := h.GetPubKey() if err != nil || newPublicKey == nil || len(newPublicKey.Bytes()) == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "new public key cannot be empty") + return errorsmod.Wrap(clienttypes.ErrInvalidHeader, "new public key cannot be empty") } return nil diff --git a/modules/light-clients/06-solomachine/types/header_test.go b/modules/light-clients/06-solomachine/header_test.go similarity index 61% rename from modules/light-clients/06-solomachine/types/header_test.go rename to modules/light-clients/06-solomachine/header_test.go index 607306f40c3..d0e8e31b29a 100644 --- a/modules/light-clients/06-solomachine/types/header_test.go +++ b/modules/light-clients/06-solomachine/header_test.go @@ -1,20 +1,20 @@ -package types_test +package solomachine_test import ( - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *SoloMachineTestSuite) TestHeaderValidateBasic() { // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - header := solomachine.CreateHeader() + header := sm.CreateHeader(sm.Diversifier) cases := []struct { name string - header *types.Header + header *solomachine.Header expPass bool }{ { @@ -22,21 +22,9 @@ func (suite *SoloMachineTestSuite) TestHeaderValidateBasic() { header, true, }, - { - "sequence is zero", - &types.Header{ - Sequence: 0, - Timestamp: header.Timestamp, - Signature: header.Signature, - NewPublicKey: header.NewPublicKey, - NewDiversifier: header.NewDiversifier, - }, - false, - }, { "timestamp is zero", - &types.Header{ - Sequence: header.Sequence, + &solomachine.Header{ Timestamp: 0, Signature: header.Signature, NewPublicKey: header.NewPublicKey, @@ -46,8 +34,7 @@ func (suite *SoloMachineTestSuite) TestHeaderValidateBasic() { }, { "signature is empty", - &types.Header{ - Sequence: header.Sequence, + &solomachine.Header{ Timestamp: header.Timestamp, Signature: []byte{}, NewPublicKey: header.NewPublicKey, @@ -57,8 +44,7 @@ func (suite *SoloMachineTestSuite) TestHeaderValidateBasic() { }, { "diversifier contains only spaces", - &types.Header{ - Sequence: header.Sequence, + &solomachine.Header{ Timestamp: header.Timestamp, Signature: header.Signature, NewPublicKey: header.NewPublicKey, @@ -68,8 +54,7 @@ func (suite *SoloMachineTestSuite) TestHeaderValidateBasic() { }, { "public key is nil", - &types.Header{ - Sequence: header.Sequence, + &solomachine.Header{ Timestamp: header.Timestamp, Signature: header.Signature, NewPublicKey: nil, diff --git a/modules/light-clients/06-solomachine/keys.go b/modules/light-clients/06-solomachine/keys.go new file mode 100644 index 00000000000..cbb665d6fe3 --- /dev/null +++ b/modules/light-clients/06-solomachine/keys.go @@ -0,0 +1,5 @@ +package solomachine + +const ( + ModuleName = "06-solomachine" +) diff --git a/modules/light-clients/06-solomachine/misbehaviour.go b/modules/light-clients/06-solomachine/misbehaviour.go new file mode 100644 index 00000000000..8533f0b4fb3 --- /dev/null +++ b/modules/light-clients/06-solomachine/misbehaviour.go @@ -0,0 +1,68 @@ +package solomachine + +import ( + "bytes" + + errorsmod "cosmossdk.io/errors" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +var _ exported.ClientMessage = &Misbehaviour{} + +// ClientType is a Solo Machine light client. +func (misbehaviour Misbehaviour) ClientType() string { + return exported.Solomachine +} + +// Type implements Misbehaviour interface. +func (misbehaviour Misbehaviour) Type() string { + return exported.TypeClientMisbehaviour +} + +// ValidateBasic implements Misbehaviour interface. +func (misbehaviour Misbehaviour) ValidateBasic() error { + if misbehaviour.Sequence == 0 { + return errorsmod.Wrap(clienttypes.ErrInvalidMisbehaviour, "sequence cannot be 0") + } + + if err := misbehaviour.SignatureOne.ValidateBasic(); err != nil { + return errorsmod.Wrap(err, "signature one failed basic validation") + } + + if err := misbehaviour.SignatureTwo.ValidateBasic(); err != nil { + return errorsmod.Wrap(err, "signature two failed basic validation") + } + + // misbehaviour signatures cannot be identical. + if bytes.Equal(misbehaviour.SignatureOne.Signature, misbehaviour.SignatureTwo.Signature) { + return errorsmod.Wrap(clienttypes.ErrInvalidMisbehaviour, "misbehaviour signatures cannot be equal") + } + + // message data signed cannot be identical if both paths are the same. + if bytes.Equal(misbehaviour.SignatureOne.Path, misbehaviour.SignatureTwo.Path) && + bytes.Equal(misbehaviour.SignatureOne.Data, misbehaviour.SignatureTwo.Data) { + return errorsmod.Wrap(clienttypes.ErrInvalidMisbehaviour, "misbehaviour signature data must be signed over different messages") + } + + return nil +} + +// ValidateBasic ensures that the signature and data fields are non-empty. +func (sd SignatureAndData) ValidateBasic() error { + if len(sd.Signature) == 0 { + return errorsmod.Wrap(ErrInvalidSignatureAndData, "signature cannot be empty") + } + if len(sd.Data) == 0 { + return errorsmod.Wrap(ErrInvalidSignatureAndData, "data for signature cannot be empty") + } + if len(sd.Path) == 0 { + return errorsmod.Wrap(ErrInvalidSignatureAndData, "path for signature cannot be empty") + } + if sd.Timestamp == 0 { + return errorsmod.Wrap(ErrInvalidSignatureAndData, "timestamp cannot be 0") + } + + return nil +} diff --git a/modules/light-clients/06-solomachine/misbehaviour_handle.go b/modules/light-clients/06-solomachine/misbehaviour_handle.go new file mode 100644 index 00000000000..7e8b3822410 --- /dev/null +++ b/modules/light-clients/06-solomachine/misbehaviour_handle.go @@ -0,0 +1,75 @@ +package solomachine + +import ( + "github.com/cosmos/cosmos-sdk/codec" + + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// CheckForMisbehaviour returns true for type Misbehaviour (passed VerifyClientMessage check), otherwise returns false +func (cs ClientState) CheckForMisbehaviour(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, clientMsg exported.ClientMessage) bool { + if _, ok := clientMsg.(*Misbehaviour); ok { + return true + } + + return false +} + +func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, misbehaviour *Misbehaviour) error { + // NOTE: a check that the misbehaviour message data are not equal is done by + // misbehaviour.ValidateBasic which is called by the 02-client keeper. + // verify first signature + if err := cs.verifySignatureAndData(cdc, misbehaviour, misbehaviour.SignatureOne); err != nil { + return errorsmod.Wrap(err, "failed to verify signature one") + } + + // verify second signature + if err := cs.verifySignatureAndData(cdc, misbehaviour, misbehaviour.SignatureTwo); err != nil { + return errorsmod.Wrap(err, "failed to verify signature two") + } + + return nil +} + +// verifySignatureAndData verifies that the currently registered public key has signed +// over the provided data and that the data is valid. The data is valid if it can be +// unmarshaled into the specified data type. +func (cs ClientState) verifySignatureAndData(cdc codec.BinaryCodec, misbehaviour *Misbehaviour, sigAndData *SignatureAndData) error { + // do not check misbehaviour timestamp since we want to allow processing of past misbehaviour + if err := cdc.Unmarshal(sigAndData.Path, new(commitmenttypes.MerklePath)); err != nil { + return err + } + + signBytes := SignBytes{ + Sequence: misbehaviour.Sequence, + Timestamp: sigAndData.Timestamp, + Diversifier: cs.ConsensusState.Diversifier, + Path: sigAndData.Path, + Data: sigAndData.Data, + } + + data, err := cdc.Marshal(&signBytes) + if err != nil { + return err + } + + sigData, err := UnmarshalSignatureData(cdc, sigAndData.Signature) + if err != nil { + return err + } + + publicKey, err := cs.ConsensusState.GetPubKey() + if err != nil { + return err + } + + if err := VerifySignature(publicKey, data, sigData); err != nil { + return err + } + + return nil +} diff --git a/modules/light-clients/06-solomachine/types/misbehaviour_test.go b/modules/light-clients/06-solomachine/misbehaviour_test.go similarity index 54% rename from modules/light-clients/06-solomachine/types/misbehaviour_test.go rename to modules/light-clients/06-solomachine/misbehaviour_test.go index 47724375494..0ac774a6ea5 100644 --- a/modules/light-clients/06-solomachine/types/misbehaviour_test.go +++ b/modules/light-clients/06-solomachine/misbehaviour_test.go @@ -1,109 +1,109 @@ -package types_test +package solomachine_test import ( - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *SoloMachineTestSuite) TestMisbehaviour() { misbehaviour := suite.solomachine.CreateMisbehaviour() suite.Require().Equal(exported.Solomachine, misbehaviour.ClientType()) - suite.Require().Equal(suite.solomachine.ClientID, misbehaviour.GetClientID()) } func (suite *SoloMachineTestSuite) TestMisbehaviourValidateBasic() { // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { testCases := []struct { name string - malleateMisbehaviour func(misbehaviour *types.Misbehaviour) + malleateMisbehaviour func(misbehaviour *solomachine.Misbehaviour) expPass bool }{ { "valid misbehaviour", - func(*types.Misbehaviour) {}, + func(*solomachine.Misbehaviour) {}, true, }, - { - "invalid client ID", - func(misbehaviour *types.Misbehaviour) { - misbehaviour.ClientId = "(badclientid)" - }, - false, - }, { "sequence is zero", - func(misbehaviour *types.Misbehaviour) { + func(misbehaviour *solomachine.Misbehaviour) { misbehaviour.Sequence = 0 }, false, }, { "signature one sig is empty", - func(misbehaviour *types.Misbehaviour) { + func(misbehaviour *solomachine.Misbehaviour) { misbehaviour.SignatureOne.Signature = []byte{} }, false, }, { "signature two sig is empty", - func(misbehaviour *types.Misbehaviour) { + func(misbehaviour *solomachine.Misbehaviour) { misbehaviour.SignatureTwo.Signature = []byte{} }, false, }, { "signature one data is empty", - func(misbehaviour *types.Misbehaviour) { + func(misbehaviour *solomachine.Misbehaviour) { misbehaviour.SignatureOne.Data = nil }, false, }, { "signature two data is empty", - func(misbehaviour *types.Misbehaviour) { + func(misbehaviour *solomachine.Misbehaviour) { misbehaviour.SignatureTwo.Data = []byte{} }, false, }, { "signatures are identical", - func(misbehaviour *types.Misbehaviour) { + func(misbehaviour *solomachine.Misbehaviour) { misbehaviour.SignatureTwo.Signature = misbehaviour.SignatureOne.Signature }, false, }, { - "data signed is identical", - func(misbehaviour *types.Misbehaviour) { + "data signed is identical but path differs", + func(misbehaviour *solomachine.Misbehaviour) { + misbehaviour.SignatureTwo.Data = misbehaviour.SignatureOne.Data + }, + true, + }, + { + "data signed and path are identical", + func(misbehaviour *solomachine.Misbehaviour) { + misbehaviour.SignatureTwo.Path = misbehaviour.SignatureOne.Path misbehaviour.SignatureTwo.Data = misbehaviour.SignatureOne.Data }, false, }, { - "data type for SignatureOne is unspecified", - func(misbehaviour *types.Misbehaviour) { - misbehaviour.SignatureOne.DataType = types.UNSPECIFIED + "data path for SignatureOne is unspecified", + func(misbehaviour *solomachine.Misbehaviour) { + misbehaviour.SignatureOne.Path = []byte{} }, false, }, { - "data type for SignatureTwo is unspecified", - func(misbehaviour *types.Misbehaviour) { - misbehaviour.SignatureTwo.DataType = types.UNSPECIFIED + "data path for SignatureTwo is unspecified", + func(misbehaviour *solomachine.Misbehaviour) { + misbehaviour.SignatureTwo.Path = []byte{} }, false, }, { "timestamp for SignatureOne is zero", - func(misbehaviour *types.Misbehaviour) { + func(misbehaviour *solomachine.Misbehaviour) { misbehaviour.SignatureOne.Timestamp = 0 }, false, }, { "timestamp for SignatureTwo is zero", - func(misbehaviour *types.Misbehaviour) { + func(misbehaviour *solomachine.Misbehaviour) { misbehaviour.SignatureTwo.Timestamp = 0 }, false, }, @@ -113,7 +113,7 @@ func (suite *SoloMachineTestSuite) TestMisbehaviourValidateBasic() { tc := tc suite.Run(tc.name, func() { - misbehaviour := solomachine.CreateMisbehaviour() + misbehaviour := sm.CreateMisbehaviour() tc.malleateMisbehaviour(misbehaviour) err := misbehaviour.ValidateBasic() diff --git a/modules/light-clients/06-solomachine/module.go b/modules/light-clients/06-solomachine/module.go index 60cfedb88f0..3b168e0bcea 100644 --- a/modules/light-clients/06-solomachine/module.go +++ b/modules/light-clients/06-solomachine/module.go @@ -1,10 +1,56 @@ package solomachine import ( - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" + "encoding/json" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" ) -// Name returns the solo machine client name. -func Name() string { - return types.SubModuleName +var _ module.AppModuleBasic = AppModuleBasic{} + +// AppModuleBasic defines the basic application module used by the solo machine light client. +// Only the RegisterInterfaces function needs to be implemented. All other function perform +// a no-op. +type AppModuleBasic struct{} + +// Name returns the solo machine module name. +func (AppModuleBasic) Name() string { + return ModuleName +} + +// RegisterLegacyAminoCodec performs a no-op. The solo machine client does not support amino. +func (AppModuleBasic) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} + +// RegisterInterfaces registers module concrete types into protobuf Any. This allows core IBC +// to unmarshal solo machine types. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + RegisterInterfaces(registry) +} + +// DefaultGenesis performs a no-op. Genesis is not supported for solo machine. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return nil +} + +// ValidateGenesis performs a no-op. Genesis is not supported for solo machine. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + return nil +} + +// RegisterGRPCGatewayRoutes performs a no-op. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} + +// GetTxCmd performs a no-op. Please see the 02-client cli commands. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +// GetQueryCmd performs a no-op. Please see the 02-client cli commands. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil } diff --git a/modules/light-clients/06-solomachine/proof.go b/modules/light-clients/06-solomachine/proof.go new file mode 100644 index 00000000000..aab15c17d3c --- /dev/null +++ b/modules/light-clients/06-solomachine/proof.go @@ -0,0 +1,43 @@ +package solomachine + +import ( + errorsmod "cosmossdk.io/errors" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/crypto/types/multisig" + "github.com/cosmos/cosmos-sdk/types/tx/signing" +) + +// VerifySignature verifies if the the provided public key generated the signature +// over the given data. Single and Multi signature public keys are supported. +// The signature data type must correspond to the public key type. An error is +// returned if signature verification fails or an invalid SignatureData type is +// provided. +func VerifySignature(pubKey cryptotypes.PubKey, signBytes []byte, sigData signing.SignatureData) error { + switch pubKey := pubKey.(type) { + case multisig.PubKey: + data, ok := sigData.(*signing.MultiSignatureData) + if !ok { + return errorsmod.Wrapf(ErrSignatureVerificationFailed, "invalid signature data type, expected %T, got %T", (*signing.MultiSignatureData)(nil), data) + } + + // The function supplied fulfills the VerifyMultisignature interface. No special + // adjustments need to be made to the sign bytes based on the sign mode. + if err := pubKey.VerifyMultisignature(func(signing.SignMode) ([]byte, error) { + return signBytes, nil + }, data); err != nil { + return err + } + + default: + data, ok := sigData.(*signing.SingleSignatureData) + if !ok { + return errorsmod.Wrapf(ErrSignatureVerificationFailed, "invalid signature data type, expected %T, got %T", (*signing.SingleSignatureData)(nil), data) + } + + if !pubKey.VerifySignature(signBytes, data.Signature) { + return ErrSignatureVerificationFailed + } + } + + return nil +} diff --git a/modules/light-clients/06-solomachine/proof_test.go b/modules/light-clients/06-solomachine/proof_test.go new file mode 100644 index 00000000000..25702a19c84 --- /dev/null +++ b/modules/light-clients/06-solomachine/proof_test.go @@ -0,0 +1,67 @@ +package solomachine_test + +import ( + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" +) + +func (suite *SoloMachineTestSuite) TestVerifySignature() { + cdc := suite.chainA.App.AppCodec() + signBytes := []byte("sign bytes") + + singleSignature := suite.solomachine.GenerateSignature(signBytes) + singleSigData, err := solomachine.UnmarshalSignatureData(cdc, singleSignature) + suite.Require().NoError(err) + + multiSignature := suite.solomachineMulti.GenerateSignature(signBytes) + multiSigData, err := solomachine.UnmarshalSignatureData(cdc, multiSignature) + suite.Require().NoError(err) + + testCases := []struct { + name string + publicKey cryptotypes.PubKey + sigData signing.SignatureData + expPass bool + }{ + { + "single signature with regular public key", + suite.solomachine.PublicKey, + singleSigData, + true, + }, + { + "multi signature with multisig public key", + suite.solomachineMulti.PublicKey, + multiSigData, + true, + }, + { + "single signature with multisig public key", + suite.solomachineMulti.PublicKey, + singleSigData, + false, + }, + { + "multi signature with regular public key", + suite.solomachine.PublicKey, + multiSigData, + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + err := solomachine.VerifySignature(tc.publicKey, signBytes, tc.sigData) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} diff --git a/modules/light-clients/06-solomachine/types/proposal_handle.go b/modules/light-clients/06-solomachine/proposal_handle.go similarity index 52% rename from modules/light-clients/06-solomachine/types/proposal_handle.go rename to modules/light-clients/06-solomachine/proposal_handle.go index c4316f982a8..2e6fdfd7ed8 100644 --- a/modules/light-clients/06-solomachine/types/proposal_handle.go +++ b/modules/light-clients/06-solomachine/proposal_handle.go @@ -1,14 +1,14 @@ -package types +package solomachine import ( "reflect" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // CheckSubstituteAndUpdateState verifies that the subject is allowed to be updated by @@ -21,43 +21,32 @@ import ( func (cs ClientState) CheckSubstituteAndUpdateState( ctx sdk.Context, cdc codec.BinaryCodec, subjectClientStore, _ sdk.KVStore, substituteClient exported.ClientState, -) (exported.ClientState, error) { - if !cs.AllowUpdateAfterProposal { - return nil, sdkerrors.Wrapf( - clienttypes.ErrUpdateClientFailed, - "solo machine client is not allowed to updated with a proposal", - ) - } - +) error { substituteClientState, ok := substituteClient.(*ClientState) if !ok { - return nil, sdkerrors.Wrapf( - clienttypes.ErrInvalidClientType, "substitute client state type %T, expected %T", substituteClient, &ClientState{}, - ) + return errorsmod.Wrapf(clienttypes.ErrInvalidClientType, "substitute client state type %T, expected %T", substituteClient, &ClientState{}) } subjectPublicKey, err := cs.ConsensusState.GetPubKey() if err != nil { - return nil, sdkerrors.Wrap(err, "failed to get consensus public key") + return errorsmod.Wrap(err, "failed to get consensus public key") } substitutePublicKey, err := substituteClientState.ConsensusState.GetPubKey() if err != nil { - return nil, sdkerrors.Wrap(err, "failed to get substitute client public key") + return errorsmod.Wrap(err, "failed to get substitute client public key") } if reflect.DeepEqual(subjectPublicKey, substitutePublicKey) { - return nil, sdkerrors.Wrapf( - clienttypes.ErrInvalidHeader, "subject and substitute have the same public key", - ) + return errorsmod.Wrapf(clienttypes.ErrInvalidHeader, "subject and substitute have the same public key") } - clientState := &cs - // update to substitute parameters - clientState.Sequence = substituteClientState.Sequence - clientState.ConsensusState = substituteClientState.ConsensusState - clientState.IsFrozen = false + cs.Sequence = substituteClientState.Sequence + cs.ConsensusState = substituteClientState.ConsensusState + cs.IsFrozen = false + + setClientState(subjectClientStore, cdc, &cs) - return clientState, nil + return nil } diff --git a/modules/light-clients/06-solomachine/proposal_handle_test.go b/modules/light-clients/06-solomachine/proposal_handle_test.go new file mode 100644 index 00000000000..22a3c0d624a --- /dev/null +++ b/modules/light-clients/06-solomachine/proposal_handle_test.go @@ -0,0 +1,83 @@ +package solomachine_test + +import ( + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func (suite *SoloMachineTestSuite) TestCheckSubstituteAndUpdateState() { + var ( + subjectClientState *solomachine.ClientState + substituteClientState exported.ClientState + ) + + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "substitute is not the solo machine", func() { + substituteClientState = &ibctm.ClientState{} + }, false, + }, + { + "subject public key is nil", func() { + subjectClientState.ConsensusState.PublicKey = nil + }, false, + }, + + { + "substitute public key is nil", func() { + substituteClientState.(*solomachine.ClientState).ConsensusState.PublicKey = nil + }, false, + }, + { + "subject and substitute use the same public key", func() { + substituteClientState.(*solomachine.ClientState).ConsensusState.PublicKey = subjectClientState.ConsensusState.PublicKey + }, false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() + + subjectClientState = sm.ClientState() + substitute := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "substitute", "testing", 5) + substituteClientState = substitute.ClientState() + + tc.malleate() + + subjectClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), sm.ClientID) + substituteClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), substitute.ClientID) + + err := subjectClientState.CheckSubstituteAndUpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), subjectClientStore, substituteClientStore, substituteClientState) + + if tc.expPass { + suite.Require().NoError(err) + + // ensure updated client state is set in store + bz := subjectClientStore.Get(host.ClientStateKey()) + updatedClient := clienttypes.MustUnmarshalClientState(suite.chainA.App.AppCodec(), bz).(*solomachine.ClientState) + + suite.Require().Equal(substituteClientState.(*solomachine.ClientState).ConsensusState, updatedClient.ConsensusState) + suite.Require().Equal(substituteClientState.(*solomachine.ClientState).Sequence, updatedClient.Sequence) + suite.Require().Equal(false, updatedClient.IsFrozen) + + } else { + suite.Require().Error(err) + } + }) + } + } +} diff --git a/modules/light-clients/06-solomachine/types/solomachine.go b/modules/light-clients/06-solomachine/solomachine.go similarity index 69% rename from modules/light-clients/06-solomachine/types/solomachine.go rename to modules/light-clients/06-solomachine/solomachine.go index 0ce953e12c8..41511910bf4 100644 --- a/modules/light-clients/06-solomachine/types/solomachine.go +++ b/modules/light-clients/06-solomachine/solomachine.go @@ -1,10 +1,8 @@ -package types +package solomachine import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - - "github.com/cosmos/ibc-go/v4/modules/core/exported" ) // Interface implementation checks. @@ -32,13 +30,3 @@ func (h Header) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { func (hd HeaderData) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { return unpacker.UnpackAny(hd.NewPubKey, new(cryptotypes.PubKey)) } - -// UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method -func (csd ClientStateData) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - return unpacker.UnpackAny(csd.ClientState, new(exported.ClientState)) -} - -// UnpackInterfaces implements the UnpackInterfaceMessages.UnpackInterfaces method -func (csd ConsensusStateData) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - return unpacker.UnpackAny(csd.ConsensusState, new(exported.ConsensusState)) -} diff --git a/modules/light-clients/06-solomachine/solomachine.pb.go b/modules/light-clients/06-solomachine/solomachine.pb.go new file mode 100644 index 00000000000..f2152041bdf --- /dev/null +++ b/modules/light-clients/06-solomachine/solomachine.pb.go @@ -0,0 +1,2236 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/lightclients/solomachine/v3/solomachine.proto + +package solomachine + +import ( + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// ClientState defines a solo machine client that tracks the current consensus +// state and if the client is frozen. +type ClientState struct { + // latest sequence of the client state + Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` + // frozen sequence of the solo machine + IsFrozen bool `protobuf:"varint,2,opt,name=is_frozen,json=isFrozen,proto3" json:"is_frozen,omitempty" yaml:"is_frozen"` + ConsensusState *ConsensusState `protobuf:"bytes,3,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty" yaml:"consensus_state"` +} + +func (m *ClientState) Reset() { *m = ClientState{} } +func (m *ClientState) String() string { return proto.CompactTextString(m) } +func (*ClientState) ProtoMessage() {} +func (*ClientState) Descriptor() ([]byte, []int) { + return fileDescriptor_264187157b9220a4, []int{0} +} +func (m *ClientState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClientState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ClientState.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 *ClientState) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientState.Merge(m, src) +} +func (m *ClientState) XXX_Size() int { + return m.Size() +} +func (m *ClientState) XXX_DiscardUnknown() { + xxx_messageInfo_ClientState.DiscardUnknown(m) +} + +var xxx_messageInfo_ClientState proto.InternalMessageInfo + +// ConsensusState defines a solo machine consensus state. The sequence of a +// consensus state is contained in the "height" key used in storing the +// consensus state. +type ConsensusState struct { + // public key of the solo machine + PublicKey *types.Any `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty" yaml:"public_key"` + // diversifier allows the same public key to be re-used across different solo + // machine clients (potentially on different chains) without being considered + // misbehaviour. + Diversifier string `protobuf:"bytes,2,opt,name=diversifier,proto3" json:"diversifier,omitempty"` + Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (m *ConsensusState) Reset() { *m = ConsensusState{} } +func (m *ConsensusState) String() string { return proto.CompactTextString(m) } +func (*ConsensusState) ProtoMessage() {} +func (*ConsensusState) Descriptor() ([]byte, []int) { + return fileDescriptor_264187157b9220a4, []int{1} +} +func (m *ConsensusState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConsensusState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConsensusState.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 *ConsensusState) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConsensusState.Merge(m, src) +} +func (m *ConsensusState) XXX_Size() int { + return m.Size() +} +func (m *ConsensusState) XXX_DiscardUnknown() { + xxx_messageInfo_ConsensusState.DiscardUnknown(m) +} + +var xxx_messageInfo_ConsensusState proto.InternalMessageInfo + +// Header defines a solo machine consensus header +type Header struct { + Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + NewPublicKey *types.Any `protobuf:"bytes,3,opt,name=new_public_key,json=newPublicKey,proto3" json:"new_public_key,omitempty" yaml:"new_public_key"` + NewDiversifier string `protobuf:"bytes,4,opt,name=new_diversifier,json=newDiversifier,proto3" json:"new_diversifier,omitempty" yaml:"new_diversifier"` +} + +func (m *Header) Reset() { *m = Header{} } +func (m *Header) String() string { return proto.CompactTextString(m) } +func (*Header) ProtoMessage() {} +func (*Header) Descriptor() ([]byte, []int) { + return fileDescriptor_264187157b9220a4, []int{2} +} +func (m *Header) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Header.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 *Header) XXX_Merge(src proto.Message) { + xxx_messageInfo_Header.Merge(m, src) +} +func (m *Header) XXX_Size() int { + return m.Size() +} +func (m *Header) XXX_DiscardUnknown() { + xxx_messageInfo_Header.DiscardUnknown(m) +} + +var xxx_messageInfo_Header proto.InternalMessageInfo + +// Misbehaviour defines misbehaviour for a solo machine which consists +// of a sequence and two signatures over different messages at that sequence. +type Misbehaviour struct { + Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` + SignatureOne *SignatureAndData `protobuf:"bytes,2,opt,name=signature_one,json=signatureOne,proto3" json:"signature_one,omitempty" yaml:"signature_one"` + SignatureTwo *SignatureAndData `protobuf:"bytes,3,opt,name=signature_two,json=signatureTwo,proto3" json:"signature_two,omitempty" yaml:"signature_two"` +} + +func (m *Misbehaviour) Reset() { *m = Misbehaviour{} } +func (m *Misbehaviour) String() string { return proto.CompactTextString(m) } +func (*Misbehaviour) ProtoMessage() {} +func (*Misbehaviour) Descriptor() ([]byte, []int) { + return fileDescriptor_264187157b9220a4, []int{3} +} +func (m *Misbehaviour) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Misbehaviour) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Misbehaviour.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 *Misbehaviour) XXX_Merge(src proto.Message) { + xxx_messageInfo_Misbehaviour.Merge(m, src) +} +func (m *Misbehaviour) XXX_Size() int { + return m.Size() +} +func (m *Misbehaviour) XXX_DiscardUnknown() { + xxx_messageInfo_Misbehaviour.DiscardUnknown(m) +} + +var xxx_messageInfo_Misbehaviour proto.InternalMessageInfo + +// SignatureAndData contains a signature and the data signed over to create that +// signature. +type SignatureAndData struct { + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` + Path []byte `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (m *SignatureAndData) Reset() { *m = SignatureAndData{} } +func (m *SignatureAndData) String() string { return proto.CompactTextString(m) } +func (*SignatureAndData) ProtoMessage() {} +func (*SignatureAndData) Descriptor() ([]byte, []int) { + return fileDescriptor_264187157b9220a4, []int{4} +} +func (m *SignatureAndData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SignatureAndData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SignatureAndData.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 *SignatureAndData) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignatureAndData.Merge(m, src) +} +func (m *SignatureAndData) XXX_Size() int { + return m.Size() +} +func (m *SignatureAndData) XXX_DiscardUnknown() { + xxx_messageInfo_SignatureAndData.DiscardUnknown(m) +} + +var xxx_messageInfo_SignatureAndData proto.InternalMessageInfo + +// TimestampedSignatureData contains the signature data and the timestamp of the +// signature. +type TimestampedSignatureData struct { + SignatureData []byte `protobuf:"bytes,1,opt,name=signature_data,json=signatureData,proto3" json:"signature_data,omitempty" yaml:"signature_data"` + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (m *TimestampedSignatureData) Reset() { *m = TimestampedSignatureData{} } +func (m *TimestampedSignatureData) String() string { return proto.CompactTextString(m) } +func (*TimestampedSignatureData) ProtoMessage() {} +func (*TimestampedSignatureData) Descriptor() ([]byte, []int) { + return fileDescriptor_264187157b9220a4, []int{5} +} +func (m *TimestampedSignatureData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TimestampedSignatureData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TimestampedSignatureData.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 *TimestampedSignatureData) XXX_Merge(src proto.Message) { + xxx_messageInfo_TimestampedSignatureData.Merge(m, src) +} +func (m *TimestampedSignatureData) XXX_Size() int { + return m.Size() +} +func (m *TimestampedSignatureData) XXX_DiscardUnknown() { + xxx_messageInfo_TimestampedSignatureData.DiscardUnknown(m) +} + +var xxx_messageInfo_TimestampedSignatureData proto.InternalMessageInfo + +// SignBytes defines the signed bytes used for signature verification. +type SignBytes struct { + // the sequence number + Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` + // the proof timestamp + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // the public key diversifier + Diversifier string `protobuf:"bytes,3,opt,name=diversifier,proto3" json:"diversifier,omitempty"` + // the standardised path bytes + Path []byte `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"` + // the marshaled data bytes + Data []byte `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *SignBytes) Reset() { *m = SignBytes{} } +func (m *SignBytes) String() string { return proto.CompactTextString(m) } +func (*SignBytes) ProtoMessage() {} +func (*SignBytes) Descriptor() ([]byte, []int) { + return fileDescriptor_264187157b9220a4, []int{6} +} +func (m *SignBytes) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SignBytes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SignBytes.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 *SignBytes) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignBytes.Merge(m, src) +} +func (m *SignBytes) XXX_Size() int { + return m.Size() +} +func (m *SignBytes) XXX_DiscardUnknown() { + xxx_messageInfo_SignBytes.DiscardUnknown(m) +} + +var xxx_messageInfo_SignBytes proto.InternalMessageInfo + +// HeaderData returns the SignBytes data for update verification. +type HeaderData struct { + // header public key + NewPubKey *types.Any `protobuf:"bytes,1,opt,name=new_pub_key,json=newPubKey,proto3" json:"new_pub_key,omitempty" yaml:"new_pub_key"` + // header diversifier + NewDiversifier string `protobuf:"bytes,2,opt,name=new_diversifier,json=newDiversifier,proto3" json:"new_diversifier,omitempty" yaml:"new_diversifier"` +} + +func (m *HeaderData) Reset() { *m = HeaderData{} } +func (m *HeaderData) String() string { return proto.CompactTextString(m) } +func (*HeaderData) ProtoMessage() {} +func (*HeaderData) Descriptor() ([]byte, []int) { + return fileDescriptor_264187157b9220a4, []int{7} +} +func (m *HeaderData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeaderData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeaderData.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 *HeaderData) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeaderData.Merge(m, src) +} +func (m *HeaderData) XXX_Size() int { + return m.Size() +} +func (m *HeaderData) XXX_DiscardUnknown() { + xxx_messageInfo_HeaderData.DiscardUnknown(m) +} + +var xxx_messageInfo_HeaderData proto.InternalMessageInfo + +func init() { + proto.RegisterType((*ClientState)(nil), "ibc.lightclients.solomachine.v3.ClientState") + proto.RegisterType((*ConsensusState)(nil), "ibc.lightclients.solomachine.v3.ConsensusState") + proto.RegisterType((*Header)(nil), "ibc.lightclients.solomachine.v3.Header") + proto.RegisterType((*Misbehaviour)(nil), "ibc.lightclients.solomachine.v3.Misbehaviour") + proto.RegisterType((*SignatureAndData)(nil), "ibc.lightclients.solomachine.v3.SignatureAndData") + proto.RegisterType((*TimestampedSignatureData)(nil), "ibc.lightclients.solomachine.v3.TimestampedSignatureData") + proto.RegisterType((*SignBytes)(nil), "ibc.lightclients.solomachine.v3.SignBytes") + proto.RegisterType((*HeaderData)(nil), "ibc.lightclients.solomachine.v3.HeaderData") +} + +func init() { + proto.RegisterFile("ibc/lightclients/solomachine/v3/solomachine.proto", fileDescriptor_264187157b9220a4) +} + +var fileDescriptor_264187157b9220a4 = []byte{ + // 709 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x6e, 0xd3, 0x4a, + 0x14, 0xce, 0xa4, 0xbe, 0x55, 0x33, 0xc9, 0x4d, 0x7b, 0xad, 0xb4, 0x4a, 0xa3, 0xab, 0x38, 0xf2, + 0xaa, 0x9b, 0xda, 0xb7, 0xad, 0x74, 0x91, 0xca, 0x86, 0xa6, 0x15, 0x42, 0x50, 0x04, 0x72, 0xcb, + 0x86, 0x4d, 0x34, 0x76, 0x26, 0xce, 0x08, 0x7b, 0x26, 0x64, 0xc6, 0x89, 0x82, 0x58, 0xb0, 0x64, + 0xc9, 0x02, 0xf6, 0x08, 0x89, 0x77, 0x61, 0xd9, 0x65, 0x57, 0x11, 0x6a, 0x25, 0x1e, 0x20, 0x4f, + 0x80, 0x3c, 0x76, 0xe2, 0x9f, 0x96, 0x54, 0x42, 0xec, 0xe6, 0x9c, 0x39, 0x3f, 0xdf, 0xf7, 0xcd, + 0x39, 0x36, 0xdc, 0x23, 0xb6, 0x63, 0x7a, 0xc4, 0xed, 0x0b, 0xc7, 0x23, 0x98, 0x0a, 0x6e, 0x72, + 0xe6, 0x31, 0x1f, 0x39, 0x7d, 0x42, 0xb1, 0x39, 0x3a, 0x48, 0x9b, 0xc6, 0x60, 0xc8, 0x04, 0x53, + 0x35, 0x62, 0x3b, 0x46, 0x3a, 0xc5, 0x48, 0xc7, 0x8c, 0x0e, 0x1a, 0x35, 0x97, 0xb9, 0x4c, 0xc6, + 0x9a, 0xe1, 0x29, 0x4a, 0x6b, 0x6c, 0xbb, 0x8c, 0xb9, 0x1e, 0x36, 0xa5, 0x65, 0x07, 0x3d, 0x13, + 0xd1, 0x49, 0x74, 0xa5, 0x5f, 0x02, 0x58, 0x3e, 0x96, 0xb5, 0xce, 0x04, 0x12, 0x58, 0x6d, 0xc0, + 0x35, 0x8e, 0x5f, 0x07, 0x98, 0x3a, 0xb8, 0x0e, 0x5a, 0x60, 0x47, 0xb1, 0x16, 0xb6, 0xba, 0x07, + 0x4b, 0x84, 0x77, 0x7a, 0x43, 0xf6, 0x06, 0xd3, 0x7a, 0xb1, 0x05, 0x76, 0xd6, 0xda, 0xb5, 0xd9, + 0x54, 0xdb, 0x98, 0x20, 0xdf, 0x3b, 0xd4, 0x17, 0x57, 0xba, 0xb5, 0x46, 0xf8, 0x43, 0x79, 0x54, + 0x05, 0x5c, 0x77, 0x18, 0xe5, 0x98, 0xf2, 0x80, 0x77, 0x78, 0xd8, 0xa1, 0xbe, 0xd2, 0x02, 0x3b, + 0xe5, 0x7d, 0xd3, 0xb8, 0x83, 0x8a, 0x71, 0x3c, 0xcf, 0x93, 0xc0, 0xda, 0x8d, 0xd9, 0x54, 0xdb, + 0x8a, 0x3a, 0xe5, 0x2a, 0xea, 0x56, 0xd5, 0xc9, 0xc4, 0x1e, 0x2a, 0xef, 0x3f, 0x6b, 0x05, 0xfd, + 0x0b, 0x80, 0xd5, 0x6c, 0x11, 0xf5, 0x31, 0x84, 0x83, 0xc0, 0xf6, 0x88, 0xd3, 0x79, 0x85, 0x27, + 0x92, 0x5f, 0x79, 0xbf, 0x66, 0x44, 0xea, 0x18, 0x73, 0x75, 0x8c, 0x23, 0x3a, 0x69, 0x6f, 0xce, + 0xa6, 0xda, 0x3f, 0x51, 0xbb, 0x24, 0x43, 0xb7, 0x4a, 0x91, 0xf1, 0x04, 0x4f, 0xd4, 0x16, 0x2c, + 0x77, 0xc9, 0x08, 0x0f, 0x39, 0xe9, 0x11, 0x3c, 0x94, 0x7a, 0x94, 0xac, 0xb4, 0x4b, 0xfd, 0x17, + 0x96, 0x04, 0xf1, 0x31, 0x17, 0xc8, 0x1f, 0x48, 0xda, 0x8a, 0x95, 0x38, 0x62, 0x90, 0x3f, 0x00, + 0x5c, 0x7d, 0x84, 0x51, 0x37, 0x1f, 0x0e, 0x72, 0xe1, 0xe1, 0x2d, 0x27, 0x2e, 0x45, 0x22, 0x18, + 0x62, 0xd9, 0xac, 0x62, 0x25, 0x0e, 0xf5, 0x05, 0xac, 0x52, 0x3c, 0xee, 0xa4, 0xc8, 0xad, 0x2c, + 0x21, 0xb7, 0x3d, 0x9b, 0x6a, 0x9b, 0x11, 0xb9, 0x6c, 0x96, 0x6e, 0x55, 0x28, 0x1e, 0x3f, 0x5f, + 0x70, 0x3c, 0x86, 0xeb, 0x61, 0x40, 0x9a, 0xa7, 0x12, 0xf2, 0x4c, 0xbf, 0x46, 0x2e, 0x40, 0xb7, + 0x42, 0x24, 0x27, 0x89, 0x23, 0x26, 0xfa, 0xb1, 0x08, 0x2b, 0x4f, 0x09, 0xb7, 0x71, 0x1f, 0x8d, + 0x08, 0x0b, 0x86, 0x4b, 0x27, 0x6d, 0x00, 0xff, 0x5e, 0x70, 0xeb, 0x30, 0x1a, 0x11, 0x2e, 0xef, + 0xef, 0xdd, 0x39, 0x34, 0x67, 0xf3, 0xac, 0x23, 0xda, 0x3d, 0x41, 0x02, 0xb5, 0xeb, 0xb3, 0xa9, + 0x56, 0x8b, 0x80, 0x66, 0x2a, 0xea, 0x56, 0x65, 0x61, 0x3f, 0xa3, 0xb9, 0x8e, 0x62, 0xcc, 0x62, + 0xfd, 0xfe, 0x54, 0x47, 0x31, 0x66, 0xe9, 0x8e, 0xe7, 0x63, 0x16, 0xcb, 0xf2, 0x16, 0x6e, 0xe4, + 0x2b, 0x64, 0x9f, 0x1a, 0xe4, 0x9f, 0x5a, 0x85, 0xca, 0x00, 0x89, 0x7e, 0x3c, 0x03, 0xf2, 0x1c, + 0xfa, 0xba, 0x48, 0x20, 0x09, 0xba, 0x62, 0xc9, 0x73, 0x76, 0x9c, 0x94, 0xdb, 0xa7, 0xef, 0x1d, + 0x80, 0xf5, 0xf3, 0xb9, 0x0f, 0x77, 0x17, 0x48, 0x24, 0x8c, 0x07, 0xb0, 0x9a, 0x10, 0x90, 0xe5, + 0x25, 0x96, 0xf4, 0xf4, 0x64, 0xef, 0x75, 0x2b, 0xd1, 0xf0, 0xe4, 0x06, 0x84, 0xe2, 0xed, 0x10, + 0x3e, 0x01, 0x58, 0x0a, 0xfb, 0xb6, 0x27, 0x02, 0xf3, 0xa5, 0x43, 0xb1, 0xb4, 0x5a, 0x7e, 0x1d, + 0x57, 0x6e, 0xae, 0xe3, 0x5c, 0x38, 0xe5, 0x16, 0xe1, 0xfe, 0x4a, 0x84, 0x8b, 0x71, 0x7d, 0x05, + 0x10, 0x46, 0x8b, 0x29, 0xa9, 0x9c, 0xc2, 0x72, 0xbc, 0x2a, 0x77, 0x7e, 0x3a, 0xb6, 0x66, 0x53, + 0x4d, 0xcd, 0x6c, 0x57, 0xfc, 0xed, 0x88, 0x56, 0xeb, 0x17, 0x7b, 0x55, 0xfc, 0xbd, 0xbd, 0x6a, + 0xf7, 0xbe, 0x5d, 0x35, 0xc1, 0xc5, 0x55, 0x13, 0x7c, 0xbf, 0x6a, 0x82, 0x0f, 0xd7, 0xcd, 0xc2, + 0xc5, 0x75, 0xb3, 0x70, 0x79, 0xdd, 0x2c, 0xbc, 0x3c, 0x75, 0x89, 0xe8, 0x07, 0xb6, 0xe1, 0x30, + 0xdf, 0x74, 0x18, 0xf7, 0x19, 0x37, 0x89, 0xed, 0xec, 0xba, 0xcc, 0x1c, 0xdd, 0x33, 0x7d, 0xd6, + 0x0d, 0x3c, 0xcc, 0xa3, 0xff, 0xcf, 0xee, 0xfc, 0x07, 0xf4, 0xdf, 0xff, 0xbb, 0xa9, 0xf1, 0xbe, + 0x9f, 0x3a, 0xdb, 0xab, 0x92, 0xe3, 0xc1, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0xe1, 0xf5, + 0xc9, 0xb6, 0x06, 0x00, 0x00, +} + +func (m *ClientState) 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 *ClientState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ConsensusState != nil { + { + size, err := m.ConsensusState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSolomachine(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.IsFrozen { + i-- + if m.IsFrozen { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if m.Sequence != 0 { + i = encodeVarintSolomachine(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ConsensusState) 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 *ConsensusState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timestamp != 0 { + i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x18 + } + if len(m.Diversifier) > 0 { + i -= len(m.Diversifier) + copy(dAtA[i:], m.Diversifier) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Diversifier))) + i-- + dAtA[i] = 0x12 + } + if m.PublicKey != nil { + { + size, err := m.PublicKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSolomachine(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Header) 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 *Header) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewDiversifier) > 0 { + i -= len(m.NewDiversifier) + copy(dAtA[i:], m.NewDiversifier) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.NewDiversifier))) + i-- + dAtA[i] = 0x22 + } + if m.NewPublicKey != nil { + { + size, err := m.NewPublicKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSolomachine(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x12 + } + if m.Timestamp != 0 { + i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Misbehaviour) 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 *Misbehaviour) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Misbehaviour) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SignatureTwo != nil { + { + size, err := m.SignatureTwo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSolomachine(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.SignatureOne != nil { + { + size, err := m.SignatureOne.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSolomachine(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Sequence != 0 { + i = encodeVarintSolomachine(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SignatureAndData) 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 *SignatureAndData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignatureAndData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timestamp != 0 { + i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x20 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x1a + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x12 + } + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TimestampedSignatureData) 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 *TimestampedSignatureData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TimestampedSignatureData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timestamp != 0 { + i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x10 + } + if len(m.SignatureData) > 0 { + i -= len(m.SignatureData) + copy(dAtA[i:], m.SignatureData) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.SignatureData))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SignBytes) 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 *SignBytes) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SignBytes) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x2a + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x22 + } + if len(m.Diversifier) > 0 { + i -= len(m.Diversifier) + copy(dAtA[i:], m.Diversifier) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.Diversifier))) + i-- + dAtA[i] = 0x1a + } + if m.Timestamp != 0 { + i = encodeVarintSolomachine(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x10 + } + if m.Sequence != 0 { + i = encodeVarintSolomachine(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *HeaderData) 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 *HeaderData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeaderData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewDiversifier) > 0 { + i -= len(m.NewDiversifier) + copy(dAtA[i:], m.NewDiversifier) + i = encodeVarintSolomachine(dAtA, i, uint64(len(m.NewDiversifier))) + i-- + dAtA[i] = 0x12 + } + if m.NewPubKey != nil { + { + size, err := m.NewPubKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSolomachine(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintSolomachine(dAtA []byte, offset int, v uint64) int { + offset -= sovSolomachine(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ClientState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sequence != 0 { + n += 1 + sovSolomachine(uint64(m.Sequence)) + } + if m.IsFrozen { + n += 2 + } + if m.ConsensusState != nil { + l = m.ConsensusState.Size() + n += 1 + l + sovSolomachine(uint64(l)) + } + return n +} + +func (m *ConsensusState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PublicKey != nil { + l = m.PublicKey.Size() + n += 1 + l + sovSolomachine(uint64(l)) + } + l = len(m.Diversifier) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + if m.Timestamp != 0 { + n += 1 + sovSolomachine(uint64(m.Timestamp)) + } + return n +} + +func (m *Header) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Timestamp != 0 { + n += 1 + sovSolomachine(uint64(m.Timestamp)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + if m.NewPublicKey != nil { + l = m.NewPublicKey.Size() + n += 1 + l + sovSolomachine(uint64(l)) + } + l = len(m.NewDiversifier) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + return n +} + +func (m *Misbehaviour) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sequence != 0 { + n += 1 + sovSolomachine(uint64(m.Sequence)) + } + if m.SignatureOne != nil { + l = m.SignatureOne.Size() + n += 1 + l + sovSolomachine(uint64(l)) + } + if m.SignatureTwo != nil { + l = m.SignatureTwo.Size() + n += 1 + l + sovSolomachine(uint64(l)) + } + return n +} + +func (m *SignatureAndData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + l = len(m.Path) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + if m.Timestamp != 0 { + n += 1 + sovSolomachine(uint64(m.Timestamp)) + } + return n +} + +func (m *TimestampedSignatureData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SignatureData) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + if m.Timestamp != 0 { + n += 1 + sovSolomachine(uint64(m.Timestamp)) + } + return n +} + +func (m *SignBytes) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sequence != 0 { + n += 1 + sovSolomachine(uint64(m.Sequence)) + } + if m.Timestamp != 0 { + n += 1 + sovSolomachine(uint64(m.Timestamp)) + } + l = len(m.Diversifier) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + l = len(m.Path) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + return n +} + +func (m *HeaderData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NewPubKey != nil { + l = m.NewPubKey.Size() + n += 1 + l + sovSolomachine(uint64(l)) + } + l = len(m.NewDiversifier) + if l > 0 { + n += 1 + l + sovSolomachine(uint64(l)) + } + return n +} + +func sovSolomachine(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSolomachine(x uint64) (n int) { + return sovSolomachine(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ClientState) 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 ErrIntOverflowSolomachine + } + 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: ClientState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClientState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + m.Sequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsFrozen", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsFrozen = bool(v != 0) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsensusState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConsensusState == nil { + m.ConsensusState = &ConsensusState{} + } + if err := m.ConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSolomachine(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSolomachine + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConsensusState) 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 ErrIntOverflowSolomachine + } + 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: ConsensusState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConsensusState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PublicKey == nil { + m.PublicKey = &types.Any{} + } + if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Diversifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + 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 ErrInvalidLengthSolomachine + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Diversifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSolomachine(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSolomachine + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Header) 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 ErrIntOverflowSolomachine + } + 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: Header: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Header: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewPublicKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NewPublicKey == nil { + m.NewPublicKey = &types.Any{} + } + if err := m.NewPublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewDiversifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + 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 ErrInvalidLengthSolomachine + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NewDiversifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSolomachine(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSolomachine + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Misbehaviour) 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 ErrIntOverflowSolomachine + } + 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: Misbehaviour: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Misbehaviour: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + m.Sequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SignatureOne", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SignatureOne == nil { + m.SignatureOne = &SignatureAndData{} + } + if err := m.SignatureOne.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SignatureTwo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SignatureTwo == nil { + m.SignatureTwo = &SignatureAndData{} + } + if err := m.SignatureTwo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSolomachine(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSolomachine + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SignatureAndData) 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 ErrIntOverflowSolomachine + } + 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: SignatureAndData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SignatureAndData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) + if m.Path == nil { + m.Path = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSolomachine(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSolomachine + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TimestampedSignatureData) 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 ErrIntOverflowSolomachine + } + 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: TimestampedSignatureData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TimestampedSignatureData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SignatureData", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SignatureData = append(m.SignatureData[:0], dAtA[iNdEx:postIndex]...) + if m.SignatureData == nil { + m.SignatureData = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSolomachine(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSolomachine + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SignBytes) 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 ErrIntOverflowSolomachine + } + 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: SignBytes: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SignBytes: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + m.Sequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Diversifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + 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 ErrInvalidLengthSolomachine + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Diversifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = append(m.Path[:0], dAtA[iNdEx:postIndex]...) + if m.Path == nil { + m.Path = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSolomachine(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSolomachine + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HeaderData) 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 ErrIntOverflowSolomachine + } + 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: HeaderData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HeaderData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewPubKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSolomachine + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NewPubKey == nil { + m.NewPubKey = &types.Any{} + } + if err := m.NewPubKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewDiversifier", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSolomachine + } + 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 ErrInvalidLengthSolomachine + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSolomachine + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NewDiversifier = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSolomachine(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSolomachine + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSolomachine(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSolomachine + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSolomachine + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSolomachine + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthSolomachine + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupSolomachine + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthSolomachine + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthSolomachine = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSolomachine = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupSolomachine = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/light-clients/06-solomachine/solomachine_test.go b/modules/light-clients/06-solomachine/solomachine_test.go new file mode 100644 index 00000000000..15c4461edbd --- /dev/null +++ b/modules/light-clients/06-solomachine/solomachine_test.go @@ -0,0 +1,204 @@ +package solomachine_test + +import ( + "testing" + "time" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + 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" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + "github.com/cosmos/ibc-go/v7/testing/mock" +) + +var ( + channelIDSolomachine = "channel-on-solomachine" // channelID generated on solo machine side + clientIDSolomachine = "06-solomachine-0" +) + +type SoloMachineTestSuite struct { + suite.Suite + + solomachine *ibctesting.Solomachine // singlesig public key + solomachineMulti *ibctesting.Solomachine // multisig public key + coordinator *ibctesting.Coordinator + + // testing chain used for convenience and readability + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain + + store sdk.KVStore +} + +func (suite *SoloMachineTestSuite) SetupTest() { + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) + suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) + suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) + + suite.solomachine = ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinesingle", "testing", 1) + suite.solomachineMulti = ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinemulti", "testing", 4) + + suite.store = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), exported.Solomachine) +} + +func TestSoloMachineTestSuite(t *testing.T) { + suite.Run(t, new(SoloMachineTestSuite)) +} + +func (suite *SoloMachineTestSuite) SetupSolomachine() string { + clientID := suite.solomachine.CreateClient(suite.chainA) + + connectionID := suite.solomachine.ConnOpenInit(suite.chainA, clientID) + + // open try is not necessary as the solo machine implementation is mocked + + suite.solomachine.ConnOpenAck(suite.chainA, clientID, connectionID) + + // open confirm is not necessary as the solo machine implementation is mocked + + channelID := suite.solomachine.ChanOpenInit(suite.chainA, connectionID) + + // open try is not necessary as the solo machine implementation is mocked + + suite.solomachine.ChanOpenAck(suite.chainA, channelID) + + // open confirm is not necessary as the solo machine implementation is mocked + + return channelID +} + +func (suite *SoloMachineTestSuite) TestRecvPacket() { + channelID := suite.SetupSolomachine() + packet := channeltypes.NewPacket( + mock.MockPacketData, + 1, + transfertypes.PortID, + channelIDSolomachine, + transfertypes.PortID, + channelID, + clienttypes.ZeroHeight(), + uint64(suite.chainA.GetContext().BlockTime().Add(time.Hour).UnixNano()), + ) + + // send packet is not necessary as the solo machine implementation is mocked + + suite.solomachine.RecvPacket(suite.chainA, packet) + + // close init is not necessary as the solomachine implementation is mocked + + suite.solomachine.ChanCloseConfirm(suite.chainA, transfertypes.PortID, channelID) +} + +func (suite *SoloMachineTestSuite) TestAcknowledgePacket() { + channelID := suite.SetupSolomachine() + + packet := suite.solomachine.SendTransfer(suite.chainA, transfertypes.PortID, channelID) + + // recv packet is not necessary as the solo machine implementation is mocked + + suite.solomachine.AcknowledgePacket(suite.chainA, packet) + + // close init is not necessary as the solomachine implementation is mocked + + suite.solomachine.ChanCloseConfirm(suite.chainA, transfertypes.PortID, channelID) +} + +func (suite *SoloMachineTestSuite) TestTimeout() { + channelID := suite.SetupSolomachine() + packet := suite.solomachine.SendTransfer(suite.chainA, transfertypes.PortID, channelID, func(msg *transfertypes.MsgTransfer) { + msg.TimeoutTimestamp = suite.solomachine.Time + 1 + }) + + // simulate solomachine time increment + suite.solomachine.Time++ + + suite.solomachine.UpdateClient(suite.chainA, clientIDSolomachine) + + suite.solomachine.TimeoutPacket(suite.chainA, packet) + + suite.solomachine.ChanCloseConfirm(suite.chainA, transfertypes.PortID, channelID) +} + +func (suite *SoloMachineTestSuite) TestTimeoutOnClose() { + channelID := suite.SetupSolomachine() + + packet := suite.solomachine.SendTransfer(suite.chainA, transfertypes.PortID, channelID) + + suite.solomachine.TimeoutPacketOnClose(suite.chainA, packet, channelID) +} + +func (suite *SoloMachineTestSuite) GetSequenceFromStore() uint64 { + bz := suite.store.Get(host.ClientStateKey()) + suite.Require().NotNil(bz) + + var clientState exported.ClientState + err := suite.chainA.Codec.UnmarshalInterface(bz, &clientState) + suite.Require().NoError(err) + return clientState.GetLatestHeight().GetRevisionHeight() +} + +func (suite *SoloMachineTestSuite) GetInvalidProof() []byte { + invalidProof, err := suite.chainA.Codec.Marshal(&solomachine.TimestampedSignatureData{Timestamp: suite.solomachine.Time}) + suite.Require().NoError(err) + + return invalidProof +} + +func TestUnpackInterfaces_Header(t *testing.T) { + registry := testdata.NewTestInterfaceRegistry() + cryptocodec.RegisterInterfaces(registry) + + pk := secp256k1.GenPrivKey().PubKey() + protoAny, err := codectypes.NewAnyWithValue(pk) + require.NoError(t, err) + + header := solomachine.Header{ + NewPublicKey: protoAny, + } + bz, err := header.Marshal() + require.NoError(t, err) + + var header2 solomachine.Header + err = header2.Unmarshal(bz) + require.NoError(t, err) + + err = codectypes.UnpackInterfaces(header2, registry) + require.NoError(t, err) + + require.Equal(t, pk, header2.NewPublicKey.GetCachedValue()) +} + +func TestUnpackInterfaces_HeaderData(t *testing.T) { + registry := testdata.NewTestInterfaceRegistry() + cryptocodec.RegisterInterfaces(registry) + + pk := secp256k1.GenPrivKey().PubKey() + protoAny, err := codectypes.NewAnyWithValue(pk) + require.NoError(t, err) + + hd := solomachine.HeaderData{ + NewPubKey: protoAny, + } + bz, err := hd.Marshal() + require.NoError(t, err) + + var hd2 solomachine.HeaderData + err = hd2.Unmarshal(bz) + require.NoError(t, err) + + err = codectypes.UnpackInterfaces(hd2, registry) + require.NoError(t, err) + + require.Equal(t, pk, hd2.NewPubKey.GetCachedValue()) +} diff --git a/modules/light-clients/06-solomachine/types/client_state.go b/modules/light-clients/06-solomachine/types/client_state.go deleted file mode 100644 index aa43e77e56d..00000000000 --- a/modules/light-clients/06-solomachine/types/client_state.go +++ /dev/null @@ -1,491 +0,0 @@ -package types - -import ( - "reflect" - - "github.com/cosmos/cosmos-sdk/codec" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -var _ exported.ClientState = (*ClientState)(nil) - -// NewClientState creates a new ClientState instance. -func NewClientState(latestSequence uint64, consensusState *ConsensusState, allowUpdateAfterProposal bool) *ClientState { - return &ClientState{ - Sequence: latestSequence, - IsFrozen: false, - ConsensusState: consensusState, - AllowUpdateAfterProposal: allowUpdateAfterProposal, - } -} - -// ClientType is Solo Machine. -func (cs ClientState) ClientType() string { - return exported.Solomachine -} - -// GetLatestHeight returns the latest sequence number. -// Return exported.Height to satisfy ClientState interface -// Revision number is always 0 for a solo-machine. -func (cs ClientState) GetLatestHeight() exported.Height { - return clienttypes.NewHeight(0, cs.Sequence) -} - -// Status returns the status of the solo machine client. -// The client may be: -// - Active: if frozen sequence is 0 -// - Frozen: otherwise solo machine is frozen -func (cs ClientState) Status(_ sdk.Context, _ sdk.KVStore, _ codec.BinaryCodec) exported.Status { - if cs.IsFrozen { - return exported.Frozen - } - - return exported.Active -} - -// Validate performs basic validation of the client state fields. -func (cs ClientState) Validate() error { - if cs.Sequence == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "sequence cannot be 0") - } - if cs.ConsensusState == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "consensus state cannot be nil") - } - return cs.ConsensusState.ValidateBasic() -} - -// ZeroCustomFields returns solomachine client state with client-specific fields FrozenSequence, -// and AllowUpdateAfterProposal zeroed out -func (cs ClientState) ZeroCustomFields() exported.ClientState { - return NewClientState( - cs.Sequence, cs.ConsensusState, false, - ) -} - -// Initialize will check that initial consensus state is equal to the latest consensus state of the initial client. -func (cs ClientState) Initialize(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, consState exported.ConsensusState) error { - if !reflect.DeepEqual(cs.ConsensusState, consState) { - return sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "consensus state in initial client does not equal initial consensus state. expected: %s, got: %s", - cs.ConsensusState, consState) - } - return nil -} - -// ExportMetadata is a no-op since solomachine does not store any metadata in client store -func (cs ClientState) ExportMetadata(_ sdk.KVStore) []exported.GenesisMetadata { - return nil -} - -// VerifyUpgradeAndUpdateState returns an error since solomachine client does not support upgrades -func (cs ClientState) VerifyUpgradeAndUpdateState( - _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, - _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, -) (exported.ClientState, exported.ConsensusState, error) { - return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade solomachine client") -} - -// VerifyClientState verifies a proof of the client state of the running chain -// stored on the solo machine. -func (cs *ClientState) VerifyClientState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - prefix exported.Prefix, - counterpartyClientIdentifier string, - proof []byte, - clientState exported.ClientState, -) error { - // NOTE: the proof height sequence is incremented by one due to the connection handshake verification ordering - height = clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+1) - - publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - clientPrefixedPath := commitmenttypes.NewMerklePath(host.FullClientStatePath(counterpartyClientIdentifier)) - path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath) - if err != nil { - return err - } - - signBz, err := ClientStateSignBytes(cdc, sequence, timestamp, cs.ConsensusState.Diversifier, path, clientState) - if err != nil { - return err - } - - if err := VerifySignature(publicKey, signBz, sigData); err != nil { - return err - } - - cs.Sequence++ - cs.ConsensusState.Timestamp = timestamp - setClientState(store, cdc, cs) - return nil -} - -// VerifyClientConsensusState verifies a proof of the consensus state of the -// running chain stored on the solo machine. -func (cs *ClientState) VerifyClientConsensusState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - counterpartyClientIdentifier string, - consensusHeight exported.Height, - prefix exported.Prefix, - proof []byte, - consensusState exported.ConsensusState, -) error { - // NOTE: the proof height sequence is incremented by two due to the connection handshake verification ordering - height = clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+2) - - publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - clientPrefixedPath := commitmenttypes.NewMerklePath(host.FullConsensusStatePath(counterpartyClientIdentifier, consensusHeight)) - path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath) - if err != nil { - return err - } - - signBz, err := ConsensusStateSignBytes(cdc, sequence, timestamp, cs.ConsensusState.Diversifier, path, consensusState) - if err != nil { - return err - } - - if err := VerifySignature(publicKey, signBz, sigData); err != nil { - return err - } - - cs.Sequence++ - cs.ConsensusState.Timestamp = timestamp - setClientState(store, cdc, cs) - return nil -} - -// VerifyConnectionState verifies a proof of the connection state of the -// specified connection end stored on the target machine. -func (cs *ClientState) VerifyConnectionState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - prefix exported.Prefix, - proof []byte, - connectionID string, - connectionEnd exported.ConnectionI, -) error { - publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - connectionPath := commitmenttypes.NewMerklePath(host.ConnectionPath(connectionID)) - path, err := commitmenttypes.ApplyPrefix(prefix, connectionPath) - if err != nil { - return err - } - - signBz, err := ConnectionStateSignBytes(cdc, sequence, timestamp, cs.ConsensusState.Diversifier, path, connectionEnd) - if err != nil { - return err - } - - if err := VerifySignature(publicKey, signBz, sigData); err != nil { - return err - } - - cs.Sequence++ - cs.ConsensusState.Timestamp = timestamp - setClientState(store, cdc, cs) - return nil -} - -// VerifyChannelState verifies a proof of the channel state of the specified -// channel end, under the specified port, stored on the target machine. -func (cs *ClientState) VerifyChannelState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - channel exported.ChannelI, -) error { - publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - channelPath := commitmenttypes.NewMerklePath(host.ChannelPath(portID, channelID)) - path, err := commitmenttypes.ApplyPrefix(prefix, channelPath) - if err != nil { - return err - } - - signBz, err := ChannelStateSignBytes(cdc, sequence, timestamp, cs.ConsensusState.Diversifier, path, channel) - if err != nil { - return err - } - - if err := VerifySignature(publicKey, signBz, sigData); err != nil { - return err - } - - cs.Sequence++ - cs.ConsensusState.Timestamp = timestamp - setClientState(store, cdc, cs) - return nil -} - -// VerifyPacketCommitment verifies a proof of an outgoing packet commitment at -// the specified port, specified channel, and specified sequence. -func (cs *ClientState) VerifyPacketCommitment( - ctx sdk.Context, - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - _ uint64, - _ uint64, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - packetSequence uint64, - commitmentBytes []byte, -) error { - publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, packetSequence)) - path, err := commitmenttypes.ApplyPrefix(prefix, commitmentPath) - if err != nil { - return err - } - - signBz, err := PacketCommitmentSignBytes(cdc, sequence, timestamp, cs.ConsensusState.Diversifier, path, commitmentBytes) - if err != nil { - return err - } - - if err := VerifySignature(publicKey, signBz, sigData); err != nil { - return err - } - - cs.Sequence++ - cs.ConsensusState.Timestamp = timestamp - setClientState(store, cdc, cs) - return nil -} - -// VerifyPacketAcknowledgement verifies a proof of an incoming packet -// acknowledgement at the specified port, specified channel, and specified sequence. -func (cs *ClientState) VerifyPacketAcknowledgement( - ctx sdk.Context, - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - _ uint64, - _ uint64, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - packetSequence uint64, - acknowledgement []byte, -) error { - publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, packetSequence)) - path, err := commitmenttypes.ApplyPrefix(prefix, ackPath) - if err != nil { - return err - } - - signBz, err := PacketAcknowledgementSignBytes(cdc, sequence, timestamp, cs.ConsensusState.Diversifier, path, acknowledgement) - if err != nil { - return err - } - - if err := VerifySignature(publicKey, signBz, sigData); err != nil { - return err - } - - cs.Sequence++ - cs.ConsensusState.Timestamp = timestamp - setClientState(store, cdc, cs) - return nil -} - -// VerifyPacketReceiptAbsence verifies a proof of the absence of an -// incoming packet receipt at the specified port, specified channel, and -// specified sequence. -func (cs *ClientState) VerifyPacketReceiptAbsence( - ctx sdk.Context, - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - _ uint64, - _ uint64, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - packetSequence uint64, -) error { - publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, packetSequence)) - path, err := commitmenttypes.ApplyPrefix(prefix, receiptPath) - if err != nil { - return err - } - - signBz, err := PacketReceiptAbsenceSignBytes(cdc, sequence, timestamp, cs.ConsensusState.Diversifier, path) - if err != nil { - return err - } - - if err := VerifySignature(publicKey, signBz, sigData); err != nil { - return err - } - - cs.Sequence++ - cs.ConsensusState.Timestamp = timestamp - setClientState(store, cdc, cs) - return nil -} - -// VerifyNextSequenceRecv verifies a proof of the next sequence number to be -// received of the specified channel at the specified port. -func (cs *ClientState) VerifyNextSequenceRecv( - ctx sdk.Context, - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - _ uint64, - _ uint64, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - nextSequenceRecv uint64, -) error { - publicKey, sigData, timestamp, sequence, err := produceVerificationArgs(cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - nextSequenceRecvPath := commitmenttypes.NewMerklePath(host.NextSequenceRecvPath(portID, channelID)) - path, err := commitmenttypes.ApplyPrefix(prefix, nextSequenceRecvPath) - if err != nil { - return err - } - - signBz, err := NextSequenceRecvSignBytes(cdc, sequence, timestamp, cs.ConsensusState.Diversifier, path, nextSequenceRecv) - if err != nil { - return err - } - - if err := VerifySignature(publicKey, signBz, sigData); err != nil { - return err - } - - cs.Sequence++ - cs.ConsensusState.Timestamp = timestamp - setClientState(store, cdc, cs) - return nil -} - -// produceVerificationArgs perfoms the basic checks on the arguments that are -// shared between the verification functions and returns the public key of the -// consensus state, the unmarshalled proof representing the signature and timestamp -// along with the solo-machine sequence encoded in the proofHeight. -func produceVerificationArgs( - cdc codec.BinaryCodec, - cs *ClientState, - height exported.Height, - prefix exported.Prefix, - proof []byte, -) (cryptotypes.PubKey, signing.SignatureData, uint64, uint64, error) { - if revision := height.GetRevisionNumber(); revision != 0 { - return nil, nil, 0, 0, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "revision must be 0 for solomachine, got revision-number: %d", revision) - } - // sequence is encoded in the revision height of height struct - sequence := height.GetRevisionHeight() - if prefix == nil { - return nil, nil, 0, 0, sdkerrors.Wrap(commitmenttypes.ErrInvalidPrefix, "prefix cannot be empty") - } - - _, ok := prefix.(*commitmenttypes.MerklePrefix) - if !ok { - return nil, nil, 0, 0, sdkerrors.Wrapf(commitmenttypes.ErrInvalidPrefix, "invalid prefix type %T, expected MerklePrefix", prefix) - } - - if proof == nil { - return nil, nil, 0, 0, sdkerrors.Wrap(ErrInvalidProof, "proof cannot be empty") - } - - timestampedSigData := &TimestampedSignatureData{} - if err := cdc.Unmarshal(proof, timestampedSigData); err != nil { - return nil, nil, 0, 0, sdkerrors.Wrapf(err, "failed to unmarshal proof into type %T", timestampedSigData) - } - - timestamp := timestampedSigData.Timestamp - - if len(timestampedSigData.SignatureData) == 0 { - return nil, nil, 0, 0, sdkerrors.Wrap(ErrInvalidProof, "signature data cannot be empty") - } - - sigData, err := UnmarshalSignatureData(cdc, timestampedSigData.SignatureData) - if err != nil { - return nil, nil, 0, 0, err - } - - if cs.ConsensusState == nil { - return nil, nil, 0, 0, sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "consensus state cannot be empty") - } - - latestSequence := cs.GetLatestHeight().GetRevisionHeight() - if latestSequence != sequence { - return nil, nil, 0, 0, sdkerrors.Wrapf( - sdkerrors.ErrInvalidHeight, - "client state sequence != proof sequence (%d != %d)", latestSequence, sequence, - ) - } - - if cs.ConsensusState.GetTimestamp() > timestamp { - return nil, nil, 0, 0, sdkerrors.Wrapf(ErrInvalidProof, "the consensus state timestamp is greater than the signature timestamp (%d >= %d)", cs.ConsensusState.GetTimestamp(), timestamp) - } - - publicKey, err := cs.ConsensusState.GetPubKey() - if err != nil { - return nil, nil, 0, 0, err - } - - return publicKey, sigData, timestamp, sequence, nil -} - -// sets the client state to the store -func setClientState(store sdk.KVStore, cdc codec.BinaryCodec, clientState exported.ClientState) { - bz := clienttypes.MustMarshalClientState(cdc, clientState) - store.Set([]byte(host.KeyClientState), bz) -} diff --git a/modules/light-clients/06-solomachine/types/client_state_test.go b/modules/light-clients/06-solomachine/types/client_state_test.go deleted file mode 100644 index 7ebd9bec925..00000000000 --- a/modules/light-clients/06-solomachine/types/client_state_test.go +++ /dev/null @@ -1,844 +0,0 @@ -package types_test - -import ( - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -const ( - counterpartyClientIdentifier = "chainA" - testConnectionID = "connectionid" - testChannelID = "testchannelid" - testPortID = "testportid" -) - -var ( - prefix = &commitmenttypes.MerklePrefix{ - KeyPrefix: []byte("ibc"), - } - consensusHeight = clienttypes.ZeroHeight() -) - -func (suite *SoloMachineTestSuite) TestStatus() { - clientState := suite.solomachine.ClientState() - // solo machine discards arguements - status := clientState.Status(suite.chainA.GetContext(), nil, nil) - suite.Require().Equal(exported.Active, status) - - // freeze solo machine - clientState.IsFrozen = true - status = clientState.Status(suite.chainA.GetContext(), nil, nil) - suite.Require().Equal(exported.Frozen, status) -} - -func (suite *SoloMachineTestSuite) TestClientStateValidateBasic() { - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - testCases := []struct { - name string - clientState *types.ClientState - expPass bool - }{ - { - "valid client state", - solomachine.ClientState(), - true, - }, - { - "empty ClientState", - &types.ClientState{}, - false, - }, - { - "sequence is zero", - types.NewClientState(0, &types.ConsensusState{solomachine.ConsensusState().PublicKey, solomachine.Diversifier, solomachine.Time}, false), - false, - }, - { - "timestamp is zero", - types.NewClientState(1, &types.ConsensusState{solomachine.ConsensusState().PublicKey, solomachine.Diversifier, 0}, false), - false, - }, - { - "diversifier is blank", - types.NewClientState(1, &types.ConsensusState{solomachine.ConsensusState().PublicKey, " ", 1}, false), - false, - }, - { - "pubkey is empty", - types.NewClientState(1, &types.ConsensusState{nil, solomachine.Diversifier, solomachine.Time}, false), - false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - err := tc.clientState.Validate() - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } - } -} - -func (suite *SoloMachineTestSuite) TestInitialize() { - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - malleatedConsensus := solomachine.ClientState().ConsensusState - malleatedConsensus.Timestamp = malleatedConsensus.Timestamp + 10 - - testCases := []struct { - name string - consState exported.ConsensusState - expPass bool - }{ - { - "valid consensus state", - solomachine.ConsensusState(), - true, - }, - { - "nil consensus state", - nil, - false, - }, - { - "invalid consensus state: Tendermint consensus state", - &ibctmtypes.ConsensusState{}, - false, - }, - { - "invalid consensus state: consensus state does not match consensus state in client", - malleatedConsensus, - false, - }, - } - - for _, tc := range testCases { - err := solomachine.ClientState().Initialize( - suite.chainA.GetContext(), suite.chainA.Codec, - suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "solomachine"), - tc.consState, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid testcase: %s failed", tc.name) - } else { - suite.Require().Error(err, "invalid testcase: %s passed", tc.name) - } - } - } -} - -func (suite *SoloMachineTestSuite) TestVerifyClientState() { - // create client for tendermint so we can use client state for verification - tmPath := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(tmPath) - clientState := suite.chainA.GetClientState(tmPath.EndpointA.ClientID) - path := suite.solomachine.GetClientStatePath(counterpartyClientIdentifier) - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - value, err := types.ClientStateSignBytes(suite.chainA.Codec, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, clientState) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(value) - - signatureDoc := &types.TimestampedSignatureData{ - SignatureData: sig, - Timestamp: solomachine.Time, - } - - proof, err := suite.chainA.Codec.Marshal(signatureDoc) - suite.Require().NoError(err) - - testCases := []struct { - name string - clientState *types.ClientState - prefix exported.Prefix - proof []byte - expPass bool - }{ - { - "successful verification", - solomachine.ClientState(), - prefix, - proof, - true, - }, - { - "ApplyPrefix failed", - solomachine.ClientState(), - nil, - proof, - false, - }, - { - "consensus state in client state is nil", - types.NewClientState(1, nil, false), - prefix, - proof, - false, - }, - { - "client state latest height is less than sequence", - types.NewClientState(solomachine.Sequence-1, - &types.ConsensusState{ - Timestamp: solomachine.Time, - PublicKey: solomachine.ConsensusState().PublicKey, - }, false), - prefix, - proof, - false, - }, - { - "consensus state timestamp is greater than signature", - types.NewClientState(solomachine.Sequence, - &types.ConsensusState{ - Timestamp: solomachine.Time + 1, - PublicKey: solomachine.ConsensusState().PublicKey, - }, false), - prefix, - proof, - false, - }, - - { - "proof is nil", - solomachine.ClientState(), - prefix, - nil, - false, - }, - { - "proof verification failed", - solomachine.ClientState(), - prefix, - suite.GetInvalidProof(), - false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - var expSeq uint64 - if tc.clientState.ConsensusState != nil { - expSeq = tc.clientState.Sequence + 1 - } - - // NOTE: to replicate the ordering of connection handshake, we must decrement proof height by 1 - height := clienttypes.NewHeight(solomachine.GetHeight().GetRevisionNumber(), solomachine.GetHeight().GetRevisionHeight()-1) - - err := tc.clientState.VerifyClientState( - suite.store, suite.chainA.Codec, height, tc.prefix, counterpartyClientIdentifier, tc.proof, clientState, - ) - - if tc.expPass { - suite.Require().NoError(err) - suite.Require().Equal(expSeq, tc.clientState.Sequence) - suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %s", suite.GetSequenceFromStore(), tc.name) - } else { - suite.Require().Error(err) - } - }) - } - } -} - -func (suite *SoloMachineTestSuite) TestVerifyClientConsensusState() { - // create client for tendermint so we can use consensus state for verification - tmPath := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(tmPath) - clientState := suite.chainA.GetClientState(tmPath.EndpointA.ClientID) - consensusState, found := suite.chainA.GetConsensusState(tmPath.EndpointA.ClientID, clientState.GetLatestHeight()) - suite.Require().True(found) - - path := suite.solomachine.GetConsensusStatePath(counterpartyClientIdentifier, consensusHeight) - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - value, err := types.ConsensusStateSignBytes(suite.chainA.Codec, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, consensusState) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(value) - signatureDoc := &types.TimestampedSignatureData{ - SignatureData: sig, - Timestamp: solomachine.Time, - } - - proof, err := suite.chainA.Codec.Marshal(signatureDoc) - suite.Require().NoError(err) - - testCases := []struct { - name string - clientState *types.ClientState - prefix exported.Prefix - proof []byte - expPass bool - }{ - { - "successful verification", - solomachine.ClientState(), - prefix, - proof, - true, - }, - { - "ApplyPrefix failed", - solomachine.ClientState(), - nil, - proof, - false, - }, - { - "consensus state in client state is nil", - types.NewClientState(1, nil, false), - prefix, - proof, - false, - }, - { - "client state latest height is less than sequence", - types.NewClientState(solomachine.Sequence-1, - &types.ConsensusState{ - Timestamp: solomachine.Time, - PublicKey: solomachine.ConsensusState().PublicKey, - }, false), - prefix, - proof, - false, - }, - { - "consensus state timestamp is greater than signature", - types.NewClientState(solomachine.Sequence, - &types.ConsensusState{ - Timestamp: solomachine.Time + 1, - PublicKey: solomachine.ConsensusState().PublicKey, - }, false), - prefix, - proof, - false, - }, - - { - "proof is nil", - solomachine.ClientState(), - prefix, - nil, - false, - }, - { - "proof verification failed", - solomachine.ClientState(), - prefix, - suite.GetInvalidProof(), - false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - var expSeq uint64 - if tc.clientState.ConsensusState != nil { - expSeq = tc.clientState.Sequence + 1 - } - - // NOTE: to replicate the ordering of connection handshake, we must decrement proof height by 1 - height := clienttypes.NewHeight(solomachine.GetHeight().GetRevisionNumber(), solomachine.GetHeight().GetRevisionHeight()-2) - - err := tc.clientState.VerifyClientConsensusState( - suite.store, suite.chainA.Codec, height, counterpartyClientIdentifier, consensusHeight, tc.prefix, tc.proof, consensusState, - ) - - if tc.expPass { - suite.Require().NoError(err) - suite.Require().Equal(expSeq, tc.clientState.Sequence) - suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %s", suite.GetSequenceFromStore(), tc.name) - } else { - suite.Require().Error(err) - } - }) - } - } -} - -func (suite *SoloMachineTestSuite) TestVerifyConnectionState() { - counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, *prefix) - conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions()), 0) - - path := suite.solomachine.GetConnectionStatePath(testConnectionID) - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - value, err := types.ConnectionStateSignBytes(suite.chainA.Codec, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, conn) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(value) - signatureDoc := &types.TimestampedSignatureData{ - SignatureData: sig, - Timestamp: solomachine.Time, - } - - proof, err := suite.chainA.Codec.Marshal(signatureDoc) - suite.Require().NoError(err) - - testCases := []struct { - name string - clientState *types.ClientState - prefix exported.Prefix - proof []byte - expPass bool - }{ - { - "successful verification", - solomachine.ClientState(), - prefix, - proof, - true, - }, - { - "ApplyPrefix failed", - solomachine.ClientState(), - commitmenttypes.NewMerklePrefix([]byte{}), - proof, - false, - }, - { - "proof is nil", - solomachine.ClientState(), - prefix, - nil, - false, - }, - { - "proof verification failed", - solomachine.ClientState(), - prefix, - suite.GetInvalidProof(), - false, - }, - } - - for i, tc := range testCases { - tc := tc - - expSeq := tc.clientState.Sequence + 1 - - err := tc.clientState.VerifyConnectionState( - suite.store, suite.chainA.Codec, solomachine.GetHeight(), tc.prefix, tc.proof, testConnectionID, conn, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(expSeq, tc.clientState.Sequence) - suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %d: %s", suite.GetSequenceFromStore(), i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - } - } - } -} - -func (suite *SoloMachineTestSuite) TestVerifyChannelState() { - counterparty := channeltypes.NewCounterparty(testPortID, testChannelID) - ch := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, counterparty, []string{testConnectionID}, "1.0.0") - - path := suite.solomachine.GetChannelStatePath(testPortID, testChannelID) - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - value, err := types.ChannelStateSignBytes(suite.chainA.Codec, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, ch) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(value) - signatureDoc := &types.TimestampedSignatureData{ - SignatureData: sig, - Timestamp: solomachine.Time, - } - - proof, err := suite.chainA.Codec.Marshal(signatureDoc) - suite.Require().NoError(err) - - testCases := []struct { - name string - clientState *types.ClientState - prefix exported.Prefix - proof []byte - expPass bool - }{ - { - "successful verification", - solomachine.ClientState(), - prefix, - proof, - true, - }, - { - "ApplyPrefix failed", - solomachine.ClientState(), - nil, - proof, - false, - }, - { - "proof is nil", - solomachine.ClientState(), - prefix, - nil, - false, - }, - { - "proof verification failed", - solomachine.ClientState(), - prefix, - suite.GetInvalidProof(), - false, - }, - } - - for i, tc := range testCases { - tc := tc - - expSeq := tc.clientState.Sequence + 1 - - err := tc.clientState.VerifyChannelState( - suite.store, suite.chainA.Codec, solomachine.GetHeight(), tc.prefix, tc.proof, testPortID, testChannelID, ch, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(expSeq, tc.clientState.Sequence) - suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %d: %s", suite.GetSequenceFromStore(), i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - } - } - } -} - -func (suite *SoloMachineTestSuite) TestVerifyPacketCommitment() { - commitmentBytes := []byte("COMMITMENT BYTES") - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - path := solomachine.GetPacketCommitmentPath(testPortID, testChannelID) - - value, err := types.PacketCommitmentSignBytes(suite.chainA.Codec, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, commitmentBytes) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(value) - signatureDoc := &types.TimestampedSignatureData{ - SignatureData: sig, - Timestamp: solomachine.Time, - } - - proof, err := suite.chainA.Codec.Marshal(signatureDoc) - suite.Require().NoError(err) - - testCases := []struct { - name string - clientState *types.ClientState - prefix exported.Prefix - proof []byte - expPass bool - }{ - { - "successful verification", - solomachine.ClientState(), - prefix, - proof, - true, - }, - { - "ApplyPrefix failed", - solomachine.ClientState(), - commitmenttypes.NewMerklePrefix([]byte{}), - proof, - false, - }, - { - "proof is nil", - solomachine.ClientState(), - prefix, - nil, - false, - }, - { - "proof verification failed", - solomachine.ClientState(), - prefix, - suite.GetInvalidProof(), - false, - }, - } - - for i, tc := range testCases { - tc := tc - - expSeq := tc.clientState.Sequence + 1 - ctx := suite.chainA.GetContext() - - err := tc.clientState.VerifyPacketCommitment( - ctx, suite.store, suite.chainA.Codec, solomachine.GetHeight(), 0, 0, tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence, commitmentBytes, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %d: %s", suite.GetSequenceFromStore(), i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - } - } - } -} - -func (suite *SoloMachineTestSuite) TestVerifyPacketAcknowledgement() { - ack := []byte("ACK") - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - path := solomachine.GetPacketAcknowledgementPath(testPortID, testChannelID) - - value, err := types.PacketAcknowledgementSignBytes(suite.chainA.Codec, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, ack) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(value) - signatureDoc := &types.TimestampedSignatureData{ - SignatureData: sig, - Timestamp: solomachine.Time, - } - - proof, err := suite.chainA.Codec.Marshal(signatureDoc) - suite.Require().NoError(err) - - testCases := []struct { - name string - clientState *types.ClientState - prefix exported.Prefix - proof []byte - expPass bool - }{ - { - "successful verification", - solomachine.ClientState(), - prefix, - proof, - true, - }, - { - "ApplyPrefix failed", - solomachine.ClientState(), - commitmenttypes.NewMerklePrefix([]byte{}), - proof, - false, - }, - { - "proof is nil", - solomachine.ClientState(), - prefix, - nil, - false, - }, - { - "proof verification failed", - solomachine.ClientState(), - prefix, - suite.GetInvalidProof(), - false, - }, - } - - for i, tc := range testCases { - tc := tc - - expSeq := tc.clientState.Sequence + 1 - ctx := suite.chainA.GetContext() - - err := tc.clientState.VerifyPacketAcknowledgement( - ctx, suite.store, suite.chainA.Codec, solomachine.GetHeight(), 0, 0, tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence, ack, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %d: %s", suite.GetSequenceFromStore(), i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - } - } - } -} - -func (suite *SoloMachineTestSuite) TestVerifyPacketReceiptAbsence() { - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - // absence uses receipt path as well - path := solomachine.GetPacketReceiptPath(testPortID, testChannelID) - - value, err := types.PacketReceiptAbsenceSignBytes(suite.chainA.Codec, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(value) - signatureDoc := &types.TimestampedSignatureData{ - SignatureData: sig, - Timestamp: solomachine.Time, - } - - proof, err := suite.chainA.Codec.Marshal(signatureDoc) - suite.Require().NoError(err) - - testCases := []struct { - name string - clientState *types.ClientState - prefix exported.Prefix - proof []byte - expPass bool - }{ - { - "successful verification", - solomachine.ClientState(), - prefix, - proof, - true, - }, - { - "ApplyPrefix failed", - solomachine.ClientState(), - commitmenttypes.NewMerklePrefix([]byte{}), - proof, - false, - }, - { - "proof is nil", - solomachine.ClientState(), - prefix, - nil, - false, - }, - { - "proof verification failed", - solomachine.ClientState(), - prefix, - suite.GetInvalidProof(), - false, - }, - } - - for i, tc := range testCases { - tc := tc - - expSeq := tc.clientState.Sequence + 1 - ctx := suite.chainA.GetContext() - - err := tc.clientState.VerifyPacketReceiptAbsence( - ctx, suite.store, suite.chainA.Codec, solomachine.GetHeight(), 0, 0, tc.prefix, tc.proof, testPortID, testChannelID, solomachine.Sequence, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %d: %s", suite.GetSequenceFromStore(), i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - } - } - } -} - -func (suite *SoloMachineTestSuite) TestVerifyNextSeqRecv() { - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - nextSeqRecv := solomachine.Sequence + 1 - path := solomachine.GetNextSequenceRecvPath(testPortID, testChannelID) - - value, err := types.NextSequenceRecvSignBytes(suite.chainA.Codec, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, nextSeqRecv) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(value) - signatureDoc := &types.TimestampedSignatureData{ - SignatureData: sig, - Timestamp: solomachine.Time, - } - - proof, err := suite.chainA.Codec.Marshal(signatureDoc) - suite.Require().NoError(err) - - testCases := []struct { - name string - clientState *types.ClientState - prefix exported.Prefix - proof []byte - expPass bool - }{ - { - "successful verification", - solomachine.ClientState(), - prefix, - proof, - true, - }, - { - "ApplyPrefix failed", - solomachine.ClientState(), - commitmenttypes.NewMerklePrefix([]byte{}), - proof, - false, - }, - { - "proof is nil", - solomachine.ClientState(), - prefix, - nil, - false, - }, - { - "proof verification failed", - solomachine.ClientState(), - prefix, - suite.GetInvalidProof(), - false, - }, - } - - for i, tc := range testCases { - tc := tc - - expSeq := tc.clientState.Sequence + 1 - ctx := suite.chainA.GetContext() - - err := tc.clientState.VerifyNextSequenceRecv( - ctx, suite.store, suite.chainA.Codec, solomachine.GetHeight(), 0, 0, tc.prefix, tc.proof, testPortID, testChannelID, nextSeqRecv, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().Equal(expSeq, tc.clientState.Sequence) - suite.Require().Equal(expSeq, suite.GetSequenceFromStore(), "sequence not updated in the store (%d) on valid test case %d: %s", suite.GetSequenceFromStore(), i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - } - } - } -} diff --git a/modules/light-clients/06-solomachine/types/codec.go b/modules/light-clients/06-solomachine/types/codec.go deleted file mode 100644 index 2fc3c930f5b..00000000000 --- a/modules/light-clients/06-solomachine/types/codec.go +++ /dev/null @@ -1,131 +0,0 @@ -package types - -import ( - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -// RegisterInterfaces register the ibc channel submodule interfaces to protobuf -// Any. -func RegisterInterfaces(registry codectypes.InterfaceRegistry) { - registry.RegisterImplementations( - (*exported.ClientState)(nil), - &ClientState{}, - ) - registry.RegisterImplementations( - (*exported.ConsensusState)(nil), - &ConsensusState{}, - ) - registry.RegisterImplementations( - (*exported.Header)(nil), - &Header{}, - ) - registry.RegisterImplementations( - (*exported.Misbehaviour)(nil), - &Misbehaviour{}, - ) -} - -func UnmarshalSignatureData(cdc codec.BinaryCodec, data []byte) (signing.SignatureData, error) { - protoSigData := &signing.SignatureDescriptor_Data{} - if err := cdc.Unmarshal(data, protoSigData); err != nil { - return nil, sdkerrors.Wrapf(err, "failed to unmarshal proof into type %T", protoSigData) - } - - sigData := signing.SignatureDataFromProto(protoSigData) - - return sigData, nil -} - -// UnmarshalDataByType attempts to unmarshal the data to the specified type. An error is -// return if it fails. -func UnmarshalDataByType(cdc codec.BinaryCodec, dataType DataType, data []byte) (Data, error) { - if len(data) == 0 { - return nil, sdkerrors.Wrap(ErrInvalidSignatureAndData, "data cannot be empty") - } - - switch dataType { - case UNSPECIFIED: - return nil, sdkerrors.Wrap(ErrInvalidDataType, "data type cannot be UNSPECIFIED") - - case CLIENT: - clientData := &ClientStateData{} - if err := cdc.Unmarshal(data, clientData); err != nil { - return nil, err - } - - // unpack any - if _, err := clienttypes.UnpackClientState(clientData.ClientState); err != nil { - return nil, err - } - return clientData, nil - - case CONSENSUS: - consensusData := &ConsensusStateData{} - if err := cdc.Unmarshal(data, consensusData); err != nil { - return nil, err - } - - // unpack any - if _, err := clienttypes.UnpackConsensusState(consensusData.ConsensusState); err != nil { - return nil, err - } - return consensusData, nil - - case CONNECTION: - connectionData := &ConnectionStateData{} - if err := cdc.Unmarshal(data, connectionData); err != nil { - return nil, err - } - - return connectionData, nil - - case CHANNEL: - channelData := &ChannelStateData{} - if err := cdc.Unmarshal(data, channelData); err != nil { - return nil, err - } - - return channelData, nil - - case PACKETCOMMITMENT: - commitmentData := &PacketCommitmentData{} - if err := cdc.Unmarshal(data, commitmentData); err != nil { - return nil, err - } - - return commitmentData, nil - - case PACKETACKNOWLEDGEMENT: - ackData := &PacketAcknowledgementData{} - if err := cdc.Unmarshal(data, ackData); err != nil { - return nil, err - } - - return ackData, nil - - case PACKETRECEIPTABSENCE: - receiptAbsenceData := &PacketReceiptAbsenceData{} - if err := cdc.Unmarshal(data, receiptAbsenceData); err != nil { - return nil, err - } - - return receiptAbsenceData, nil - - case NEXTSEQUENCERECV: - nextSeqRecvData := &NextSequenceRecvData{} - if err := cdc.Unmarshal(data, nextSeqRecvData); err != nil { - return nil, err - } - - return nextSeqRecvData, nil - - default: - return nil, sdkerrors.Wrapf(ErrInvalidDataType, "unsupported data type %T", dataType) - } -} diff --git a/modules/light-clients/06-solomachine/types/codec_test.go b/modules/light-clients/06-solomachine/types/codec_test.go deleted file mode 100644 index ed2afdafc41..00000000000 --- a/modules/light-clients/06-solomachine/types/codec_test.go +++ /dev/null @@ -1,186 +0,0 @@ -package types_test - -import ( - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -func (suite SoloMachineTestSuite) TestUnmarshalDataByType() { - var ( - data []byte - err error - ) - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - cdc := suite.chainA.App.AppCodec() - cases := []struct { - name string - dataType types.DataType - malleate func() - expPass bool - }{ - { - "empty data", types.CLIENT, func() { - data = []byte{} - }, false, - }, - { - "unspecified", types.UNSPECIFIED, func() { - path := solomachine.GetClientStatePath(counterpartyClientIdentifier) - data, err = types.ClientStateDataBytes(cdc, path, solomachine.ClientState()) - suite.Require().NoError(err) - }, false, - }, - { - "client", types.CLIENT, func() { - path := solomachine.GetClientStatePath(counterpartyClientIdentifier) - data, err = types.ClientStateDataBytes(cdc, path, solomachine.ClientState()) - suite.Require().NoError(err) - }, true, - }, - { - "bad client (provides consensus state data)", types.CLIENT, func() { - path := solomachine.GetConsensusStatePath(counterpartyClientIdentifier, clienttypes.NewHeight(0, 5)) - data, err = types.ConsensusStateDataBytes(cdc, path, solomachine.ConsensusState()) - suite.Require().NoError(err) - }, false, - }, - { - "consensus", types.CONSENSUS, func() { - path := solomachine.GetConsensusStatePath(counterpartyClientIdentifier, clienttypes.NewHeight(0, 5)) - data, err = types.ConsensusStateDataBytes(cdc, path, solomachine.ConsensusState()) - suite.Require().NoError(err) - }, true, - }, - { - "bad consensus (provides client state data)", types.CONSENSUS, func() { - path := solomachine.GetClientStatePath(counterpartyClientIdentifier) - data, err = types.ClientStateDataBytes(cdc, path, solomachine.ClientState()) - suite.Require().NoError(err) - }, false, - }, - { - "connection", types.CONNECTION, func() { - counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, *prefix) - conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions()), 0) - path := solomachine.GetConnectionStatePath("connectionID") - - data, err = types.ConnectionStateDataBytes(cdc, path, conn) - suite.Require().NoError(err) - }, true, - }, - { - "bad connection (uses channel data)", types.CONNECTION, func() { - counterparty := channeltypes.NewCounterparty(testPortID, testChannelID) - ch := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, counterparty, []string{testConnectionID}, "1.0.0") - path := solomachine.GetChannelStatePath("portID", "channelID") - - data, err = types.ChannelStateDataBytes(cdc, path, ch) - suite.Require().NoError(err) - }, false, - }, - { - "channel", types.CHANNEL, func() { - counterparty := channeltypes.NewCounterparty(testPortID, testChannelID) - ch := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, counterparty, []string{testConnectionID}, "1.0.0") - path := solomachine.GetChannelStatePath("portID", "channelID") - - data, err = types.ChannelStateDataBytes(cdc, path, ch) - suite.Require().NoError(err) - }, true, - }, - { - "bad channel (uses connection data)", types.CHANNEL, func() { - counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, *prefix) - conn := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions()), 0) - path := solomachine.GetConnectionStatePath("connectionID") - - data, err = types.ConnectionStateDataBytes(cdc, path, conn) - suite.Require().NoError(err) - }, false, - }, - { - "packet commitment", types.PACKETCOMMITMENT, func() { - commitment := []byte("packet commitment") - path := solomachine.GetPacketCommitmentPath("portID", "channelID") - - data, err = types.PacketCommitmentDataBytes(cdc, path, commitment) - suite.Require().NoError(err) - }, true, - }, - { - "bad packet commitment (uses next seq recv)", types.PACKETCOMMITMENT, func() { - path := solomachine.GetNextSequenceRecvPath("portID", "channelID") - - data, err = types.NextSequenceRecvDataBytes(cdc, path, 10) - suite.Require().NoError(err) - }, false, - }, - { - "packet acknowledgement", types.PACKETACKNOWLEDGEMENT, func() { - commitment := []byte("packet acknowledgement") - path := solomachine.GetPacketAcknowledgementPath("portID", "channelID") - - data, err = types.PacketAcknowledgementDataBytes(cdc, path, commitment) - suite.Require().NoError(err) - }, true, - }, - { - "bad packet acknowledgement (uses next sequence recv)", types.PACKETACKNOWLEDGEMENT, func() { - path := solomachine.GetNextSequenceRecvPath("portID", "channelID") - - data, err = types.NextSequenceRecvDataBytes(cdc, path, 10) - suite.Require().NoError(err) - }, false, - }, - { - "packet acknowledgement absence", types.PACKETRECEIPTABSENCE, func() { - path := solomachine.GetPacketReceiptPath("portID", "channelID") - - data, err = types.PacketReceiptAbsenceDataBytes(cdc, path) - suite.Require().NoError(err) - }, true, - }, - { - "next sequence recv", types.NEXTSEQUENCERECV, func() { - path := solomachine.GetNextSequenceRecvPath("portID", "channelID") - - data, err = types.NextSequenceRecvDataBytes(cdc, path, 10) - suite.Require().NoError(err) - }, true, - }, - { - "bad next sequence recv (uses packet commitment)", types.NEXTSEQUENCERECV, func() { - commitment := []byte("packet commitment") - path := solomachine.GetPacketCommitmentPath("portID", "channelID") - - data, err = types.PacketCommitmentDataBytes(cdc, path, commitment) - suite.Require().NoError(err) - }, false, - }, - } - - for _, tc := range cases { - tc := tc - - suite.Run(tc.name, func() { - tc.malleate() - - data, err := types.UnmarshalDataByType(cdc, tc.dataType, data) - - if tc.expPass { - suite.Require().NoError(err) - suite.Require().NotNil(data) - } else { - suite.Require().Error(err) - suite.Require().Nil(data) - } - }) - } - } -} diff --git a/modules/light-clients/06-solomachine/types/errors.go b/modules/light-clients/06-solomachine/types/errors.go deleted file mode 100644 index 3e27f60732a..00000000000 --- a/modules/light-clients/06-solomachine/types/errors.go +++ /dev/null @@ -1,18 +0,0 @@ -package types - -import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -const ( - SubModuleName = "solo machine" -) - -var ( - ErrInvalidHeader = sdkerrors.Register(SubModuleName, 2, "invalid header") - ErrInvalidSequence = sdkerrors.Register(SubModuleName, 3, "invalid sequence") - ErrInvalidSignatureAndData = sdkerrors.Register(SubModuleName, 4, "invalid signature and data") - ErrSignatureVerificationFailed = sdkerrors.Register(SubModuleName, 5, "signature verification failed") - ErrInvalidProof = sdkerrors.Register(SubModuleName, 6, "invalid solo machine proof") - ErrInvalidDataType = sdkerrors.Register(SubModuleName, 7, "invalid data type") -) diff --git a/modules/light-clients/06-solomachine/types/misbehaviour.go b/modules/light-clients/06-solomachine/types/misbehaviour.go deleted file mode 100644 index 6c002c45046..00000000000 --- a/modules/light-clients/06-solomachine/types/misbehaviour.go +++ /dev/null @@ -1,77 +0,0 @@ -package types - -import ( - "bytes" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -var _ exported.Misbehaviour = &Misbehaviour{} - -// ClientType is a Solo Machine light client. -func (misbehaviour Misbehaviour) ClientType() string { - return exported.Solomachine -} - -// GetClientID returns the ID of the client that committed a misbehaviour. -func (misbehaviour Misbehaviour) GetClientID() string { - return misbehaviour.ClientId -} - -// Type implements Evidence interface. -func (misbehaviour Misbehaviour) Type() string { - return exported.TypeClientMisbehaviour -} - -// ValidateBasic implements Evidence interface. -func (misbehaviour Misbehaviour) ValidateBasic() error { - if err := host.ClientIdentifierValidator(misbehaviour.ClientId); err != nil { - return sdkerrors.Wrap(err, "invalid client identifier for solo machine") - } - - if misbehaviour.Sequence == 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "sequence cannot be 0") - } - - if err := misbehaviour.SignatureOne.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "signature one failed basic validation") - } - - if err := misbehaviour.SignatureTwo.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "signature two failed basic validation") - } - - // misbehaviour signatures cannot be identical - if bytes.Equal(misbehaviour.SignatureOne.Signature, misbehaviour.SignatureTwo.Signature) { - return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "misbehaviour signatures cannot be equal") - } - - // message data signed cannot be identical - if bytes.Equal(misbehaviour.SignatureOne.Data, misbehaviour.SignatureTwo.Data) { - return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "misbehaviour signature data must be signed over different messages") - } - - return nil -} - -// ValidateBasic ensures that the signature and data fields are non-empty. -func (sd SignatureAndData) ValidateBasic() error { - if len(sd.Signature) == 0 { - return sdkerrors.Wrap(ErrInvalidSignatureAndData, "signature cannot be empty") - } - if len(sd.Data) == 0 { - return sdkerrors.Wrap(ErrInvalidSignatureAndData, "data for signature cannot be empty") - } - if sd.DataType == UNSPECIFIED { - return sdkerrors.Wrap(ErrInvalidSignatureAndData, "data type cannot be UNSPECIFIED") - } - if sd.Timestamp == 0 { - return sdkerrors.Wrap(ErrInvalidSignatureAndData, "timestamp cannot be 0") - } - - return nil -} diff --git a/modules/light-clients/06-solomachine/types/misbehaviour_handle.go b/modules/light-clients/06-solomachine/types/misbehaviour_handle.go deleted file mode 100644 index 339ec884f1b..00000000000 --- a/modules/light-clients/06-solomachine/types/misbehaviour_handle.go +++ /dev/null @@ -1,86 +0,0 @@ -package types - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -// CheckMisbehaviourAndUpdateState determines whether or not the currently registered -// public key signed over two different messages with the same sequence. If this is true -// the client state is updated to a frozen status. -// NOTE: Misbehaviour is not tracked for previous public keys, a solo machine may update to -// a new public key before the misbehaviour is processed. Therefore, misbehaviour is data -// order processing dependent. -func (cs ClientState) CheckMisbehaviourAndUpdateState( - ctx sdk.Context, - cdc codec.BinaryCodec, - clientStore sdk.KVStore, - misbehaviour exported.Misbehaviour, -) (exported.ClientState, error) { - soloMisbehaviour, ok := misbehaviour.(*Misbehaviour) - if !ok { - return nil, sdkerrors.Wrapf( - clienttypes.ErrInvalidClientType, - "misbehaviour type %T, expected %T", misbehaviour, &Misbehaviour{}, - ) - } - - // NOTE: a check that the misbehaviour message data are not equal is done by - // misbehaviour.ValidateBasic which is called by the 02-client keeper. - - // verify first signature - if err := verifySignatureAndData(cdc, cs, soloMisbehaviour, soloMisbehaviour.SignatureOne); err != nil { - return nil, sdkerrors.Wrap(err, "failed to verify signature one") - } - - // verify second signature - if err := verifySignatureAndData(cdc, cs, soloMisbehaviour, soloMisbehaviour.SignatureTwo); err != nil { - return nil, sdkerrors.Wrap(err, "failed to verify signature two") - } - - cs.IsFrozen = true - return &cs, nil -} - -// verifySignatureAndData verifies that the currently registered public key has signed -// over the provided data and that the data is valid. The data is valid if it can be -// unmarshaled into the specified data type. -func verifySignatureAndData(cdc codec.BinaryCodec, clientState ClientState, misbehaviour *Misbehaviour, sigAndData *SignatureAndData) error { - // do not check misbehaviour timestamp since we want to allow processing of past misbehaviour - - // ensure data can be unmarshaled to the specified data type - if _, err := UnmarshalDataByType(cdc, sigAndData.DataType, sigAndData.Data); err != nil { - return err - } - - data, err := MisbehaviourSignBytes( - cdc, - misbehaviour.Sequence, sigAndData.Timestamp, - clientState.ConsensusState.Diversifier, - sigAndData.DataType, - sigAndData.Data, - ) - if err != nil { - return err - } - - sigData, err := UnmarshalSignatureData(cdc, sigAndData.Signature) - if err != nil { - return err - } - - publicKey, err := clientState.ConsensusState.GetPubKey() - if err != nil { - return err - } - - if err := VerifySignature(publicKey, data, sigData); err != nil { - return err - } - - return nil -} diff --git a/modules/light-clients/06-solomachine/types/misbehaviour_handle_test.go b/modules/light-clients/06-solomachine/types/misbehaviour_handle_test.go deleted file mode 100644 index d2718f75689..00000000000 --- a/modules/light-clients/06-solomachine/types/misbehaviour_handle_test.go +++ /dev/null @@ -1,264 +0,0 @@ -package types_test - -import ( - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -func (suite *SoloMachineTestSuite) TestCheckMisbehaviourAndUpdateState() { - var ( - clientState exported.ClientState - misbehaviour exported.Misbehaviour - ) - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - testCases := []struct { - name string - setup func() - expPass bool - }{ - { - "valid misbehaviour", - func() { - clientState = solomachine.ClientState() - misbehaviour = solomachine.CreateMisbehaviour() - }, - true, - }, - { - "old misbehaviour is successful (timestamp is less than current consensus state)", - func() { - clientState = solomachine.ClientState() - solomachine.Time = solomachine.Time - 5 - misbehaviour = solomachine.CreateMisbehaviour() - }, true, - }, - { - "wrong client state type", - func() { - clientState = &ibctmtypes.ClientState{} - misbehaviour = solomachine.CreateMisbehaviour() - }, - false, - }, - { - "invalid misbehaviour type", - func() { - clientState = solomachine.ClientState() - misbehaviour = &ibctmtypes.Misbehaviour{} - }, - false, - }, - { - "invalid SignatureOne SignatureData", - func() { - clientState = solomachine.ClientState() - m := solomachine.CreateMisbehaviour() - - m.SignatureOne.Signature = suite.GetInvalidProof() - misbehaviour = m - }, false, - }, - { - "invalid SignatureTwo SignatureData", - func() { - clientState = solomachine.ClientState() - m := solomachine.CreateMisbehaviour() - - m.SignatureTwo.Signature = suite.GetInvalidProof() - misbehaviour = m - }, false, - }, - { - "invalid SignatureOne timestamp", - func() { - clientState = solomachine.ClientState() - m := solomachine.CreateMisbehaviour() - - m.SignatureOne.Timestamp = 1000000000000 - misbehaviour = m - }, false, - }, - { - "invalid SignatureTwo timestamp", - func() { - clientState = solomachine.ClientState() - m := solomachine.CreateMisbehaviour() - - m.SignatureTwo.Timestamp = 1000000000000 - misbehaviour = m - }, false, - }, - { - "invalid first signature data", - func() { - clientState = solomachine.ClientState() - - // store in temp before assigning to interface type - m := solomachine.CreateMisbehaviour() - - msg := []byte("DATA ONE") - signBytes := &types.SignBytes{ - Sequence: solomachine.Sequence + 1, - Timestamp: solomachine.Time, - Diversifier: solomachine.Diversifier, - DataType: types.CLIENT, - Data: msg, - } - - data, err := suite.chainA.Codec.Marshal(signBytes) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(data) - - m.SignatureOne.Signature = sig - m.SignatureOne.Data = msg - misbehaviour = m - }, - false, - }, - { - "invalid second signature data", - func() { - clientState = solomachine.ClientState() - - // store in temp before assigning to interface type - m := solomachine.CreateMisbehaviour() - - msg := []byte("DATA TWO") - signBytes := &types.SignBytes{ - Sequence: solomachine.Sequence + 1, - Timestamp: solomachine.Time, - Diversifier: solomachine.Diversifier, - DataType: types.CLIENT, - Data: msg, - } - - data, err := suite.chainA.Codec.Marshal(signBytes) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(data) - - m.SignatureTwo.Signature = sig - m.SignatureTwo.Data = msg - misbehaviour = m - }, - false, - }, - { - "wrong pubkey generates first signature", - func() { - clientState = solomachine.ClientState() - badMisbehaviour := solomachine.CreateMisbehaviour() - - // update public key to a new one - solomachine.CreateHeader() - m := solomachine.CreateMisbehaviour() - - // set SignatureOne to use the wrong signature - m.SignatureOne = badMisbehaviour.SignatureOne - misbehaviour = m - }, false, - }, - { - "wrong pubkey generates second signature", - func() { - clientState = solomachine.ClientState() - badMisbehaviour := solomachine.CreateMisbehaviour() - - // update public key to a new one - solomachine.CreateHeader() - m := solomachine.CreateMisbehaviour() - - // set SignatureTwo to use the wrong signature - m.SignatureTwo = badMisbehaviour.SignatureTwo - misbehaviour = m - }, false, - }, - - { - "signatures sign over different sequence", - func() { - clientState = solomachine.ClientState() - - // store in temp before assigning to interface type - m := solomachine.CreateMisbehaviour() - - // Signature One - msg := []byte("DATA ONE") - // sequence used is plus 1 - signBytes := &types.SignBytes{ - Sequence: solomachine.Sequence + 1, - Timestamp: solomachine.Time, - Diversifier: solomachine.Diversifier, - DataType: types.CLIENT, - Data: msg, - } - - data, err := suite.chainA.Codec.Marshal(signBytes) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(data) - - m.SignatureOne.Signature = sig - m.SignatureOne.Data = msg - - // Signature Two - msg = []byte("DATA TWO") - // sequence used is minus 1 - - signBytes = &types.SignBytes{ - Sequence: solomachine.Sequence - 1, - Timestamp: solomachine.Time, - Diversifier: solomachine.Diversifier, - DataType: types.CLIENT, - Data: msg, - } - data, err = suite.chainA.Codec.Marshal(signBytes) - suite.Require().NoError(err) - - sig = solomachine.GenerateSignature(data) - - m.SignatureTwo.Signature = sig - m.SignatureTwo.Data = msg - - misbehaviour = m - }, - false, - }, - { - "consensus state pubkey is nil", - func() { - cs := solomachine.ClientState() - cs.ConsensusState.PublicKey = nil - clientState = cs - misbehaviour = solomachine.CreateMisbehaviour() - }, - false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - // setup test - tc.setup() - - clientState, err := clientState.CheckMisbehaviourAndUpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), suite.store, misbehaviour) - - if tc.expPass { - suite.Require().NoError(err) - suite.Require().True(clientState.(*types.ClientState).IsFrozen, "client not frozen") - } else { - suite.Require().Error(err) - suite.Require().Nil(clientState) - } - }) - } - } -} diff --git a/modules/light-clients/06-solomachine/types/proof.go b/modules/light-clients/06-solomachine/types/proof.go deleted file mode 100644 index 7389121488f..00000000000 --- a/modules/light-clients/06-solomachine/types/proof.go +++ /dev/null @@ -1,477 +0,0 @@ -package types - -import ( - "github.com/cosmos/cosmos-sdk/codec" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/crypto/types/multisig" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -// VerifySignature verifies if the the provided public key generated the signature -// over the given data. Single and Multi signature public keys are supported. -// The signature data type must correspond to the public key type. An error is -// returned if signature verification fails or an invalid SignatureData type is -// provided. -func VerifySignature(pubKey cryptotypes.PubKey, signBytes []byte, sigData signing.SignatureData) error { - switch pubKey := pubKey.(type) { - case multisig.PubKey: - data, ok := sigData.(*signing.MultiSignatureData) - if !ok { - return sdkerrors.Wrapf(ErrSignatureVerificationFailed, "invalid signature data type, expected %T, got %T", (*signing.MultiSignatureData)(nil), data) - } - - // The function supplied fulfills the VerifyMultisignature interface. No special - // adjustments need to be made to the sign bytes based on the sign mode. - if err := pubKey.VerifyMultisignature(func(signing.SignMode) ([]byte, error) { - return signBytes, nil - }, data); err != nil { - return err - } - - default: - data, ok := sigData.(*signing.SingleSignatureData) - if !ok { - return sdkerrors.Wrapf(ErrSignatureVerificationFailed, "invalid signature data type, expected %T, got %T", (*signing.SingleSignatureData)(nil), data) - } - - if !pubKey.VerifySignature(signBytes, data.Signature) { - return ErrSignatureVerificationFailed - } - } - - return nil -} - -// MisbehaviourSignBytes returns the sign bytes for verification of misbehaviour. -func MisbehaviourSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - dataType DataType, - data []byte, -) ([]byte, error) { - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: dataType, - Data: data, - } - - return cdc.Marshal(signBytes) -} - -// HeaderSignBytes returns the sign bytes for verification of misbehaviour. -func HeaderSignBytes( - cdc codec.BinaryCodec, - header *Header, -) ([]byte, error) { - data := &HeaderData{ - NewPubKey: header.NewPublicKey, - NewDiversifier: header.NewDiversifier, - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: header.Sequence, - Timestamp: header.Timestamp, - Diversifier: header.NewDiversifier, - DataType: HEADER, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// ClientStateSignBytes returns the sign bytes for verification of the -// client state. -func ClientStateSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - path commitmenttypes.MerklePath, - clientState exported.ClientState, -) ([]byte, error) { - dataBz, err := ClientStateDataBytes(cdc, path, clientState) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: CLIENT, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// ClientStateDataBytes returns the client state data bytes used in constructing -// SignBytes. -func ClientStateDataBytes( - cdc codec.BinaryCodec, - path commitmenttypes.MerklePath, // nolint: interfacer - clientState exported.ClientState, -) ([]byte, error) { - any, err := clienttypes.PackClientState(clientState) - if err != nil { - return nil, err - } - - data := &ClientStateData{ - Path: []byte(path.String()), - ClientState: any, - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - return dataBz, nil -} - -// ConsensusStateSignBytes returns the sign bytes for verification of the -// consensus state. -func ConsensusStateSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - path commitmenttypes.MerklePath, - consensusState exported.ConsensusState, -) ([]byte, error) { - dataBz, err := ConsensusStateDataBytes(cdc, path, consensusState) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: CONSENSUS, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// ConsensusStateDataBytes returns the consensus state data bytes used in constructing -// SignBytes. -func ConsensusStateDataBytes( - cdc codec.BinaryCodec, - path commitmenttypes.MerklePath, // nolint: interfacer - consensusState exported.ConsensusState, -) ([]byte, error) { - any, err := clienttypes.PackConsensusState(consensusState) - if err != nil { - return nil, err - } - - data := &ConsensusStateData{ - Path: []byte(path.String()), - ConsensusState: any, - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - return dataBz, nil -} - -// ConnectionStateSignBytes returns the sign bytes for verification of the -// connection state. -func ConnectionStateSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - path commitmenttypes.MerklePath, - connectionEnd exported.ConnectionI, -) ([]byte, error) { - dataBz, err := ConnectionStateDataBytes(cdc, path, connectionEnd) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: CONNECTION, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// ConnectionStateDataBytes returns the connection state data bytes used in constructing -// SignBytes. -func ConnectionStateDataBytes( - cdc codec.BinaryCodec, - path commitmenttypes.MerklePath, // nolint: interfacer - connectionEnd exported.ConnectionI, -) ([]byte, error) { - connection, ok := connectionEnd.(connectiontypes.ConnectionEnd) - if !ok { - return nil, sdkerrors.Wrapf( - connectiontypes.ErrInvalidConnection, - "expected type %T, got %T", connectiontypes.ConnectionEnd{}, connectionEnd, - ) - } - - data := &ConnectionStateData{ - Path: []byte(path.String()), - Connection: &connection, - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - return dataBz, nil -} - -// ChannelStateSignBytes returns the sign bytes for verification of the -// channel state. -func ChannelStateSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - path commitmenttypes.MerklePath, - channelEnd exported.ChannelI, -) ([]byte, error) { - dataBz, err := ChannelStateDataBytes(cdc, path, channelEnd) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: CHANNEL, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// ChannelStateDataBytes returns the channel state data bytes used in constructing -// SignBytes. -func ChannelStateDataBytes( - cdc codec.BinaryCodec, - path commitmenttypes.MerklePath, // nolint: interfacer - channelEnd exported.ChannelI, -) ([]byte, error) { - channel, ok := channelEnd.(channeltypes.Channel) - if !ok { - return nil, sdkerrors.Wrapf( - channeltypes.ErrInvalidChannel, - "expected channel type %T, got %T", channeltypes.Channel{}, channelEnd) - } - - data := &ChannelStateData{ - Path: []byte(path.String()), - Channel: &channel, - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - return dataBz, nil -} - -// PacketCommitmentSignBytes returns the sign bytes for verification of the -// packet commitment. -func PacketCommitmentSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - path commitmenttypes.MerklePath, - commitmentBytes []byte, -) ([]byte, error) { - dataBz, err := PacketCommitmentDataBytes(cdc, path, commitmentBytes) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: PACKETCOMMITMENT, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// PacketCommitmentDataBytes returns the packet commitment data bytes used in constructing -// SignBytes. -func PacketCommitmentDataBytes( - cdc codec.BinaryCodec, - path commitmenttypes.MerklePath, // nolint: interfacer - commitmentBytes []byte, -) ([]byte, error) { - data := &PacketCommitmentData{ - Path: []byte(path.String()), - Commitment: commitmentBytes, - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - return dataBz, nil -} - -// PacketAcknowledgementSignBytes returns the sign bytes for verification of -// the acknowledgement. -func PacketAcknowledgementSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - path commitmenttypes.MerklePath, - acknowledgement []byte, -) ([]byte, error) { - dataBz, err := PacketAcknowledgementDataBytes(cdc, path, acknowledgement) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: PACKETACKNOWLEDGEMENT, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// PacketAcknowledgementDataBytes returns the packet acknowledgement data bytes used in constructing -// SignBytes. -func PacketAcknowledgementDataBytes( - cdc codec.BinaryCodec, - path commitmenttypes.MerklePath, // nolint: interfacer - acknowledgement []byte, -) ([]byte, error) { - data := &PacketAcknowledgementData{ - Path: []byte(path.String()), - Acknowledgement: acknowledgement, - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - return dataBz, nil -} - -// PacketReceiptAbsenceSignBytes returns the sign bytes for verification -// of the absence of an receipt. -func PacketReceiptAbsenceSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - path commitmenttypes.MerklePath, -) ([]byte, error) { - dataBz, err := PacketReceiptAbsenceDataBytes(cdc, path) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: PACKETRECEIPTABSENCE, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// PacketReceiptAbsenceDataBytes returns the packet receipt absence data bytes -// used in constructing SignBytes. -func PacketReceiptAbsenceDataBytes( - cdc codec.BinaryCodec, - path commitmenttypes.MerklePath, // nolint: interfacer -) ([]byte, error) { - data := &PacketReceiptAbsenceData{ - Path: []byte(path.String()), - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - return dataBz, nil -} - -// NextSequenceRecvSignBytes returns the sign bytes for verification of the next -// sequence to be received. -func NextSequenceRecvSignBytes( - cdc codec.BinaryCodec, - sequence, timestamp uint64, - diversifier string, - path commitmenttypes.MerklePath, - nextSequenceRecv uint64, -) ([]byte, error) { - dataBz, err := NextSequenceRecvDataBytes(cdc, path, nextSequenceRecv) - if err != nil { - return nil, err - } - - signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: NEXTSEQUENCERECV, - Data: dataBz, - } - - return cdc.Marshal(signBytes) -} - -// NextSequenceRecvDataBytes returns the next sequence recv data bytes used in constructing -// SignBytes. -func NextSequenceRecvDataBytes( - cdc codec.BinaryCodec, - path commitmenttypes.MerklePath, // nolint: interfacer - nextSequenceRecv uint64, -) ([]byte, error) { - data := &NextSequenceRecvData{ - Path: []byte(path.String()), - NextSeqRecv: nextSequenceRecv, - } - - dataBz, err := cdc.Marshal(data) - if err != nil { - return nil, err - } - - return dataBz, nil -} diff --git a/modules/light-clients/06-solomachine/types/proof_test.go b/modules/light-clients/06-solomachine/types/proof_test.go deleted file mode 100644 index f7f386e6339..00000000000 --- a/modules/light-clients/06-solomachine/types/proof_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package types_test - -import ( - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - solomachinetypes "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -func (suite *SoloMachineTestSuite) TestVerifySignature() { - cdc := suite.chainA.App.AppCodec() - signBytes := []byte("sign bytes") - - singleSignature := suite.solomachine.GenerateSignature(signBytes) - singleSigData, err := solomachinetypes.UnmarshalSignatureData(cdc, singleSignature) - suite.Require().NoError(err) - - multiSignature := suite.solomachineMulti.GenerateSignature(signBytes) - multiSigData, err := solomachinetypes.UnmarshalSignatureData(cdc, multiSignature) - suite.Require().NoError(err) - - testCases := []struct { - name string - publicKey cryptotypes.PubKey - sigData signing.SignatureData - expPass bool - }{ - { - "single signature with regular public key", - suite.solomachine.PublicKey, - singleSigData, - true, - }, - { - "multi signature with multisig public key", - suite.solomachineMulti.PublicKey, - multiSigData, - true, - }, - { - "single signature with multisig public key", - suite.solomachineMulti.PublicKey, - singleSigData, - false, - }, - { - "multi signature with regular public key", - suite.solomachine.PublicKey, - multiSigData, - false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - err := solomachinetypes.VerifySignature(tc.publicKey, signBytes, tc.sigData) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *SoloMachineTestSuite) TestClientStateSignBytes() { - cdc := suite.chainA.App.AppCodec() - - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - // success - path := solomachine.GetClientStatePath(counterpartyClientIdentifier) - bz, err := types.ClientStateSignBytes(cdc, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, solomachine.ClientState()) - suite.Require().NoError(err) - suite.Require().NotNil(bz) - - // nil client state - bz, err = types.ClientStateSignBytes(cdc, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, nil) - suite.Require().Error(err) - suite.Require().Nil(bz) - } -} - -func (suite *SoloMachineTestSuite) TestConsensusStateSignBytes() { - cdc := suite.chainA.App.AppCodec() - - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - // success - path := solomachine.GetConsensusStatePath(counterpartyClientIdentifier, consensusHeight) - bz, err := types.ConsensusStateSignBytes(cdc, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, solomachine.ConsensusState()) - suite.Require().NoError(err) - suite.Require().NotNil(bz) - - // nil consensus state - bz, err = types.ConsensusStateSignBytes(cdc, solomachine.Sequence, solomachine.Time, solomachine.Diversifier, path, nil) - suite.Require().Error(err) - suite.Require().Nil(bz) - } -} diff --git a/modules/light-clients/06-solomachine/types/proposal_handle_test.go b/modules/light-clients/06-solomachine/types/proposal_handle_test.go deleted file mode 100644 index b283cdbfdd9..00000000000 --- a/modules/light-clients/06-solomachine/types/proposal_handle_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package types_test - -import ( - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -func (suite *SoloMachineTestSuite) TestCheckSubstituteAndUpdateState() { - var ( - subjectClientState *types.ClientState - substituteClientState exported.ClientState - ) - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "valid substitute", func() { - subjectClientState.AllowUpdateAfterProposal = true - }, true, - }, - { - "subject not allowed to be updated", func() { - subjectClientState.AllowUpdateAfterProposal = false - }, false, - }, - { - "substitute is not the solo machine", func() { - substituteClientState = &ibctmtypes.ClientState{} - }, false, - }, - { - "subject public key is nil", func() { - subjectClientState.ConsensusState.PublicKey = nil - }, false, - }, - - { - "substitute public key is nil", func() { - substituteClientState.(*types.ClientState).ConsensusState.PublicKey = nil - }, false, - }, - { - "subject and substitute use the same public key", func() { - substituteClientState.(*types.ClientState).ConsensusState.PublicKey = subjectClientState.ConsensusState.PublicKey - }, false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() - - subjectClientState = solomachine.ClientState() - subjectClientState.AllowUpdateAfterProposal = true - substitute := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "substitute", "testing", 5) - substituteClientState = substitute.ClientState() - - tc.malleate() - - subjectClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), solomachine.ClientID) - substituteClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), substitute.ClientID) - - updatedClient, err := subjectClientState.CheckSubstituteAndUpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), subjectClientStore, substituteClientStore, substituteClientState) - - if tc.expPass { - suite.Require().NoError(err) - - suite.Require().Equal(substituteClientState.(*types.ClientState).ConsensusState, updatedClient.(*types.ClientState).ConsensusState) - suite.Require().Equal(substituteClientState.(*types.ClientState).Sequence, updatedClient.(*types.ClientState).Sequence) - suite.Require().Equal(false, updatedClient.(*types.ClientState).IsFrozen) - } else { - suite.Require().Error(err) - suite.Require().Nil(updatedClient) - } - }) - } - } -} diff --git a/modules/light-clients/06-solomachine/types/solomachine_test.go b/modules/light-clients/06-solomachine/types/solomachine_test.go deleted file mode 100644 index b286afc4ef7..00000000000 --- a/modules/light-clients/06-solomachine/types/solomachine_test.go +++ /dev/null @@ -1,113 +0,0 @@ -package types_test - -import ( - "testing" - - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/testutil/testdata" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -type SoloMachineTestSuite struct { - suite.Suite - - solomachine *ibctesting.Solomachine // singlesig public key - solomachineMulti *ibctesting.Solomachine // multisig public key - coordinator *ibctesting.Coordinator - - // testing chain used for convenience and readability - chainA *ibctesting.TestChain - chainB *ibctesting.TestChain - - store sdk.KVStore -} - -func (suite *SoloMachineTestSuite) SetupTest() { - suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) - suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) - suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) - - suite.solomachine = ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinesingle", "testing", 1) - suite.solomachineMulti = ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinemulti", "testing", 4) - - suite.store = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), exported.Solomachine) -} - -func TestSoloMachineTestSuite(t *testing.T) { - suite.Run(t, new(SoloMachineTestSuite)) -} - -func (suite *SoloMachineTestSuite) GetSequenceFromStore() uint64 { - bz := suite.store.Get(host.ClientStateKey()) - suite.Require().NotNil(bz) - - var clientState exported.ClientState - err := suite.chainA.Codec.UnmarshalInterface(bz, &clientState) - suite.Require().NoError(err) - return clientState.GetLatestHeight().GetRevisionHeight() -} - -func (suite *SoloMachineTestSuite) GetInvalidProof() []byte { - invalidProof, err := suite.chainA.Codec.Marshal(&types.TimestampedSignatureData{Timestamp: suite.solomachine.Time}) - suite.Require().NoError(err) - - return invalidProof -} - -func TestUnpackInterfaces_Header(t *testing.T) { - registry := testdata.NewTestInterfaceRegistry() - cryptocodec.RegisterInterfaces(registry) - - pk := secp256k1.GenPrivKey().PubKey().(cryptotypes.PubKey) - any, err := codectypes.NewAnyWithValue(pk) - require.NoError(t, err) - - header := types.Header{ - NewPublicKey: any, - } - bz, err := header.Marshal() - require.NoError(t, err) - - var header2 types.Header - err = header2.Unmarshal(bz) - require.NoError(t, err) - - err = codectypes.UnpackInterfaces(header2, registry) - require.NoError(t, err) - - require.Equal(t, pk, header2.NewPublicKey.GetCachedValue()) -} - -func TestUnpackInterfaces_HeaderData(t *testing.T) { - registry := testdata.NewTestInterfaceRegistry() - cryptocodec.RegisterInterfaces(registry) - - pk := secp256k1.GenPrivKey().PubKey().(cryptotypes.PubKey) - any, err := codectypes.NewAnyWithValue(pk) - require.NoError(t, err) - - hd := types.HeaderData{ - NewPubKey: any, - } - bz, err := hd.Marshal() - require.NoError(t, err) - - var hd2 types.HeaderData - err = hd2.Unmarshal(bz) - require.NoError(t, err) - - err = codectypes.UnpackInterfaces(hd2, registry) - require.NoError(t, err) - - require.Equal(t, pk, hd2.NewPubKey.GetCachedValue()) -} diff --git a/modules/light-clients/06-solomachine/types/update.go b/modules/light-clients/06-solomachine/types/update.go deleted file mode 100644 index a810548692d..00000000000 --- a/modules/light-clients/06-solomachine/types/update.go +++ /dev/null @@ -1,90 +0,0 @@ -package types - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -// CheckHeaderAndUpdateState checks if the provided header is valid and updates -// the consensus state if appropriate. It returns an error if: -// - the header provided is not parseable to a solo machine header -// - the header sequence does not match the current sequence -// - the header timestamp is less than the consensus state timestamp -// - the currently registered public key did not provide the update signature -func (cs ClientState) CheckHeaderAndUpdateState( - ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, - header exported.Header, -) (exported.ClientState, exported.ConsensusState, error) { - smHeader, ok := header.(*Header) - if !ok { - return nil, nil, sdkerrors.Wrapf( - clienttypes.ErrInvalidHeader, "header type %T, expected %T", header, &Header{}, - ) - } - - if err := checkHeader(cdc, &cs, smHeader); err != nil { - return nil, nil, err - } - - clientState, consensusState := update(&cs, smHeader) - return clientState, consensusState, nil -} - -// checkHeader checks if the Solo Machine update signature is valid. -func checkHeader(cdc codec.BinaryCodec, clientState *ClientState, header *Header) error { - // assert update sequence is current sequence - if header.Sequence != clientState.Sequence { - return sdkerrors.Wrapf( - clienttypes.ErrInvalidHeader, - "header sequence does not match the client state sequence (%d != %d)", header.Sequence, clientState.Sequence, - ) - } - - // assert update timestamp is not less than current consensus state timestamp - if header.Timestamp < clientState.ConsensusState.Timestamp { - return sdkerrors.Wrapf( - clienttypes.ErrInvalidHeader, - "header timestamp is less than to the consensus state timestamp (%d < %d)", header.Timestamp, clientState.ConsensusState.Timestamp, - ) - } - - // assert currently registered public key signed over the new public key with correct sequence - data, err := HeaderSignBytes(cdc, header) - if err != nil { - return err - } - - sigData, err := UnmarshalSignatureData(cdc, header.Signature) - if err != nil { - return err - } - - publicKey, err := clientState.ConsensusState.GetPubKey() - if err != nil { - return err - } - - if err := VerifySignature(publicKey, data, sigData); err != nil { - return sdkerrors.Wrap(ErrInvalidHeader, err.Error()) - } - - return nil -} - -// update the consensus state to the new public key and an incremented sequence -func update(clientState *ClientState, header *Header) (*ClientState, *ConsensusState) { - consensusState := &ConsensusState{ - PublicKey: header.NewPublicKey, - Diversifier: header.NewDiversifier, - Timestamp: header.Timestamp, - } - - // increment sequence number - clientState.Sequence++ - clientState.ConsensusState = consensusState - return clientState, consensusState -} diff --git a/modules/light-clients/06-solomachine/types/update_test.go b/modules/light-clients/06-solomachine/types/update_test.go deleted file mode 100644 index 459c72d0d76..00000000000 --- a/modules/light-clients/06-solomachine/types/update_test.go +++ /dev/null @@ -1,181 +0,0 @@ -package types_test - -import ( - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" -) - -func (suite *SoloMachineTestSuite) TestCheckHeaderAndUpdateState() { - var ( - clientState exported.ClientState - header exported.Header - ) - - // test singlesig and multisig public keys - for _, solomachine := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { - - testCases := []struct { - name string - setup func() - expPass bool - }{ - { - "successful update", - func() { - clientState = solomachine.ClientState() - header = solomachine.CreateHeader() - }, - true, - }, - { - "wrong client state type", - func() { - clientState = &ibctmtypes.ClientState{} - header = solomachine.CreateHeader() - }, - false, - }, - { - "invalid header type", - func() { - clientState = solomachine.ClientState() - header = &ibctmtypes.Header{} - }, - false, - }, - { - "wrong sequence in header", - func() { - clientState = solomachine.ClientState() - // store in temp before assigning to interface type - h := solomachine.CreateHeader() - h.Sequence++ - header = h - }, - false, - }, - { - "invalid header Signature", - func() { - clientState = solomachine.ClientState() - h := solomachine.CreateHeader() - h.Signature = suite.GetInvalidProof() - header = h - }, false, - }, - { - "invalid timestamp in header", - func() { - clientState = solomachine.ClientState() - h := solomachine.CreateHeader() - h.Timestamp-- - header = h - }, false, - }, - { - "signature uses wrong sequence", - func() { - clientState = solomachine.ClientState() - solomachine.Sequence++ - header = solomachine.CreateHeader() - }, - false, - }, - { - "signature uses new pubkey to sign", - func() { - // store in temp before assinging to interface type - cs := solomachine.ClientState() - h := solomachine.CreateHeader() - - publicKey, err := codectypes.NewAnyWithValue(solomachine.PublicKey) - suite.NoError(err) - - data := &types.HeaderData{ - NewPubKey: publicKey, - NewDiversifier: h.NewDiversifier, - } - - dataBz, err := suite.chainA.Codec.Marshal(data) - suite.Require().NoError(err) - - // generate invalid signature - signBytes := &types.SignBytes{ - Sequence: cs.Sequence, - Timestamp: solomachine.Time, - Diversifier: solomachine.Diversifier, - DataType: types.CLIENT, - Data: dataBz, - } - - signBz, err := suite.chainA.Codec.Marshal(signBytes) - suite.Require().NoError(err) - - sig := solomachine.GenerateSignature(signBz) - suite.Require().NoError(err) - h.Signature = sig - - clientState = cs - header = h - }, - false, - }, - { - "signature signs over old pubkey", - func() { - // store in temp before assinging to interface type - cs := solomachine.ClientState() - oldPubKey := solomachine.PublicKey - h := solomachine.CreateHeader() - - // generate invalid signature - data := append(sdk.Uint64ToBigEndian(cs.Sequence), oldPubKey.Bytes()...) - sig := solomachine.GenerateSignature(data) - h.Signature = sig - - clientState = cs - header = h - }, - false, - }, - { - "consensus state public key is nil", - func() { - cs := solomachine.ClientState() - cs.ConsensusState.PublicKey = nil - clientState = cs - header = solomachine.CreateHeader() - }, - false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - // setup test - tc.setup() - - clientState, consensusState, err := clientState.CheckHeaderAndUpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, header) - - if tc.expPass { - suite.Require().NoError(err) - suite.Require().Equal(header.(*types.Header).NewPublicKey, clientState.(*types.ClientState).ConsensusState.PublicKey) - suite.Require().Equal(false, clientState.(*types.ClientState).IsFrozen) - suite.Require().Equal(header.(*types.Header).Sequence+1, clientState.(*types.ClientState).Sequence) - suite.Require().Equal(consensusState, clientState.(*types.ClientState).ConsensusState) - } else { - suite.Require().Error(err) - suite.Require().Nil(clientState) - suite.Require().Nil(consensusState) - } - }) - } - } -} diff --git a/modules/light-clients/06-solomachine/update.go b/modules/light-clients/06-solomachine/update.go new file mode 100644 index 00000000000..8d044e0a2e9 --- /dev/null +++ b/modules/light-clients/06-solomachine/update.go @@ -0,0 +1,107 @@ +package solomachine + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// VerifyClientMessage introspects the provided ClientMessage and checks its validity +// A Solomachine Header is considered valid if the currently registered public key has signed over the new public key with the correct sequence +// A Solomachine Misbehaviour is considered valid if duplicate signatures of the current public key are found on two different messages at a given sequence +func (cs ClientState) VerifyClientMessage(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) error { + switch msg := clientMsg.(type) { + case *Header: + return cs.verifyHeader(ctx, cdc, clientStore, msg) + case *Misbehaviour: + return cs.verifyMisbehaviour(ctx, cdc, clientStore, msg) + default: + return errorsmod.Wrapf(clienttypes.ErrInvalidClientType, "expected type of %T or %T, got type %T", Header{}, Misbehaviour{}, msg) + } +} + +func (cs ClientState) verifyHeader(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, header *Header) error { + // assert update timestamp is not less than current consensus state timestamp + if header.Timestamp < cs.ConsensusState.Timestamp { + return errorsmod.Wrapf( + clienttypes.ErrInvalidHeader, + "header timestamp is less than to the consensus state timestamp (%d < %d)", header.Timestamp, cs.ConsensusState.Timestamp, + ) + } + + // assert currently registered public key signed over the new public key with correct sequence + headerData := &HeaderData{ + NewPubKey: header.NewPublicKey, + NewDiversifier: header.NewDiversifier, + } + + dataBz, err := cdc.Marshal(headerData) + if err != nil { + return err + } + + signBytes := &SignBytes{ + Sequence: cs.Sequence, + Timestamp: header.Timestamp, + Diversifier: cs.ConsensusState.Diversifier, + Path: []byte(SentinelHeaderPath), + Data: dataBz, + } + + data, err := cdc.Marshal(signBytes) + if err != nil { + return err + } + + sigData, err := UnmarshalSignatureData(cdc, header.Signature) + if err != nil { + return err + } + + publicKey, err := cs.ConsensusState.GetPubKey() + if err != nil { + return err + } + + if err := VerifySignature(publicKey, data, sigData); err != nil { + return errorsmod.Wrap(ErrInvalidHeader, err.Error()) + } + + return nil +} + +// UpdateState updates the consensus state to the new public key and an incremented sequence. +// A list containing the updated consensus height is returned. +func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) []exported.Height { + smHeader, ok := clientMsg.(*Header) + if !ok { + panic(fmt.Errorf("unsupported ClientMessage: %T", clientMsg)) + } + + // create new solomachine ConsensusState + consensusState := &ConsensusState{ + PublicKey: smHeader.NewPublicKey, + Diversifier: smHeader.NewDiversifier, + Timestamp: smHeader.Timestamp, + } + + cs.Sequence++ + cs.ConsensusState = consensusState + + setClientState(clientStore, cdc, &cs) + + return []exported.Height{clienttypes.NewHeight(0, cs.Sequence)} +} + +// UpdateStateOnMisbehaviour updates state upon misbehaviour. This method should only be called on misbehaviour +// as it does not perform any misbehaviour checks. +func (cs ClientState) UpdateStateOnMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, _ exported.ClientMessage) { + cs.IsFrozen = true + + setClientState(clientStore, cdc, &cs) +} diff --git a/modules/light-clients/06-solomachine/update_test.go b/modules/light-clients/06-solomachine/update_test.go new file mode 100644 index 00000000000..923237b0d06 --- /dev/null +++ b/modules/light-clients/06-solomachine/update_test.go @@ -0,0 +1,546 @@ +package solomachine_test + +import ( + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +func (suite *SoloMachineTestSuite) TestVerifyClientMessageHeader() { + var ( + clientMsg exported.ClientMessage + clientState *solomachine.ClientState + ) + + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + + testCases := []struct { + name string + setup func() + expPass bool + }{ + { + "successful header", + func() { + clientMsg = sm.CreateHeader(sm.Diversifier) + }, + true, + }, + { + "successful header with new diversifier", + func() { + clientMsg = sm.CreateHeader(sm.Diversifier + "0") + }, + true, + }, + { + "successful misbehaviour", + func() { + clientMsg = sm.CreateMisbehaviour() + }, + true, + }, + { + "invalid client message type", + func() { + clientMsg = &ibctm.Header{} + }, + false, + }, + { + "invalid header Signature", + func() { + h := sm.CreateHeader(sm.Diversifier) + h.Signature = suite.GetInvalidProof() + clientMsg = h + }, false, + }, + { + "invalid timestamp in header", + func() { + h := sm.CreateHeader(sm.Diversifier) + h.Timestamp-- + clientMsg = h + }, false, + }, + { + "signature uses wrong sequence", + func() { + sm.Sequence++ + clientMsg = sm.CreateHeader(sm.Diversifier) + }, + false, + }, + { + "signature uses new pubkey to sign", + func() { + // store in temp before assinging to interface type + cs := sm.ClientState() + h := sm.CreateHeader(sm.Diversifier) + + publicKey, err := codectypes.NewAnyWithValue(sm.PublicKey) + suite.NoError(err) + + data := &solomachine.HeaderData{ + NewPubKey: publicKey, + NewDiversifier: h.NewDiversifier, + } + + dataBz, err := suite.chainA.Codec.Marshal(data) + suite.Require().NoError(err) + + // generate invalid signature + signBytes := &solomachine.SignBytes{ + Sequence: cs.Sequence, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte("invalid signature data"), + Data: dataBz, + } + + signBz, err := suite.chainA.Codec.Marshal(signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(signBz) + suite.Require().NoError(err) + h.Signature = sig + + clientState = cs + clientMsg = h + }, + false, + }, + { + "signature signs over old pubkey", + func() { + // store in temp before assinging to interface type + cs := sm.ClientState() + oldPubKey := sm.PublicKey + h := sm.CreateHeader(sm.Diversifier) + + // generate invalid signature + data := append(sdk.Uint64ToBigEndian(cs.Sequence), oldPubKey.Bytes()...) + sig := sm.GenerateSignature(data) + h.Signature = sig + + clientState = cs + clientMsg = h + }, + false, + }, + { + "consensus state public key is nil - header", + func() { + clientState.ConsensusState.PublicKey = nil + clientMsg = sm.CreateHeader(sm.Diversifier) + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + clientState = sm.ClientState() + + // setup test + tc.setup() + + err := clientState.VerifyClientMessage(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } + } +} + +func (suite *SoloMachineTestSuite) TestVerifyClientMessageMisbehaviour() { + var ( + clientMsg exported.ClientMessage + clientState *solomachine.ClientState + ) + + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + + testCases := []struct { + name string + setup func() + expPass bool + }{ + { + "successful misbehaviour", + func() { + clientMsg = sm.CreateMisbehaviour() + }, + true, + }, + { + "old misbehaviour is successful (timestamp is less than current consensus state)", + func() { + clientState = sm.ClientState() + sm.Time -= 5 + clientMsg = sm.CreateMisbehaviour() + }, true, + }, + { + "invalid client message type", + func() { + clientMsg = &ibctm.Header{} + }, + false, + }, + { + "consensus state pubkey is nil", + func() { + clientState.ConsensusState.PublicKey = nil + clientMsg = sm.CreateMisbehaviour() + }, + false, + }, + { + "invalid SignatureOne SignatureData", + func() { + m := sm.CreateMisbehaviour() + + m.SignatureOne.Signature = suite.GetInvalidProof() + clientMsg = m + }, false, + }, + { + "invalid SignatureTwo SignatureData", + func() { + m := sm.CreateMisbehaviour() + + m.SignatureTwo.Signature = suite.GetInvalidProof() + clientMsg = m + }, false, + }, + { + "invalid SignatureOne timestamp", + func() { + m := sm.CreateMisbehaviour() + + m.SignatureOne.Timestamp = 1000000000000 + clientMsg = m + }, false, + }, + { + "invalid SignatureTwo timestamp", + func() { + m := sm.CreateMisbehaviour() + + m.SignatureTwo.Timestamp = 1000000000000 + clientMsg = m + }, false, + }, + { + "invalid first signature data", + func() { + // store in temp before assigning to interface type + m := sm.CreateMisbehaviour() + + msg := []byte("DATA ONE") + signBytes := &solomachine.SignBytes{ + Sequence: sm.Sequence + 1, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte("invalid signature data"), + Data: msg, + } + + data, err := suite.chainA.Codec.Marshal(signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(data) + + m.SignatureOne.Signature = sig + m.SignatureOne.Data = msg + clientMsg = m + }, + false, + }, + { + "invalid second signature data", + func() { + // store in temp before assigning to interface type + m := sm.CreateMisbehaviour() + + msg := []byte("DATA TWO") + signBytes := &solomachine.SignBytes{ + Sequence: sm.Sequence + 1, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte("invalid signature data"), + Data: msg, + } + + data, err := suite.chainA.Codec.Marshal(signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(data) + + m.SignatureTwo.Signature = sig + m.SignatureTwo.Data = msg + clientMsg = m + }, + false, + }, + { + "wrong pubkey generates first signature", + func() { + badMisbehaviour := sm.CreateMisbehaviour() + + // update public key to a new one + sm.CreateHeader(sm.Diversifier) + m := sm.CreateMisbehaviour() + + // set SignatureOne to use the wrong signature + m.SignatureOne = badMisbehaviour.SignatureOne + clientMsg = m + }, false, + }, + { + "wrong pubkey generates second signature", + func() { + badMisbehaviour := sm.CreateMisbehaviour() + + // update public key to a new one + sm.CreateHeader(sm.Diversifier) + m := sm.CreateMisbehaviour() + + // set SignatureTwo to use the wrong signature + m.SignatureTwo = badMisbehaviour.SignatureTwo + clientMsg = m + }, false, + }, + { + "signatures sign over different sequence", + func() { + // store in temp before assigning to interface type + m := sm.CreateMisbehaviour() + + // Signature One + msg := []byte("DATA ONE") + // sequence used is plus 1 + signBytes := &solomachine.SignBytes{ + Sequence: sm.Sequence + 1, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte("invalid signature data"), + Data: msg, + } + + data, err := suite.chainA.Codec.Marshal(signBytes) + suite.Require().NoError(err) + + sig := sm.GenerateSignature(data) + + m.SignatureOne.Signature = sig + m.SignatureOne.Data = msg + + // Signature Two + msg = []byte("DATA TWO") + // sequence used is minus 1 + + signBytes = &solomachine.SignBytes{ + Sequence: sm.Sequence - 1, + Timestamp: sm.Time, + Diversifier: sm.Diversifier, + Path: []byte("invalid signature data"), + Data: msg, + } + data, err = suite.chainA.Codec.Marshal(signBytes) + suite.Require().NoError(err) + + sig = sm.GenerateSignature(data) + + m.SignatureTwo.Signature = sig + m.SignatureTwo.Data = msg + + clientMsg = m + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + clientState = sm.ClientState() + + // setup test + tc.setup() + + err := clientState.VerifyClientMessage(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } + } +} + +func (suite *SoloMachineTestSuite) TestUpdateState() { + var ( + clientState exported.ClientState + clientMsg exported.ClientMessage + ) + + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + + testCases := []struct { + name string + setup func() + expPass bool + }{ + { + "successful update", + func() { + clientState = sm.ClientState() + clientMsg = sm.CreateHeader(sm.Diversifier) + }, + true, + }, + { + "invalid type misbehaviour", + func() { + clientState = sm.ClientState() + clientMsg = sm.CreateMisbehaviour() + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + tc.setup() // setup test + + if tc.expPass { + consensusHeights := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) + + clientStateBz := suite.store.Get(host.ClientStateKey()) + suite.Require().NotEmpty(clientStateBz) + + newClientState := clienttypes.MustUnmarshalClientState(suite.chainA.Codec, clientStateBz) + + suite.Require().Len(consensusHeights, 1) + suite.Require().Equal(uint64(0), consensusHeights[0].GetRevisionNumber()) + suite.Require().Equal(newClientState.(*solomachine.ClientState).Sequence, consensusHeights[0].GetRevisionHeight()) + + suite.Require().False(newClientState.(*solomachine.ClientState).IsFrozen) + suite.Require().Equal(clientMsg.(*solomachine.Header).NewPublicKey, newClientState.(*solomachine.ClientState).ConsensusState.PublicKey) + suite.Require().Equal(clientMsg.(*solomachine.Header).NewDiversifier, newClientState.(*solomachine.ClientState).ConsensusState.Diversifier) + suite.Require().Equal(clientMsg.(*solomachine.Header).Timestamp, newClientState.(*solomachine.ClientState).ConsensusState.Timestamp) + } else { + suite.Require().Panics(func() { + clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) + }) + } + }) + } + } +} + +func (suite *SoloMachineTestSuite) TestCheckForMisbehaviour() { + var clientMsg exported.ClientMessage + + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() { + clientMsg = sm.CreateMisbehaviour() + }, + true, + }, + { + "normal header returns false", + func() { + clientMsg = sm.CreateHeader(sm.Diversifier) + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + clientState := sm.ClientState() + + tc.malleate() + + foundMisbehaviour := clientState.CheckForMisbehaviour(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) + + if tc.expPass { + suite.Require().True(foundMisbehaviour) + } else { + suite.Require().False(foundMisbehaviour) + } + }) + } + } +} + +func (suite *SoloMachineTestSuite) TestUpdateStateOnMisbehaviour() { + // test singlesig and multisig public keys + for _, sm := range []*ibctesting.Solomachine{suite.solomachine, suite.solomachineMulti} { + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + clientState := sm.ClientState() + + tc.malleate() + + clientState.UpdateStateOnMisbehaviour(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, nil) + + if tc.expPass { + clientStateBz := suite.store.Get(host.ClientStateKey()) + suite.Require().NotEmpty(clientStateBz) + + newClientState := clienttypes.MustUnmarshalClientState(suite.chainA.Codec, clientStateBz) + + suite.Require().True(newClientState.(*solomachine.ClientState).IsFrozen) + } + }) + } + } +} diff --git a/modules/light-clients/07-tendermint/client_state.go b/modules/light-clients/07-tendermint/client_state.go new file mode 100644 index 00000000000..53daf119393 --- /dev/null +++ b/modules/light-clients/07-tendermint/client_state.go @@ -0,0 +1,340 @@ +package tendermint + +import ( + "strings" + "time" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + ics23 "github.com/cosmos/ics23/go" + "github.com/tendermint/tendermint/light" + tmtypes "github.com/tendermint/tendermint/types" + + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +var _ exported.ClientState = (*ClientState)(nil) + +// NewClientState creates a new ClientState instance +func NewClientState( + chainID string, trustLevel Fraction, + trustingPeriod, ubdPeriod, maxClockDrift time.Duration, + latestHeight clienttypes.Height, specs []*ics23.ProofSpec, + upgradePath []string, +) *ClientState { + return &ClientState{ + ChainId: chainID, + TrustLevel: trustLevel, + TrustingPeriod: trustingPeriod, + UnbondingPeriod: ubdPeriod, + MaxClockDrift: maxClockDrift, + LatestHeight: latestHeight, + FrozenHeight: clienttypes.ZeroHeight(), + ProofSpecs: specs, + UpgradePath: upgradePath, + } +} + +// GetChainID returns the chain-id +func (cs ClientState) GetChainID() string { + return cs.ChainId +} + +// ClientType is tendermint. +func (cs ClientState) ClientType() string { + return exported.Tendermint +} + +// GetLatestHeight returns latest block height. +func (cs ClientState) GetLatestHeight() exported.Height { + return cs.LatestHeight +} + +// GetTimestampAtHeight returns the timestamp in nanoseconds of the consensus state at the given height. +func (cs ClientState) GetTimestampAtHeight( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height exported.Height, +) (uint64, error) { + // get consensus state at height from clientStore to check for expiry + consState, found := GetConsensusState(clientStore, cdc, height) + if !found { + return 0, errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "height (%s)", height) + } + return consState.GetTimestamp(), nil +} + +// Status returns the status of the tendermint client. +// The client may be: +// - Active: FrozenHeight is zero and client is not expired +// - Frozen: Frozen Height is not zero +// - Expired: the latest consensus state timestamp + trusting period <= current time +// +// A frozen client will become expired, so the Frozen status +// has higher precedence. +func (cs ClientState) Status( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, +) exported.Status { + if !cs.FrozenHeight.IsZero() { + return exported.Frozen + } + + // get latest consensus state from clientStore to check for expiry + consState, found := GetConsensusState(clientStore, cdc, cs.GetLatestHeight()) + if !found { + // if the client state does not have an associated consensus state for its latest height + // then it must be expired + return exported.Expired + } + + if cs.IsExpired(consState.Timestamp, ctx.BlockTime()) { + return exported.Expired + } + + return exported.Active +} + +// IsExpired returns whether or not the client has passed the trusting period since the last +// update (in which case no headers are considered valid). +func (cs ClientState) IsExpired(latestTimestamp, now time.Time) bool { + expirationTime := latestTimestamp.Add(cs.TrustingPeriod) + return !expirationTime.After(now) +} + +// Validate performs a basic validation of the client state fields. +func (cs ClientState) Validate() error { + if strings.TrimSpace(cs.ChainId) == "" { + return errorsmod.Wrap(ErrInvalidChainID, "chain id cannot be empty string") + } + + // NOTE: the value of tmtypes.MaxChainIDLen may change in the future. + // If this occurs, the code here must account for potential difference + // between the tendermint version being run by the counterparty chain + // and the tendermint version used by this light client. + // https://github.com/cosmos/ibc-go/issues/177 + if len(cs.ChainId) > tmtypes.MaxChainIDLen { + return errorsmod.Wrapf(ErrInvalidChainID, "chainID is too long; got: %d, max: %d", len(cs.ChainId), tmtypes.MaxChainIDLen) + } + + if err := light.ValidateTrustLevel(cs.TrustLevel.ToTendermint()); err != nil { + return err + } + if cs.TrustingPeriod <= 0 { + return errorsmod.Wrap(ErrInvalidTrustingPeriod, "trusting period must be greater than zero") + } + if cs.UnbondingPeriod <= 0 { + return errorsmod.Wrap(ErrInvalidUnbondingPeriod, "unbonding period must be greater than zero") + } + if cs.MaxClockDrift <= 0 { + return errorsmod.Wrap(ErrInvalidMaxClockDrift, "max clock drift must be greater than zero") + } + + // the latest height revision number must match the chain id revision number + if cs.LatestHeight.RevisionNumber != clienttypes.ParseChainID(cs.ChainId) { + return errorsmod.Wrapf(ErrInvalidHeaderHeight, + "latest height revision number must match chain id revision number (%d != %d)", cs.LatestHeight.RevisionNumber, clienttypes.ParseChainID(cs.ChainId)) + } + if cs.LatestHeight.RevisionHeight == 0 { + return errorsmod.Wrapf(ErrInvalidHeaderHeight, "tendermint client's latest height revision height cannot be zero") + } + if cs.TrustingPeriod >= cs.UnbondingPeriod { + return errorsmod.Wrapf( + ErrInvalidTrustingPeriod, + "trusting period (%s) should be < unbonding period (%s)", cs.TrustingPeriod, cs.UnbondingPeriod, + ) + } + + if cs.ProofSpecs == nil { + return errorsmod.Wrap(ErrInvalidProofSpecs, "proof specs cannot be nil for tm client") + } + for i, spec := range cs.ProofSpecs { + if spec == nil { + return errorsmod.Wrapf(ErrInvalidProofSpecs, "proof spec cannot be nil at index: %d", i) + } + } + // UpgradePath may be empty, but if it isn't, each key must be non-empty + for i, k := range cs.UpgradePath { + if strings.TrimSpace(k) == "" { + return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "key in upgrade path at index %d cannot be empty", i) + } + } + + return nil +} + +// GetProofSpecs returns the format the client expects for proof verification +// as a string array specifying the proof type for each position in chained proof +func (cs ClientState) GetProofSpecs() []*ics23.ProofSpec { + return cs.ProofSpecs +} + +// ZeroCustomFields returns a ClientState that is a copy of the current ClientState +// with all client customizable fields zeroed out +func (cs ClientState) ZeroCustomFields() exported.ClientState { + // copy over all chain-specified fields + // and leave custom fields empty + return &ClientState{ + ChainId: cs.ChainId, + UnbondingPeriod: cs.UnbondingPeriod, + LatestHeight: cs.LatestHeight, + ProofSpecs: cs.ProofSpecs, + UpgradePath: cs.UpgradePath, + } +} + +// Initialize checks that the initial consensus state is an 07-tendermint consensus state and +// sets the client state, consensus state and associated metadata in the provided client store. +func (cs ClientState) Initialize(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, consState exported.ConsensusState) error { + consensusState, ok := consState.(*ConsensusState) + if !ok { + return errorsmod.Wrapf(clienttypes.ErrInvalidConsensus, "invalid initial consensus state. expected type: %T, got: %T", + &ConsensusState{}, consState) + } + + setClientState(clientStore, cdc, &cs) + setConsensusState(clientStore, cdc, consensusState, cs.GetLatestHeight()) + setConsensusMetadata(ctx, clientStore, cs.GetLatestHeight()) + + return nil +} + +// VerifyMembership is a generic proof verification method which verifies a proof of the existence of a value at a given CommitmentPath at the specified height. +// The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24). +// If a zero proof height is passed in, it will fail to retrieve the associated consensus state. +func (cs ClientState) VerifyMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height exported.Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path exported.Path, + value []byte, +) error { + if cs.GetLatestHeight().LT(height) { + return errorsmod.Wrapf( + ibcerrors.ErrInvalidHeight, + "client state height < proof height (%d < %d), please ensure the client has been updated", cs.GetLatestHeight(), height, + ) + } + + if err := verifyDelayPeriodPassed(ctx, clientStore, height, delayTimePeriod, delayBlockPeriod); err != nil { + return err + } + + var merkleProof commitmenttypes.MerkleProof + if err := cdc.Unmarshal(proof, &merkleProof); err != nil { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "failed to unmarshal proof into ICS 23 commitment merkle proof") + } + + merklePath, ok := path.(commitmenttypes.MerklePath) + if !ok { + return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "expected %T, got %T", commitmenttypes.MerklePath{}, path) + } + + consensusState, found := GetConsensusState(clientStore, cdc, height) + if !found { + return errorsmod.Wrap(clienttypes.ErrConsensusStateNotFound, "please ensure the proof was constructed against a height that exists on the client") + } + + if err := merkleProof.VerifyMembership(cs.ProofSpecs, consensusState.GetRoot(), merklePath, value); err != nil { + return err + } + + return nil +} + +// VerifyNonMembership is a generic proof verification method which verifies the absence of a given CommitmentPath at a specified height. +// The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24). +// If a zero proof height is passed in, it will fail to retrieve the associated consensus state. +func (cs ClientState) VerifyNonMembership( + ctx sdk.Context, + clientStore sdk.KVStore, + cdc codec.BinaryCodec, + height exported.Height, + delayTimePeriod uint64, + delayBlockPeriod uint64, + proof []byte, + path exported.Path, +) error { + if cs.GetLatestHeight().LT(height) { + return errorsmod.Wrapf( + ibcerrors.ErrInvalidHeight, + "client state height < proof height (%d < %d), please ensure the client has been updated", cs.GetLatestHeight(), height, + ) + } + + if err := verifyDelayPeriodPassed(ctx, clientStore, height, delayTimePeriod, delayBlockPeriod); err != nil { + return err + } + + var merkleProof commitmenttypes.MerkleProof + if err := cdc.Unmarshal(proof, &merkleProof); err != nil { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "failed to unmarshal proof into ICS 23 commitment merkle proof") + } + + merklePath, ok := path.(commitmenttypes.MerklePath) + if !ok { + return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "expected %T, got %T", commitmenttypes.MerklePath{}, path) + } + + consensusState, found := GetConsensusState(clientStore, cdc, height) + if !found { + return errorsmod.Wrap(clienttypes.ErrConsensusStateNotFound, "please ensure the proof was constructed against a height that exists on the client") + } + + if err := merkleProof.VerifyNonMembership(cs.ProofSpecs, consensusState.GetRoot(), merklePath); err != nil { + return err + } + + return nil +} + +// verifyDelayPeriodPassed will ensure that at least delayTimePeriod amount of time and delayBlockPeriod number of blocks have passed +// since consensus state was submitted before allowing verification to continue. +func verifyDelayPeriodPassed(ctx sdk.Context, store sdk.KVStore, proofHeight exported.Height, delayTimePeriod, delayBlockPeriod uint64) error { + if delayTimePeriod != 0 { + // check that executing chain's timestamp has passed consensusState's processed time + delay time period + processedTime, ok := GetProcessedTime(store, proofHeight) + if !ok { + return errorsmod.Wrapf(ErrProcessedTimeNotFound, "processed time not found for height: %s", proofHeight) + } + + currentTimestamp := uint64(ctx.BlockTime().UnixNano()) + validTime := processedTime + delayTimePeriod + + // NOTE: delay time period is inclusive, so if currentTimestamp is validTime, then we return no error + if currentTimestamp < validTime { + return errorsmod.Wrapf(ErrDelayPeriodNotPassed, "cannot verify packet until time: %d, current time: %d", + validTime, currentTimestamp) + } + + } + + if delayBlockPeriod != 0 { + // check that executing chain's height has passed consensusState's processed height + delay block period + processedHeight, ok := GetProcessedHeight(store, proofHeight) + if !ok { + return errorsmod.Wrapf(ErrProcessedHeightNotFound, "processed height not found for height: %s", proofHeight) + } + + currentHeight := clienttypes.GetSelfHeight(ctx) + validHeight := clienttypes.NewHeight(processedHeight.GetRevisionNumber(), processedHeight.GetRevisionHeight()+delayBlockPeriod) + + // NOTE: delay block period is inclusive, so if currentHeight is validHeight, then we return no error + if currentHeight.LT(validHeight) { + return errorsmod.Wrapf(ErrDelayPeriodNotPassed, "cannot verify packet until height: %s, current height: %s", + validHeight, currentHeight) + } + } + + return nil +} diff --git a/modules/light-clients/07-tendermint/client_state_test.go b/modules/light-clients/07-tendermint/client_state_test.go new file mode 100644 index 00000000000..2a70d4199a6 --- /dev/null +++ b/modules/light-clients/07-tendermint/client_state_test.go @@ -0,0 +1,678 @@ +package tendermint_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + ics23 "github.com/cosmos/ics23/go" + + 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" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "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/ibc-go/v7/testing" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" +) + +const ( + // Do not change the length of these variables + fiftyCharChainID = "12345678901234567890123456789012345678901234567890" + fiftyOneCharChainID = "123456789012345678901234567890123456789012345678901" +) + +var invalidProof = []byte("invalid proof") + +func (suite *TendermintTestSuite) TestStatus() { + var ( + path *ibctesting.Path + clientState *ibctm.ClientState + ) + + testCases := []struct { + name string + malleate func() + expStatus exported.Status + }{ + {"client is active", func() {}, exported.Active}, + {"client is frozen", func() { + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) + path.EndpointA.SetClientState(clientState) + }, exported.Frozen}, + {"client status without consensus state", func() { + clientState.LatestHeight = clientState.LatestHeight.Increment().(clienttypes.Height) + path.EndpointA.SetClientState(clientState) + }, exported.Expired}, + {"client status is expired", func() { + suite.coordinator.IncrementTimeBy(clientState.TrustingPeriod) + }, exported.Expired}, + } + + for _, tc := range testCases { + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupClients(path) + + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + clientState = path.EndpointA.GetClientState().(*ibctm.ClientState) + + tc.malleate() + + status := clientState.Status(suite.chainA.GetContext(), clientStore, suite.chainA.App.AppCodec()) + suite.Require().Equal(tc.expStatus, status) + + } +} + +func (suite *TendermintTestSuite) TestValidate() { + testCases := []struct { + name string + clientState *ibctm.ClientState + expPass bool + }{ + { + name: "valid client", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: true, + }, + { + name: "valid client with nil upgrade path", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), nil), + expPass: true, + }, + { + name: "invalid chainID", + clientState: ibctm.NewClientState(" ", ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + // NOTE: if this test fails, the code must account for the change in chainID length across tendermint versions! + // Do not only fix the test, fix the code! + // https://github.com/cosmos/ibc-go/issues/177 + name: "valid chainID - chainID validation failed for chainID of length 50! ", + clientState: ibctm.NewClientState(fiftyCharChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: true, + }, + { + // NOTE: if this test fails, the code must account for the change in chainID length across tendermint versions! + // Do not only fix the test, fix the code! + // https://github.com/cosmos/ibc-go/issues/177 + name: "invalid chainID - chainID validation did not fail for chainID of length 51! ", + clientState: ibctm.NewClientState(fiftyOneCharChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid trust level", + clientState: ibctm.NewClientState(chainID, ibctm.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid zero trusting period", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, 0, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid negative trusting period", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, -1, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid zero unbonding period", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, trustingPeriod, 0, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid negative unbonding period", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, trustingPeriod, -1, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid zero max clock drift", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, 0, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid negative max clock drift", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, -1, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid revision number", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "invalid revision height", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "trusting period not less than unbonding period", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath), + expPass: false, + }, + { + name: "proof specs is nil", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, nil, upgradePath), + expPass: false, + }, + { + name: "proof specs contains nil", + clientState: ibctm.NewClientState(chainID, ibctm.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, []*ics23.ProofSpec{ics23.TendermintSpec, nil}, upgradePath), + expPass: false, + }, + } + + for _, tc := range testCases { + err := tc.clientState.Validate() + if tc.expPass { + suite.Require().NoError(err, tc.name) + } else { + suite.Require().Error(err, tc.name) + } + } +} + +func (suite *TendermintTestSuite) TestInitialize() { + testCases := []struct { + name string + consensusState exported.ConsensusState + expPass bool + }{ + { + name: "valid consensus", + consensusState: &ibctm.ConsensusState{}, + expPass: true, + }, + { + name: "invalid consensus: consensus state is solomachine consensus", + consensusState: ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2).ConsensusState(), + expPass: false, + }, + } + + for _, tc := range testCases { + suite.SetupTest() + path := ibctesting.NewPath(suite.chainA, suite.chainB) + + tmConfig, ok := path.EndpointB.ClientConfig.(*ibctesting.TendermintConfig) + suite.Require().True(ok) + + clientState := ibctm.NewClientState( + path.EndpointB.Chain.ChainID, + tmConfig.TrustLevel, tmConfig.TrustingPeriod, tmConfig.UnbondingPeriod, tmConfig.MaxClockDrift, + suite.chainB.LastHeader.GetTrustedHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, + ) + + store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + err := clientState.Initialize(suite.chainA.GetContext(), suite.chainA.Codec, store, tc.consensusState) + + if tc.expPass { + suite.Require().NoError(err, "valid case returned an error") + suite.Require().True(store.Has(host.ClientStateKey())) + suite.Require().True(store.Has(host.ConsensusStateKey(suite.chainB.LastHeader.GetTrustedHeight()))) + } else { + suite.Require().Error(err, "invalid case didn't return an error") + suite.Require().False(store.Has(host.ClientStateKey())) + suite.Require().False(store.Has(host.ConsensusStateKey(suite.chainB.LastHeader.GetTrustedHeight()))) + } + } +} + +func (suite *TendermintTestSuite) TestVerifyMembership() { + var ( + testingpath *ibctesting.Path + delayTimePeriod uint64 + delayBlockPeriod uint64 + err error + proofHeight exported.Height + proof []byte + path exported.Path + value []byte + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "successful ClientState verification", + func() { + // default proof construction uses ClientState + }, + true, + }, + { + "successful ConsensusState verification", func() { + key := host.FullConsensusStateKey(testingpath.EndpointB.ClientID, testingpath.EndpointB.GetClientState().GetLatestHeight()) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + + consensusState := testingpath.EndpointB.GetConsensusState(testingpath.EndpointB.GetClientState().GetLatestHeight()).(*ibctm.ConsensusState) + value, err = suite.chainB.Codec.MarshalInterface(consensusState) + suite.Require().NoError(err) + }, + true, + }, + { + "successful Connection verification", func() { + key := host.ConnectionKey(testingpath.EndpointB.ConnectionID) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + + connection := testingpath.EndpointB.GetConnection() + value, err = suite.chainB.Codec.Marshal(&connection) + suite.Require().NoError(err) + }, + true, + }, + { + "successful Channel verification", func() { + key := host.ChannelKey(testingpath.EndpointB.ChannelConfig.PortID, testingpath.EndpointB.ChannelID) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + + channel := testingpath.EndpointB.GetChannel() + value, err = suite.chainB.Codec.Marshal(&channel) + suite.Require().NoError(err) + }, + true, + }, + { + "successful PacketCommitment verification", func() { + // send from chainB to chainA since we are proving chainB sent a packet + sequence, err := testingpath.EndpointB.SendPacket(clienttypes.NewHeight(1, 100), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + + // make packet commitment proof + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, testingpath.EndpointB.ChannelConfig.PortID, testingpath.EndpointB.ChannelID, testingpath.EndpointA.ChannelConfig.PortID, testingpath.EndpointA.ChannelID, clienttypes.NewHeight(1, 100), 0) + key := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = testingpath.EndpointB.QueryProof(key) + + value = channeltypes.CommitPacket(suite.chainA.App.GetIBCKeeper().Codec(), packet) + }, true, + }, + { + "successful Acknowledgement verification", func() { + // send from chainA to chainB since we are proving chainB wrote an acknowledgement + sequence, err := testingpath.EndpointA.SendPacket(clienttypes.NewHeight(1, 100), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + + // write receipt and ack + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, testingpath.EndpointA.ChannelConfig.PortID, testingpath.EndpointA.ChannelID, testingpath.EndpointB.ChannelConfig.PortID, testingpath.EndpointB.ChannelID, clienttypes.NewHeight(1, 100), 0) + err = testingpath.EndpointB.RecvPacket(packet) + suite.Require().NoError(err) + + key := host.PacketAcknowledgementKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = testingpath.EndpointB.QueryProof(key) + + value = channeltypes.CommitAcknowledgement(ibcmock.MockAcknowledgement.Acknowledgement()) + }, + true, + }, + { + "successful NextSequenceRecv verification", func() { + // send from chainA to chainB since we are proving chainB incremented the sequence recv + + // send packet + sequence, err := testingpath.EndpointA.SendPacket(clienttypes.NewHeight(1, 100), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + + // next seq recv incremented + packet := channeltypes.NewPacket(ibctesting.MockPacketData, sequence, testingpath.EndpointA.ChannelConfig.PortID, testingpath.EndpointA.ChannelID, testingpath.EndpointB.ChannelConfig.PortID, testingpath.EndpointB.ChannelID, clienttypes.NewHeight(1, 100), 0) + err = testingpath.EndpointB.RecvPacket(packet) + suite.Require().NoError(err) + + key := host.NextSequenceRecvKey(packet.GetSourcePort(), packet.GetSourceChannel()) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = testingpath.EndpointB.QueryProof(key) + + value = sdk.Uint64ToBigEndian(packet.GetSequence() + 1) + }, + true, + }, + { + "successful verification outside IBC store", func() { + key := transfertypes.PortKey + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(commitmenttypes.NewMerklePrefix([]byte(transfertypes.StoreKey)), merklePath) + suite.Require().NoError(err) + + clientState := testingpath.EndpointA.GetClientState() + proof, proofHeight = suite.chainB.QueryProofForStore(transfertypes.StoreKey, key, int64(clientState.GetLatestHeight().GetRevisionHeight())) + + value = []byte(suite.chainB.GetSimApp().TransferKeeper.GetPort(suite.chainB.GetContext())) + suite.Require().NoError(err) + }, + true, + }, + { + "delay time period has passed", func() { + delayTimePeriod = uint64(time.Second.Nanoseconds()) + }, + true, + }, + { + "delay time period has not passed", func() { + delayTimePeriod = uint64(time.Hour.Nanoseconds()) + }, + false, + }, + { + "delay block period has passed", func() { + delayBlockPeriod = 1 + }, + true, + }, + { + "delay block period has not passed", func() { + delayBlockPeriod = 1000 + }, + false, + }, + { + "latest client height < height", func() { + proofHeight = testingpath.EndpointA.GetClientState().GetLatestHeight().Increment() + }, false, + }, + { + "invalid path type", + func() { + path = ibcmock.KeyPath{} + }, + false, + }, + { + "failed to unmarshal merkle proof", func() { + proof = invalidProof + }, false, + }, + { + "consensus state not found", func() { + proofHeight = clienttypes.ZeroHeight() + }, false, + }, + { + "proof verification failed", func() { + // change the value being proved + value = []byte("invalid value") + }, false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + testingpath = ibctesting.NewPath(suite.chainA, suite.chainB) + testingpath.SetChannelOrdered() + suite.coordinator.Setup(testingpath) + + // reset time and block delays to 0, malleate may change to a specific non-zero value. + delayTimePeriod = 0 + delayBlockPeriod = 0 + + // create default proof, merklePath, and value which passes + // may be overwritten by malleate() + key := host.FullClientStateKey(testingpath.EndpointB.ClientID) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + + clientState := testingpath.EndpointB.GetClientState().(*ibctm.ClientState) + value, err = suite.chainB.Codec.MarshalInterface(clientState) + suite.Require().NoError(err) + + tc.malleate() // make changes as necessary + + clientState = testingpath.EndpointA.GetClientState().(*ibctm.ClientState) + + ctx := suite.chainA.GetContext() + store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, testingpath.EndpointA.ClientID) + + err = clientState.VerifyMembership( + ctx, store, suite.chainA.Codec, proofHeight, delayTimePeriod, delayBlockPeriod, + proof, path, value, + ) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TendermintTestSuite) TestVerifyNonMembership() { + var ( + testingpath *ibctesting.Path + delayTimePeriod uint64 + delayBlockPeriod uint64 + err error + proofHeight exported.Height + path exported.Path + proof []byte + invalidClientID = "09-tendermint" + invalidConnectionID = "connection-100" + invalidChannelID = "channel-800" + invalidPortID = "invalid-port" + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "successful ClientState verification of non membership", + func() { + // default proof construction uses ClientState + }, + true, + }, + { + "successful ConsensusState verification of non membership", func() { + key := host.FullConsensusStateKey(invalidClientID, testingpath.EndpointB.GetClientState().GetLatestHeight()) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + }, + true, + }, + { + "successful Connection verification of non membership", func() { + key := host.ConnectionKey(invalidConnectionID) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + }, + true, + }, + { + "successful Channel verification of non membership", func() { + key := host.ChannelKey(testingpath.EndpointB.ChannelConfig.PortID, invalidChannelID) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + }, + true, + }, + { + "successful PacketCommitment verification of non membership", func() { + // make packet commitment proof + key := host.PacketCommitmentKey(invalidPortID, invalidChannelID, 1) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = testingpath.EndpointB.QueryProof(key) + }, true, + }, + { + "successful Acknowledgement verification of non membership", func() { + key := host.PacketAcknowledgementKey(invalidPortID, invalidChannelID, 1) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = testingpath.EndpointB.QueryProof(key) + }, + true, + }, + { + "successful NextSequenceRecv verification of non membership", func() { + key := host.NextSequenceRecvKey(invalidPortID, invalidChannelID) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = testingpath.EndpointB.QueryProof(key) + }, + true, + }, + { + "successful verification of non membership outside IBC store", func() { + key := []byte{0x08} + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(commitmenttypes.NewMerklePrefix([]byte(transfertypes.StoreKey)), merklePath) + suite.Require().NoError(err) + + clientState := testingpath.EndpointA.GetClientState() + proof, proofHeight = suite.chainB.QueryProofForStore(transfertypes.StoreKey, key, int64(clientState.GetLatestHeight().GetRevisionHeight())) + }, + true, + }, + { + "delay time period has passed", func() { + delayTimePeriod = uint64(time.Second.Nanoseconds()) + }, + true, + }, + { + "delay time period has not passed", func() { + delayTimePeriod = uint64(time.Hour.Nanoseconds()) + }, + false, + }, + { + "delay block period has passed", func() { + delayBlockPeriod = 1 + }, + true, + }, + { + "delay block period has not passed", func() { + delayBlockPeriod = 1000 + }, + false, + }, + { + "latest client height < height", func() { + proofHeight = testingpath.EndpointA.GetClientState().GetLatestHeight().Increment() + }, false, + }, + { + "invalid path type", + func() { + path = ibcmock.KeyPath{} + }, + false, + }, + { + "failed to unmarshal merkle proof", func() { + proof = invalidProof + }, false, + }, + { + "consensus state not found", func() { + proofHeight = clienttypes.ZeroHeight() + }, false, + }, + { + "verify non membership fails as path exists", func() { + // change the value being proved + key := host.FullClientStateKey(testingpath.EndpointB.ClientID) + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + }, false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + testingpath = ibctesting.NewPath(suite.chainA, suite.chainB) + testingpath.SetChannelOrdered() + suite.coordinator.Setup(testingpath) + + // reset time and block delays to 0, malleate may change to a specific non-zero value. + delayTimePeriod = 0 + delayBlockPeriod = 0 + + // create default proof, merklePath, and value which passes + // may be overwritten by malleate() + key := host.FullClientStateKey("invalid-client-id") + + merklePath := commitmenttypes.NewMerklePath(string(key)) + path, err = commitmenttypes.ApplyPrefix(suite.chainB.GetPrefix(), merklePath) + suite.Require().NoError(err) + + proof, proofHeight = suite.chainB.QueryProof(key) + + tc.malleate() // make changes as necessary + + clientState := testingpath.EndpointA.GetClientState().(*ibctm.ClientState) + + ctx := suite.chainA.GetContext() + store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, testingpath.EndpointA.ClientID) + + err = clientState.VerifyNonMembership( + ctx, store, suite.chainA.Codec, proofHeight, delayTimePeriod, delayBlockPeriod, + proof, path, + ) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} diff --git a/modules/light-clients/07-tendermint/types/codec.go b/modules/light-clients/07-tendermint/codec.go similarity index 79% rename from modules/light-clients/07-tendermint/types/codec.go rename to modules/light-clients/07-tendermint/codec.go index 28e68a2b7b4..09f093ab9d7 100644 --- a/modules/light-clients/07-tendermint/types/codec.go +++ b/modules/light-clients/07-tendermint/codec.go @@ -1,9 +1,9 @@ -package types +package tendermint import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // RegisterInterfaces registers the tendermint concrete client-related @@ -18,11 +18,11 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { &ConsensusState{}, ) registry.RegisterImplementations( - (*exported.Header)(nil), + (*exported.ClientMessage)(nil), &Header{}, ) registry.RegisterImplementations( - (*exported.Misbehaviour)(nil), + (*exported.ClientMessage)(nil), &Misbehaviour{}, ) } diff --git a/modules/light-clients/07-tendermint/types/consensus_state.go b/modules/light-clients/07-tendermint/consensus_state.go similarity index 77% rename from modules/light-clients/07-tendermint/types/consensus_state.go rename to modules/light-clients/07-tendermint/consensus_state.go index 7f563285898..065c2dfa250 100644 --- a/modules/light-clients/07-tendermint/types/consensus_state.go +++ b/modules/light-clients/07-tendermint/consensus_state.go @@ -1,15 +1,15 @@ -package types +package tendermint import ( "time" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmtypes "github.com/tendermint/tendermint/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // SentinelRoot is used as a stand-in root value for the consensus state set at the upgrade height @@ -46,13 +46,13 @@ func (cs ConsensusState) GetTimestamp() uint64 { // as opposed to a consensus state constructed by the chain. func (cs ConsensusState) ValidateBasic() error { if cs.Root.Empty() { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "root cannot be empty") + return errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "root cannot be empty") } if err := tmtypes.ValidateHash(cs.NextValidatorsHash); err != nil { - return sdkerrors.Wrap(err, "next validators hash is invalid") + return errorsmod.Wrap(err, "next validators hash is invalid") } if cs.Timestamp.Unix() <= 0 { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "timestamp must be a positive Unix time") + return errorsmod.Wrap(clienttypes.ErrInvalidConsensus, "timestamp must be a positive Unix time") } return nil } diff --git a/modules/light-clients/07-tendermint/types/consensus_state_test.go b/modules/light-clients/07-tendermint/consensus_state_test.go similarity index 77% rename from modules/light-clients/07-tendermint/types/consensus_state_test.go rename to modules/light-clients/07-tendermint/consensus_state_test.go index 86337eb5258..853217dd9cc 100644 --- a/modules/light-clients/07-tendermint/types/consensus_state_test.go +++ b/modules/light-clients/07-tendermint/consensus_state_test.go @@ -1,22 +1,22 @@ -package types_test +package tendermint_test import ( "time" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + 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" ) func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { testCases := []struct { msg string - consensusState *types.ConsensusState + consensusState *ibctm.ConsensusState expectPass bool }{ { "success", - &types.ConsensusState{ + &ibctm.ConsensusState{ Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot([]byte("app_hash")), NextValidatorsHash: suite.valsHash, @@ -25,16 +25,16 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { }, { "success with sentinel", - &types.ConsensusState{ + &ibctm.ConsensusState{ Timestamp: suite.now, - Root: commitmenttypes.NewMerkleRoot([]byte(types.SentinelRoot)), + Root: commitmenttypes.NewMerkleRoot([]byte(ibctm.SentinelRoot)), NextValidatorsHash: suite.valsHash, }, true, }, { "root is nil", - &types.ConsensusState{ + &ibctm.ConsensusState{ Timestamp: suite.now, Root: commitmenttypes.MerkleRoot{}, NextValidatorsHash: suite.valsHash, @@ -43,7 +43,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { }, { "root is empty", - &types.ConsensusState{ + &ibctm.ConsensusState{ Timestamp: suite.now, Root: commitmenttypes.MerkleRoot{}, NextValidatorsHash: suite.valsHash, @@ -52,7 +52,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { }, { "nextvalshash is invalid", - &types.ConsensusState{ + &ibctm.ConsensusState{ Timestamp: suite.now, Root: commitmenttypes.NewMerkleRoot([]byte("app_hash")), NextValidatorsHash: []byte("hi"), @@ -62,7 +62,7 @@ func (suite *TendermintTestSuite) TestConsensusStateValidateBasic() { { "timestamp is zero", - &types.ConsensusState{ + &ibctm.ConsensusState{ Timestamp: time.Time{}, Root: commitmenttypes.NewMerkleRoot([]byte("app_hash")), NextValidatorsHash: suite.valsHash, diff --git a/modules/light-clients/07-tendermint/doc.go b/modules/light-clients/07-tendermint/doc.go index 26aa430a82d..85f183b8d9d 100644 --- a/modules/light-clients/07-tendermint/doc.go +++ b/modules/light-clients/07-tendermint/doc.go @@ -1,5 +1,7 @@ /* -Package tendermint implements a concrete `ConsensusState`, `Header`, -`Misbehaviour` and `Equivocation` types for the Tendermint consensus light client. +Package tendermint implements a concrete ClientState, ConsensusState, +Header, Misbehaviour and types for the Tendermint consensus light client. +This implementation is based off the ICS 07 specification +(https://github.com/cosmos/ibc/tree/main/spec/client/ics-007-tendermint-client) */ package tendermint diff --git a/modules/light-clients/07-tendermint/errors.go b/modules/light-clients/07-tendermint/errors.go new file mode 100644 index 00000000000..8bbb58ec33a --- /dev/null +++ b/modules/light-clients/07-tendermint/errors.go @@ -0,0 +1,22 @@ +package tendermint + +import ( + errorsmod "cosmossdk.io/errors" +) + +// IBC tendermint client sentinel errors +var ( + ErrInvalidChainID = errorsmod.Register(ModuleName, 2, "invalid chain-id") + ErrInvalidTrustingPeriod = errorsmod.Register(ModuleName, 3, "invalid trusting period") + ErrInvalidUnbondingPeriod = errorsmod.Register(ModuleName, 4, "invalid unbonding period") + ErrInvalidHeaderHeight = errorsmod.Register(ModuleName, 5, "invalid header height") + ErrInvalidHeader = errorsmod.Register(ModuleName, 6, "invalid header") + ErrInvalidMaxClockDrift = errorsmod.Register(ModuleName, 7, "invalid max clock drift") + ErrProcessedTimeNotFound = errorsmod.Register(ModuleName, 8, "processed time not found") + ErrProcessedHeightNotFound = errorsmod.Register(ModuleName, 9, "processed height not found") + ErrDelayPeriodNotPassed = errorsmod.Register(ModuleName, 10, "packet-specified delay period has not been reached") + ErrTrustingPeriodExpired = errorsmod.Register(ModuleName, 11, "time since latest trusted state has passed the trusting period") + ErrUnbondingPeriodExpired = errorsmod.Register(ModuleName, 12, "time since latest trusted state has passed the unbonding period") + ErrInvalidProofSpecs = errorsmod.Register(ModuleName, 13, "invalid proof specs") + ErrInvalidValidatorSet = errorsmod.Register(ModuleName, 14, "invalid validator set") +) diff --git a/modules/light-clients/07-tendermint/types/fraction.go b/modules/light-clients/07-tendermint/fraction.go similarity index 97% rename from modules/light-clients/07-tendermint/types/fraction.go rename to modules/light-clients/07-tendermint/fraction.go index e445f19ba6f..772c6d9c171 100644 --- a/modules/light-clients/07-tendermint/types/fraction.go +++ b/modules/light-clients/07-tendermint/fraction.go @@ -1,4 +1,4 @@ -package types +package tendermint import ( tmmath "github.com/tendermint/tendermint/libs/math" diff --git a/modules/light-clients/07-tendermint/types/genesis.go b/modules/light-clients/07-tendermint/genesis.go similarity index 79% rename from modules/light-clients/07-tendermint/types/genesis.go rename to modules/light-clients/07-tendermint/genesis.go index 2a36e1653e4..f9c0e6c99a8 100644 --- a/modules/light-clients/07-tendermint/types/genesis.go +++ b/modules/light-clients/07-tendermint/genesis.go @@ -1,10 +1,10 @@ -package types +package tendermint import ( sdk "github.com/cosmos/cosmos-sdk/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // ExportMetadata exports all the consensus metadata in the client store so they can be included in clients genesis diff --git a/modules/light-clients/07-tendermint/types/genesis_test.go b/modules/light-clients/07-tendermint/genesis_test.go similarity index 74% rename from modules/light-clients/07-tendermint/types/genesis_test.go rename to modules/light-clients/07-tendermint/genesis_test.go index 03fe79a935c..26033f6bfa7 100644 --- a/modules/light-clients/07-tendermint/types/genesis_test.go +++ b/modules/light-clients/07-tendermint/genesis_test.go @@ -1,11 +1,11 @@ -package types_test +package tendermint_test import ( sdk "github.com/cosmos/cosmos-sdk/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) // expected export ordering: @@ -19,26 +19,26 @@ func (suite *TendermintTestSuite) TestExportMetadata() { clientState := path.EndpointA.GetClientState() height := clientState.GetLatestHeight() - initIteration := types.GetIterationKey(clientStore, height) + initIteration := ibctm.GetIterationKey(clientStore, height) suite.Require().NotEqual(0, len(initIteration)) - initProcessedTime, found := types.GetProcessedTime(clientStore, height) + initProcessedTime, found := ibctm.GetProcessedTime(clientStore, height) suite.Require().True(found) - initProcessedHeight, found := types.GetProcessedHeight(clientStore, height) + initProcessedHeight, found := ibctm.GetProcessedHeight(clientStore, height) suite.Require().True(found) gm := clientState.ExportMetadata(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID)) suite.Require().NotNil(gm, "client with metadata returned nil exported metadata") suite.Require().Len(gm, 3, "exported metadata has unexpected length") - suite.Require().Equal(types.ProcessedHeightKey(height), gm[0].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.ProcessedHeightKey(height), gm[0].GetKey(), "metadata has unexpected key") actualProcessedHeight, err := clienttypes.ParseHeight(string(gm[0].GetValue())) suite.Require().NoError(err) suite.Require().Equal(initProcessedHeight, actualProcessedHeight, "metadata has unexpected value") - suite.Require().Equal(types.ProcessedTimeKey(height), gm[1].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.ProcessedTimeKey(height), gm[1].GetKey(), "metadata has unexpected key") suite.Require().Equal(initProcessedTime, sdk.BigEndianToUint64(gm[1].GetValue()), "metadata has unexpected value") - suite.Require().Equal(types.IterationKey(height), gm[2].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.IterationKey(height), gm[2].GetKey(), "metadata has unexpected key") suite.Require().Equal(initIteration, gm[2].GetValue(), "metadata has unexpected value") // test updating client and exporting metadata @@ -48,11 +48,11 @@ func (suite *TendermintTestSuite) TestExportMetadata() { clientState = path.EndpointA.GetClientState() updateHeight := clientState.GetLatestHeight() - iteration := types.GetIterationKey(clientStore, updateHeight) + iteration := ibctm.GetIterationKey(clientStore, updateHeight) suite.Require().NotEqual(0, len(initIteration)) - processedTime, found := types.GetProcessedTime(clientStore, updateHeight) + processedTime, found := ibctm.GetProcessedTime(clientStore, updateHeight) suite.Require().True(found) - processedHeight, found := types.GetProcessedHeight(clientStore, updateHeight) + processedHeight, found := ibctm.GetProcessedHeight(clientStore, updateHeight) suite.Require().True(found) gm = clientState.ExportMetadata(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID)) @@ -63,27 +63,27 @@ func (suite *TendermintTestSuite) TestExportMetadata() { // initProcessedHeight, initProcessedTime, processedHeight, processedTime, initIteration, iteration // check init processed height and time - suite.Require().Equal(types.ProcessedHeightKey(height), gm[0].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.ProcessedHeightKey(height), gm[0].GetKey(), "metadata has unexpected key") actualProcessedHeight, err = clienttypes.ParseHeight(string(gm[0].GetValue())) suite.Require().NoError(err) suite.Require().Equal(initProcessedHeight, actualProcessedHeight, "metadata has unexpected value") - suite.Require().Equal(types.ProcessedTimeKey(height), gm[1].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.ProcessedTimeKey(height), gm[1].GetKey(), "metadata has unexpected key") suite.Require().Equal(initProcessedTime, sdk.BigEndianToUint64(gm[1].GetValue()), "metadata has unexpected value") // check processed height and time after update - suite.Require().Equal(types.ProcessedHeightKey(updateHeight), gm[2].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.ProcessedHeightKey(updateHeight), gm[2].GetKey(), "metadata has unexpected key") actualProcessedHeight, err = clienttypes.ParseHeight(string(gm[2].GetValue())) suite.Require().NoError(err) suite.Require().Equal(processedHeight, actualProcessedHeight, "metadata has unexpected value") - suite.Require().Equal(types.ProcessedTimeKey(updateHeight), gm[3].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.ProcessedTimeKey(updateHeight), gm[3].GetKey(), "metadata has unexpected key") suite.Require().Equal(processedTime, sdk.BigEndianToUint64(gm[3].GetValue()), "metadata has unexpected value") // check iteration keys - suite.Require().Equal(types.IterationKey(height), gm[4].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.IterationKey(height), gm[4].GetKey(), "metadata has unexpected key") suite.Require().Equal(initIteration, gm[4].GetValue(), "metadata has unexpected value") - suite.Require().Equal(types.IterationKey(updateHeight), gm[5].GetKey(), "metadata has unexpected key") + suite.Require().Equal(ibctm.IterationKey(updateHeight), gm[5].GetKey(), "metadata has unexpected key") suite.Require().Equal(iteration, gm[5].GetValue(), "metadata has unexpected value") } diff --git a/modules/light-clients/07-tendermint/types/header.go b/modules/light-clients/07-tendermint/header.go similarity index 72% rename from modules/light-clients/07-tendermint/types/header.go rename to modules/light-clients/07-tendermint/header.go index e3a420680b9..e158eaab5d1 100644 --- a/modules/light-clients/07-tendermint/types/header.go +++ b/modules/light-clients/07-tendermint/header.go @@ -1,18 +1,18 @@ -package types +package tendermint import ( "bytes" "time" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" tmtypes "github.com/tendermint/tendermint/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) -var _ exported.Header = &Header{} +var _ exported.ClientMessage = &Header{} // ConsensusState returns the updated consensus state associated with the header func (h Header) ConsensusState() *ConsensusState { @@ -49,34 +49,34 @@ func (h Header) GetTime() time.Time { // with MsgCreateClient func (h Header) ValidateBasic() error { if h.SignedHeader == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "tendermint signed header cannot be nil") + return errorsmod.Wrap(clienttypes.ErrInvalidHeader, "tendermint signed header cannot be nil") } if h.Header == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "tendermint header cannot be nil") + return errorsmod.Wrap(clienttypes.ErrInvalidHeader, "tendermint header cannot be nil") } tmSignedHeader, err := tmtypes.SignedHeaderFromProto(h.SignedHeader) if err != nil { - return sdkerrors.Wrap(err, "header is not a tendermint header") + return errorsmod.Wrap(err, "header is not a tendermint header") } if err := tmSignedHeader.ValidateBasic(h.Header.GetChainID()); err != nil { - return sdkerrors.Wrap(err, "header failed basic validation") + return errorsmod.Wrap(err, "header failed basic validation") } // TrustedHeight is less than Header for updates and misbehaviour if h.TrustedHeight.GTE(h.GetHeight()) { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "TrustedHeight %d must be less than header height %d", + return errorsmod.Wrapf(ErrInvalidHeaderHeight, "TrustedHeight %d must be less than header height %d", h.TrustedHeight, h.GetHeight()) } if h.ValidatorSet == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set is nil") + return errorsmod.Wrap(clienttypes.ErrInvalidHeader, "validator set is nil") } tmValset, err := tmtypes.ValidatorSetFromProto(h.ValidatorSet) if err != nil { - return sdkerrors.Wrap(err, "validator set is not tendermint validator set") + return errorsmod.Wrap(err, "validator set is not tendermint validator set") } if !bytes.Equal(h.Header.ValidatorsHash, tmValset.Hash()) { - return sdkerrors.Wrap(clienttypes.ErrInvalidHeader, "validator set does not match hash") + return errorsmod.Wrap(clienttypes.ErrInvalidHeader, "validator set does not match hash") } return nil } diff --git a/modules/light-clients/07-tendermint/types/header_test.go b/modules/light-clients/07-tendermint/header_test.go similarity index 88% rename from modules/light-clients/07-tendermint/types/header_test.go rename to modules/light-clients/07-tendermint/header_test.go index 128882f8393..5325bdb7a62 100644 --- a/modules/light-clients/07-tendermint/types/header_test.go +++ b/modules/light-clients/07-tendermint/header_test.go @@ -1,13 +1,13 @@ -package types_test +package tendermint_test import ( "time" tmprotocrypto "github.com/tendermint/tendermint/proto/tendermint/crypto" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ) func (suite *TendermintTestSuite) TestGetHeight() { @@ -21,7 +21,7 @@ func (suite *TendermintTestSuite) TestGetTime() { } func (suite *TendermintTestSuite) TestHeaderValidateBasic() { - var header *types.Header + var header *ibctm.Header testCases := []struct { name string malleate func() diff --git a/modules/light-clients/07-tendermint/keys.go b/modules/light-clients/07-tendermint/keys.go new file mode 100644 index 00000000000..bc2fd02dec1 --- /dev/null +++ b/modules/light-clients/07-tendermint/keys.go @@ -0,0 +1,5 @@ +package tendermint + +const ( + ModuleName = "07-tendermint" +) diff --git a/modules/light-clients/07-tendermint/migrations/expected_keepers.go b/modules/light-clients/07-tendermint/migrations/expected_keepers.go new file mode 100644 index 00000000000..e47a82e40c1 --- /dev/null +++ b/modules/light-clients/07-tendermint/migrations/expected_keepers.go @@ -0,0 +1,16 @@ +package migrations + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// ClientKeeper expected account IBC client keeper +type ClientKeeper interface { + GetClientState(ctx sdk.Context, clientID string) (exported.ClientState, bool) + IterateClientStates(ctx sdk.Context, prefix []byte, cb func(string, exported.ClientState) bool) + ClientStore(ctx sdk.Context, clientID string) sdk.KVStore + Logger(ctx sdk.Context) log.Logger +} diff --git a/modules/light-clients/07-tendermint/migrations/migrations.go b/modules/light-clients/07-tendermint/migrations/migrations.go new file mode 100644 index 00000000000..f5d28fe468f --- /dev/null +++ b/modules/light-clients/07-tendermint/migrations/migrations.go @@ -0,0 +1,46 @@ +package migrations + +import ( + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" +) + +// PruneExpiredConsensusStates prunes all expired tendermint consensus states. This function +// may optionally be called during in-place store migrations. The ibc store key must be provided. +func PruneExpiredConsensusStates(ctx sdk.Context, cdc codec.BinaryCodec, clientKeeper ClientKeeper) (int, error) { + var clientIDs []string + clientKeeper.IterateClientStates(ctx, []byte(exported.Tendermint), func(clientID string, _ exported.ClientState) bool { + clientIDs = append(clientIDs, clientID) + return false + }) + + // keep track of the total consensus states pruned so chains can + // understand how much space is saved when the migration is run + var totalPruned int + + for _, clientID := range clientIDs { + clientStore := clientKeeper.ClientStore(ctx, clientID) + + clientState, ok := clientKeeper.GetClientState(ctx, clientID) + if !ok { + return 0, errorsmod.Wrapf(clienttypes.ErrClientNotFound, "clientID %s", clientID) + } + + tmClientState, ok := clientState.(*ibctm.ClientState) + if !ok { + return 0, errorsmod.Wrap(clienttypes.ErrInvalidClient, "client state is not tendermint even though client id contains 07-tendermint") + } + + totalPruned += ibctm.PruneAllExpiredConsensusStates(ctx, clientStore, cdc, tmClientState) + } + + clientLogger := clientKeeper.Logger(ctx) + clientLogger.Info("pruned expired tendermint consensus states", "total", totalPruned) + + return totalPruned, nil +} diff --git a/modules/light-clients/07-tendermint/migrations/migrations_test.go b/modules/light-clients/07-tendermint/migrations/migrations_test.go new file mode 100644 index 00000000000..0bfc1031725 --- /dev/null +++ b/modules/light-clients/07-tendermint/migrations/migrations_test.go @@ -0,0 +1,178 @@ +package migrations_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/suite" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctmmigrations "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint/migrations" + ibctesting "github.com/cosmos/ibc-go/v7/testing" +) + +type MigrationsTestSuite struct { + suite.Suite + + coordinator *ibctesting.Coordinator + + // testing chains used for convenience and readability + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain +} + +func (suite *MigrationsTestSuite) SetupTest() { + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) + suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) + suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) +} + +func TestTendermintTestSuite(t *testing.T) { + suite.Run(t, new(MigrationsTestSuite)) +} + +// test pruning of multiple expired tendermint consensus states +func (suite *MigrationsTestSuite) TestPruneExpiredConsensusStates() { + // create multiple tendermint clients and a solo machine client + // the solo machine is used to verify this pruning function only modifies + // the tendermint store. + + numTMClients := 3 + paths := make([]*ibctesting.Path, numTMClients) + + for i := 0; i < numTMClients; i++ { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupClients(path) + + paths[i] = path + } + + solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1) + smClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), solomachine.ClientID) + + // set client state + bz, err := suite.chainA.App.AppCodec().MarshalInterface(solomachine.ClientState()) + suite.Require().NoError(err) + smClientStore.Set(host.ClientStateKey(), bz) + + bz, err = suite.chainA.App.AppCodec().MarshalInterface(solomachine.ConsensusState()) + suite.Require().NoError(err) + smHeight := clienttypes.NewHeight(0, 1) + smClientStore.Set(host.ConsensusStateKey(smHeight), bz) + + pruneHeightMap := make(map[*ibctesting.Path][]exported.Height) + unexpiredHeightMap := make(map[*ibctesting.Path][]exported.Height) + + for _, path := range paths { + // collect all heights expected to be pruned + var pruneHeights []exported.Height + pruneHeights = append(pruneHeights, path.EndpointA.GetClientState().GetLatestHeight()) + + // these heights will be expired and also pruned + for i := 0; i < 3; i++ { + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + pruneHeights = append(pruneHeights, path.EndpointA.GetClientState().GetLatestHeight()) + } + + // double chedck all information is currently stored + for _, pruneHeight := range pruneHeights { + consState, ok := suite.chainA.GetConsensusState(path.EndpointA.ClientID, pruneHeight) + suite.Require().True(ok) + suite.Require().NotNil(consState) + + ctx := suite.chainA.GetContext() + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) + + processedTime, ok := ibctm.GetProcessedTime(clientStore, pruneHeight) + suite.Require().True(ok) + suite.Require().NotNil(processedTime) + + processedHeight, ok := ibctm.GetProcessedHeight(clientStore, pruneHeight) + suite.Require().True(ok) + suite.Require().NotNil(processedHeight) + + expectedConsKey := ibctm.GetIterationKey(clientStore, pruneHeight) + suite.Require().NotNil(expectedConsKey) + } + pruneHeightMap[path] = pruneHeights + } + + // Increment the time by a week + suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) + + for _, path := range paths { + // create the consensus state that can be used as trusted height for next update + var unexpiredHeights []exported.Height + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + unexpiredHeights = append(unexpiredHeights, path.EndpointA.GetClientState().GetLatestHeight()) + + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + unexpiredHeights = append(unexpiredHeights, path.EndpointA.GetClientState().GetLatestHeight()) + + unexpiredHeightMap[path] = unexpiredHeights + } + + // Increment the time by another week, then update the client. + // This will cause the consensus states created before the first time increment + // to be expired + suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) + totalPruned, err := ibctmmigrations.PruneExpiredConsensusStates(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), suite.chainA.GetSimApp().IBCKeeper.ClientKeeper) + suite.Require().NoError(err) + suite.Require().NotZero(totalPruned) + + for _, path := range paths { + ctx := suite.chainA.GetContext() + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) + + // ensure everything has been pruned + for i, pruneHeight := range pruneHeightMap[path] { + consState, ok := suite.chainA.GetConsensusState(path.EndpointA.ClientID, pruneHeight) + suite.Require().False(ok, i) + suite.Require().Nil(consState, i) + + processedTime, ok := ibctm.GetProcessedTime(clientStore, pruneHeight) + suite.Require().False(ok, i) + suite.Require().Equal(uint64(0), processedTime, i) + + processedHeight, ok := ibctm.GetProcessedHeight(clientStore, pruneHeight) + suite.Require().False(ok, i) + suite.Require().Nil(processedHeight, i) + + expectedConsKey := ibctm.GetIterationKey(clientStore, pruneHeight) + suite.Require().Nil(expectedConsKey, i) + } + + // ensure metadata is set for unexpired consensus state + for _, height := range unexpiredHeightMap[path] { + consState, ok := suite.chainA.GetConsensusState(path.EndpointA.ClientID, height) + suite.Require().True(ok) + suite.Require().NotNil(consState) + + processedTime, ok := ibctm.GetProcessedTime(clientStore, height) + suite.Require().True(ok) + suite.Require().NotEqual(uint64(0), processedTime) + + processedHeight, ok := ibctm.GetProcessedHeight(clientStore, height) + suite.Require().True(ok) + suite.Require().NotEqual(clienttypes.ZeroHeight(), processedHeight) + + consKey := ibctm.GetIterationKey(clientStore, height) + suite.Require().Equal(host.ConsensusStateKey(height), consKey) + } + } + + // verify that solomachine client and consensus state were not removed + smClientStore = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), solomachine.ClientID) + bz = smClientStore.Get(host.ClientStateKey()) + suite.Require().NotEmpty(bz) + + bz = smClientStore.Get(host.ConsensusStateKey(smHeight)) + suite.Require().NotEmpty(bz) +} diff --git a/modules/light-clients/07-tendermint/types/misbehaviour.go b/modules/light-clients/07-tendermint/misbehaviour.go similarity index 68% rename from modules/light-clients/07-tendermint/types/misbehaviour.go rename to modules/light-clients/07-tendermint/misbehaviour.go index f4355cf21f6..827518f6f74 100644 --- a/modules/light-clients/07-tendermint/types/misbehaviour.go +++ b/modules/light-clients/07-tendermint/misbehaviour.go @@ -1,20 +1,20 @@ -package types +package tendermint import ( "time" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + errorsmod "cosmossdk.io/errors" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) -var _ exported.Misbehaviour = &Misbehaviour{} +var _ exported.ClientMessage = &Misbehaviour{} -// Use the same FrozenHeight for all misbehaviour +// FrozenHeight is same for all misbehaviour var FrozenHeight = clienttypes.NewHeight(0, 1) // NewMisbehaviour creates a new Misbehaviour instance. @@ -31,11 +31,6 @@ func (misbehaviour Misbehaviour) ClientType() string { return exported.Tendermint } -// GetClientID returns the ID of the client that committed a misbehaviour. -func (misbehaviour Misbehaviour) GetClientID() string { - return misbehaviour.ClientId -} - // GetTime returns the timestamp at which misbehaviour occurred. It uses the // maximum value from both headers to prevent producing an invalid header outside // of the misbehaviour age range. @@ -50,56 +45,56 @@ func (misbehaviour Misbehaviour) GetTime() time.Time { // ValidateBasic implements Misbehaviour interface func (misbehaviour Misbehaviour) ValidateBasic() error { if misbehaviour.Header1 == nil { - return sdkerrors.Wrap(ErrInvalidHeader, "misbehaviour Header1 cannot be nil") + return errorsmod.Wrap(ErrInvalidHeader, "misbehaviour Header1 cannot be nil") } if misbehaviour.Header2 == nil { - return sdkerrors.Wrap(ErrInvalidHeader, "misbehaviour Header2 cannot be nil") + return errorsmod.Wrap(ErrInvalidHeader, "misbehaviour Header2 cannot be nil") } if misbehaviour.Header1.TrustedHeight.RevisionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header1 cannot have zero revision height") + return errorsmod.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header1 cannot have zero revision height") } if misbehaviour.Header2.TrustedHeight.RevisionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header2 cannot have zero revision height") + return errorsmod.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header2 cannot have zero revision height") } if misbehaviour.Header1.TrustedValidators == nil { - return sdkerrors.Wrap(ErrInvalidValidatorSet, "trusted validator set in Header1 cannot be empty") + return errorsmod.Wrap(ErrInvalidValidatorSet, "trusted validator set in Header1 cannot be empty") } if misbehaviour.Header2.TrustedValidators == nil { - return sdkerrors.Wrap(ErrInvalidValidatorSet, "trusted validator set in Header2 cannot be empty") + return errorsmod.Wrap(ErrInvalidValidatorSet, "trusted validator set in Header2 cannot be empty") } if misbehaviour.Header1.Header.ChainID != misbehaviour.Header2.Header.ChainID { - return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers must have identical chainIDs") + return errorsmod.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers must have identical chainIDs") } if err := host.ClientIdentifierValidator(misbehaviour.ClientId); err != nil { - return sdkerrors.Wrap(err, "misbehaviour client ID is invalid") + return errorsmod.Wrap(err, "misbehaviour client ID is invalid") } // ValidateBasic on both validators if err := misbehaviour.Header1.ValidateBasic(); err != nil { - return sdkerrors.Wrap( + return errorsmod.Wrap( clienttypes.ErrInvalidMisbehaviour, - sdkerrors.Wrap(err, "header 1 failed validation").Error(), + errorsmod.Wrap(err, "header 1 failed validation").Error(), ) } if err := misbehaviour.Header2.ValidateBasic(); err != nil { - return sdkerrors.Wrap( + return errorsmod.Wrap( clienttypes.ErrInvalidMisbehaviour, - sdkerrors.Wrap(err, "header 2 failed validation").Error(), + errorsmod.Wrap(err, "header 2 failed validation").Error(), ) } // Ensure that Height1 is greater than or equal to Height2 if misbehaviour.Header1.GetHeight().LT(misbehaviour.Header2.GetHeight()) { - return sdkerrors.Wrapf(clienttypes.ErrInvalidMisbehaviour, "Header1 height is less than Header2 height (%s < %s)", misbehaviour.Header1.GetHeight(), misbehaviour.Header2.GetHeight()) + return errorsmod.Wrapf(clienttypes.ErrInvalidMisbehaviour, "Header1 height is less than Header2 height (%s < %s)", misbehaviour.Header1.GetHeight(), misbehaviour.Header2.GetHeight()) } blockID1, err := tmtypes.BlockIDFromProto(&misbehaviour.Header1.SignedHeader.Commit.BlockID) if err != nil { - return sdkerrors.Wrap(err, "invalid block ID from header 1 in misbehaviour") + return errorsmod.Wrap(err, "invalid block ID from header 1 in misbehaviour") } blockID2, err := tmtypes.BlockIDFromProto(&misbehaviour.Header2.SignedHeader.Commit.BlockID) if err != nil { - return sdkerrors.Wrap(err, "invalid block ID from header 2 in misbehaviour") + return errorsmod.Wrap(err, "invalid block ID from header 2 in misbehaviour") } if err := validCommit(misbehaviour.Header1.Header.ChainID, *blockID1, @@ -117,15 +112,15 @@ func (misbehaviour Misbehaviour) ValidateBasic() error { func validCommit(chainID string, blockID tmtypes.BlockID, commit *tmproto.Commit, valSet *tmproto.ValidatorSet) (err error) { tmCommit, err := tmtypes.CommitFromProto(commit) if err != nil { - return sdkerrors.Wrap(err, "commit is not tendermint commit type") + return errorsmod.Wrap(err, "commit is not tendermint commit type") } tmValset, err := tmtypes.ValidatorSetFromProto(valSet) if err != nil { - return sdkerrors.Wrap(err, "validator set is not tendermint validator set type") + return errorsmod.Wrap(err, "validator set is not tendermint validator set type") } if err := tmValset.VerifyCommitLight(chainID, blockID, tmCommit.Height, tmCommit); err != nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "validator set did not commit to header") + return errorsmod.Wrap(clienttypes.ErrInvalidMisbehaviour, "validator set did not commit to header") } return nil diff --git a/modules/light-clients/07-tendermint/misbehaviour_handle.go b/modules/light-clients/07-tendermint/misbehaviour_handle.go new file mode 100644 index 00000000000..ef3e654179d --- /dev/null +++ b/modules/light-clients/07-tendermint/misbehaviour_handle.go @@ -0,0 +1,170 @@ +package tendermint + +import ( + "bytes" + "reflect" + "time" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + tmtypes "github.com/tendermint/tendermint/types" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// CheckForMisbehaviour detects duplicate height misbehaviour and BFT time violation misbehaviour +// in a submitted Header message and verifies the correctness of a submitted Misbehaviour ClientMessage +func (cs ClientState) CheckForMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, msg exported.ClientMessage) bool { + switch msg := msg.(type) { + case *Header: + tmHeader := msg + consState := tmHeader.ConsensusState() + + // Check if the Client store already has a consensus state for the header's height + // If the consensus state exists, and it matches the header then we return early + // since header has already been submitted in a previous UpdateClient. + existingConsState, _ := GetConsensusState(clientStore, cdc, tmHeader.GetHeight()) + if existingConsState != nil { + // This header has already been submitted and the necessary state is already stored + // in client store, thus we can return early without further validation. + if reflect.DeepEqual(existingConsState, tmHeader.ConsensusState()) { //nolint:gosimple + return false + } + + // A consensus state already exists for this height, but it does not match the provided header. + // The assumption is that Header has already been validated. Thus we can return true as misbehaviour is present + return true + } + + // Check that consensus state timestamps are monotonic + prevCons, prevOk := GetPreviousConsensusState(clientStore, cdc, tmHeader.GetHeight()) + nextCons, nextOk := GetNextConsensusState(clientStore, cdc, tmHeader.GetHeight()) + // if previous consensus state exists, check consensus state time is greater than previous consensus state time + // if previous consensus state is not before current consensus state return true + if prevOk && !prevCons.Timestamp.Before(consState.Timestamp) { + return true + } + // if next consensus state exists, check consensus state time is less than next consensus state time + // if next consensus state is not after current consensus state return true + if nextOk && !nextCons.Timestamp.After(consState.Timestamp) { + return true + } + case *Misbehaviour: + // if heights are equal check that this is valid misbehaviour of a fork + // otherwise if heights are unequal check that this is valid misbehavior of BFT time violation + if msg.Header1.GetHeight().EQ(msg.Header2.GetHeight()) { + blockID1, err := tmtypes.BlockIDFromProto(&msg.Header1.SignedHeader.Commit.BlockID) + if err != nil { + return false + } + + blockID2, err := tmtypes.BlockIDFromProto(&msg.Header2.SignedHeader.Commit.BlockID) + if err != nil { + return false + } + + // Ensure that Commit Hashes are different + if !bytes.Equal(blockID1.Hash, blockID2.Hash) { + return true + } + + } else if !msg.Header1.SignedHeader.Header.Time.After(msg.Header2.SignedHeader.Header.Time) { + // Header1 is at greater height than Header2, therefore Header1 time must be less than or equal to + // Header2 time in order to be valid misbehaviour (violation of monotonic time). + return true + } + } + + return false +} + +// verifyMisbehaviour determines whether or not two conflicting +// headers at the same height would have convinced the light client. +// +// NOTE: consensusState1 is the trusted consensus state that corresponds to the TrustedHeight +// of misbehaviour.Header1 +// Similarly, consensusState2 is the trusted consensus state that corresponds +// to misbehaviour.Header2 +// Misbehaviour sets frozen height to {0, 1} since it is only used as a boolean value (zero or non-zero). +func (cs *ClientState) verifyMisbehaviour(ctx sdk.Context, clientStore sdk.KVStore, cdc codec.BinaryCodec, misbehaviour *Misbehaviour) error { + // Regardless of the type of misbehaviour, ensure that both headers are valid and would have been accepted by light-client + + // Retrieve trusted consensus states for each Header in misbehaviour + tmConsensusState1, found := GetConsensusState(clientStore, cdc, misbehaviour.Header1.TrustedHeight) + if !found { + return errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "could not get trusted consensus state from clientStore for Header1 at TrustedHeight: %s", misbehaviour.Header1.TrustedHeight) + } + + tmConsensusState2, found := GetConsensusState(clientStore, cdc, misbehaviour.Header2.TrustedHeight) + if !found { + return errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "could not get trusted consensus state from clientStore for Header2 at TrustedHeight: %s", misbehaviour.Header2.TrustedHeight) + } + + // Check the validity of the two conflicting headers against their respective + // trusted consensus states + // NOTE: header height and commitment root assertions are checked in + // misbehaviour.ValidateBasic by the client keeper and msg.ValidateBasic + // by the base application. + if err := checkMisbehaviourHeader( + cs, tmConsensusState1, misbehaviour.Header1, ctx.BlockTime(), + ); err != nil { + return errorsmod.Wrap(err, "verifying Header1 in Misbehaviour failed") + } + if err := checkMisbehaviourHeader( + cs, tmConsensusState2, misbehaviour.Header2, ctx.BlockTime(), + ); err != nil { + return errorsmod.Wrap(err, "verifying Header2 in Misbehaviour failed") + } + + return nil +} + +// checkMisbehaviourHeader checks that a Header in Misbehaviour is valid misbehaviour given +// a trusted ConsensusState +func checkMisbehaviourHeader( + clientState *ClientState, consState *ConsensusState, header *Header, currentTimestamp time.Time, +) error { + tmTrustedValset, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators) + if err != nil { + return errorsmod.Wrap(err, "trusted validator set is not tendermint validator set type") + } + + tmCommit, err := tmtypes.CommitFromProto(header.Commit) + if err != nil { + return errorsmod.Wrap(err, "commit is not tendermint commit type") + } + + // check the trusted fields for the header against ConsensusState + if err := checkTrustedHeader(header, consState); err != nil { + return err + } + + // assert that the age of the trusted consensus state is not older than the trusting period + if currentTimestamp.Sub(consState.Timestamp) >= clientState.TrustingPeriod { + return errorsmod.Wrapf( + ErrTrustingPeriodExpired, + "current timestamp minus the latest consensus state timestamp is greater than or equal to the trusting period (%d >= %d)", + currentTimestamp.Sub(consState.Timestamp), clientState.TrustingPeriod, + ) + } + + chainID := clientState.GetChainID() + // If chainID is in revision format, then set revision number of chainID with the revision number + // of the misbehaviour header + // NOTE: misbehaviour verification is not supported for chains which upgrade to a new chainID without + // strictly following the chainID revision format + if clienttypes.IsRevisionFormat(chainID) { + chainID, _ = clienttypes.SetRevisionNumber(chainID, header.GetHeight().GetRevisionNumber()) + } + + // - ValidatorSet must have TrustLevel similarity with trusted FromValidatorSet + // - ValidatorSets on both headers are valid given the last trusted ValidatorSet + if err := tmTrustedValset.VerifyCommitLightTrusting( + chainID, tmCommit, clientState.TrustLevel.ToTendermint(), + ); err != nil { + return errorsmod.Wrapf(clienttypes.ErrInvalidMisbehaviour, "validator set in header has too much change from trusted validator set: %v", err) + } + return nil +} diff --git a/modules/light-clients/07-tendermint/misbehaviour_handle_test.go b/modules/light-clients/07-tendermint/misbehaviour_handle_test.go new file mode 100644 index 00000000000..ae7a2dd126b --- /dev/null +++ b/modules/light-clients/07-tendermint/misbehaviour_handle_test.go @@ -0,0 +1,648 @@ +package tendermint_test + +import ( + "fmt" + "strings" + "time" + + tmtypes "github.com/tendermint/tendermint/types" + + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctestingmock "github.com/cosmos/ibc-go/v7/testing/mock" +) + +func (suite *TendermintTestSuite) TestVerifyMisbehaviour() { + // Setup different validators and signers for testing different types of updates + altPrivVal := ibctestingmock.NewPV() + altPubKey, err := altPrivVal.GetPubKey() + suite.Require().NoError(err) + + // create modified heights to use for test-cases + altVal := tmtypes.NewValidator(altPubKey, 100) + + // Create alternative validator set with only altVal, invalid update (too much change in valSet) + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + altSigners := getAltSigners(altVal, altPrivVal) + + var ( + path *ibctesting.Path + misbehaviour exported.ClientMessage + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "valid fork misbehaviour", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, + true, + }, + { + "valid time misbehaviour", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+3, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, + true, + }, + { + "valid time misbehaviour, header 1 time stricly less than header 2 time", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+3, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Hour), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, + true, + }, + { + "valid misbehavior at height greater than last consensusState", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, true, + }, + { + "valid misbehaviour with different trusted heights", func() { + trustedHeight1 := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals1, found := suite.chainB.GetValsAtHeight(int64(trustedHeight1.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + trustedHeight2 := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals2, found := suite.chainB.GetValsAtHeight(int64(trustedHeight2.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight1, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals1, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight2, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals2, suite.chainB.Signers), + } + }, + true, + }, + { + "valid misbehaviour at a previous revision", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + + // increment revision number + err = path.EndpointB.UpgradeChain() + suite.Require().NoError(err) + }, + true, + }, + { + "valid misbehaviour at a future revision", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + futureRevision := fmt.Sprintf("%s-%d", strings.TrimSuffix(suite.chainB.ChainID, fmt.Sprintf("-%d", clienttypes.ParseChainID(suite.chainB.ChainID))), height.GetRevisionNumber()+1) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(futureRevision, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(futureRevision, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, + true, + }, + { + "valid misbehaviour with trusted heights at a previous revision", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + // increment revision of chainID + err = path.EndpointB.UpgradeChain() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, + true, + }, + { + "consensus state's valset hash different from misbehaviour should still pass", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.chainB.Vals.Validators, altValSet.Proposer)) + bothSigners := suite.chainB.Signers + bothSigners[altValSet.Proposer.Address.String()] = altPrivVal + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), bothValSet, suite.chainB.NextVals, trustedVals, bothSigners), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, bothValSet, suite.chainB.NextVals, trustedVals, bothSigners), + } + }, true, + }, + { + "invalid misbehaviour: misbehaviour from different chain", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader("evmos", int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader("evmos", int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "misbehaviour trusted validators does not match validator hash in trusted consensus state", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, altValSet, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, altValSet, suite.chainB.Signers), + } + }, false, + }, + { + "trusted consensus state does not exist", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight.Increment().(clienttypes.Height), suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "invalid tendermint misbehaviour", func() { + misbehaviour = &solomachine.Misbehaviour{} + }, false, + }, + { + "trusting period expired", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + suite.chainA.ExpireClient(path.EndpointA.ClientConfig.(*ibctesting.TendermintConfig).TrustingPeriod) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "header 1 valset has too much change", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), altValSet, suite.chainB.NextVals, trustedVals, altSigners), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "header 2 valset has too much change", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, altValSet, suite.chainB.NextVals, trustedVals, altSigners), + } + }, false, + }, + { + "both header 1 and header 2 valsets have too much change", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), altValSet, suite.chainB.NextVals, trustedVals, altSigners), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, altValSet, suite.chainB.NextVals, trustedVals, altSigners), + } + }, false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + err := path.EndpointA.CreateClient() + suite.Require().NoError(err) + + tc.malleate() + + clientState := path.EndpointA.GetClientState() + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + + err = clientState.VerifyClientMessage(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, misbehaviour) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +// test both fork and time misbehaviour for chainIDs not in the revision format +// this function is separate as it must use a global variable in the testing package +// to initialize chains not in the revision format +func (suite *TendermintTestSuite) TestVerifyMisbehaviourNonRevisionChainID() { + // NOTE: chains set to non revision format + ibctesting.ChainIDSuffix = "" + + // Setup different validators and signers for testing different types of updates + altPrivVal := ibctestingmock.NewPV() + altPubKey, err := altPrivVal.GetPubKey() + suite.Require().NoError(err) + + // create modified heights to use for test-cases + altVal := tmtypes.NewValidator(altPubKey, 100) + + // Create alternative validator set with only altVal, invalid update (too much change in valSet) + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + altSigners := getAltSigners(altVal, altPrivVal) + + var ( + path *ibctesting.Path + misbehaviour exported.ClientMessage + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "valid fork misbehaviour", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, + true, + }, + { + "valid time misbehaviour", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+3, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, + true, + }, + { + "valid time misbehaviour, header 1 time stricly less than header 2 time", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+3, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Hour), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, + true, + }, + { + "valid misbehavior at height greater than last consensusState", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, true, + }, + { + "valid misbehaviour with different trusted heights", func() { + trustedHeight1 := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals1, found := suite.chainB.GetValsAtHeight(int64(trustedHeight1.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + trustedHeight2 := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals2, found := suite.chainB.GetValsAtHeight(int64(trustedHeight2.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight1, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals1, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight2, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals2, suite.chainB.Signers), + } + }, + true, + }, + { + "consensus state's valset hash different from misbehaviour should still pass", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.chainB.Vals.Validators, altValSet.Proposer)) + bothSigners := suite.chainB.Signers + bothSigners[altValSet.Proposer.Address.String()] = altPrivVal + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), bothValSet, suite.chainB.NextVals, trustedVals, bothSigners), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, bothValSet, suite.chainB.NextVals, trustedVals, bothSigners), + } + }, true, + }, + { + "invalid misbehaviour: misbehaviour from different chain", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader("evmos", int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader("evmos", int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "misbehaviour trusted validators does not match validator hash in trusted consensus state", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, altValSet, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, altValSet, suite.chainB.Signers), + } + }, false, + }, + { + "trusted consensus state does not exist", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight.Increment().(clienttypes.Height), suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "invalid tendermint misbehaviour", func() { + misbehaviour = &solomachine.Misbehaviour{} + }, false, + }, + { + "trusting period expired", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + suite.chainA.ExpireClient(path.EndpointA.ClientConfig.(*ibctesting.TendermintConfig).TrustingPeriod) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "header 1 valset has too much change", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), altValSet, suite.chainB.NextVals, trustedVals, altSigners), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "header 2 valset has too much change", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, altValSet, suite.chainB.NextVals, trustedVals, altSigners), + } + }, false, + }, + { + "both header 1 and header 2 valsets have too much change", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviour = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), altValSet, suite.chainB.NextVals, trustedVals, altSigners), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, altValSet, suite.chainB.NextVals, trustedVals, altSigners), + } + }, false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + err := path.EndpointA.CreateClient() + suite.Require().NoError(err) + + tc.malleate() + + clientState := path.EndpointA.GetClientState() + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + + err = clientState.VerifyClientMessage(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, misbehaviour) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } + + // NOTE: reset chain creation to revision format + ibctesting.ChainIDSuffix = "-1" +} diff --git a/modules/light-clients/07-tendermint/types/misbehaviour_test.go b/modules/light-clients/07-tendermint/misbehaviour_test.go similarity index 79% rename from modules/light-clients/07-tendermint/types/misbehaviour_test.go rename to modules/light-clients/07-tendermint/misbehaviour_test.go index 5b67212be5e..d49df447f3c 100644 --- a/modules/light-clients/07-tendermint/types/misbehaviour_test.go +++ b/modules/light-clients/07-tendermint/misbehaviour_test.go @@ -1,4 +1,4 @@ -package types_test +package tendermint_test import ( "time" @@ -7,24 +7,23 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibctestingmock "github.com/cosmos/ibc-go/v4/testing/mock" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/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/ibc-go/v7/testing" + ibctestingmock "github.com/cosmos/ibc-go/v7/testing/mock" ) func (suite *TendermintTestSuite) TestMisbehaviour() { heightMinus1 := clienttypes.NewHeight(0, height.RevisionHeight-1) - misbehaviour := &types.Misbehaviour{ + misbehaviour := &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, suite.valSet, suite.signers), ClientId: clientID, } suite.Require().Equal(exported.Tendermint, misbehaviour.ClientType()) - suite.Require().Equal(clientID, misbehaviour.GetClientID()) } func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { @@ -48,130 +47,130 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { testCases := []struct { name string - misbehaviour *types.Misbehaviour - malleateMisbehaviour func(misbehaviour *types.Misbehaviour) error + misbehaviour *ibctm.Misbehaviour + malleateMisbehaviour func(misbehaviour *ibctm.Misbehaviour) error expPass bool }{ { "valid fork misbehaviour, two headers at same height have different time", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, suite.valSet, suite.signers), ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, true, }, { "valid time misbehaviour, both headers at different heights are at same time", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+5), heightMinus1, suite.now, suite.valSet, suite.valSet, suite.valSet, suite.signers), Header2: suite.header, ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, true, }, { "misbehaviour Header1 is nil", - types.NewMisbehaviour(clientID, nil, suite.header), - func(m *types.Misbehaviour) error { return nil }, + ibctm.NewMisbehaviour(clientID, nil, suite.header), + func(m *ibctm.Misbehaviour) error { return nil }, false, }, { "misbehaviour Header2 is nil", - types.NewMisbehaviour(clientID, suite.header, nil), - func(m *types.Misbehaviour) error { return nil }, + ibctm.NewMisbehaviour(clientID, suite.header, nil), + func(m *ibctm.Misbehaviour) error { return nil }, false, }, { "valid misbehaviour with different trusted headers", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.NewHeight(0, height.RevisionHeight-3), suite.now.Add(time.Minute), suite.valSet, suite.valSet, bothValSet, suite.signers), ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, true, }, { "trusted height is 0 in Header1", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, suite.valSet, suite.signers), Header2: suite.header, ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, false, }, { "trusted height is 0 in Header2", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, suite.valSet, suite.signers), ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, false, }, { "trusted valset is nil in Header1", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, nil, suite.signers), Header2: suite.header, ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, false, }, { "trusted valset is nil in Header2", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, nil, suite.signers), ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, false, }, { "invalid client ID ", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, suite.valSet, suite.signers), ClientId: "GAIA", }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, false, }, { "chainIDs do not match", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, suite.valSet, suite.signers), ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, false, }, { "header2 height is greater", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, 6, clienttypes.NewHeight(0, height.RevisionHeight+1), suite.now, suite.valSet, suite.valSet, suite.valSet, suite.signers), ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { return nil }, + func(misbehaviour *ibctm.Misbehaviour) error { return nil }, false, }, { "header 1 doesn't have 2/3 majority", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, suite.valSet, bothSigners), Header2: suite.header, ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { + func(misbehaviour *ibctm.Misbehaviour) error { // voteSet contains only altVal which is less than 2/3 of total power (height/1height) wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header1.GetHeight().GetRevisionHeight()), 1, tmproto.PrecommitType, altValSet) blockID, err := tmtypes.BlockIDFromProto(&misbehaviour.Header1.Commit.BlockID) @@ -187,12 +186,12 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { }, { "header 2 doesn't have 2/3 majority", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, suite.valSet, bothSigners), ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { + func(misbehaviour *ibctm.Misbehaviour) error { // voteSet contains only altVal which is less than 2/3 of total power (height/1height) wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header2.GetHeight().GetRevisionHeight()), 1, tmproto.PrecommitType, altValSet) blockID, err := tmtypes.BlockIDFromProto(&misbehaviour.Header2.Commit.BlockID) @@ -208,12 +207,12 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { }, { "validators sign off on wrong commit", - &types.Misbehaviour{ + &ibctm.Misbehaviour{ Header1: suite.header, Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, suite.valSet, bothSigners), ClientId: clientID, }, - func(misbehaviour *types.Misbehaviour) error { + func(misbehaviour *ibctm.Misbehaviour) error { tmBlockID := ibctesting.MakeBlockID(tmhash.Sum([]byte("other_hash")), 3, tmhash.Sum([]byte("other_partset"))) misbehaviour.Header2.Commit.BlockID = tmBlockID.ToProto() return nil diff --git a/modules/light-clients/07-tendermint/module.go b/modules/light-clients/07-tendermint/module.go index 05be0ea1217..c66bc36102d 100644 --- a/modules/light-clients/07-tendermint/module.go +++ b/modules/light-clients/07-tendermint/module.go @@ -1,10 +1,56 @@ package tendermint import ( - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + "encoding/json" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" ) -// Name returns the IBC client name -func Name() string { - return types.SubModuleName +var _ module.AppModuleBasic = AppModuleBasic{} + +// AppModuleBasic defines the basic application module used by the tendermint light client. +// Only the RegisterInterfaces function needs to be implemented. All other function perform +// a no-op. +type AppModuleBasic struct{} + +// Name returns the tendermint module name. +func (AppModuleBasic) Name() string { + return ModuleName +} + +// RegisterLegacyAminoCodec performs a no-op. The Tendermint client does not support amino. +func (AppModuleBasic) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} + +// RegisterInterfaces registers module concrete types into protobuf Any. This allows core IBC +// to unmarshal tendermint light client types. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + RegisterInterfaces(registry) +} + +// DefaultGenesis performs a no-op. Genesis is not supported for the tendermint light client. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return nil +} + +// ValidateGenesis performs a no-op. Genesis is not supported for the tendermint light cilent. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + return nil +} + +// RegisterGRPCGatewayRoutes performs a no-op. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} + +// GetTxCmd performs a no-op. Please see the 02-client cli commands. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +// GetQueryCmd performs a no-op. Please see the 02-client cli commands. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil } diff --git a/modules/light-clients/07-tendermint/types/proposal_handle.go b/modules/light-clients/07-tendermint/proposal_handle.go similarity index 69% rename from modules/light-clients/07-tendermint/types/proposal_handle.go rename to modules/light-clients/07-tendermint/proposal_handle.go index 85720f7eaeb..98b37ebf019 100644 --- a/modules/light-clients/07-tendermint/types/proposal_handle.go +++ b/modules/light-clients/07-tendermint/proposal_handle.go @@ -1,15 +1,15 @@ -package types +package tendermint import ( "reflect" "time" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // CheckSubstituteAndUpdateState will try to update the client with the state of the @@ -19,24 +19,22 @@ import ( // Please see ADR 026 for more information. // // The following must always be true: -// - The substitute client is the same type as the subject client -// - The subject and substitute client states match in all parameters (expect frozen height, latest height, and chain-id) +// - The substitute client is the same type as the subject client +// - The subject and substitute client states match in all parameters (expect frozen height, latest height, and chain-id) // // In case 1) before updating the client, the client will be unfrozen by resetting // the FrozenHeight to the zero Height. func (cs ClientState) CheckSubstituteAndUpdateState( ctx sdk.Context, cdc codec.BinaryCodec, subjectClientStore, substituteClientStore sdk.KVStore, substituteClient exported.ClientState, -) (exported.ClientState, error) { +) error { substituteClientState, ok := substituteClient.(*ClientState) if !ok { - return nil, sdkerrors.Wrapf( - clienttypes.ErrInvalidClient, "expected type %T, got %T", &ClientState{}, substituteClient, - ) + return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "expected type %T, got %T", &ClientState{}, substituteClient) } if !IsMatchingClientState(cs, *substituteClientState) { - return nil, sdkerrors.Wrap(clienttypes.ErrInvalidSubstitute, "subject client state does not match substitute client state") + return errorsmod.Wrap(clienttypes.ErrInvalidSubstitute, "subject client state does not match substitute client state") } if cs.Status(ctx, subjectClientStore, cdc) == exported.Frozen { @@ -48,22 +46,22 @@ func (cs ClientState) CheckSubstituteAndUpdateState( // starting from initial height and ending on the latest height (inclusive) height := substituteClientState.GetLatestHeight() - consensusState, err := GetConsensusState(substituteClientStore, cdc, height) - if err != nil { - return nil, sdkerrors.Wrap(err, "unable to retrieve latest consensus state for substitute client") + consensusState, found := GetConsensusState(substituteClientStore, cdc, height) + if !found { + return errorsmod.Wrap(clienttypes.ErrConsensusStateNotFound, "unable to retrieve latest consensus state for substitute client") } - SetConsensusState(subjectClientStore, cdc, consensusState, height) + setConsensusState(subjectClientStore, cdc, consensusState, height) // set metadata stored for the substitute consensus state processedHeight, found := GetProcessedHeight(substituteClientStore, height) if !found { - return nil, sdkerrors.Wrap(clienttypes.ErrUpdateClientFailed, "unable to retrieve processed height for substitute client latest height") + return errorsmod.Wrap(clienttypes.ErrUpdateClientFailed, "unable to retrieve processed height for substitute client latest height") } processedTime, found := GetProcessedTime(substituteClientStore, height) if !found { - return nil, sdkerrors.Wrap(clienttypes.ErrUpdateClientFailed, "unable to retrieve processed time for substitute client latest height") + return errorsmod.Wrap(clienttypes.ErrUpdateClientFailed, "unable to retrieve processed time for substitute client latest height") } setConsensusMetadataWithValues(subjectClientStore, height, processedHeight, processedTime) @@ -76,8 +74,9 @@ func (cs ClientState) CheckSubstituteAndUpdateState( // no validation is necessary since the substitute is verified to be Active // in 02-client. + setClientState(subjectClientStore, cdc, &cs) - return &cs, nil + return nil } // IsMatchingClientState returns true if all the client state parameters match diff --git a/modules/light-clients/07-tendermint/types/proposal_handle_test.go b/modules/light-clients/07-tendermint/proposal_handle_test.go similarity index 65% rename from modules/light-clients/07-tendermint/types/proposal_handle_test.go rename to modules/light-clients/07-tendermint/proposal_handle_test.go index bdd2d98ead5..e6c3ef7d906 100644 --- a/modules/light-clients/07-tendermint/types/proposal_handle_test.go +++ b/modules/light-clients/07-tendermint/proposal_handle_test.go @@ -1,12 +1,12 @@ -package types_test +package tendermint_test import ( "time" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/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/ibc-go/v7/testing" ) var frozenHeight = clienttypes.NewHeight(0, 1) @@ -28,13 +28,13 @@ func (suite *TendermintTestSuite) TestCheckSubstituteUpdateStateBasic() { { "non-matching substitute", func() { suite.coordinator.SetupClients(substitutePath) - substituteClientState, ok := suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*types.ClientState) + substituteClientState, ok := suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*ibctm.ClientState) suite.Require().True(ok) // change trusting period so that test should fail substituteClientState.TrustingPeriod = time.Hour * 24 * 7 tmClientState := substituteClientState - tmClientState.ChainId = tmClientState.ChainId + "different chain" + tmClientState.ChainId += "different chain" }, }, } @@ -48,7 +48,7 @@ func (suite *TendermintTestSuite) TestCheckSubstituteUpdateStateBasic() { substitutePath = ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(subjectPath) - subjectClientState := suite.chainA.GetClientState(subjectPath.EndpointA.ClientID).(*types.ClientState) + subjectClientState := suite.chainA.GetClientState(subjectPath.EndpointA.ClientID).(*ibctm.ClientState) // expire subject client suite.coordinator.IncrementTimeBy(subjectClientState.TrustingPeriod) @@ -59,50 +59,26 @@ func (suite *TendermintTestSuite) TestCheckSubstituteUpdateStateBasic() { subjectClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), subjectPath.EndpointA.ClientID) substituteClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), substitutePath.EndpointA.ClientID) - updatedClient, err := subjectClientState.CheckSubstituteAndUpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), subjectClientStore, substituteClientStore, substituteClientState) + err := subjectClientState.CheckSubstituteAndUpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), subjectClientStore, substituteClientStore, substituteClientState) suite.Require().Error(err) - suite.Require().Nil(updatedClient) }) } } -// to expire clients, time needs to be fast forwarded on both chainA and chainB. -// this is to prevent headers from failing when attempting to update later. func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() { testCases := []struct { name string FreezeClient bool - ExpireClient bool expPass bool }{ { - name: "PASS: update checks are deprecated, client is frozen and expired", - FreezeClient: true, - ExpireClient: true, - expPass: true, - }, - { - name: "PASS: update checks are deprecated, not frozen or expired", - FreezeClient: false, - ExpireClient: false, - expPass: true, - }, - { - name: "PASS: update checks are deprecated, not frozen or expired", + name: "PASS: update checks are deprecated, client is not frozen", FreezeClient: false, - ExpireClient: false, expPass: true, }, { name: "PASS: update checks are deprecated, client is frozen", FreezeClient: true, - ExpireClient: false, - expPass: true, - }, - { - name: "PASS: update checks are deprecated, client is expired", - FreezeClient: false, - ExpireClient: true, expPass: true, }, } @@ -110,37 +86,23 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() { for _, tc := range testCases { tc := tc - // for each test case a header used for unexpiring clients and unfreezing - // a client are each tested to ensure that unexpiry headers cannot update - // a client when a unfreezing header is required. suite.Run(tc.name, func() { - // start by testing unexpiring the client suite.SetupTest() // reset // construct subject using test case parameters subjectPath := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(subjectPath) - subjectClientState := suite.chainA.GetClientState(subjectPath.EndpointA.ClientID).(*types.ClientState) + subjectClientState := suite.chainA.GetClientState(subjectPath.EndpointA.ClientID).(*ibctm.ClientState) - // apply freezing or expiry as determined by the test case if tc.FreezeClient { subjectClientState.FrozenHeight = frozenHeight } - if tc.ExpireClient { - // expire subject client - suite.coordinator.IncrementTimeBy(subjectClientState.TrustingPeriod) - suite.coordinator.CommitBlock(suite.chainA, suite.chainB) - } // construct the substitute to match the subject client - // NOTE: the substitute is explicitly created after the freezing or expiry occurs, - // primarily to prevent the substitute from becoming frozen. It also should be - // the natural flow of events in practice. The subject will become frozen/expired - // and a substitute will be created along with a governance proposal as a response substitutePath := ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(substitutePath) - substituteClientState := suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*types.ClientState) + substituteClientState := suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*ibctm.ClientState) // update trusting period of substitute client state substituteClientState.TrustingPeriod = time.Hour * 24 * 7 suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitutePath.EndpointA.ClientID, substituteClientState) @@ -154,7 +116,7 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() { } // get updated substitute - substituteClientState = suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*types.ClientState) + substituteClientState = suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*ibctm.ClientState) // test that subject gets updated chain-id newChainID := "new-chain-id" @@ -164,39 +126,40 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() { substituteClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), substitutePath.EndpointA.ClientID) expectedConsState := substitutePath.EndpointA.GetConsensusState(substituteClientState.GetLatestHeight()) - expectedProcessedTime, found := types.GetProcessedTime(substituteClientStore, substituteClientState.GetLatestHeight()) + expectedProcessedTime, found := ibctm.GetProcessedTime(substituteClientStore, substituteClientState.GetLatestHeight()) suite.Require().True(found) - expectedProcessedHeight, found := types.GetProcessedTime(substituteClientStore, substituteClientState.GetLatestHeight()) + expectedProcessedHeight, found := ibctm.GetProcessedTime(substituteClientStore, substituteClientState.GetLatestHeight()) suite.Require().True(found) - expectedIterationKey := types.GetIterationKey(substituteClientStore, substituteClientState.GetLatestHeight()) + expectedIterationKey := ibctm.GetIterationKey(substituteClientStore, substituteClientState.GetLatestHeight()) - updatedClient, err := subjectClientState.CheckSubstituteAndUpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), subjectClientStore, substituteClientStore, substituteClientState) + err := subjectClientState.CheckSubstituteAndUpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), subjectClientStore, substituteClientStore, substituteClientState) if tc.expPass { suite.Require().NoError(err) - suite.Require().Equal(clienttypes.ZeroHeight(), updatedClient.(*types.ClientState).FrozenHeight) + + updatedClient := subjectPath.EndpointA.GetClientState() + suite.Require().Equal(clienttypes.ZeroHeight(), updatedClient.(*ibctm.ClientState).FrozenHeight) subjectClientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), subjectPath.EndpointA.ClientID) // check that the correct consensus state was copied over suite.Require().Equal(substituteClientState.GetLatestHeight(), updatedClient.GetLatestHeight()) subjectConsState := subjectPath.EndpointA.GetConsensusState(updatedClient.GetLatestHeight()) - subjectProcessedTime, found := types.GetProcessedTime(subjectClientStore, updatedClient.GetLatestHeight()) + subjectProcessedTime, found := ibctm.GetProcessedTime(subjectClientStore, updatedClient.GetLatestHeight()) suite.Require().True(found) - subjectProcessedHeight, found := types.GetProcessedTime(substituteClientStore, updatedClient.GetLatestHeight()) + subjectProcessedHeight, found := ibctm.GetProcessedTime(substituteClientStore, updatedClient.GetLatestHeight()) suite.Require().True(found) - subjectIterationKey := types.GetIterationKey(substituteClientStore, updatedClient.GetLatestHeight()) + subjectIterationKey := ibctm.GetIterationKey(substituteClientStore, updatedClient.GetLatestHeight()) suite.Require().Equal(expectedConsState, subjectConsState) suite.Require().Equal(expectedProcessedTime, subjectProcessedTime) suite.Require().Equal(expectedProcessedHeight, subjectProcessedHeight) suite.Require().Equal(expectedIterationKey, subjectIterationKey) - suite.Require().Equal(newChainID, updatedClient.(*types.ClientState).ChainId) - suite.Require().Equal(time.Hour*24*7, updatedClient.(*types.ClientState).TrustingPeriod) + suite.Require().Equal(newChainID, updatedClient.(*ibctm.ClientState).ChainId) + suite.Require().Equal(time.Hour*24*7, updatedClient.(*ibctm.ClientState).TrustingPeriod) } else { suite.Require().Error(err) - suite.Require().Nil(updatedClient) } }) } @@ -205,7 +168,7 @@ func (suite *TendermintTestSuite) TestCheckSubstituteAndUpdateState() { func (suite *TendermintTestSuite) TestIsMatchingClientState() { var ( subjectPath, substitutePath *ibctesting.Path - subjectClientState, substituteClientState *types.ClientState + subjectClientState, substituteClientState *ibctm.ClientState ) testCases := []struct { @@ -215,8 +178,8 @@ func (suite *TendermintTestSuite) TestIsMatchingClientState() { }{ { "matching clients", func() { - subjectClientState = suite.chainA.GetClientState(subjectPath.EndpointA.ClientID).(*types.ClientState) - substituteClientState = suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*types.ClientState) + subjectClientState = suite.chainA.GetClientState(subjectPath.EndpointA.ClientID).(*ibctm.ClientState) + substituteClientState = suite.chainA.GetClientState(substitutePath.EndpointA.ClientID).(*ibctm.ClientState) }, true, }, { @@ -239,14 +202,14 @@ func (suite *TendermintTestSuite) TestIsMatchingClientState() { }, { "matching, trusting period is different", func() { - subjectClientState.TrustingPeriod = time.Duration(time.Hour * 10) - substituteClientState.TrustingPeriod = time.Duration(time.Hour * 1) + subjectClientState.TrustingPeriod = time.Hour * 10 + substituteClientState.TrustingPeriod = time.Hour * 1 }, true, }, { "not matching, trust level is different", func() { - subjectClientState.TrustLevel = types.Fraction{2, 3} - substituteClientState.TrustLevel = types.Fraction{1, 3} + subjectClientState.TrustLevel = ibctm.Fraction{2, 3} + substituteClientState.TrustLevel = ibctm.Fraction{1, 3} }, false, }, } @@ -264,7 +227,7 @@ func (suite *TendermintTestSuite) TestIsMatchingClientState() { tc.malleate() - suite.Require().Equal(tc.expPass, types.IsMatchingClientState(*subjectClientState, *substituteClientState)) + suite.Require().Equal(tc.expPass, ibctm.IsMatchingClientState(*subjectClientState, *substituteClientState)) }) } } diff --git a/modules/light-clients/07-tendermint/types/store.go b/modules/light-clients/07-tendermint/store.go similarity index 89% rename from modules/light-clients/07-tendermint/types/store.go rename to modules/light-clients/07-tendermint/store.go index 1c1157f65de..8f992bc5183 100644 --- a/modules/light-clients/07-tendermint/types/store.go +++ b/modules/light-clients/07-tendermint/store.go @@ -1,4 +1,4 @@ -package types +package tendermint import ( "bytes" @@ -8,11 +8,10 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) /* @@ -43,38 +42,30 @@ var ( KeyIteration = []byte("/iterationKey") ) -// SetConsensusState stores the consensus state at the given height. -func SetConsensusState(clientStore sdk.KVStore, cdc codec.BinaryCodec, consensusState *ConsensusState, height exported.Height) { +// setClientState stores the client state +func setClientState(clientStore sdk.KVStore, cdc codec.BinaryCodec, clientState *ClientState) { + key := host.ClientStateKey() + val := clienttypes.MustMarshalClientState(cdc, clientState) + clientStore.Set(key, val) +} + +// setConsensusState stores the consensus state at the given height. +func setConsensusState(clientStore sdk.KVStore, cdc codec.BinaryCodec, consensusState *ConsensusState, height exported.Height) { key := host.ConsensusStateKey(height) val := clienttypes.MustMarshalConsensusState(cdc, consensusState) clientStore.Set(key, val) } -// GetConsensusState retrieves the consensus state from the client prefixed -// store. An error is returned if the consensus state does not exist. -func GetConsensusState(store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height) (*ConsensusState, error) { +// GetConsensusState retrieves the consensus state from the client prefixed store. +// If the ConsensusState does not exist in state for the provided height a nil value and false boolean flag is returned +func GetConsensusState(store sdk.KVStore, cdc codec.BinaryCodec, height exported.Height) (*ConsensusState, bool) { bz := store.Get(host.ConsensusStateKey(height)) - if bz == nil { - return nil, sdkerrors.Wrapf( - clienttypes.ErrConsensusStateNotFound, - "consensus state does not exist for height %s", height, - ) - } - - consensusStateI, err := clienttypes.UnmarshalConsensusState(cdc, bz) - if err != nil { - return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "unmarshal error: %v", err) - } - - consensusState, ok := consensusStateI.(*ConsensusState) - if !ok { - return nil, sdkerrors.Wrapf( - clienttypes.ErrInvalidConsensus, - "invalid consensus type %T, expected %T", consensusState, &ConsensusState{}, - ) + if len(bz) == 0 { + return nil, false } - return consensusState, nil + consensusStateI := clienttypes.MustUnmarshalConsensusState(cdc, bz) + return consensusStateI.(*ConsensusState), true } // deleteConsensusState deletes the consensus state at the given height @@ -109,11 +100,11 @@ func IterateConsensusMetadata(store sdk.KVStore, cb func(key, val []byte) bool) } // iterate over iteration keys - iterator = sdk.KVStorePrefixIterator(store, []byte(KeyIterateConsensusStatePrefix)) + iter := sdk.KVStorePrefixIterator(store, []byte(KeyIterateConsensusStatePrefix)) - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - if cb(iterator.Key(), iterator.Value()) { + defer iter.Close() + for ; iter.Valid(); iter.Next() { + if cb(iter.Key(), iter.Value()) { break } } @@ -138,7 +129,7 @@ func SetProcessedTime(clientStore sdk.KVStore, height exported.Height, timeNs ui func GetProcessedTime(clientStore sdk.KVStore, height exported.Height) (uint64, bool) { key := ProcessedTimeKey(height) bz := clientStore.Get(key) - if bz == nil { + if len(bz) == 0 { return 0, false } return sdk.BigEndianToUint64(bz), true @@ -169,7 +160,7 @@ func SetProcessedHeight(clientStore sdk.KVStore, consHeight, processedHeight exp func GetProcessedHeight(clientStore sdk.KVStore, height exported.Height) (exported.Height, bool) { key := ProcessedHeightKey(height) bz := clientStore.Get(key) - if bz == nil { + if len(bz) == 0 { return nil, false } processedHeight, err := clienttypes.ParseHeight(string(bz)) @@ -224,7 +215,7 @@ func GetHeightFromIterationKey(iterKey []byte) exported.Height { // IterateConsensusStateAscending iterates through the consensus states in ascending order. It calls the provided // callback on each height, until stop=true is returned. -func IterateConsensusStateAscending(clientStore sdk.KVStore, cb func(height exported.Height) (stop bool)) error { +func IterateConsensusStateAscending(clientStore sdk.KVStore, cb func(height exported.Height) (stop bool)) { iterator := sdk.KVStorePrefixIterator(clientStore, []byte(KeyIterateConsensusStatePrefix)) defer iterator.Close() @@ -232,10 +223,9 @@ func IterateConsensusStateAscending(clientStore sdk.KVStore, cb func(height expo iterKey := iterator.Key() height := GetHeightFromIterationKey(iterKey) if cb(height) { - return nil + break } } - return nil } // GetNextConsensusState returns the lowest consensus state that is larger than the given height. @@ -283,17 +273,16 @@ func GetPreviousConsensusState(clientStore sdk.KVStore, cdc codec.BinaryCodec, h // PruneAllExpiredConsensusStates iterates over all consensus states for a given // client store. If a consensus state is expired, it is deleted and its metadata -// is deleted. +// is deleted. The number of consensus states pruned is returned. func PruneAllExpiredConsensusStates( ctx sdk.Context, clientStore sdk.KVStore, cdc codec.BinaryCodec, clientState *ClientState, -) (err error) { +) int { var heights []exported.Height pruneCb := func(height exported.Height) bool { - consState, err := GetConsensusState(clientStore, cdc, height) - // this error should never occur - if err != nil { + consState, found := GetConsensusState(clientStore, cdc, height) + if !found { // consensus state should always be found return true } @@ -305,22 +294,19 @@ func PruneAllExpiredConsensusStates( } IterateConsensusStateAscending(clientStore, pruneCb) - if err != nil { - return err - } for _, height := range heights { deleteConsensusState(clientStore, height) deleteConsensusMetadata(clientStore, height) } - return nil + return len(heights) } // Helper function for GetNextConsensusState and GetPreviousConsensusState func getTmConsensusState(clientStore sdk.KVStore, cdc codec.BinaryCodec, key []byte) (*ConsensusState, bool) { bz := clientStore.Get(key) - if bz == nil { + if len(bz) == 0 { return nil, false } diff --git a/modules/light-clients/07-tendermint/types/store_test.go b/modules/light-clients/07-tendermint/store_test.go similarity index 58% rename from modules/light-clients/07-tendermint/types/store_test.go rename to modules/light-clients/07-tendermint/store_test.go index af003ba442d..9aa24613431 100644 --- a/modules/light-clients/07-tendermint/types/store_test.go +++ b/modules/light-clients/07-tendermint/store_test.go @@ -1,16 +1,16 @@ -package types_test +package tendermint_test import ( "math" "time" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - solomachinetypes "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func (suite *TendermintTestSuite) TestGetConsensusState() { @@ -23,31 +23,32 @@ func (suite *TendermintTestSuite) TestGetConsensusState() { name string malleate func() expPass bool + expPanic bool }{ { - "success", func() {}, true, + "success", func() {}, true, false, }, { "consensus state not found", func() { // use height with no consensus state set height = height.(clienttypes.Height).Increment() - }, false, + }, false, false, }, { "not a consensus state interface", func() { // marshal an empty client state and set as consensus state store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - clientStateBz := suite.chainA.App.GetIBCKeeper().ClientKeeper.MustMarshalClientState(&types.ClientState{}) + clientStateBz := suite.chainA.App.GetIBCKeeper().ClientKeeper.MustMarshalClientState(&tendermint.ClientState{}) store.Set(host.ConsensusStateKey(height), clientStateBz) - }, false, + }, false, true, }, { "invalid consensus state (solomachine)", func() { // marshal and set solomachine consensus state store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - consensusStateBz := suite.chainA.App.GetIBCKeeper().ClientKeeper.MustMarshalConsensusState(&solomachinetypes.ConsensusState{}) + consensusStateBz := suite.chainA.App.GetIBCKeeper().ClientKeeper.MustMarshalConsensusState(&solomachine.ConsensusState{}) store.Set(host.ConsensusStateKey(height), consensusStateBz) - }, false, + }, false, true, }, } @@ -64,16 +65,26 @@ func (suite *TendermintTestSuite) TestGetConsensusState() { tc.malleate() // change vars as necessary + if tc.expPanic { + suite.Require().Panics(func() { + store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + tendermint.GetConsensusState(store, suite.chainA.Codec, height) + }) + + return + } + store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - consensusState, err := types.GetConsensusState(store, suite.chainA.Codec, height) + consensusState, found := tendermint.GetConsensusState(store, suite.chainA.Codec, height) if tc.expPass { - suite.Require().NoError(err) + suite.Require().True(found) + expConsensusState, found := suite.chainA.GetConsensusState(path.EndpointA.ClientID, height) suite.Require().True(found) suite.Require().Equal(expConsensusState, consensusState) } else { - suite.Require().Error(err) + suite.Require().False(found) suite.Require().Nil(consensusState) } }) @@ -96,7 +107,7 @@ func (suite *TendermintTestSuite) TestGetProcessedTime() { height := clientState.GetLatestHeight() store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - actualTime, ok := types.GetProcessedTime(store, height) + actualTime, ok := tendermint.GetProcessedTime(store, height) suite.Require().True(ok, "could not retrieve processed time for stored consensus state") suite.Require().Equal(uint64(expectedTime.UnixNano()), actualTime, "retrieved processed time is not expected value") @@ -112,12 +123,12 @@ func (suite *TendermintTestSuite) TestGetProcessedTime() { height = clientState.GetLatestHeight() store = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - actualTime, ok = types.GetProcessedTime(store, height) + actualTime, ok = tendermint.GetProcessedTime(store, height) suite.Require().True(ok, "could not retrieve processed time for stored consensus state") suite.Require().Equal(uint64(expectedTime.UnixNano()), actualTime, "retrieved processed time is not expected value") // try to get processed time for height that doesn't exist in store - _, ok = types.GetProcessedTime(store, clienttypes.NewHeight(1, 1)) + _, ok = tendermint.GetProcessedTime(store, clienttypes.NewHeight(1, 1)) suite.Require().False(ok, "retrieved processed time for a non-existent consensus state") } @@ -129,8 +140,8 @@ func (suite *TendermintTestSuite) TestIterationKey() { clienttypes.NewHeight(math.MaxUint64, math.MaxUint64), } for _, h := range testHeights { - k := types.IterationKey(h) - retrievedHeight := types.GetHeightFromIterationKey(k) + k := tendermint.IterationKey(h) + retrievedHeight := tendermint.GetHeightFromIterationKey(k) suite.Require().Equal(h, retrievedHeight, "retrieving height from iteration key failed") } } @@ -139,16 +150,16 @@ func (suite *TendermintTestSuite) TestIterateConsensusStates() { nextValsHash := []byte("nextVals") // Set iteration keys and consensus states - types.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(0, 1)) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(0, 1), types.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash0-1")), nextValsHash)) - types.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(4, 9)) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(4, 9), types.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash4-9")), nextValsHash)) - types.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(0, 10)) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(0, 10), types.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash0-10")), nextValsHash)) - types.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(0, 4)) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(0, 4), types.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash0-4")), nextValsHash)) - types.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(40, 1)) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(40, 1), types.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash40-1")), nextValsHash)) + tendermint.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(0, 1)) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(0, 1), tendermint.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash0-1")), nextValsHash)) + tendermint.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(4, 9)) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(4, 9), tendermint.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash4-9")), nextValsHash)) + tendermint.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(0, 10)) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(0, 10), tendermint.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash0-10")), nextValsHash)) + tendermint.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(0, 4)) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(0, 4), tendermint.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash0-4")), nextValsHash)) + tendermint.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), clienttypes.NewHeight(40, 1)) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", clienttypes.NewHeight(40, 1), tendermint.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("hash40-1")), nextValsHash)) var testArr []string cb := func(height exported.Height) bool { @@ -156,39 +167,39 @@ func (suite *TendermintTestSuite) TestIterateConsensusStates() { return false } - types.IterateConsensusStateAscending(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), cb) + tendermint.IterateConsensusStateAscending(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), cb) expectedArr := []string{"0-1", "0-4", "0-10", "4-9", "40-1"} suite.Require().Equal(expectedArr, testArr) } func (suite *TendermintTestSuite) TestGetNeighboringConsensusStates() { nextValsHash := []byte("nextVals") - cs01 := types.NewConsensusState(time.Now().UTC(), commitmenttypes.NewMerkleRoot([]byte("hash0-1")), nextValsHash) - cs04 := types.NewConsensusState(time.Now().UTC(), commitmenttypes.NewMerkleRoot([]byte("hash0-4")), nextValsHash) - cs49 := types.NewConsensusState(time.Now().UTC(), commitmenttypes.NewMerkleRoot([]byte("hash4-9")), nextValsHash) + cs01 := tendermint.NewConsensusState(time.Now().UTC(), commitmenttypes.NewMerkleRoot([]byte("hash0-1")), nextValsHash) + cs04 := tendermint.NewConsensusState(time.Now().UTC(), commitmenttypes.NewMerkleRoot([]byte("hash0-4")), nextValsHash) + cs49 := tendermint.NewConsensusState(time.Now().UTC(), commitmenttypes.NewMerkleRoot([]byte("hash4-9")), nextValsHash) height01 := clienttypes.NewHeight(0, 1) height04 := clienttypes.NewHeight(0, 4) height49 := clienttypes.NewHeight(4, 9) // Set iteration keys and consensus states - types.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), height01) + tendermint.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), height01) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", height01, cs01) - types.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), height04) + tendermint.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), height04) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", height04, cs04) - types.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), height49) + tendermint.SetIterationKey(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), height49) suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), "testClient", height49, cs49) - prevCs01, ok := types.GetPreviousConsensusState(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), suite.chainA.Codec, height01) + prevCs01, ok := tendermint.GetPreviousConsensusState(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), suite.chainA.Codec, height01) suite.Require().Nil(prevCs01, "consensus state exists before lowest consensus state") suite.Require().False(ok) - prevCs49, ok := types.GetPreviousConsensusState(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), suite.chainA.Codec, height49) + prevCs49, ok := tendermint.GetPreviousConsensusState(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), suite.chainA.Codec, height49) suite.Require().Equal(cs04, prevCs49, "previous consensus state is not returned correctly") suite.Require().True(ok) - nextCs01, ok := types.GetNextConsensusState(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), suite.chainA.Codec, height01) + nextCs01, ok := tendermint.GetNextConsensusState(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), suite.chainA.Codec, height01) suite.Require().Equal(cs04, nextCs01, "next consensus state not returned correctly") suite.Require().True(ok) - nextCs49, ok := types.GetNextConsensusState(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), suite.chainA.Codec, height49) + nextCs49, ok := tendermint.GetNextConsensusState(suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), "testClient"), suite.chainA.Codec, height49) suite.Require().Nil(nextCs49, "next consensus state exists after highest consensus state") suite.Require().False(ok) } diff --git a/modules/light-clients/07-tendermint/types/tendermint.pb.go b/modules/light-clients/07-tendermint/tendermint.pb.go similarity index 84% rename from modules/light-clients/07-tendermint/types/tendermint.pb.go rename to modules/light-clients/07-tendermint/tendermint.pb.go index 3c34c10a9ad..dcff8304099 100644 --- a/modules/light-clients/07-tendermint/types/tendermint.pb.go +++ b/modules/light-clients/07-tendermint/tendermint.pb.go @@ -1,16 +1,16 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: ibc/lightclients/tendermint/v1/tendermint.proto -package types +package tendermint import ( fmt "fmt" - _go "github.com/confio/ics23/go" - types "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - types1 "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + types "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + types1 "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + _go "github.com/cosmos/ics23/go" github_com_tendermint_tendermint_libs_bytes "github.com/tendermint/tendermint/libs/bytes" types2 "github.com/tendermint/tendermint/proto/tendermint/types" _ "google.golang.org/protobuf/types/known/durationpb" @@ -144,7 +144,8 @@ var xxx_messageInfo_ConsensusState proto.InternalMessageInfo // Misbehaviour is a wrapper over two conflicting Headers // that implements Misbehaviour interface expected by ICS-02 type Misbehaviour struct { - ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` + // ClientID is deprecated + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` // Deprecated: Do not use. Header1 *Header `protobuf:"bytes,2,opt,name=header_1,json=header1,proto3" json:"header_1,omitempty" yaml:"header_1"` Header2 *Header `protobuf:"bytes,3,opt,name=header_2,json=header2,proto3" json:"header_2,omitempty" yaml:"header_2"` } @@ -322,75 +323,76 @@ func init() { } var fileDescriptor_c6d6cf2b288949be = []byte{ - // 1082 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcf, 0x6f, 0xe3, 0xc4, - 0x17, 0x6f, 0xda, 0x7e, 0xb7, 0xc9, 0x24, 0xdd, 0xf6, 0x6b, 0x4a, 0x37, 0x2d, 0xdd, 0x38, 0x32, - 0x52, 0xc9, 0x81, 0xda, 0x24, 0xbb, 0x12, 0x52, 0xc5, 0x05, 0x77, 0x17, 0xb5, 0x88, 0x95, 0x2a, - 0x97, 0x1f, 0x12, 0x12, 0x32, 0x13, 0x7b, 0x92, 0x8c, 0xd6, 0xf6, 0x58, 0x9e, 0x49, 0x68, 0xf9, - 0x0b, 0xe0, 0x80, 0xb4, 0x47, 0xc4, 0x89, 0x03, 0x7f, 0xcc, 0x1e, 0x7b, 0xe4, 0x64, 0x50, 0x7b, - 0xe5, 0x94, 0x23, 0x27, 0x34, 0x3f, 0x6c, 0x4f, 0xb3, 0x5d, 0xaa, 0xe5, 0x12, 0xcd, 0x7b, 0xef, - 0xf3, 0x3e, 0x9f, 0xcc, 0x9b, 0x37, 0x6f, 0x0c, 0x1c, 0x3c, 0x0c, 0x9c, 0x08, 0x8f, 0x27, 0x2c, - 0x88, 0x30, 0x4a, 0x18, 0x75, 0x18, 0x4a, 0x42, 0x94, 0xc5, 0x38, 0x61, 0xce, 0xac, 0xaf, 0x59, - 0x76, 0x9a, 0x11, 0x46, 0x8c, 0x0e, 0x1e, 0x06, 0xb6, 0x9e, 0x60, 0x6b, 0x90, 0x59, 0x7f, 0xb7, - 0xab, 0xe5, 0xb3, 0x8b, 0x14, 0x51, 0x67, 0x06, 0x23, 0x1c, 0x42, 0x46, 0x32, 0xc9, 0xb0, 0xbb, - 0xf7, 0x0a, 0x42, 0xfc, 0xaa, 0x68, 0x2b, 0xcd, 0x08, 0x19, 0x15, 0x56, 0x67, 0x4c, 0xc8, 0x38, - 0x42, 0x8e, 0xb0, 0x86, 0xd3, 0x91, 0x13, 0x4e, 0x33, 0xc8, 0x30, 0x49, 0x54, 0xdc, 0x5c, 0x8c, - 0x33, 0x1c, 0x23, 0xca, 0x60, 0x9c, 0x16, 0x00, 0xbe, 0xbf, 0x80, 0x64, 0xc8, 0x91, 0x7f, 0x97, - 0xef, 0x49, 0xae, 0x14, 0xe0, 0xbd, 0x0a, 0x40, 0xe2, 0x18, 0xb3, 0xb8, 0x00, 0x95, 0x96, 0x02, - 0x6e, 0x8d, 0xc9, 0x98, 0x88, 0xa5, 0xc3, 0x57, 0xd2, 0x6b, 0xfd, 0xb5, 0x06, 0x9a, 0x47, 0x82, - 0xef, 0x8c, 0x41, 0x86, 0x8c, 0x1d, 0x50, 0x0f, 0x26, 0x10, 0x27, 0x3e, 0x0e, 0xdb, 0xb5, 0x6e, - 0xad, 0xd7, 0xf0, 0xd6, 0x84, 0x7d, 0x12, 0x1a, 0x08, 0x34, 0x59, 0x36, 0xa5, 0xcc, 0x8f, 0xd0, - 0x0c, 0x45, 0xed, 0xe5, 0x6e, 0xad, 0xd7, 0x1c, 0xf4, 0xec, 0x7f, 0xaf, 0xa7, 0xfd, 0x49, 0x06, - 0x03, 0xbe, 0x61, 0x77, 0xf7, 0x65, 0x6e, 0x2e, 0xcd, 0x73, 0xd3, 0xb8, 0x80, 0x71, 0x74, 0x68, - 0x69, 0x54, 0x96, 0x07, 0x84, 0xf5, 0x19, 0x37, 0x8c, 0x11, 0xd8, 0x10, 0x16, 0x4e, 0xc6, 0x7e, - 0x8a, 0x32, 0x4c, 0xc2, 0xf6, 0x8a, 0x90, 0xda, 0xb1, 0x65, 0xb1, 0xec, 0xa2, 0x58, 0xf6, 0x13, - 0x55, 0x4c, 0xd7, 0x52, 0xdc, 0xdb, 0x1a, 0x77, 0x95, 0x6f, 0xfd, 0xfc, 0x87, 0x59, 0xf3, 0xee, - 0x17, 0xde, 0x53, 0xe1, 0x34, 0x30, 0xd8, 0x9c, 0x26, 0x43, 0x92, 0x84, 0x9a, 0xd0, 0xea, 0x5d, - 0x42, 0xef, 0x2a, 0xa1, 0x07, 0x52, 0x68, 0x91, 0x40, 0x2a, 0x6d, 0x94, 0x6e, 0x25, 0x85, 0xc0, - 0x46, 0x0c, 0xcf, 0xfd, 0x20, 0x22, 0xc1, 0x73, 0x3f, 0xcc, 0xf0, 0x88, 0xb5, 0xff, 0xf7, 0x86, - 0x5b, 0x5a, 0xc8, 0x97, 0x42, 0xeb, 0x31, 0x3c, 0x3f, 0xe2, 0xce, 0x27, 0xdc, 0x67, 0x7c, 0x03, - 0xd6, 0x47, 0x19, 0xf9, 0x1e, 0x25, 0xfe, 0x04, 0xf1, 0x03, 0x69, 0xdf, 0x13, 0x22, 0xbb, 0xe2, - 0x88, 0x78, 0x8b, 0xd8, 0xaa, 0x73, 0x66, 0x7d, 0xfb, 0x58, 0x20, 0xdc, 0x3d, 0xa5, 0xb2, 0x25, - 0x55, 0x6e, 0xa4, 0x5b, 0x5e, 0x4b, 0xda, 0x12, 0xcb, 0xe9, 0x23, 0xc8, 0x10, 0x65, 0x05, 0xfd, - 0xda, 0x9b, 0xd2, 0xdf, 0x48, 0xb7, 0xbc, 0x96, 0xb4, 0x15, 0xfd, 0x09, 0x68, 0x8a, 0xab, 0xe3, - 0xd3, 0x14, 0x05, 0xb4, 0x5d, 0xef, 0xae, 0xf4, 0x9a, 0x83, 0x4d, 0x1b, 0x07, 0x74, 0xf0, 0xc8, - 0x3e, 0xe5, 0x91, 0xb3, 0x14, 0x05, 0xee, 0x76, 0xd5, 0x42, 0x1a, 0xdc, 0xf2, 0x40, 0x5a, 0x40, - 0xa8, 0x71, 0x08, 0x5a, 0xd3, 0x74, 0x9c, 0xc1, 0x10, 0xf9, 0x29, 0x64, 0x93, 0x76, 0xa3, 0xbb, - 0xd2, 0x6b, 0xb8, 0x0f, 0xe6, 0xb9, 0xf9, 0x96, 0x3a, 0x37, 0x2d, 0x6a, 0x79, 0x4d, 0x65, 0x9e, - 0x42, 0x36, 0x31, 0x20, 0xd8, 0x81, 0x51, 0x44, 0xbe, 0xf3, 0xa7, 0x69, 0x08, 0x19, 0xf2, 0xe1, - 0x88, 0xa1, 0xcc, 0x47, 0xe7, 0x29, 0xce, 0x2e, 0xda, 0xa0, 0x5b, 0xeb, 0xd5, 0xdd, 0xfd, 0x79, - 0x6e, 0x76, 0x25, 0xd1, 0x6b, 0xa1, 0x56, 0xbb, 0xe6, 0x6d, 0x8b, 0xe8, 0x17, 0x22, 0xf8, 0x31, - 0x8f, 0x3d, 0x15, 0x21, 0x83, 0x02, 0xf3, 0x96, 0xbc, 0x18, 0xd3, 0x21, 0x9a, 0xc0, 0x19, 0x26, - 0xd3, 0xac, 0xdd, 0x14, 0x42, 0xef, 0xcf, 0x73, 0x73, 0xff, 0xb5, 0x42, 0x7a, 0x02, 0x97, 0xdb, - 0x5b, 0x94, 0x7b, 0xa6, 0x01, 0x0e, 0x57, 0x7f, 0xf8, 0xd5, 0x5c, 0xb2, 0x7e, 0x5b, 0x06, 0xf7, - 0x8f, 0x48, 0x42, 0x51, 0x42, 0xa7, 0x54, 0xde, 0x78, 0x17, 0x34, 0xca, 0xa1, 0x23, 0xae, 0x3c, - 0x3f, 0xd2, 0xc5, 0xb6, 0xfc, 0xbc, 0x40, 0xb8, 0x75, 0x7e, 0xa4, 0x2f, 0x78, 0xf7, 0x55, 0x69, - 0xc6, 0x47, 0x60, 0x35, 0x23, 0x84, 0xa9, 0x99, 0x60, 0x69, 0x1d, 0x51, 0x4d, 0xa1, 0x59, 0xdf, - 0x7e, 0x86, 0xb2, 0xe7, 0x11, 0xf2, 0x08, 0x61, 0xee, 0x2a, 0xa7, 0xf1, 0x44, 0x96, 0xf1, 0x63, - 0x0d, 0x6c, 0x25, 0xe8, 0x9c, 0xf9, 0xe5, 0xa4, 0xa5, 0xfe, 0x04, 0xd2, 0x89, 0xb8, 0xf7, 0x2d, - 0xf7, 0xab, 0x79, 0x6e, 0xbe, 0x23, 0xab, 0x70, 0x1b, 0xca, 0xfa, 0x3b, 0x37, 0x1f, 0x8f, 0x31, - 0x9b, 0x4c, 0x87, 0x5c, 0x4e, 0x9f, 0xff, 0xda, 0x32, 0xc2, 0x43, 0xea, 0x0c, 0x2f, 0x18, 0xa2, - 0xf6, 0x31, 0x3a, 0x77, 0xf9, 0xc2, 0x33, 0x38, 0xdd, 0x97, 0x25, 0xdb, 0x31, 0xa4, 0x13, 0x55, - 0xa6, 0x9f, 0x96, 0x41, 0x4b, 0xaf, 0x9e, 0xd1, 0x07, 0x0d, 0xd9, 0xdc, 0xe5, 0x5c, 0x74, 0xb7, - 0xe6, 0xb9, 0xb9, 0x29, 0xff, 0x56, 0x19, 0xb2, 0xbc, 0xba, 0x5c, 0x9f, 0x84, 0x06, 0x04, 0xf5, - 0x09, 0x82, 0x21, 0xca, 0xfc, 0xbe, 0xaa, 0xcb, 0xfe, 0x5d, 0xb3, 0xf2, 0x58, 0xe0, 0xdd, 0xce, - 0x55, 0x6e, 0xae, 0xc9, 0x75, 0x7f, 0x9e, 0x9b, 0x1b, 0x52, 0xa4, 0x20, 0xb3, 0xbc, 0x35, 0xb9, - 0xec, 0x6b, 0x12, 0x03, 0x35, 0x23, 0xff, 0x83, 0xc4, 0xe0, 0x15, 0x89, 0x41, 0x29, 0x31, 0x50, - 0xf5, 0xf8, 0x65, 0x05, 0xdc, 0x93, 0x68, 0x03, 0x82, 0x75, 0x8a, 0xc7, 0x09, 0x0a, 0x7d, 0x09, - 0x51, 0x2d, 0xd3, 0xd1, 0x75, 0xe4, 0x7b, 0x78, 0x26, 0x60, 0x4a, 0x70, 0xef, 0x32, 0x37, 0x6b, - 0xd5, 0x24, 0xb8, 0x41, 0x61, 0x79, 0x2d, 0xaa, 0x61, 0xf9, 0xa0, 0x29, 0xcf, 0xd8, 0xa7, 0xa8, - 0x68, 0xab, 0x5b, 0x24, 0xca, 0xc3, 0x3b, 0x43, 0xcc, 0x6d, 0x57, 0xf4, 0x37, 0xd2, 0x2d, 0xaf, - 0x35, 0xd3, 0x70, 0xc6, 0xb7, 0x40, 0x3e, 0x05, 0x42, 0x5f, 0x0c, 0xb2, 0x95, 0x3b, 0x07, 0xd9, - 0x43, 0x35, 0xc8, 0xde, 0xd6, 0x1e, 0x98, 0x32, 0xdf, 0xf2, 0xd6, 0x95, 0x43, 0x8d, 0xb2, 0x08, - 0x18, 0x05, 0xa2, 0x6a, 0x56, 0xf5, 0xb8, 0xdc, 0xb5, 0x8b, 0x87, 0xf3, 0xdc, 0xdc, 0xb9, 0xa9, - 0x52, 0x71, 0x58, 0xde, 0xff, 0x95, 0xb3, 0x6a, 0x5b, 0xeb, 0x53, 0x50, 0x2f, 0x1e, 0x59, 0x63, - 0x0f, 0x34, 0x92, 0x69, 0x8c, 0x32, 0x1e, 0x11, 0x27, 0xb3, 0xea, 0x55, 0x0e, 0xa3, 0x0b, 0x9a, - 0x21, 0x4a, 0x48, 0x8c, 0x13, 0x11, 0x5f, 0x16, 0x71, 0xdd, 0xe5, 0xfa, 0x2f, 0xaf, 0x3a, 0xb5, - 0xcb, 0xab, 0x4e, 0xed, 0xcf, 0xab, 0x4e, 0xed, 0xc5, 0x75, 0x67, 0xe9, 0xf2, 0xba, 0xb3, 0xf4, - 0xfb, 0x75, 0x67, 0xe9, 0xeb, 0xa7, 0xda, 0x15, 0x0b, 0x08, 0x8d, 0x09, 0xe5, 0x9f, 0x5e, 0x07, - 0x63, 0xe2, 0xcc, 0x1e, 0x3b, 0x31, 0x09, 0xa7, 0x11, 0xa2, 0xf2, 0x43, 0xec, 0xa0, 0xf8, 0x12, - 0xfb, 0xe0, 0xc3, 0x83, 0xc5, 0x4f, 0xa5, 0xe1, 0x3d, 0x31, 0x52, 0x1e, 0xfd, 0x13, 0x00, 0x00, - 0xff, 0xff, 0x0b, 0x9f, 0x2c, 0x5c, 0xb8, 0x09, 0x00, 0x00, + // 1089 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0x6f, 0xda, 0xb2, 0x4d, 0x26, 0xe9, 0x76, 0x31, 0xa5, 0x9b, 0x96, 0x6e, 0x1c, 0x19, 0xa9, + 0xf4, 0x40, 0x6d, 0x92, 0x22, 0xad, 0x54, 0xb8, 0xe0, 0x2e, 0xa8, 0xbb, 0x62, 0xa5, 0xca, 0xe5, + 0x8f, 0x84, 0x84, 0xcc, 0xc4, 0x9e, 0x24, 0xa3, 0xb5, 0x3d, 0x96, 0x67, 0x1c, 0x5a, 0x3e, 0x01, + 0x9c, 0xd8, 0x23, 0xe2, 0xc4, 0x81, 0x0f, 0xb3, 0xc7, 0x1e, 0x39, 0x19, 0xd4, 0x7e, 0x83, 0x1c, + 0x38, 0x70, 0x42, 0xf3, 0xc7, 0xf6, 0xb4, 0xdb, 0xa5, 0x5a, 0x2e, 0xd1, 0xbc, 0xf7, 0x7e, 0xef, + 0xf7, 0xcb, 0xbc, 0x79, 0xf3, 0xc6, 0xc0, 0xc1, 0xa3, 0xc0, 0x89, 0xf0, 0x64, 0xca, 0x82, 0x08, + 0xa3, 0x84, 0x51, 0x87, 0xa1, 0x24, 0x44, 0x59, 0x8c, 0x13, 0xe6, 0xcc, 0x06, 0x9a, 0x65, 0xa7, + 0x19, 0x61, 0xc4, 0xe8, 0xe1, 0x51, 0x60, 0xeb, 0x09, 0xb6, 0x06, 0x99, 0x0d, 0xb6, 0xfa, 0x5a, + 0x3e, 0x3b, 0x4b, 0x11, 0x75, 0x66, 0x30, 0xc2, 0x21, 0x64, 0x24, 0x93, 0x0c, 0x5b, 0xdb, 0x2f, + 0x21, 0xc4, 0x6f, 0x19, 0x0d, 0x08, 0x8d, 0x09, 0x75, 0x70, 0x40, 0x87, 0xfb, 0xfc, 0x1f, 0xa4, + 0x19, 0x21, 0xe3, 0x32, 0xda, 0x9b, 0x10, 0x32, 0x89, 0x90, 0x23, 0xac, 0x51, 0x3e, 0x76, 0xc2, + 0x3c, 0x83, 0x0c, 0x93, 0x44, 0xc5, 0xcd, 0xeb, 0x71, 0x86, 0x63, 0x44, 0x19, 0x8c, 0xd3, 0x12, + 0xc0, 0xf7, 0x1b, 0x90, 0x0c, 0x39, 0xf2, 0xef, 0x73, 0x05, 0xb9, 0x52, 0x80, 0xf7, 0x6a, 0x00, + 0x89, 0x63, 0xcc, 0xe2, 0x12, 0x54, 0x59, 0x0a, 0xb8, 0x3e, 0x21, 0x13, 0x22, 0x96, 0x0e, 0x5f, + 0x49, 0xaf, 0xf5, 0xf7, 0x0a, 0x68, 0x1f, 0x0a, 0xbe, 0x13, 0x06, 0x19, 0x32, 0x36, 0x41, 0x33, + 0x98, 0x42, 0x9c, 0xf8, 0x38, 0xec, 0x36, 0xfa, 0x8d, 0xdd, 0x96, 0xb7, 0x22, 0xec, 0xc7, 0xa1, + 0x81, 0x40, 0x9b, 0x65, 0x39, 0x65, 0x7e, 0x84, 0x66, 0x28, 0xea, 0x2e, 0xf6, 0x1b, 0xbb, 0xed, + 0xe1, 0xae, 0xfd, 0xdf, 0xf5, 0xb5, 0x3f, 0xcb, 0x60, 0xc0, 0x37, 0xec, 0x6e, 0xbd, 0x28, 0xcc, + 0x85, 0x79, 0x61, 0x1a, 0x67, 0x30, 0x8e, 0x0e, 0x2c, 0x8d, 0xca, 0xf2, 0x80, 0xb0, 0x3e, 0xe7, + 0x86, 0x31, 0x06, 0x6b, 0xc2, 0xc2, 0xc9, 0xc4, 0x4f, 0x51, 0x86, 0x49, 0xd8, 0x5d, 0x12, 0x52, + 0x9b, 0xb6, 0x2c, 0x96, 0x5d, 0x16, 0xcb, 0x7e, 0xa4, 0x8a, 0xe9, 0x5a, 0x8a, 0x7b, 0x43, 0xe3, + 0xae, 0xf3, 0xad, 0x5f, 0xfe, 0x34, 0x1b, 0xde, 0xdd, 0xd2, 0x7b, 0x2c, 0x9c, 0x06, 0x06, 0xf7, + 0xf2, 0x64, 0x44, 0x92, 0x50, 0x13, 0x5a, 0xbe, 0x4d, 0xe8, 0x5d, 0x25, 0x74, 0x5f, 0x0a, 0x5d, + 0x27, 0x90, 0x4a, 0x6b, 0x95, 0x5b, 0x49, 0x21, 0xb0, 0x16, 0xc3, 0x53, 0x3f, 0x88, 0x48, 0xf0, + 0xcc, 0x0f, 0x33, 0x3c, 0x66, 0xdd, 0x37, 0x5e, 0x73, 0x4b, 0xd7, 0xf2, 0xa5, 0xd0, 0x6a, 0x0c, + 0x4f, 0x0f, 0xb9, 0xf3, 0x11, 0xf7, 0x19, 0xdf, 0x82, 0xd5, 0x71, 0x46, 0x7e, 0x40, 0x89, 0x3f, + 0x45, 0xfc, 0x40, 0xba, 0x77, 0x84, 0xc8, 0x96, 0x38, 0x22, 0xde, 0x22, 0xb6, 0xea, 0x9c, 0xd9, + 0xc0, 0x3e, 0x12, 0x08, 0x77, 0x5b, 0xa9, 0xac, 0x4b, 0x95, 0x2b, 0xe9, 0x96, 0xd7, 0x91, 0xb6, + 0xc4, 0x72, 0xfa, 0x08, 0x32, 0x44, 0x59, 0x49, 0xbf, 0xf2, 0xba, 0xf4, 0x57, 0xd2, 0x2d, 0xaf, + 0x23, 0x6d, 0x45, 0x7f, 0x02, 0xda, 0xe2, 0xea, 0xf8, 0x34, 0x45, 0x01, 0xed, 0x36, 0xfb, 0x4b, + 0x82, 0x5c, 0x5e, 0x2f, 0x5b, 0x5c, 0x2f, 0xce, 0x7c, 0xcc, 0x31, 0x27, 0x29, 0x0a, 0xdc, 0x8d, + 0xba, 0x99, 0xb4, 0x44, 0xcb, 0x03, 0x69, 0x09, 0xa1, 0xc6, 0x01, 0xe8, 0xe4, 0xe9, 0x24, 0x83, + 0x21, 0xf2, 0x53, 0xc8, 0xa6, 0xdd, 0x56, 0x7f, 0x69, 0xb7, 0xe5, 0xde, 0x9f, 0x17, 0xe6, 0x5b, + 0xea, 0x04, 0xb5, 0xa8, 0xe5, 0xb5, 0x95, 0x79, 0x0c, 0xd9, 0xd4, 0x80, 0x60, 0x13, 0x46, 0x11, + 0xf9, 0xde, 0xcf, 0xd3, 0x10, 0x32, 0xe4, 0xc3, 0x31, 0x43, 0x99, 0x8f, 0x4e, 0x53, 0x9c, 0x9d, + 0x75, 0x41, 0xbf, 0xb1, 0xdb, 0x74, 0x77, 0xe6, 0x85, 0xd9, 0x97, 0x44, 0xaf, 0x84, 0x5a, 0xdd, + 0x86, 0xb7, 0x21, 0xa2, 0x5f, 0x8a, 0xe0, 0x27, 0x3c, 0xf6, 0xa9, 0x08, 0x19, 0x14, 0x98, 0x37, + 0xe4, 0xc5, 0x98, 0x8e, 0xd0, 0x14, 0xce, 0x30, 0xc9, 0xb3, 0x6e, 0x5b, 0x08, 0xbd, 0x3f, 0x2f, + 0xcc, 0x9d, 0x57, 0x0a, 0xe9, 0x09, 0x5c, 0x6e, 0xfb, 0xba, 0xdc, 0x53, 0x0d, 0x70, 0xb0, 0xfc, + 0xe3, 0x6f, 0xe6, 0x82, 0xf5, 0xfb, 0x22, 0xb8, 0x7b, 0x48, 0x12, 0x8a, 0x12, 0x9a, 0x53, 0x79, + 0xf7, 0x5d, 0xd0, 0xaa, 0xc6, 0x8f, 0xb8, 0xfc, 0xbc, 0xfe, 0xd7, 0x1b, 0xf4, 0x8b, 0x12, 0xe1, + 0x36, 0xf9, 0xe1, 0x3e, 0xe7, 0x7d, 0x58, 0xa7, 0x19, 0x1f, 0x83, 0xe5, 0x8c, 0x10, 0xa6, 0xa6, + 0x83, 0xa5, 0xf5, 0x46, 0x3d, 0x8f, 0x66, 0x03, 0xfb, 0x29, 0xca, 0x9e, 0x45, 0xc8, 0x23, 0x84, + 0xb9, 0xcb, 0x9c, 0xc6, 0x13, 0x59, 0xc6, 0x4f, 0x0d, 0xb0, 0x9e, 0xa0, 0x53, 0xe6, 0x57, 0x33, + 0x98, 0xfa, 0x53, 0x48, 0xa7, 0x62, 0x02, 0x74, 0xdc, 0xaf, 0xe7, 0x85, 0xf9, 0x8e, 0xac, 0xc2, + 0x4d, 0x28, 0xeb, 0x9f, 0xc2, 0xfc, 0x70, 0x82, 0xd9, 0x34, 0x1f, 0x71, 0x39, 0xfd, 0x65, 0xd0, + 0x96, 0x11, 0x1e, 0x51, 0x67, 0x74, 0xc6, 0x10, 0xb5, 0x8f, 0xd0, 0xa9, 0xcb, 0x17, 0x9e, 0xc1, + 0xe9, 0xbe, 0xaa, 0xd8, 0x8e, 0x20, 0x9d, 0xaa, 0x32, 0xfd, 0xbc, 0x08, 0x3a, 0x7a, 0xf5, 0x8c, + 0x7d, 0xd0, 0x92, 0x6d, 0x5e, 0x4d, 0x48, 0xd1, 0x88, 0xf7, 0xe4, 0xdf, 0xaa, 0x42, 0xfc, 0x18, + 0x9a, 0xd2, 0x7a, 0x1c, 0x1a, 0x10, 0x34, 0xa7, 0x08, 0x86, 0x28, 0xf3, 0x07, 0xaa, 0x32, 0x3b, + 0xb7, 0xcd, 0xcd, 0x23, 0x81, 0x77, 0x7b, 0x17, 0x85, 0xb9, 0x22, 0xd7, 0x83, 0x79, 0x61, 0xae, + 0x49, 0x99, 0x92, 0xcc, 0xf2, 0x56, 0xe4, 0x72, 0xa0, 0x49, 0x0c, 0xd5, 0xbc, 0xfc, 0x1f, 0x12, + 0xc3, 0x97, 0x24, 0x86, 0x95, 0xc4, 0x50, 0x55, 0xe4, 0xd7, 0x25, 0x70, 0x47, 0xa2, 0x0d, 0x08, + 0x56, 0x29, 0x9e, 0x24, 0x28, 0xf4, 0x25, 0x44, 0x35, 0x4d, 0x4f, 0xd7, 0x91, 0x6f, 0xe5, 0x89, + 0x80, 0x29, 0xc1, 0xed, 0xf3, 0xc2, 0x6c, 0xd4, 0x53, 0xe1, 0x0a, 0x85, 0xe5, 0x75, 0xa8, 0x86, + 0xe5, 0x43, 0xa7, 0x3a, 0x65, 0x9f, 0xa2, 0xb2, 0xb1, 0x6e, 0x90, 0xa8, 0x8e, 0xef, 0x04, 0x31, + 0xb7, 0x5b, 0xd3, 0x5f, 0x49, 0xb7, 0xbc, 0xce, 0x4c, 0xc3, 0x19, 0xdf, 0x01, 0xf9, 0x2c, 0x08, + 0x7d, 0x31, 0xd4, 0x96, 0x6e, 0x1d, 0x6a, 0x0f, 0xd4, 0x50, 0x7b, 0x5b, 0x7b, 0x6c, 0xaa, 0x7c, + 0xcb, 0x5b, 0x55, 0x0e, 0x35, 0xd6, 0x22, 0x60, 0x94, 0x88, 0xba, 0x5d, 0xd5, 0x43, 0x73, 0xdb, + 0x2e, 0x1e, 0xcc, 0x0b, 0x73, 0xf3, 0xaa, 0x4a, 0xcd, 0x61, 0x79, 0x6f, 0x2a, 0x67, 0xdd, 0xb8, + 0xd6, 0x13, 0xd0, 0x2c, 0x1f, 0x5c, 0x63, 0x1b, 0xb4, 0x92, 0x3c, 0x46, 0x19, 0x8f, 0x88, 0x93, + 0x59, 0xf6, 0x6a, 0x87, 0xd1, 0x07, 0xed, 0x10, 0x25, 0x24, 0xc6, 0x89, 0x88, 0x2f, 0x8a, 0xb8, + 0xee, 0x72, 0xc3, 0x17, 0x17, 0xbd, 0xc6, 0xf9, 0x45, 0xaf, 0xf1, 0xd7, 0x45, 0xaf, 0xf1, 0xfc, + 0xb2, 0xb7, 0x70, 0x7e, 0xd9, 0x5b, 0xf8, 0xe3, 0xb2, 0xb7, 0xf0, 0xcd, 0x13, 0xed, 0x92, 0x95, + 0x9f, 0x3f, 0xa3, 0x60, 0x6f, 0x42, 0x9c, 0xd9, 0x43, 0x27, 0x26, 0x61, 0x1e, 0x21, 0x2a, 0x3f, + 0xd2, 0xf6, 0xca, 0xaf, 0xb4, 0x0f, 0x1e, 0xee, 0xd5, 0x7b, 0xfd, 0xa8, 0x5e, 0x8e, 0xee, 0x88, + 0xc9, 0xb2, 0xff, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0xfc, 0x54, 0x53, 0xd9, 0x09, 0x00, + 0x00, } func (m *ClientState) Marshal() (dAtA []byte, err error) { @@ -476,7 +478,7 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x32 - n3, err3 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxClockDrift, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift):]) + n3, err3 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.MaxClockDrift, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.MaxClockDrift):]) if err3 != nil { return 0, err3 } @@ -484,7 +486,7 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTendermint(dAtA, i, uint64(n3)) i-- dAtA[i] = 0x2a - n4, err4 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod):]) + n4, err4 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod):]) if err4 != nil { return 0, err4 } @@ -492,7 +494,7 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTendermint(dAtA, i, uint64(n4)) i-- dAtA[i] = 0x22 - n5, err5 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.TrustingPeriod, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.TrustingPeriod):]) + n5, err5 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.TrustingPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TrustingPeriod):]) if err5 != nil { return 0, err5 } @@ -557,7 +559,7 @@ func (m *ConsensusState) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x12 - n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + n8, err8 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp):]) if err8 != nil { return 0, err8 } @@ -747,11 +749,11 @@ func (m *ClientState) Size() (n int) { } l = m.TrustLevel.Size() n += 1 + l + sovTendermint(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.TrustingPeriod) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TrustingPeriod) n += 1 + l + sovTendermint(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.UnbondingPeriod) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod) n += 1 + l + sovTendermint(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxClockDrift) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.MaxClockDrift) n += 1 + l + sovTendermint(uint64(l)) l = m.FrozenHeight.Size() n += 1 + l + sovTendermint(uint64(l)) @@ -784,7 +786,7 @@ func (m *ConsensusState) Size() (n int) { } var l int _ = l - l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp) n += 1 + l + sovTendermint(uint64(l)) l = m.Root.Size() n += 1 + l + sovTendermint(uint64(l)) @@ -983,7 +985,7 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.TrustingPeriod, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.TrustingPeriod, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1016,7 +1018,7 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.UnbondingPeriod, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.UnbondingPeriod, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1049,7 +1051,7 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.MaxClockDrift, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.MaxClockDrift, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1304,7 +1306,7 @@ func (m *ConsensusState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/modules/light-clients/07-tendermint/types/tendermint_test.go b/modules/light-clients/07-tendermint/tendermint_test.go similarity index 91% rename from modules/light-clients/07-tendermint/types/tendermint_test.go rename to modules/light-clients/07-tendermint/tendermint_test.go index f653f94fe48..21554335a18 100644 --- a/modules/light-clients/07-tendermint/types/tendermint_test.go +++ b/modules/light-clients/07-tendermint/tendermint_test.go @@ -1,4 +1,4 @@ -package types_test +package tendermint_test import ( "testing" @@ -11,11 +11,11 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibctestingmock "github.com/cosmos/ibc-go/v4/testing/mock" - "github.com/cosmos/ibc-go/v4/testing/simapp" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctestingmock "github.com/cosmos/ibc-go/v7/testing/mock" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) const ( @@ -50,7 +50,7 @@ type TendermintTestSuite struct { valSet *tmtypes.ValidatorSet signers map[string]tmtypes.PrivValidator valsHash tmbytes.HexBytes - header *ibctmtypes.Header + header *ibctm.Header now time.Time headerTime time.Time clientTime time.Time diff --git a/modules/light-clients/07-tendermint/types/client_state.go b/modules/light-clients/07-tendermint/types/client_state.go deleted file mode 100644 index 229fa53adb7..00000000000 --- a/modules/light-clients/07-tendermint/types/client_state.go +++ /dev/null @@ -1,583 +0,0 @@ -package types - -import ( - "strings" - "time" - - ics23 "github.com/confio/ics23/go" - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/tendermint/tendermint/light" - tmtypes "github.com/tendermint/tendermint/types" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -var _ exported.ClientState = (*ClientState)(nil) - -// NewClientState creates a new ClientState instance -func NewClientState( - chainID string, trustLevel Fraction, - trustingPeriod, ubdPeriod, maxClockDrift time.Duration, - latestHeight clienttypes.Height, specs []*ics23.ProofSpec, - upgradePath []string, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour bool, -) *ClientState { - return &ClientState{ - ChainId: chainID, - TrustLevel: trustLevel, - TrustingPeriod: trustingPeriod, - UnbondingPeriod: ubdPeriod, - MaxClockDrift: maxClockDrift, - LatestHeight: latestHeight, - FrozenHeight: clienttypes.ZeroHeight(), - ProofSpecs: specs, - UpgradePath: upgradePath, - AllowUpdateAfterExpiry: allowUpdateAfterExpiry, - AllowUpdateAfterMisbehaviour: allowUpdateAfterMisbehaviour, - } -} - -// GetChainID returns the chain-id -func (cs ClientState) GetChainID() string { - return cs.ChainId -} - -// ClientType is tendermint. -func (cs ClientState) ClientType() string { - return exported.Tendermint -} - -// GetLatestHeight returns latest block height. -func (cs ClientState) GetLatestHeight() exported.Height { - return cs.LatestHeight -} - -// Status returns the status of the tendermint client. -// The client may be: -// - Active: FrozenHeight is zero and client is not expired -// - Frozen: Frozen Height is not zero -// - Expired: the latest consensus state timestamp + trusting period <= current time -// -// A frozen client will become expired, so the Frozen status -// has higher precedence. -func (cs ClientState) Status( - ctx sdk.Context, - clientStore sdk.KVStore, - cdc codec.BinaryCodec, -) exported.Status { - if !cs.FrozenHeight.IsZero() { - return exported.Frozen - } - - // get latest consensus state from clientStore to check for expiry - consState, err := GetConsensusState(clientStore, cdc, cs.GetLatestHeight()) - if err != nil { - // if the client state does not have an associated consensus state for its latest height - // then it must be expired - return exported.Expired - } - - if cs.IsExpired(consState.Timestamp, ctx.BlockTime()) { - return exported.Expired - } - - return exported.Active -} - -// IsExpired returns whether or not the client has passed the trusting period since the last -// update (in which case no headers are considered valid). -func (cs ClientState) IsExpired(latestTimestamp, now time.Time) bool { - expirationTime := latestTimestamp.Add(cs.TrustingPeriod) - return !expirationTime.After(now) -} - -// Validate performs a basic validation of the client state fields. -func (cs ClientState) Validate() error { - if strings.TrimSpace(cs.ChainId) == "" { - return sdkerrors.Wrap(ErrInvalidChainID, "chain id cannot be empty string") - } - - // NOTE: the value of tmtypes.MaxChainIDLen may change in the future. - // If this occurs, the code here must account for potential difference - // between the tendermint version being run by the counterparty chain - // and the tendermint version used by this light client. - // https://github.com/cosmos/ibc-go/issues/177 - if len(cs.ChainId) > tmtypes.MaxChainIDLen { - return sdkerrors.Wrapf(ErrInvalidChainID, "chainID is too long; got: %d, max: %d", len(cs.ChainId), tmtypes.MaxChainIDLen) - } - - if err := light.ValidateTrustLevel(cs.TrustLevel.ToTendermint()); err != nil { - return err - } - if cs.TrustingPeriod == 0 { - return sdkerrors.Wrap(ErrInvalidTrustingPeriod, "trusting period cannot be zero") - } - if cs.UnbondingPeriod == 0 { - return sdkerrors.Wrap(ErrInvalidUnbondingPeriod, "unbonding period cannot be zero") - } - if cs.MaxClockDrift == 0 { - return sdkerrors.Wrap(ErrInvalidMaxClockDrift, "max clock drift cannot be zero") - } - - // the latest height revision number must match the chain id revision number - if cs.LatestHeight.RevisionNumber != clienttypes.ParseChainID(cs.ChainId) { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, - "latest height revision number must match chain id revision number (%d != %d)", cs.LatestHeight.RevisionNumber, clienttypes.ParseChainID(cs.ChainId)) - } - if cs.LatestHeight.RevisionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "tendermint client's latest height revision height cannot be zero") - } - if cs.TrustingPeriod >= cs.UnbondingPeriod { - return sdkerrors.Wrapf( - ErrInvalidTrustingPeriod, - "trusting period (%s) should be < unbonding period (%s)", cs.TrustingPeriod, cs.UnbondingPeriod, - ) - } - - if cs.ProofSpecs == nil { - return sdkerrors.Wrap(ErrInvalidProofSpecs, "proof specs cannot be nil for tm client") - } - for i, spec := range cs.ProofSpecs { - if spec == nil { - return sdkerrors.Wrapf(ErrInvalidProofSpecs, "proof spec cannot be nil at index: %d", i) - } - } - // UpgradePath may be empty, but if it isn't, each key must be non-empty - for i, k := range cs.UpgradePath { - if strings.TrimSpace(k) == "" { - return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "key in upgrade path at index %d cannot be empty", i) - } - } - - return nil -} - -// GetProofSpecs returns the format the client expects for proof verification -// as a string array specifying the proof type for each position in chained proof -func (cs ClientState) GetProofSpecs() []*ics23.ProofSpec { - return cs.ProofSpecs -} - -// ZeroCustomFields returns a ClientState that is a copy of the current ClientState -// with all client customizable fields zeroed out -func (cs ClientState) ZeroCustomFields() exported.ClientState { - // copy over all chain-specified fields - // and leave custom fields empty - return &ClientState{ - ChainId: cs.ChainId, - UnbondingPeriod: cs.UnbondingPeriod, - LatestHeight: cs.LatestHeight, - ProofSpecs: cs.ProofSpecs, - UpgradePath: cs.UpgradePath, - } -} - -// Initialize will check that initial consensus state is a Tendermint consensus state -// and will store ProcessedTime for initial consensus state as ctx.BlockTime() -func (cs ClientState) Initialize(ctx sdk.Context, _ codec.BinaryCodec, clientStore sdk.KVStore, consState exported.ConsensusState) error { - if _, ok := consState.(*ConsensusState); !ok { - return sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "invalid initial consensus state. expected type: %T, got: %T", - &ConsensusState{}, consState) - } - // set metadata for initial consensus state. - setConsensusMetadata(ctx, clientStore, cs.GetLatestHeight()) - return nil -} - -// VerifyClientState verifies a proof of the client state of the running chain -// stored on the target machine -func (cs ClientState) VerifyClientState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - prefix exported.Prefix, - counterpartyClientIdentifier string, - proof []byte, - clientState exported.ClientState, -) error { - merkleProof, provingConsensusState, err := produceVerificationArgs(store, cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - clientPrefixedPath := commitmenttypes.NewMerklePath(host.FullClientStatePath(counterpartyClientIdentifier)) - path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath) - if err != nil { - return err - } - - if clientState == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "client state cannot be empty") - } - - _, ok := clientState.(*ClientState) - if !ok { - return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "invalid client type %T, expected %T", clientState, &ClientState{}) - } - - bz, err := cdc.MarshalInterface(clientState) - if err != nil { - return err - } - - return merkleProof.VerifyMembership(cs.ProofSpecs, provingConsensusState.GetRoot(), path, bz) -} - -// VerifyClientConsensusState verifies a proof of the consensus state of the -// Tendermint client stored on the target machine. -func (cs ClientState) VerifyClientConsensusState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - counterpartyClientIdentifier string, - consensusHeight exported.Height, - prefix exported.Prefix, - proof []byte, - consensusState exported.ConsensusState, -) error { - merkleProof, provingConsensusState, err := produceVerificationArgs(store, cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - clientPrefixedPath := commitmenttypes.NewMerklePath(host.FullConsensusStatePath(counterpartyClientIdentifier, consensusHeight)) - path, err := commitmenttypes.ApplyPrefix(prefix, clientPrefixedPath) - if err != nil { - return err - } - - if consensusState == nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "consensus state cannot be empty") - } - - _, ok := consensusState.(*ConsensusState) - if !ok { - return sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "invalid consensus type %T, expected %T", consensusState, &ConsensusState{}) - } - - bz, err := cdc.MarshalInterface(consensusState) - if err != nil { - return err - } - - if err := merkleProof.VerifyMembership(cs.ProofSpecs, provingConsensusState.GetRoot(), path, bz); err != nil { - return err - } - - return nil -} - -// VerifyConnectionState verifies a proof of the connection state of the -// specified connection end stored on the target machine. -func (cs ClientState) VerifyConnectionState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - prefix exported.Prefix, - proof []byte, - connectionID string, - connectionEnd exported.ConnectionI, -) error { - merkleProof, consensusState, err := produceVerificationArgs(store, cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - connectionPath := commitmenttypes.NewMerklePath(host.ConnectionPath(connectionID)) - path, err := commitmenttypes.ApplyPrefix(prefix, connectionPath) - if err != nil { - return err - } - - connection, ok := connectionEnd.(connectiontypes.ConnectionEnd) - if !ok { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "invalid connection type %T", connectionEnd) - } - - bz, err := cdc.Marshal(&connection) - if err != nil { - return err - } - - if err := merkleProof.VerifyMembership(cs.ProofSpecs, consensusState.GetRoot(), path, bz); err != nil { - return err - } - - return nil -} - -// VerifyChannelState verifies a proof of the channel state of the specified -// channel end, under the specified port, stored on the target machine. -func (cs ClientState) VerifyChannelState( - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - channel exported.ChannelI, -) error { - merkleProof, consensusState, err := produceVerificationArgs(store, cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - channelPath := commitmenttypes.NewMerklePath(host.ChannelPath(portID, channelID)) - path, err := commitmenttypes.ApplyPrefix(prefix, channelPath) - if err != nil { - return err - } - - channelEnd, ok := channel.(channeltypes.Channel) - if !ok { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "invalid channel type %T", channel) - } - - bz, err := cdc.Marshal(&channelEnd) - if err != nil { - return err - } - - if err := merkleProof.VerifyMembership(cs.ProofSpecs, consensusState.GetRoot(), path, bz); err != nil { - return err - } - - return nil -} - -// VerifyPacketCommitment verifies a proof of an outgoing packet commitment at -// the specified port, specified channel, and specified sequence. -func (cs ClientState) VerifyPacketCommitment( - ctx sdk.Context, - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - delayTimePeriod uint64, - delayBlockPeriod uint64, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - sequence uint64, - commitmentBytes []byte, -) error { - merkleProof, consensusState, err := produceVerificationArgs(store, cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - // check delay period has passed - if err := verifyDelayPeriodPassed(ctx, store, height, delayTimePeriod, delayBlockPeriod); err != nil { - return err - } - - commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, sequence)) - path, err := commitmenttypes.ApplyPrefix(prefix, commitmentPath) - if err != nil { - return err - } - - if err := merkleProof.VerifyMembership(cs.ProofSpecs, consensusState.GetRoot(), path, commitmentBytes); err != nil { - return err - } - - return nil -} - -// VerifyPacketAcknowledgement verifies a proof of an incoming packet -// acknowledgement at the specified port, specified channel, and specified sequence. -func (cs ClientState) VerifyPacketAcknowledgement( - ctx sdk.Context, - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - delayTimePeriod uint64, - delayBlockPeriod uint64, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - sequence uint64, - acknowledgement []byte, -) error { - merkleProof, consensusState, err := produceVerificationArgs(store, cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - // check delay period has passed - if err := verifyDelayPeriodPassed(ctx, store, height, delayTimePeriod, delayBlockPeriod); err != nil { - return err - } - - ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, sequence)) - path, err := commitmenttypes.ApplyPrefix(prefix, ackPath) - if err != nil { - return err - } - - if err := merkleProof.VerifyMembership(cs.ProofSpecs, consensusState.GetRoot(), path, channeltypes.CommitAcknowledgement(acknowledgement)); err != nil { - return err - } - - return nil -} - -// VerifyPacketReceiptAbsence verifies a proof of the absence of an -// incoming packet receipt at the specified port, specified channel, and -// specified sequence. -func (cs ClientState) VerifyPacketReceiptAbsence( - ctx sdk.Context, - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - delayTimePeriod uint64, - delayBlockPeriod uint64, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - sequence uint64, -) error { - merkleProof, consensusState, err := produceVerificationArgs(store, cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - // check delay period has passed - if err := verifyDelayPeriodPassed(ctx, store, height, delayTimePeriod, delayBlockPeriod); err != nil { - return err - } - - receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, sequence)) - path, err := commitmenttypes.ApplyPrefix(prefix, receiptPath) - if err != nil { - return err - } - - if err := merkleProof.VerifyNonMembership(cs.ProofSpecs, consensusState.GetRoot(), path); err != nil { - return err - } - - return nil -} - -// VerifyNextSequenceRecv verifies a proof of the next sequence number to be -// received of the specified channel at the specified port. -func (cs ClientState) VerifyNextSequenceRecv( - ctx sdk.Context, - store sdk.KVStore, - cdc codec.BinaryCodec, - height exported.Height, - delayTimePeriod uint64, - delayBlockPeriod uint64, - prefix exported.Prefix, - proof []byte, - portID, - channelID string, - nextSequenceRecv uint64, -) error { - merkleProof, consensusState, err := produceVerificationArgs(store, cdc, cs, height, prefix, proof) - if err != nil { - return err - } - - // check delay period has passed - if err := verifyDelayPeriodPassed(ctx, store, height, delayTimePeriod, delayBlockPeriod); err != nil { - return err - } - - nextSequenceRecvPath := commitmenttypes.NewMerklePath(host.NextSequenceRecvPath(portID, channelID)) - path, err := commitmenttypes.ApplyPrefix(prefix, nextSequenceRecvPath) - if err != nil { - return err - } - - bz := sdk.Uint64ToBigEndian(nextSequenceRecv) - - if err := merkleProof.VerifyMembership(cs.ProofSpecs, consensusState.GetRoot(), path, bz); err != nil { - return err - } - - return nil -} - -// verifyDelayPeriodPassed will ensure that at least delayTimePeriod amount of time and delayBlockPeriod number of blocks have passed -// since consensus state was submitted before allowing verification to continue. -func verifyDelayPeriodPassed(ctx sdk.Context, store sdk.KVStore, proofHeight exported.Height, delayTimePeriod, delayBlockPeriod uint64) error { - // check that executing chain's timestamp has passed consensusState's processed time + delay time period - processedTime, ok := GetProcessedTime(store, proofHeight) - if !ok { - return sdkerrors.Wrapf(ErrProcessedTimeNotFound, "processed time not found for height: %s", proofHeight) - } - currentTimestamp := uint64(ctx.BlockTime().UnixNano()) - validTime := processedTime + delayTimePeriod - // NOTE: delay time period is inclusive, so if currentTimestamp is validTime, then we return no error - if currentTimestamp < validTime { - return sdkerrors.Wrapf(ErrDelayPeriodNotPassed, "cannot verify packet until time: %d, current time: %d", - validTime, currentTimestamp) - } - // check that executing chain's height has passed consensusState's processed height + delay block period - processedHeight, ok := GetProcessedHeight(store, proofHeight) - if !ok { - return sdkerrors.Wrapf(ErrProcessedHeightNotFound, "processed height not found for height: %s", proofHeight) - } - currentHeight := clienttypes.GetSelfHeight(ctx) - validHeight := clienttypes.NewHeight(processedHeight.GetRevisionNumber(), processedHeight.GetRevisionHeight()+delayBlockPeriod) - // NOTE: delay block period is inclusive, so if currentHeight is validHeight, then we return no error - if currentHeight.LT(validHeight) { - return sdkerrors.Wrapf(ErrDelayPeriodNotPassed, "cannot verify packet until height: %s, current height: %s", - validHeight, currentHeight) - } - return nil -} - -// produceVerificationArgs perfoms the basic checks on the arguments that are -// shared between the verification functions and returns the unmarshalled -// merkle proof, the consensus state and an error if one occurred. -func produceVerificationArgs( - store sdk.KVStore, - cdc codec.BinaryCodec, - cs ClientState, - height exported.Height, - prefix exported.Prefix, - proof []byte, -) (merkleProof commitmenttypes.MerkleProof, consensusState *ConsensusState, err error) { - if cs.GetLatestHeight().LT(height) { - return commitmenttypes.MerkleProof{}, nil, sdkerrors.Wrapf( - sdkerrors.ErrInvalidHeight, - "client state height < proof height (%d < %d), please ensure the client has been updated", cs.GetLatestHeight(), height, - ) - } - - if prefix == nil { - return commitmenttypes.MerkleProof{}, nil, sdkerrors.Wrap(commitmenttypes.ErrInvalidPrefix, "prefix cannot be empty") - } - - _, ok := prefix.(*commitmenttypes.MerklePrefix) - if !ok { - return commitmenttypes.MerkleProof{}, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidPrefix, "invalid prefix type %T, expected *MerklePrefix", prefix) - } - - if proof == nil { - return commitmenttypes.MerkleProof{}, nil, sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "proof cannot be empty") - } - - if err = cdc.Unmarshal(proof, &merkleProof); err != nil { - return commitmenttypes.MerkleProof{}, nil, sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "failed to unmarshal proof into commitment merkle proof") - } - - consensusState, err = GetConsensusState(store, cdc, height) - if err != nil { - return commitmenttypes.MerkleProof{}, nil, sdkerrors.Wrap(err, "please ensure the proof was constructed against a height that exists on the client") - } - - return merkleProof, consensusState, nil -} diff --git a/modules/light-clients/07-tendermint/types/client_state_test.go b/modules/light-clients/07-tendermint/types/client_state_test.go deleted file mode 100644 index cf596933b6f..00000000000 --- a/modules/light-clients/07-tendermint/types/client_state_test.go +++ /dev/null @@ -1,880 +0,0 @@ -package types_test - -import ( - "time" - - ics23 "github.com/confio/ics23/go" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" -) - -const ( - testClientID = "clientidone" - testConnectionID = "connectionid" - testPortID = "testportid" - testChannelID = "testchannelid" - testSequence = 1 - - // Do not change the length of these variables - fiftyCharChainID = "12345678901234567890123456789012345678901234567890" - fiftyOneCharChainID = "123456789012345678901234567890123456789012345678901" -) - -var invalidProof = []byte("invalid proof") - -func (suite *TendermintTestSuite) TestStatus() { - var ( - path *ibctesting.Path - clientState *types.ClientState - ) - - testCases := []struct { - name string - malleate func() - expStatus exported.Status - }{ - {"client is active", func() {}, exported.Active}, - {"client is frozen", func() { - clientState.FrozenHeight = clienttypes.NewHeight(0, 1) - path.EndpointA.SetClientState(clientState) - }, exported.Frozen}, - {"client status without consensus state", func() { - clientState.LatestHeight = clientState.LatestHeight.Increment().(clienttypes.Height) - path.EndpointA.SetClientState(clientState) - }, exported.Expired}, - {"client status is expired", func() { - suite.coordinator.IncrementTimeBy(clientState.TrustingPeriod) - }, exported.Expired}, - } - - for _, tc := range testCases { - path = ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(path) - - clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - clientState = path.EndpointA.GetClientState().(*types.ClientState) - - tc.malleate() - - status := clientState.Status(suite.chainA.GetContext(), clientStore, suite.chainA.App.AppCodec()) - suite.Require().Equal(tc.expStatus, status) - - } -} - -func (suite *TendermintTestSuite) TestValidate() { - testCases := []struct { - name string - clientState *types.ClientState - expPass bool - }{ - { - name: "valid client", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: true, - }, - { - name: "valid client with nil upgrade path", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), nil, false, false), - expPass: true, - }, - { - name: "invalid chainID", - clientState: types.NewClientState(" ", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - // NOTE: if this test fails, the code must account for the change in chainID length across tendermint versions! - // Do not only fix the test, fix the code! - // https://github.com/cosmos/ibc-go/issues/177 - name: "valid chainID - chainID validation failed for chainID of length 50! ", - clientState: types.NewClientState(fiftyCharChainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: true, - }, - { - // NOTE: if this test fails, the code must account for the change in chainID length across tendermint versions! - // Do not only fix the test, fix the code! - // https://github.com/cosmos/ibc-go/issues/177 - name: "invalid chainID - chainID validation did not fail for chainID of length 51! ", - clientState: types.NewClientState(fiftyOneCharChainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - name: "invalid trust level", - clientState: types.NewClientState(chainID, types.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - name: "invalid trusting period", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, 0, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - name: "invalid unbonding period", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, 0, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - name: "invalid max clock drift", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, 0, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - name: "invalid revision number", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - name: "invalid revision height", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - name: "trusting period not less than unbonding period", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - expPass: false, - }, - { - name: "proof specs is nil", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, nil, upgradePath, false, false), - expPass: false, - }, - { - name: "proof specs contains nil", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, []*ics23.ProofSpec{ics23.TendermintSpec, nil}, upgradePath, false, false), - expPass: false, - }, - } - - for _, tc := range testCases { - err := tc.clientState.Validate() - if tc.expPass { - suite.Require().NoError(err, tc.name) - } else { - suite.Require().Error(err, tc.name) - } - } -} - -func (suite *TendermintTestSuite) TestInitialize() { - testCases := []struct { - name string - consensusState exported.ConsensusState - expPass bool - }{ - { - name: "valid consensus", - consensusState: &types.ConsensusState{}, - expPass: true, - }, - { - name: "invalid consensus: consensus state is solomachine consensus", - consensusState: ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2).ConsensusState(), - expPass: false, - }, - } - - path := ibctesting.NewPath(suite.chainA, suite.chainB) - err := path.EndpointA.CreateClient() - suite.Require().NoError(err) - - clientState := suite.chainA.GetClientState(path.EndpointA.ClientID) - store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - - for _, tc := range testCases { - err := clientState.Initialize(suite.chainA.GetContext(), suite.chainA.Codec, store, tc.consensusState) - if tc.expPass { - suite.Require().NoError(err, "valid case returned an error") - } else { - suite.Require().Error(err, "invalid case didn't return an error") - } - } -} - -func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { - testCases := []struct { - name string - clientState *types.ClientState - consensusState *types.ConsensusState - prefix commitmenttypes.MerklePrefix - proof []byte - expPass bool - }{ - // FIXME: uncomment - // { - // name: "successful verification", - // clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs()), - // consensusState: types.ConsensusState{ - // Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), - // }, - // prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), - // expPass: true, - // }, - { - name: "ApplyPrefix failed", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - consensusState: &types.ConsensusState{ - Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), - }, - prefix: commitmenttypes.MerklePrefix{}, - expPass: false, - }, - { - name: "latest client height < height", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - consensusState: &types.ConsensusState{ - Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), - }, - prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), - expPass: false, - }, - { - name: "proof verification failed", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - consensusState: &types.ConsensusState{ - Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), - NextValidatorsHash: suite.valsHash, - }, - prefix: commitmenttypes.NewMerklePrefix([]byte("ibc")), - proof: []byte{}, - expPass: false, - }, - } - - for i, tc := range testCases { - tc := tc - - err := tc.clientState.VerifyClientConsensusState( - nil, suite.cdc, height, "chainA", tc.clientState.LatestHeight, tc.prefix, tc.proof, tc.consensusState, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - } - } -} - -// test verification of the connection on chainB being represented in the -// light client on chainA -func (suite *TendermintTestSuite) TestVerifyConnectionState() { - var ( - clientState *types.ClientState - proof []byte - proofHeight exported.Height - prefix commitmenttypes.MerklePrefix - ) - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "successful verification", func() {}, true, - }, - { - "ApplyPrefix failed", func() { - prefix = commitmenttypes.MerklePrefix{} - }, false, - }, - { - "latest client height < height", func() { - proofHeight = clientState.LatestHeight.Increment() - }, false, - }, - { - "proof verification failed", func() { - proof = invalidProof - }, false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - // setup testing conditions - path := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.Setup(path) - connection := path.EndpointB.GetConnection() - - var ok bool - clientStateI := suite.chainA.GetClientState(path.EndpointA.ClientID) - clientState, ok = clientStateI.(*types.ClientState) - suite.Require().True(ok) - - prefix = suite.chainB.GetPrefix() - - // make connection proof - connectionKey := host.ConnectionKey(path.EndpointB.ConnectionID) - proof, proofHeight = suite.chainB.QueryProof(connectionKey) - - tc.malleate() // make changes as necessary - - store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - - err := clientState.VerifyConnectionState( - store, suite.chainA.Codec, proofHeight, &prefix, proof, path.EndpointB.ConnectionID, connection, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -// test verification of the channel on chainB being represented in the light -// client on chainA -func (suite *TendermintTestSuite) TestVerifyChannelState() { - var ( - clientState *types.ClientState - proof []byte - proofHeight exported.Height - prefix commitmenttypes.MerklePrefix - ) - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "successful verification", func() {}, true, - }, - { - "ApplyPrefix failed", func() { - prefix = commitmenttypes.MerklePrefix{} - }, false, - }, - { - "latest client height < height", func() { - proofHeight = clientState.LatestHeight.Increment() - }, false, - }, - { - "proof verification failed", func() { - proof = invalidProof - }, false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - // setup testing conditions - path := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.Setup(path) - channel := path.EndpointB.GetChannel() - - var ok bool - clientStateI := suite.chainA.GetClientState(path.EndpointA.ClientID) - clientState, ok = clientStateI.(*types.ClientState) - suite.Require().True(ok) - - prefix = suite.chainB.GetPrefix() - - // make channel proof - channelKey := host.ChannelKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) - proof, proofHeight = suite.chainB.QueryProof(channelKey) - - tc.malleate() // make changes as necessary - - store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - - err := clientState.VerifyChannelState( - store, suite.chainA.Codec, proofHeight, &prefix, proof, - path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, channel, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -// test verification of the packet commitment on chainB being represented -// in the light client on chainA. A send from chainB to chainA is simulated. -func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { - var ( - clientState *types.ClientState - proof []byte - delayTimePeriod uint64 - delayBlockPeriod uint64 - proofHeight exported.Height - prefix commitmenttypes.MerklePrefix - ) - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "successful verification", func() {}, true, - }, - { - name: "delay time period has passed", - malleate: func() { - delayTimePeriod = uint64(time.Second.Nanoseconds()) - }, - expPass: true, - }, - { - name: "delay time period has not passed", - malleate: func() { - delayTimePeriod = uint64(time.Hour.Nanoseconds()) - }, - expPass: false, - }, - { - name: "delay block period has passed", - malleate: func() { - delayBlockPeriod = 1 - }, - expPass: true, - }, - { - name: "delay block period has not passed", - malleate: func() { - delayBlockPeriod = 1000 - }, - expPass: false, - }, - - { - "ApplyPrefix failed", func() { - prefix = commitmenttypes.MerklePrefix{} - }, false, - }, - { - "latest client height < height", func() { - proofHeight = clientState.LatestHeight.Increment() - }, false, - }, - { - "proof verification failed", func() { - proof = invalidProof - }, false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - // setup testing conditions - path := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.Setup(path) - packet := channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, clienttypes.NewHeight(0, 100), 0) - err := path.EndpointB.SendPacket(packet) - suite.Require().NoError(err) - - var ok bool - clientStateI := suite.chainA.GetClientState(path.EndpointA.ClientID) - clientState, ok = clientStateI.(*types.ClientState) - suite.Require().True(ok) - - prefix = suite.chainB.GetPrefix() - - // make packet commitment proof - packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - proof, proofHeight = path.EndpointB.QueryProof(packetKey) - - // reset time and block delays to 0, malleate may change to a specific non-zero value. - delayTimePeriod = 0 - delayBlockPeriod = 0 - tc.malleate() // make changes as necessary - - ctx := suite.chainA.GetContext() - store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - - commitment := channeltypes.CommitPacket(suite.chainA.App.GetIBCKeeper().Codec(), packet) - err = clientState.VerifyPacketCommitment( - ctx, store, suite.chainA.Codec, proofHeight, delayTimePeriod, delayBlockPeriod, &prefix, proof, - packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -// test verification of the acknowledgement on chainB being represented -// in the light client on chainA. A send and ack from chainA to chainB -// is simulated. -func (suite *TendermintTestSuite) TestVerifyPacketAcknowledgement() { - var ( - clientState *types.ClientState - proof []byte - delayTimePeriod uint64 - delayBlockPeriod uint64 - proofHeight exported.Height - prefix commitmenttypes.MerklePrefix - ) - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "successful verification", func() {}, true, - }, - { - name: "delay time period has passed", - malleate: func() { - delayTimePeriod = uint64(time.Second.Nanoseconds()) - }, - expPass: true, - }, - { - name: "delay time period has not passed", - malleate: func() { - delayTimePeriod = uint64(time.Hour.Nanoseconds()) - }, - expPass: false, - }, - { - name: "delay block period has passed", - malleate: func() { - delayBlockPeriod = 1 - }, - expPass: true, - }, - { - name: "delay block period has not passed", - malleate: func() { - delayBlockPeriod = 10 - }, - expPass: false, - }, - - { - "ApplyPrefix failed", func() { - prefix = commitmenttypes.MerklePrefix{} - }, false, - }, - { - "latest client height < height", func() { - proofHeight = clientState.LatestHeight.Increment() - }, false, - }, - { - "proof verification failed", func() { - proof = invalidProof - }, false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - // setup testing conditions - path := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.Setup(path) - packet := channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) - - // send packet - err := path.EndpointA.SendPacket(packet) - suite.Require().NoError(err) - - // write receipt and ack - err = path.EndpointB.RecvPacket(packet) - suite.Require().NoError(err) - - var ok bool - clientStateI := suite.chainA.GetClientState(path.EndpointA.ClientID) - clientState, ok = clientStateI.(*types.ClientState) - suite.Require().True(ok) - - prefix = suite.chainB.GetPrefix() - - // make packet acknowledgement proof - acknowledgementKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) - proof, proofHeight = suite.chainB.QueryProof(acknowledgementKey) - - // reset time and block delays to 0, malleate may change to a specific non-zero value. - delayTimePeriod = 0 - delayBlockPeriod = 0 - tc.malleate() // make changes as necessary - - ctx := suite.chainA.GetContext() - store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - - err = clientState.VerifyPacketAcknowledgement( - ctx, store, suite.chainA.Codec, proofHeight, delayTimePeriod, delayBlockPeriod, &prefix, proof, - packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ibcmock.MockAcknowledgement.Acknowledgement(), - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -// test verification of the absent acknowledgement on chainB being represented -// in the light client on chainA. A send from chainB to chainA is simulated, but -// no receive. -func (suite *TendermintTestSuite) TestVerifyPacketReceiptAbsence() { - var ( - clientState *types.ClientState - proof []byte - delayTimePeriod uint64 - delayBlockPeriod uint64 - proofHeight exported.Height - prefix commitmenttypes.MerklePrefix - ) - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "successful verification", func() {}, true, - }, - { - name: "delay time period has passed", - malleate: func() { - delayTimePeriod = uint64(time.Second.Nanoseconds()) - }, - expPass: true, - }, - { - name: "delay time period has not passed", - malleate: func() { - delayTimePeriod = uint64(time.Hour.Nanoseconds()) - }, - expPass: false, - }, - { - name: "delay block period has passed", - malleate: func() { - delayBlockPeriod = 1 - }, - expPass: true, - }, - { - name: "delay block period has not passed", - malleate: func() { - delayBlockPeriod = 10 - }, - expPass: false, - }, - - { - "ApplyPrefix failed", func() { - prefix = commitmenttypes.MerklePrefix{} - }, false, - }, - { - "latest client height < height", func() { - proofHeight = clientState.LatestHeight.Increment() - }, false, - }, - { - "proof verification failed", func() { - proof = invalidProof - }, false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - // setup testing conditions - path := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.Setup(path) - packet := channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) - - // send packet, but no recv - err := path.EndpointA.SendPacket(packet) - suite.Require().NoError(err) - - var ok bool - clientStateI := suite.chainA.GetClientState(path.EndpointA.ClientID) - clientState, ok = clientStateI.(*types.ClientState) - suite.Require().True(ok) - - prefix = suite.chainB.GetPrefix() - - // make packet receipt absence proof - receiptKey := host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) - proof, proofHeight = path.EndpointB.QueryProof(receiptKey) - - // reset time and block delays to 0, malleate may change to a specific non-zero value. - delayTimePeriod = 0 - delayBlockPeriod = 0 - tc.malleate() // make changes as necessary - - ctx := suite.chainA.GetContext() - store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - - err = clientState.VerifyPacketReceiptAbsence( - ctx, store, suite.chainA.Codec, proofHeight, delayTimePeriod, delayBlockPeriod, &prefix, proof, - packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -// test verification of the next receive sequence on chainB being represented -// in the light client on chainA. A send and receive from chainB to chainA is -// simulated. -func (suite *TendermintTestSuite) TestVerifyNextSeqRecv() { - var ( - clientState *types.ClientState - proof []byte - delayTimePeriod uint64 - delayBlockPeriod uint64 - proofHeight exported.Height - prefix commitmenttypes.MerklePrefix - ) - - testCases := []struct { - name string - malleate func() - expPass bool - }{ - { - "successful verification", func() {}, true, - }, - { - name: "delay time period has passed", - malleate: func() { - delayTimePeriod = uint64(time.Second.Nanoseconds()) - }, - expPass: true, - }, - { - name: "delay time period has not passed", - malleate: func() { - delayTimePeriod = uint64(time.Hour.Nanoseconds()) - }, - expPass: false, - }, - { - name: "delay block period has passed", - malleate: func() { - delayBlockPeriod = 1 - }, - expPass: true, - }, - { - name: "delay block period has not passed", - malleate: func() { - delayBlockPeriod = 10 - }, - expPass: false, - }, - - { - "ApplyPrefix failed", func() { - prefix = commitmenttypes.MerklePrefix{} - }, false, - }, - { - "latest client height < height", func() { - proofHeight = clientState.LatestHeight.Increment() - }, false, - }, - { - "proof verification failed", func() { - proof = invalidProof - }, false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() // reset - - // setup testing conditions - path := ibctesting.NewPath(suite.chainA, suite.chainB) - path.SetChannelOrdered() - suite.coordinator.Setup(path) - packet := channeltypes.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) - - // send packet - err := path.EndpointA.SendPacket(packet) - suite.Require().NoError(err) - - // next seq recv incremented - err = path.EndpointB.RecvPacket(packet) - suite.Require().NoError(err) - - var ok bool - clientStateI := suite.chainA.GetClientState(path.EndpointA.ClientID) - clientState, ok = clientStateI.(*types.ClientState) - suite.Require().True(ok) - - prefix = suite.chainB.GetPrefix() - - // make next seq recv proof - nextSeqRecvKey := host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) - proof, proofHeight = suite.chainB.QueryProof(nextSeqRecvKey) - - // reset time and block delays to 0, malleate may change to a specific non-zero value. - delayTimePeriod = 0 - delayBlockPeriod = 0 - tc.malleate() // make changes as necessary - - ctx := suite.chainA.GetContext() - store := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - - err = clientState.VerifyNextSequenceRecv( - ctx, store, suite.chainA.Codec, proofHeight, delayTimePeriod, delayBlockPeriod, &prefix, proof, - packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()+1, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} diff --git a/modules/light-clients/07-tendermint/types/errors.go b/modules/light-clients/07-tendermint/types/errors.go deleted file mode 100644 index 7b087e41af5..00000000000 --- a/modules/light-clients/07-tendermint/types/errors.go +++ /dev/null @@ -1,26 +0,0 @@ -package types - -import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -const ( - SubModuleName = "tendermint-client" -) - -// IBC tendermint client sentinel errors -var ( - ErrInvalidChainID = sdkerrors.Register(SubModuleName, 2, "invalid chain-id") - ErrInvalidTrustingPeriod = sdkerrors.Register(SubModuleName, 3, "invalid trusting period") - ErrInvalidUnbondingPeriod = sdkerrors.Register(SubModuleName, 4, "invalid unbonding period") - ErrInvalidHeaderHeight = sdkerrors.Register(SubModuleName, 5, "invalid header height") - ErrInvalidHeader = sdkerrors.Register(SubModuleName, 6, "invalid header") - ErrInvalidMaxClockDrift = sdkerrors.Register(SubModuleName, 7, "invalid max clock drift") - ErrProcessedTimeNotFound = sdkerrors.Register(SubModuleName, 8, "processed time not found") - ErrProcessedHeightNotFound = sdkerrors.Register(SubModuleName, 9, "processed height not found") - ErrDelayPeriodNotPassed = sdkerrors.Register(SubModuleName, 10, "packet-specified delay period has not been reached") - ErrTrustingPeriodExpired = sdkerrors.Register(SubModuleName, 11, "time since latest trusted state has passed the trusting period") - ErrUnbondingPeriodExpired = sdkerrors.Register(SubModuleName, 12, "time since latest trusted state has passed the unbonding period") - ErrInvalidProofSpecs = sdkerrors.Register(SubModuleName, 13, "invalid proof specs") - ErrInvalidValidatorSet = sdkerrors.Register(SubModuleName, 14, "invalid validator set") -) diff --git a/modules/light-clients/07-tendermint/types/misbehaviour_handle.go b/modules/light-clients/07-tendermint/types/misbehaviour_handle.go deleted file mode 100644 index 0f8a8f9c76b..00000000000 --- a/modules/light-clients/07-tendermint/types/misbehaviour_handle.go +++ /dev/null @@ -1,143 +0,0 @@ -package types - -import ( - "bytes" - "time" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - tmtypes "github.com/tendermint/tendermint/types" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -// CheckMisbehaviourAndUpdateState determines whether or not two conflicting -// headers at the same height would have convinced the light client. -// -// NOTE: consensusState1 is the trusted consensus state that corresponds to the TrustedHeight -// of misbehaviour.Header1 -// Similarly, consensusState2 is the trusted consensus state that corresponds -// to misbehaviour.Header2 -// Misbehaviour sets frozen height to {0, 1} since it is only used as a boolean value (zero or non-zero). -func (cs ClientState) CheckMisbehaviourAndUpdateState( - ctx sdk.Context, - cdc codec.BinaryCodec, - clientStore sdk.KVStore, - misbehaviour exported.Misbehaviour, -) (exported.ClientState, error) { - tmMisbehaviour, ok := misbehaviour.(*Misbehaviour) - if !ok { - return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", misbehaviour, &Misbehaviour{}) - } - - // The status of the client is checked in 02-client - - // if heights are equal check that this is valid misbehaviour of a fork - // otherwise if heights are unequal check that this is valid misbehavior of BFT time violation - if tmMisbehaviour.Header1.GetHeight().EQ(tmMisbehaviour.Header2.GetHeight()) { - blockID1, err := tmtypes.BlockIDFromProto(&tmMisbehaviour.Header1.SignedHeader.Commit.BlockID) - if err != nil { - return nil, sdkerrors.Wrap(err, "invalid block ID from header 1 in misbehaviour") - } - blockID2, err := tmtypes.BlockIDFromProto(&tmMisbehaviour.Header2.SignedHeader.Commit.BlockID) - if err != nil { - return nil, sdkerrors.Wrap(err, "invalid block ID from header 2 in misbehaviour") - } - - // Ensure that Commit Hashes are different - if bytes.Equal(blockID1.Hash, blockID2.Hash) { - return nil, sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers block hashes are equal") - } - } else { - // Header1 is at greater height than Header2, therefore Header1 time must be less than or equal to - // Header2 time in order to be valid misbehaviour (violation of monotonic time). - if tmMisbehaviour.Header1.SignedHeader.Header.Time.After(tmMisbehaviour.Header2.SignedHeader.Header.Time) { - return nil, sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers are not at same height and are monotonically increasing") - } - } - - // Regardless of the type of misbehaviour, ensure that both headers are valid and would have been accepted by light-client - - // Retrieve trusted consensus states for each Header in misbehaviour - // and unmarshal from clientStore - - // Get consensus bytes from clientStore - tmConsensusState1, err := GetConsensusState(clientStore, cdc, tmMisbehaviour.Header1.TrustedHeight) - if err != nil { - return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header1 at TrustedHeight: %s", tmMisbehaviour.Header1) - } - - // Get consensus bytes from clientStore - tmConsensusState2, err := GetConsensusState(clientStore, cdc, tmMisbehaviour.Header2.TrustedHeight) - if err != nil { - return nil, sdkerrors.Wrapf(err, "could not get trusted consensus state from clientStore for Header2 at TrustedHeight: %s", tmMisbehaviour.Header2) - } - - // Check the validity of the two conflicting headers against their respective - // trusted consensus states - // NOTE: header height and commitment root assertions are checked in - // misbehaviour.ValidateBasic by the client keeper and msg.ValidateBasic - // by the base application. - if err := checkMisbehaviourHeader( - &cs, tmConsensusState1, tmMisbehaviour.Header1, ctx.BlockTime(), - ); err != nil { - return nil, sdkerrors.Wrap(err, "verifying Header1 in Misbehaviour failed") - } - if err := checkMisbehaviourHeader( - &cs, tmConsensusState2, tmMisbehaviour.Header2, ctx.BlockTime(), - ); err != nil { - return nil, sdkerrors.Wrap(err, "verifying Header2 in Misbehaviour failed") - } - - cs.FrozenHeight = FrozenHeight - - return &cs, nil -} - -// checkMisbehaviourHeader checks that a Header in Misbehaviour is valid misbehaviour given -// a trusted ConsensusState -func checkMisbehaviourHeader( - clientState *ClientState, consState *ConsensusState, header *Header, currentTimestamp time.Time, -) error { - tmTrustedValset, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators) - if err != nil { - return sdkerrors.Wrap(err, "trusted validator set is not tendermint validator set type") - } - - tmCommit, err := tmtypes.CommitFromProto(header.Commit) - if err != nil { - return sdkerrors.Wrap(err, "commit is not tendermint commit type") - } - - // check the trusted fields for the header against ConsensusState - if err := checkTrustedHeader(header, consState); err != nil { - return err - } - - // assert that the age of the trusted consensus state is not older than the trusting period - if currentTimestamp.Sub(consState.Timestamp) >= clientState.TrustingPeriod { - return sdkerrors.Wrapf( - ErrTrustingPeriodExpired, - "current timestamp minus the latest consensus state timestamp is greater than or equal to the trusting period (%d >= %d)", - currentTimestamp.Sub(consState.Timestamp), clientState.TrustingPeriod, - ) - } - - chainID := clientState.GetChainID() - // If chainID is in revision format, then set revision number of chainID with the revision number - // of the misbehaviour header - if clienttypes.IsRevisionFormat(chainID) { - chainID, _ = clienttypes.SetRevisionNumber(chainID, header.GetHeight().GetRevisionNumber()) - } - - // - ValidatorSet must have TrustLevel similarity with trusted FromValidatorSet - // - ValidatorSets on both headers are valid given the last trusted ValidatorSet - if err := tmTrustedValset.VerifyCommitLightTrusting( - chainID, tmCommit, clientState.TrustLevel.ToTendermint(), - ); err != nil { - return sdkerrors.Wrapf(clienttypes.ErrInvalidMisbehaviour, "validator set in header has too much change from trusted validator set: %v", err) - } - return nil -} diff --git a/modules/light-clients/07-tendermint/types/misbehaviour_handle_test.go b/modules/light-clients/07-tendermint/types/misbehaviour_handle_test.go deleted file mode 100644 index 92711275887..00000000000 --- a/modules/light-clients/07-tendermint/types/misbehaviour_handle_test.go +++ /dev/null @@ -1,425 +0,0 @@ -package types_test - -import ( - "fmt" - "time" - - "github.com/tendermint/tendermint/crypto/tmhash" - tmtypes "github.com/tendermint/tendermint/types" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctestingmock "github.com/cosmos/ibc-go/v4/testing/mock" -) - -func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { - altPrivVal := ibctestingmock.NewPV() - altPubKey, err := altPrivVal.GetPubKey() - suite.Require().NoError(err) - - altVal := tmtypes.NewValidator(altPubKey, 4) - - // Create alternative validator set with only altVal - altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) - - // Create bothValSet with both suite validator and altVal - bothValSet, bothSigners := getBothSigners(suite, altVal, altPrivVal) - bothValsHash := bothValSet.Hash() - - altSigners := getAltSigners(altVal, altPrivVal) - - heightMinus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-1) - heightMinus3 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-3) - - testCases := []struct { - name string - clientState exported.ClientState - consensusState1 exported.ConsensusState - height1 clienttypes.Height - consensusState2 exported.ConsensusState - height2 clienttypes.Height - misbehaviour exported.Misbehaviour - timestamp time.Time - expPass bool - }{ - { - "valid fork misbehaviour", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "valid time misbehaviour", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+3), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "valid time misbehaviour header 1 stricly less than header 2", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+3), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Hour), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "valid misbehavior at height greater than last consensusState", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "valid misbehaviour with different trusted heights", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), - heightMinus3, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, suite.valSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "valid misbehaviour at a previous revision", - types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), - heightMinus3, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight+1), heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight+1), heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, suite.valSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "valid misbehaviour at a future revision", - types.NewClientState(chainIDRevision0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), - heightMinus3, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDRevision0, 3, heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDRevision0, 3, heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, suite.valSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "valid misbehaviour with trusted heights at a previous revision", - types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), - heightMinus3, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, suite.valSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "consensus state's valset hash different from misbehaviour should still pass", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, suite.valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, suite.valSet, bothSigners), - ClientId: chainID, - }, - suite.now, - true, - }, - { - "invalid fork misbehaviour: identical headers", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "invalid time misbehaviour: monotonically increasing time", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+3), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "invalid misbehavior misbehaviour from different chain", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "invalid misbehavior misbehaviour with trusted height different from trusted consensus state", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), - heightMinus3, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, suite.valSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "invalid misbehavior misbehaviour with trusted validators different from trusted consensus state", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), - heightMinus3, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "already frozen client state", - &types.ClientState{FrozenHeight: clienttypes.NewHeight(0, 1)}, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "trusted consensus state does not exist", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - nil, // consensus state for trusted height - 1 does not exist in store - clienttypes.Height{}, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "invalid tendermint misbehaviour", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - nil, - suite.now, - false, - }, - { - "provided height > header height", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "trusting period expired", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(time.Time{}, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - heightMinus1, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), heightMinus1, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now.Add(trustingPeriod), - false, - }, - { - "trusted validators is incorrect for given consensus state", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, suite.valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, suite.valSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "first valset has too much change", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, altValSet, altValSet, bothValSet, altSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothValSet, bothSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "second valset has too much change", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, bothValSet, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), altValSet, altValSet, bothValSet, altSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - { - "both valsets have too much change", - types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), - height, - &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now, altValSet, altValSet, bothValSet, altSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight+1), height, suite.now.Add(time.Minute), altValSet, altValSet, bothValSet, altSigners), - ClientId: chainID, - }, - suite.now, - false, - }, - } - - for i, tc := range testCases { - tc := tc - suite.Run(fmt.Sprintf("Case: %s", tc.name), func() { - // reset suite to create fresh application state - suite.SetupTest() - - // Set current timestamp in context - ctx := suite.chainA.GetContext().WithBlockTime(tc.timestamp) - - // Set trusted consensus states in client store - - if tc.consensusState1 != nil { - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(ctx, clientID, tc.height1, tc.consensusState1) - } - if tc.consensusState2 != nil { - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(ctx, clientID, tc.height2, tc.consensusState2) - } - - clientState, err := tc.clientState.CheckMisbehaviourAndUpdateState( - ctx, - suite.chainA.App.AppCodec(), - suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, clientID), // pass in clientID prefixed clientStore - tc.misbehaviour, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - suite.Require().NotNil(clientState, "valid test case %d failed: %s", i, tc.name) - suite.Require().True(!clientState.(*types.ClientState).FrozenHeight.IsZero(), "valid test case %d failed: %s", i, tc.name) - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - suite.Require().Nil(clientState, "invalid test case %d passed: %s", i, tc.name) - } - }) - } -} diff --git a/modules/light-clients/07-tendermint/types/update.go b/modules/light-clients/07-tendermint/types/update.go deleted file mode 100644 index b75e9ddbf9e..00000000000 --- a/modules/light-clients/07-tendermint/types/update.go +++ /dev/null @@ -1,263 +0,0 @@ -package types - -import ( - "bytes" - "reflect" - "time" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/tendermint/tendermint/light" - tmtypes "github.com/tendermint/tendermint/types" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -// CheckHeaderAndUpdateState checks if the provided header is valid, and if valid it will: -// create the consensus state for the header.Height -// and update the client state if the header height is greater than the latest client state height -// It returns an error if: -// - the client or header provided are not parseable to tendermint types -// - the header is invalid -// - header height is less than or equal to the trusted header height -// - header revision is not equal to trusted header revision -// - header valset commit verification fails -// - header timestamp is past the trusting period in relation to the consensus state -// - header timestamp is less than or equal to the consensus state timestamp -// -// UpdateClient may be used to either create a consensus state for: -// - a future height greater than the latest client state height -// - a past height that was skipped during bisection -// If we are updating to a past height, a consensus state is created for that height to be persisted in client store -// If we are updating to a future height, the consensus state is created and the client state is updated to reflect -// the new latest height -// UpdateClient must only be used to update within a single revision, thus header revision number and trusted height's revision -// number must be the same. To update to a new revision, use a separate upgrade path -// Tendermint client validity checking uses the bisection algorithm described -// in the [Tendermint spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md). -// -// Misbehaviour Detection: -// UpdateClient will detect implicit misbehaviour by enforcing certain invariants on any new update call and will return a frozen client. -// 1. Any valid update that creates a different consensus state for an already existing height is evidence of misbehaviour and will freeze client. -// 2. Any valid update that breaks time monotonicity with respect to its neighboring consensus states is evidence of misbehaviour and will freeze client. -// Misbehaviour sets frozen height to {0, 1} since it is only used as a boolean value (zero or non-zero). -// -// Pruning: -// UpdateClient will additionally retrieve the earliest consensus state for this clientID and check if it is expired. If it is, -// that consensus state will be pruned from store along with all associated metadata. This will prevent the client store from -// becoming bloated with expired consensus states that can no longer be used for updates and packet verification. -func (cs ClientState) CheckHeaderAndUpdateState( - ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, - header exported.Header, -) (exported.ClientState, exported.ConsensusState, error) { - tmHeader, ok := header.(*Header) - if !ok { - return nil, nil, sdkerrors.Wrapf( - clienttypes.ErrInvalidHeader, "expected type %T, got %T", &Header{}, header, - ) - } - - // Check if the Client store already has a consensus state for the header's height - // If the consensus state exists, and it matches the header then we return early - // since header has already been submitted in a previous UpdateClient. - var conflictingHeader bool - prevConsState, _ := GetConsensusState(clientStore, cdc, header.GetHeight()) - if prevConsState != nil { - // This header has already been submitted and the necessary state is already stored - // in client store, thus we can return early without further validation. - if reflect.DeepEqual(prevConsState, tmHeader.ConsensusState()) { - return &cs, prevConsState, nil - } - // A consensus state already exists for this height, but it does not match the provided header. - // Thus, we must check that this header is valid, and if so we will freeze the client. - conflictingHeader = true - } - - // get consensus state from clientStore - trustedConsState, err := GetConsensusState(clientStore, cdc, tmHeader.TrustedHeight) - if err != nil { - return nil, nil, sdkerrors.Wrapf( - err, "could not get consensus state from clientstore at TrustedHeight: %s", tmHeader.TrustedHeight, - ) - } - - if err := checkValidity(&cs, trustedConsState, tmHeader, ctx.BlockTime()); err != nil { - return nil, nil, err - } - - consState := tmHeader.ConsensusState() - // Header is different from existing consensus state and also valid, so freeze the client and return - if conflictingHeader { - cs.FrozenHeight = FrozenHeight - return &cs, consState, nil - } - // Check that consensus state timestamps are monotonic - prevCons, prevOk := GetPreviousConsensusState(clientStore, cdc, header.GetHeight()) - nextCons, nextOk := GetNextConsensusState(clientStore, cdc, header.GetHeight()) - // if previous consensus state exists, check consensus state time is greater than previous consensus state time - // if previous consensus state is not before current consensus state, freeze the client and return. - if prevOk && !prevCons.Timestamp.Before(consState.Timestamp) { - cs.FrozenHeight = FrozenHeight - return &cs, consState, nil - } - // if next consensus state exists, check consensus state time is less than next consensus state time - // if next consensus state is not after current consensus state, freeze the client and return. - if nextOk && !nextCons.Timestamp.After(consState.Timestamp) { - cs.FrozenHeight = FrozenHeight - return &cs, consState, nil - } - - // Check the earliest consensus state to see if it is expired, if so then set the prune height - // so that we can delete consensus state and all associated metadata. - var ( - pruneHeight exported.Height - pruneError error - ) - pruneCb := func(height exported.Height) bool { - consState, err := GetConsensusState(clientStore, cdc, height) - // this error should never occur - if err != nil { - pruneError = err - return true - } - if cs.IsExpired(consState.Timestamp, ctx.BlockTime()) { - pruneHeight = height - } - return true - } - IterateConsensusStateAscending(clientStore, pruneCb) - if pruneError != nil { - return nil, nil, pruneError - } - // if pruneHeight is set, delete consensus state and metadata - if pruneHeight != nil { - deleteConsensusState(clientStore, pruneHeight) - deleteConsensusMetadata(clientStore, pruneHeight) - } - - newClientState, consensusState := update(ctx, clientStore, &cs, tmHeader) - return newClientState, consensusState, nil -} - -// checkTrustedHeader checks that consensus state matches trusted fields of Header -func checkTrustedHeader(header *Header, consState *ConsensusState) error { - tmTrustedValidators, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators) - if err != nil { - return sdkerrors.Wrap(err, "trusted validator set in not tendermint validator set type") - } - - // assert that trustedVals is NextValidators of last trusted header - // to do this, we check that trustedVals.Hash() == consState.NextValidatorsHash - tvalHash := tmTrustedValidators.Hash() - if !bytes.Equal(consState.NextValidatorsHash, tvalHash) { - return sdkerrors.Wrapf( - ErrInvalidValidatorSet, - "trusted validators %s, does not hash to latest trusted validators. Expected: %X, got: %X", - header.TrustedValidators, consState.NextValidatorsHash, tvalHash, - ) - } - return nil -} - -// checkValidity checks if the Tendermint header is valid. -// CONTRACT: consState.Height == header.TrustedHeight -func checkValidity( - clientState *ClientState, consState *ConsensusState, - header *Header, currentTimestamp time.Time, -) error { - if err := checkTrustedHeader(header, consState); err != nil { - return err - } - - // UpdateClient only accepts updates with a header at the same revision - // as the trusted consensus state - if header.GetHeight().GetRevisionNumber() != header.TrustedHeight.RevisionNumber { - return sdkerrors.Wrapf( - ErrInvalidHeaderHeight, - "header height revision %d does not match trusted header revision %d", - header.GetHeight().GetRevisionNumber(), header.TrustedHeight.RevisionNumber, - ) - } - - tmTrustedValidators, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators) - if err != nil { - return sdkerrors.Wrap(err, "trusted validator set in not tendermint validator set type") - } - - tmSignedHeader, err := tmtypes.SignedHeaderFromProto(header.SignedHeader) - if err != nil { - return sdkerrors.Wrap(err, "signed header in not tendermint signed header type") - } - - tmValidatorSet, err := tmtypes.ValidatorSetFromProto(header.ValidatorSet) - if err != nil { - return sdkerrors.Wrap(err, "validator set in not tendermint validator set type") - } - - // assert header height is newer than consensus state - if header.GetHeight().LTE(header.TrustedHeight) { - return sdkerrors.Wrapf( - clienttypes.ErrInvalidHeader, - "header height ≤ consensus state height (%s ≤ %s)", header.GetHeight(), header.TrustedHeight, - ) - } - - chainID := clientState.GetChainID() - // If chainID is in revision format, then set revision number of chainID with the revision number - // of the header we are verifying - // This is useful if the update is at a previous revision rather than an update to the latest revision - // of the client. - // The chainID must be set correctly for the previous revision before attempting verification. - // Updates for previous revisions are not supported if the chainID is not in revision format. - if clienttypes.IsRevisionFormat(chainID) { - chainID, _ = clienttypes.SetRevisionNumber(chainID, header.GetHeight().GetRevisionNumber()) - } - - // Construct a trusted header using the fields in consensus state - // Only Height, Time, and NextValidatorsHash are necessary for verification - trustedHeader := tmtypes.Header{ - ChainID: chainID, - Height: int64(header.TrustedHeight.RevisionHeight), - Time: consState.Timestamp, - NextValidatorsHash: consState.NextValidatorsHash, - } - signedHeader := tmtypes.SignedHeader{ - Header: &trustedHeader, - } - - // Verify next header with the passed-in trustedVals - // - asserts trusting period not passed - // - assert header timestamp is not past the trusting period - // - assert header timestamp is past latest stored consensus state timestamp - // - assert that a TrustLevel proportion of TrustedValidators signed new Commit - err = light.Verify( - &signedHeader, - tmTrustedValidators, tmSignedHeader, tmValidatorSet, - clientState.TrustingPeriod, currentTimestamp, clientState.MaxClockDrift, clientState.TrustLevel.ToTendermint(), - ) - if err != nil { - return sdkerrors.Wrap(err, "failed to verify header") - } - return nil -} - -// update the consensus state from a new header and set processed time metadata -func update(ctx sdk.Context, clientStore sdk.KVStore, clientState *ClientState, header *Header) (*ClientState, *ConsensusState) { - height := header.GetHeight().(clienttypes.Height) - if height.GT(clientState.LatestHeight) { - clientState.LatestHeight = height - } - consensusState := &ConsensusState{ - Timestamp: header.GetTime(), - Root: commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), - NextValidatorsHash: header.Header.NextValidatorsHash, - } - - // set metadata for this consensus state - setConsensusMetadata(ctx, clientStore, header.GetHeight()) - - return clientState, consensusState -} diff --git a/modules/light-clients/07-tendermint/types/update_test.go b/modules/light-clients/07-tendermint/types/update_test.go deleted file mode 100644 index 9dae5d56f7d..00000000000 --- a/modules/light-clients/07-tendermint/types/update_test.go +++ /dev/null @@ -1,450 +0,0 @@ -package types_test - -import ( - "fmt" - "time" - - tmtypes "github.com/tendermint/tendermint/types" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - types "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" - ibctestingmock "github.com/cosmos/ibc-go/v4/testing/mock" -) - -func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { - var ( - clientState *types.ClientState - consensusState *types.ConsensusState - consStateHeight clienttypes.Height - newHeader *types.Header - currentTime time.Time - bothValSet *tmtypes.ValidatorSet - bothSigners map[string]tmtypes.PrivValidator - ) - - // Setup different validators and signers for testing different types of updates - altPrivVal := ibctestingmock.NewPV() - altPubKey, err := altPrivVal.GetPubKey() - suite.Require().NoError(err) - - revisionHeight := int64(height.RevisionHeight) - - // create modified heights to use for test-cases - heightPlus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight+1) - heightMinus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-1) - heightMinus3 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-3) - heightPlus5 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight+5) - - altVal := tmtypes.NewValidator(altPubKey, revisionHeight) - // Create alternative validator set with only altVal, invalid update (too much change in valSet) - altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) - altSigners := getAltSigners(altVal, altPrivVal) - - testCases := []struct { - name string - setup func(*TendermintTestSuite) - expFrozen bool - expPass bool - }{ - { - name: "successful update with next height and same validator set", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - }, - expFrozen: false, - expPass: true, - }, - { - name: "successful update with future height and different validator set", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, bothValSet, bothValSet, suite.valSet, bothSigners) - currentTime = suite.now - }, - expFrozen: false, - expPass: true, - }, - { - name: "successful update with next height and different validator set", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), bothValSet.Hash()) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, bothValSet, bothValSet, bothValSet, bothSigners) - currentTime = suite.now - }, - expFrozen: false, - expPass: true, - }, - { - name: "successful update for a previous height", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - consStateHeight = heightMinus3 - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.RevisionHeight), heightMinus3, suite.headerTime, bothValSet, bothValSet, suite.valSet, bothSigners) - currentTime = suite.now - }, - expFrozen: false, - expPass: true, - }, - { - name: "successful update for a previous revision", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - consStateHeight = heightMinus3 - newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight), heightMinus3, suite.headerTime, bothValSet, bothValSet, suite.valSet, bothSigners) - currentTime = suite.now - }, - expPass: true, - }, - { - name: "successful update with identical header to a previous update", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, heightPlus1, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - ctx := suite.chainA.GetContext().WithBlockTime(currentTime) - // Store the header's consensus state in client store before UpdateClient call - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(ctx, clientID, heightPlus1, newHeader.ConsensusState()) - }, - expFrozen: false, - expPass: true, - }, - { - name: "misbehaviour detection: header conflicts with existing consensus state", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, heightPlus1, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - ctx := suite.chainA.GetContext().WithBlockTime(currentTime) - // Change the consensus state of header and store in client store to create a conflict - conflictConsState := newHeader.ConsensusState() - conflictConsState.Root = commitmenttypes.NewMerkleRoot([]byte("conflicting apphash")) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(ctx, clientID, heightPlus1, conflictConsState) - }, - expFrozen: true, - expPass: true, - }, - { - name: "misbehaviour detection: previous consensus state time is not before header time. time monotonicity violation", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - // create an intermediate consensus state with the same time as the newHeader to create a time violation. - // header time is after client time - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - prevConsensusState := types.NewConsensusState(suite.headerTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - ctx := suite.chainA.GetContext().WithBlockTime(currentTime) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(ctx, clientID, heightPlus1, prevConsensusState) - clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, clientID) - types.SetIterationKey(clientStore, heightPlus1) - }, - expFrozen: true, - expPass: true, - }, - { - name: "misbehaviour detection: next consensus state time is not after header time. time monotonicity violation", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - // create the next consensus state with the same time as the intermediate newHeader to create a time violation. - // header time is after clientTime - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - nextConsensusState := types.NewConsensusState(suite.headerTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - ctx := suite.chainA.GetContext().WithBlockTime(currentTime) - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(ctx, clientID, heightPlus5, nextConsensusState) - clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, clientID) - types.SetIterationKey(clientStore, heightPlus5) - }, - expFrozen: true, - expPass: true, - }, - { - name: "unsuccessful update with incorrect header chain-id", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader("ethermint", int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "unsuccessful update to a future revision", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainIDRevision0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - }, - expPass: false, - }, - { - name: "unsuccessful update: header height revision and trusted height revision mismatch", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision1, 3, height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "unsuccessful update with next height: update header mismatches nextValSetHash", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, bothValSet, bothValSet, suite.valSet, bothSigners) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "unsuccessful update with next height: update header mismatches different nextValSetHash", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), bothValSet.Hash()) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, bothValSet, suite.signers) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "unsuccessful update with future height: too much change in validator set", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, altValSet, altValSet, suite.valSet, altSigners) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "unsuccessful updates, passed in incorrect trusted validators for given consensus state", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, bothValSet, bothValSet, bothValSet, bothSigners) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "unsuccessful update: trusting period has passed since last client timestamp", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - // make current time pass trusting period from last timestamp on clientstate - currentTime = suite.now.Add(trustingPeriod) - }, - expFrozen: false, - expPass: false, - }, - { - name: "unsuccessful update: header timestamp is past current timestamp", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "unsuccessful update: header timestamp is not past last client timestamp", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.clientTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "header basic validation failed", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - // cause new header to fail validatebasic by changing commit height to mismatch header height - newHeader.SignedHeader.Commit.Height = revisionHeight - 1 - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - { - name: "header height < consensus height", - setup: func(suite *TendermintTestSuite) { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(height.RevisionNumber, heightPlus5.RevisionHeight), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - // Make new header at height less than latest client state - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, suite.valSet, suite.signers) - currentTime = suite.now - }, - expFrozen: false, - expPass: false, - }, - } - - for i, tc := range testCases { - tc := tc - suite.Run(fmt.Sprintf("Case: %s", tc.name), func() { - suite.SetupTest() // reset metadata writes - // Create bothValSet with both suite validator and altVal. Would be valid update - bothValSet, bothSigners = getBothSigners(suite, altVal, altPrivVal) - - consStateHeight = height // must be explicitly changed - // setup test - tc.setup(suite) - - // Set current timestamp in context - ctx := suite.chainA.GetContext().WithBlockTime(currentTime) - - // Set trusted consensus state in client store - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(ctx, clientID, consStateHeight, consensusState) - - height := newHeader.GetHeight() - expectedConsensus := &types.ConsensusState{ - Timestamp: newHeader.GetTime(), - Root: commitmenttypes.NewMerkleRoot(newHeader.Header.GetAppHash()), - NextValidatorsHash: newHeader.Header.NextValidatorsHash, - } - - newClientState, consensusState, err := clientState.CheckHeaderAndUpdateState( - ctx, - suite.cdc, - suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), clientID), // pass in clientID prefixed clientStore - newHeader, - ) - - if tc.expPass { - suite.Require().NoError(err, "valid test case %d failed: %s", i, tc.name) - - suite.Require().Equal(tc.expFrozen, !newClientState.(*types.ClientState).FrozenHeight.IsZero(), "client state status is unexpected after update") - - // further writes only happen if update is not misbehaviour - if !tc.expFrozen { - // Determine if clientState should be updated or not - // TODO: check the entire Height struct once GetLatestHeight returns clienttypes.Height - if height.GT(clientState.LatestHeight) { - // Header Height is greater than clientState latest Height, clientState should be updated with header.GetHeight() - suite.Require().Equal(height, newClientState.GetLatestHeight(), "clientstate height did not update") - } else { - // Update will add past consensus state, clientState should not be updated at all - suite.Require().Equal(clientState.LatestHeight, newClientState.GetLatestHeight(), "client state height updated for past header") - } - - suite.Require().Equal(expectedConsensus, consensusState, "valid test case %d failed: %s", i, tc.name) - } - } else { - suite.Require().Error(err, "invalid test case %d passed: %s", i, tc.name) - suite.Require().Nil(newClientState, "invalid test case %d passed: %s", i, tc.name) - suite.Require().Nil(consensusState, "invalid test case %d passed: %s", i, tc.name) - } - }) - } -} - -func (suite *TendermintTestSuite) TestPruneConsensusState() { - // create path and setup clients - path := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(path) - - // get the first height as it will be pruned first. - var pruneHeight exported.Height - getFirstHeightCb := func(height exported.Height) bool { - pruneHeight = height - return true - } - ctx := path.EndpointA.Chain.GetContext() - clientStore := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - err := types.IterateConsensusStateAscending(clientStore, getFirstHeightCb) - suite.Require().Nil(err) - - // this height will be expired but not pruned - path.EndpointA.UpdateClient() - expiredHeight := path.EndpointA.GetClientState().GetLatestHeight() - - // expected values that must still remain in store after pruning - expectedConsState, ok := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, expiredHeight) - suite.Require().True(ok) - ctx = path.EndpointA.Chain.GetContext() - clientStore = path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - expectedProcessTime, ok := types.GetProcessedTime(clientStore, expiredHeight) - suite.Require().True(ok) - expectedProcessHeight, ok := types.GetProcessedHeight(clientStore, expiredHeight) - suite.Require().True(ok) - expectedConsKey := types.GetIterationKey(clientStore, expiredHeight) - suite.Require().NotNil(expectedConsKey) - - // Increment the time by a week - suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) - - // create the consensus state that can be used as trusted height for next update - path.EndpointA.UpdateClient() - - // Increment the time by another week, then update the client. - // This will cause the first two consensus states to become expired. - suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) - path.EndpointA.UpdateClient() - - ctx = path.EndpointA.Chain.GetContext() - clientStore = path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) - - // check that the first expired consensus state got deleted along with all associated metadata - consState, ok := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) - suite.Require().Nil(consState, "expired consensus state not pruned") - suite.Require().False(ok) - // check processed time metadata is pruned - processTime, ok := types.GetProcessedTime(clientStore, pruneHeight) - suite.Require().Equal(uint64(0), processTime, "processed time metadata not pruned") - suite.Require().False(ok) - processHeight, ok := types.GetProcessedHeight(clientStore, pruneHeight) - suite.Require().Nil(processHeight, "processed height metadata not pruned") - suite.Require().False(ok) - - // check iteration key metadata is pruned - consKey := types.GetIterationKey(clientStore, pruneHeight) - suite.Require().Nil(consKey, "iteration key not pruned") - - // check that second expired consensus state doesn't get deleted - // this ensures that there is a cap on gas cost of UpdateClient - consState, ok = path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, expiredHeight) - suite.Require().Equal(expectedConsState, consState, "consensus state incorrectly pruned") - suite.Require().True(ok) - // check processed time metadata is not pruned - processTime, ok = types.GetProcessedTime(clientStore, expiredHeight) - suite.Require().Equal(expectedProcessTime, processTime, "processed time metadata incorrectly pruned") - suite.Require().True(ok) - - // check processed height metadata is not pruned - processHeight, ok = types.GetProcessedHeight(clientStore, expiredHeight) - suite.Require().Equal(expectedProcessHeight, processHeight, "processed height metadata incorrectly pruned") - suite.Require().True(ok) - - // check iteration key metadata is not pruned - consKey = types.GetIterationKey(clientStore, expiredHeight) - suite.Require().Equal(expectedConsKey, consKey, "iteration key incorrectly pruned") -} diff --git a/modules/light-clients/07-tendermint/update.go b/modules/light-clients/07-tendermint/update.go new file mode 100644 index 00000000000..fbd70e0fb27 --- /dev/null +++ b/modules/light-clients/07-tendermint/update.go @@ -0,0 +1,223 @@ +package tendermint + +import ( + "bytes" + "fmt" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/light" + tmtypes "github.com/tendermint/tendermint/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" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" +) + +// VerifyClientMessage checks if the clientMessage is of type Header or Misbehaviour and verifies the message +func (cs *ClientState) VerifyClientMessage( + ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, + clientMsg exported.ClientMessage, +) error { + switch msg := clientMsg.(type) { + case *Header: + return cs.verifyHeader(ctx, clientStore, cdc, msg) + case *Misbehaviour: + return cs.verifyMisbehaviour(ctx, clientStore, cdc, msg) + default: + return clienttypes.ErrInvalidClientType + } +} + +// verifyHeader returns an error if: +// - the client or header provided are not parseable to tendermint types +// - the header is invalid +// - header height is less than or equal to the trusted header height +// - header revision is not equal to trusted header revision +// - header valset commit verification fails +// - header timestamp is past the trusting period in relation to the consensus state +// - header timestamp is less than or equal to the consensus state timestamp +func (cs *ClientState) verifyHeader( + ctx sdk.Context, clientStore sdk.KVStore, cdc codec.BinaryCodec, + header *Header, +) error { + currentTimestamp := ctx.BlockTime() + + // Retrieve trusted consensus states for each Header in misbehaviour + consState, found := GetConsensusState(clientStore, cdc, header.TrustedHeight) + if !found { + return errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "could not get trusted consensus state from clientStore for Header at TrustedHeight: %s", header.TrustedHeight) + } + + if err := checkTrustedHeader(header, consState); err != nil { + return err + } + + // UpdateClient only accepts updates with a header at the same revision + // as the trusted consensus state + if header.GetHeight().GetRevisionNumber() != header.TrustedHeight.RevisionNumber { + return errorsmod.Wrapf( + ErrInvalidHeaderHeight, + "header height revision %d does not match trusted header revision %d", + header.GetHeight().GetRevisionNumber(), header.TrustedHeight.RevisionNumber, + ) + } + + tmTrustedValidators, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators) + if err != nil { + return errorsmod.Wrap(err, "trusted validator set in not tendermint validator set type") + } + + tmSignedHeader, err := tmtypes.SignedHeaderFromProto(header.SignedHeader) + if err != nil { + return errorsmod.Wrap(err, "signed header in not tendermint signed header type") + } + + tmValidatorSet, err := tmtypes.ValidatorSetFromProto(header.ValidatorSet) + if err != nil { + return errorsmod.Wrap(err, "validator set in not tendermint validator set type") + } + + // assert header height is newer than consensus state + if header.GetHeight().LTE(header.TrustedHeight) { + return errorsmod.Wrapf( + clienttypes.ErrInvalidHeader, + "header height ≤ consensus state height (%s ≤ %s)", header.GetHeight(), header.TrustedHeight, + ) + } + + // Construct a trusted header using the fields in consensus state + // Only Height, Time, and NextValidatorsHash are necessary for verification + // NOTE: updates must be within the same revision + trustedHeader := tmtypes.Header{ + ChainID: cs.GetChainID(), + Height: int64(header.TrustedHeight.RevisionHeight), + Time: consState.Timestamp, + NextValidatorsHash: consState.NextValidatorsHash, + } + signedHeader := tmtypes.SignedHeader{ + Header: &trustedHeader, + } + + // Verify next header with the passed-in trustedVals + // - asserts trusting period not passed + // - assert header timestamp is not past the trusting period + // - assert header timestamp is past latest stored consensus state timestamp + // - assert that a TrustLevel proportion of TrustedValidators signed new Commit + err = light.Verify( + &signedHeader, + tmTrustedValidators, tmSignedHeader, tmValidatorSet, + cs.TrustingPeriod, currentTimestamp, cs.MaxClockDrift, cs.TrustLevel.ToTendermint(), + ) + if err != nil { + return errorsmod.Wrap(err, "failed to verify header") + } + + return nil +} + +// UpdateState may be used to either create a consensus state for: +// - a future height greater than the latest client state height +// - a past height that was skipped during bisection +// If we are updating to a past height, a consensus state is created for that height to be persisted in client store +// If we are updating to a future height, the consensus state is created and the client state is updated to reflect +// the new latest height +// A list containing the updated consensus height is returned. +// UpdateState must only be used to update within a single revision, thus header revision number and trusted height's revision +// number must be the same. To update to a new revision, use a separate upgrade path +// UpdateState will prune the oldest consensus state if it is expired. +func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) []exported.Height { + header, ok := clientMsg.(*Header) + if !ok { + panic(fmt.Errorf("expected type %T, got %T", &Header{}, clientMsg)) + } + + cs.pruneOldestConsensusState(ctx, cdc, clientStore) + + // check for duplicate update + if consensusState, _ := GetConsensusState(clientStore, cdc, header.GetHeight()); consensusState != nil { + // perform no-op + return []exported.Height{header.GetHeight()} + } + + height := header.GetHeight().(clienttypes.Height) + if height.GT(cs.LatestHeight) { + cs.LatestHeight = height + } + + consensusState := &ConsensusState{ + Timestamp: header.GetTime(), + Root: commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), + NextValidatorsHash: header.Header.NextValidatorsHash, + } + + // set client state, consensus state and asssociated metadata + setClientState(clientStore, cdc, &cs) + setConsensusState(clientStore, cdc, consensusState, header.GetHeight()) + setConsensusMetadata(ctx, clientStore, header.GetHeight()) + + return []exported.Height{height} +} + +// pruneOldestConsensusState will retrieve the earliest consensus state for this clientID and check if it is expired. If it is, +// that consensus state will be pruned from store along with all associated metadata. This will prevent the client store from +// becoming bloated with expired consensus states that can no longer be used for updates and packet verification. +func (cs ClientState) pruneOldestConsensusState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore) { + // Check the earliest consensus state to see if it is expired, if so then set the prune height + // so that we can delete consensus state and all associated metadata. + var ( + pruneHeight exported.Height + ) + + pruneCb := func(height exported.Height) bool { + consState, found := GetConsensusState(clientStore, cdc, height) + // this error should never occur + if !found { + panic(errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "failed to retrieve consensus state at height: %s", height)) + } + + if cs.IsExpired(consState.Timestamp, ctx.BlockTime()) { + pruneHeight = height + } + + return true + } + + IterateConsensusStateAscending(clientStore, pruneCb) + + // if pruneHeight is set, delete consensus state and metadata + if pruneHeight != nil { + deleteConsensusState(clientStore, pruneHeight) + deleteConsensusMetadata(clientStore, pruneHeight) + } +} + +// UpdateStateOnMisbehaviour updates state upon misbehaviour, freezing the ClientState. This method should only be called when misbehaviour is detected +// as it does not perform any misbehaviour checks. +func (cs ClientState) UpdateStateOnMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, _ exported.ClientMessage) { + cs.FrozenHeight = FrozenHeight + + clientStore.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(cdc, &cs)) +} + +// checkTrustedHeader checks that consensus state matches trusted fields of Header +func checkTrustedHeader(header *Header, consState *ConsensusState) error { + tmTrustedValidators, err := tmtypes.ValidatorSetFromProto(header.TrustedValidators) + if err != nil { + return errorsmod.Wrap(err, "trusted validator set in not tendermint validator set type") + } + + // assert that trustedVals is NextValidators of last trusted header + // to do this, we check that trustedVals.Hash() == consState.NextValidatorsHash + tvalHash := tmTrustedValidators.Hash() + if !bytes.Equal(consState.NextValidatorsHash, tvalHash) { + return errorsmod.Wrapf( + ErrInvalidValidatorSet, + "trusted validators %s, does not hash to latest trusted validators. Expected: %X, got: %X", + header.TrustedValidators, consState.NextValidatorsHash, tvalHash, + ) + } + return nil +} diff --git a/modules/light-clients/07-tendermint/update_test.go b/modules/light-clients/07-tendermint/update_test.go new file mode 100644 index 00000000000..81374e6ffb1 --- /dev/null +++ b/modules/light-clients/07-tendermint/update_test.go @@ -0,0 +1,833 @@ +package tendermint_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + tmtypes "github.com/tendermint/tendermint/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" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "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/ibc-go/v7/testing" + ibctestingmock "github.com/cosmos/ibc-go/v7/testing/mock" +) + +func (suite *TendermintTestSuite) TestVerifyHeader() { + var ( + path *ibctesting.Path + header *ibctm.Header + ) + + // Setup different validators and signers for testing different types of updates + altPrivVal := ibctestingmock.NewPV() + altPubKey, err := altPrivVal.GetPubKey() + suite.Require().NoError(err) + + revisionHeight := int64(height.RevisionHeight) + + // create modified heights to use for test-cases + altVal := tmtypes.NewValidator(altPubKey, 100) + // Create alternative validator set with only altVal, invalid update (too much change in valSet) + altValSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{altVal}) + altSigners := getAltSigners(altVal, altPrivVal) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + name: "success", + malleate: func() {}, + expPass: true, + }, + { + name: "successful verify header for header with a previous height", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + // passing the CurrentHeader.Height as the block height as it will become a previous height once we commit N blocks + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + + // commit some blocks so that the created Header now has a previous height as the BlockHeight + suite.coordinator.CommitNBlocks(suite.chainB, 5) + + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + }, + expPass: true, + }, + { + name: "successful verify header: header with future height and different validator set", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.chainB.Vals.Validators, altVal)) + bothSigners := suite.chainB.Signers + bothSigners[altVal.Address.String()] = altPrivVal + + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+5, trustedHeight, suite.chainB.CurrentHeader.Time, bothValSet, suite.chainB.NextVals, trustedVals, bothSigners) + }, + expPass: true, + }, + { + name: "successful verify header: header with next height and different validator set", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.chainB.Vals.Validators, altVal)) + bothSigners := suite.chainB.Signers + bothSigners[altVal.Address.String()] = altPrivVal + + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, bothValSet, suite.chainB.NextVals, trustedVals, bothSigners) + }, + expPass: true, + }, + { + name: "unsuccessful updates, passed in incorrect trusted validators for given consensus state", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + // Create bothValSet with both suite validator and altVal + bothValSet := tmtypes.NewValidatorSet(append(suite.chainB.Vals.Validators, altVal)) + bothSigners := suite.chainB.Signers + bothSigners[altVal.Address.String()] = altPrivVal + + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time, bothValSet, bothValSet, bothValSet, bothSigners) + }, + expPass: false, + }, + { + name: "unsuccessful verify header with next height: update header mismatches nextValSetHash", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + // this will err as altValSet.Hash() != consState.NextValidatorsHash + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time, altValSet, altValSet, trustedVals, altSigners) + }, + expPass: false, + }, + { + name: "unsuccessful update with future height: too much change in validator set", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time, altValSet, altValSet, trustedVals, altSigners) + }, + expPass: false, + }, + { + name: "unsuccessful verify header: header height revision and trusted height revision mismatch", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + header = suite.chainB.CreateTMClientHeader(chainIDRevision1, 3, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + }, + expPass: false, + }, + { + name: "unsuccessful verify header: header height < consensus height", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + heightMinus1 := clienttypes.NewHeight(trustedHeight.RevisionNumber, trustedHeight.RevisionHeight-1) + + // Make new header at height less than latest client state + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(heightMinus1.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + }, + expPass: false, + }, + { + name: "unsuccessful verify header: header basic validation failed", + malleate: func() { + // cause header to fail validatebasic by changing commit height to mismatch header height + header.SignedHeader.Commit.Height = revisionHeight - 1 + }, + expPass: false, + }, + { + name: "unsuccessful verify header: header timestamp is not past last client timestamp", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight)) + suite.Require().True(found) + + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time.Add(-time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + }, + expPass: false, + }, + { + name: "unsuccessful verify header: header with incorrect header chain-id", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight)) + suite.Require().True(found) + + header = suite.chainB.CreateTMClientHeader(chainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + }, + expPass: false, + }, + { + name: "unsuccessful update: trusting period has passed since last client timestamp", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight)) + suite.Require().True(found) + + header = suite.chainA.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+1, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + + suite.chainB.ExpireClient(ibctesting.TrustingPeriod) + }, + expPass: false, + }, + { + name: "unsuccessful update for a previous revision", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + // passing the CurrentHeader.Height as the block height as it will become an update to previous revision once we upgrade the client + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + + // increment the revision of the chain + err = path.EndpointB.UpgradeChain() + suite.Require().NoError(err) + }, + expPass: false, + }, + { + name: "successful update with identical header to a previous update", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + // passing the CurrentHeader.Height as the block height as it will become a previous height once we commit N blocks + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + + // update client so the header constructed becomes a duplicate + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + }, + expPass: true, + }, + + { + name: "unsuccessful update to a future revision", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID+"-1", suite.chainB.CurrentHeader.Height+5, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + }, + expPass: false, + }, + + { + name: "unsuccessful update: header height revision and trusted height revision mismatch", + malleate: func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + // increment the revision of the chain + err = path.EndpointB.UpgradeChain() + suite.Require().NoError(err) + + header = suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + }, + expPass: false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + err := path.EndpointA.CreateClient() + suite.Require().NoError(err) + + // ensure counterparty state is committed + suite.coordinator.CommitBlock(suite.chainB) + header, err = path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) + suite.Require().NoError(err) + + tc.malleate() + + clientState := path.EndpointA.GetClientState() + + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + + err = clientState.VerifyClientMessage(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, header) + + if tc.expPass { + suite.Require().NoError(err, tc.name) + } else { + suite.Require().Error(err) + } + } +} + +func (suite *TendermintTestSuite) TestUpdateState() { + var ( + path *ibctesting.Path + clientMessage exported.ClientMessage + clientStore sdk.KVStore + consensusHeights []exported.Height + pruneHeight clienttypes.Height + prevClientState exported.ClientState + prevConsensusState exported.ConsensusState + ) + + testCases := []struct { + name string + malleate func() + expResult func() + expPass bool + }{ + { + "success with height later than latest height", func() { + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().LT(tmHeader.GetHeight())) + }, + func() { + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + + clientState := path.EndpointA.GetClientState() + suite.Require().True(clientState.GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed + suite.Require().True(clientState.GetLatestHeight().EQ(consensusHeights[0])) + }, true, + }, + { + "success with height earlier than latest height", func() { + // commit a block so the pre-created ClientMessage + // isn't used to update the client to a newer height + suite.coordinator.CommitBlock(suite.chainB) + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().GT(tmHeader.GetHeight())) + + prevClientState = path.EndpointA.GetClientState() + }, + func() { + clientState := path.EndpointA.GetClientState() + suite.Require().Equal(clientState, prevClientState) // fill in height, no change to client state + suite.Require().True(clientState.GetLatestHeight().GT(consensusHeights[0])) + }, true, + }, + { + "success with duplicate header", func() { + // update client in advance + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // use the same header which just updated the client + clientMessage, err = path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) + suite.Require().NoError(err) + + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + suite.Require().Equal(path.EndpointA.GetClientState().GetLatestHeight(), tmHeader.GetHeight()) + + prevClientState = path.EndpointA.GetClientState() + prevConsensusState = path.EndpointA.GetConsensusState(tmHeader.GetHeight()) + }, + func() { + clientState := path.EndpointA.GetClientState() + suite.Require().Equal(clientState, prevClientState) + suite.Require().True(clientState.GetLatestHeight().EQ(consensusHeights[0])) + + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + suite.Require().Equal(path.EndpointA.GetConsensusState(tmHeader.GetHeight()), prevConsensusState) + }, true, + }, + { + "success with pruned consensus state", func() { + // this height will be expired and pruned + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + pruneHeight = path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + // Increment the time by a week + suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) + + // create the consensus state that can be used as trusted height for next update + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // Increment the time by another week, then update the client. + // This will cause the first two consensus states to become expired. + suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // ensure counterparty state is committed + suite.coordinator.CommitBlock(suite.chainB) + clientMessage, err = path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) + suite.Require().NoError(err) + }, + func() { + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + + clientState := path.EndpointA.GetClientState() + suite.Require().True(clientState.GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed + suite.Require().True(clientState.GetLatestHeight().EQ(consensusHeights[0])) + + // ensure consensus state was pruned + _, found := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) + suite.Require().False(found) + }, true, + }, + { + "success with pruned consensus state using duplicate header", func() { + // this height will be expired and pruned + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + pruneHeight = path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + // assert that a consensus state exists at the prune height + consensusState, found := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) + suite.Require().True(found) + suite.Require().NotNil(consensusState) + + // Increment the time by a week + suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) + + // create the consensus state that can be used as trusted height for next update + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // Increment the time by another week, then update the client. + // This will cause the first two consensus states to become expired. + suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // use the same header which just updated the client + clientMessage, err = path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) + suite.Require().NoError(err) + }, + func() { + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + + clientState := path.EndpointA.GetClientState() + suite.Require().True(clientState.GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed + suite.Require().True(clientState.GetLatestHeight().EQ(consensusHeights[0])) + + // ensure consensus state was pruned + _, found := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) + suite.Require().False(found) + }, true, + }, + { + "invalid ClientMessage type", func() { + clientMessage = &ibctm.Misbehaviour{} + }, + func() {}, + false, + }, + } + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() // reset + pruneHeight = clienttypes.ZeroHeight() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + err := path.EndpointA.CreateClient() + suite.Require().NoError(err) + + // ensure counterparty state is committed + suite.coordinator.CommitBlock(suite.chainB) + clientMessage, err = path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) + suite.Require().NoError(err) + + tc.malleate() + + clientState := path.EndpointA.GetClientState() + clientStore = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + + if tc.expPass { + consensusHeights = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) + + header := clientMessage.(*ibctm.Header) + expConsensusState := &ibctm.ConsensusState{ + Timestamp: header.GetTime(), + Root: commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), + NextValidatorsHash: header.Header.NextValidatorsHash, + } + + bz := clientStore.Get(host.ConsensusStateKey(header.GetHeight())) + updatedConsensusState := clienttypes.MustUnmarshalConsensusState(suite.chainA.App.AppCodec(), bz) + + suite.Require().Equal(expConsensusState, updatedConsensusState) + + } else { + suite.Require().Panics(func() { + clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) + }) + } + + // perform custom checks + tc.expResult() + }) + } +} + +func (suite *TendermintTestSuite) TestPruneConsensusState() { + // create path and setup clients + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupClients(path) + + // get the first height as it will be pruned first. + var pruneHeight exported.Height + getFirstHeightCb := func(height exported.Height) bool { + pruneHeight = height + return true + } + ctx := path.EndpointA.Chain.GetContext() + clientStore := path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) + ibctm.IterateConsensusStateAscending(clientStore, getFirstHeightCb) + + // this height will be expired but not pruned + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + expiredHeight := path.EndpointA.GetClientState().GetLatestHeight() + + // expected values that must still remain in store after pruning + expectedConsState, ok := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, expiredHeight) + suite.Require().True(ok) + ctx = path.EndpointA.Chain.GetContext() + clientStore = path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) + expectedProcessTime, ok := ibctm.GetProcessedTime(clientStore, expiredHeight) + suite.Require().True(ok) + expectedProcessHeight, ok := ibctm.GetProcessedHeight(clientStore, expiredHeight) + suite.Require().True(ok) + expectedConsKey := ibctm.GetIterationKey(clientStore, expiredHeight) + suite.Require().NotNil(expectedConsKey) + + // Increment the time by a week + suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) + + // create the consensus state that can be used as trusted height for next update + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // Increment the time by another week, then update the client. + // This will cause the first two consensus states to become expired. + suite.coordinator.IncrementTimeBy(7 * 24 * time.Hour) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + ctx = path.EndpointA.Chain.GetContext() + clientStore = path.EndpointA.Chain.App.GetIBCKeeper().ClientKeeper.ClientStore(ctx, path.EndpointA.ClientID) + + // check that the first expired consensus state got deleted along with all associated metadata + consState, ok := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) + suite.Require().Nil(consState, "expired consensus state not pruned") + suite.Require().False(ok) + // check processed time metadata is pruned + processTime, ok := ibctm.GetProcessedTime(clientStore, pruneHeight) + suite.Require().Equal(uint64(0), processTime, "processed time metadata not pruned") + suite.Require().False(ok) + processHeight, ok := ibctm.GetProcessedHeight(clientStore, pruneHeight) + suite.Require().Nil(processHeight, "processed height metadata not pruned") + suite.Require().False(ok) + + // check iteration key metadata is pruned + consKey := ibctm.GetIterationKey(clientStore, pruneHeight) + suite.Require().Nil(consKey, "iteration key not pruned") + + // check that second expired consensus state doesn't get deleted + // this ensures that there is a cap on gas cost of UpdateClient + consState, ok = path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, expiredHeight) + suite.Require().Equal(expectedConsState, consState, "consensus state incorrectly pruned") + suite.Require().True(ok) + // check processed time metadata is not pruned + processTime, ok = ibctm.GetProcessedTime(clientStore, expiredHeight) + suite.Require().Equal(expectedProcessTime, processTime, "processed time metadata incorrectly pruned") + suite.Require().True(ok) + + // check processed height metadata is not pruned + processHeight, ok = ibctm.GetProcessedHeight(clientStore, expiredHeight) + suite.Require().Equal(expectedProcessHeight, processHeight, "processed height metadata incorrectly pruned") + suite.Require().True(ok) + + // check iteration key metadata is not pruned + consKey = ibctm.GetIterationKey(clientStore, expiredHeight) + suite.Require().Equal(expectedConsKey, consKey, "iteration key incorrectly pruned") +} + +func (suite *TendermintTestSuite) TestCheckForMisbehaviour() { + var ( + path *ibctesting.Path + clientMessage exported.ClientMessage + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "valid update no misbehaviour", + func() {}, + false, + }, + { + "consensus state already exists, already updated", + func() { + header, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + + consensusState := &ibctm.ConsensusState{ + Timestamp: header.GetTime(), + Root: commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), + NextValidatorsHash: header.Header.NextValidatorsHash, + } + + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, tmHeader.GetHeight(), consensusState) + }, + false, + }, + { + "invalid fork misbehaviour: identical headers", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + height := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + misbehaviourHeader := suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, int64(height.RevisionHeight), trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers) + clientMessage = &ibctm.Misbehaviour{ + Header1: misbehaviourHeader, + Header2: misbehaviourHeader, + } + }, false, + }, + { + "invalid time misbehaviour: monotonically increasing time", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + clientMessage = &ibctm.Misbehaviour{ + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+3, trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, false, + }, + { + "consensus state already exists, app hash mismatch", + func() { + header, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + + consensusState := &ibctm.ConsensusState{ + Timestamp: header.GetTime(), + Root: commitmenttypes.NewMerkleRoot([]byte{}), // empty bytes + NextValidatorsHash: header.Header.NextValidatorsHash, + } + + tmHeader, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, tmHeader.GetHeight(), consensusState) + }, + true, + }, + { + "previous consensus state exists and header time is before previous consensus state time", + func() { + header, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + + // offset header timestamp before previous consensus state timestamp + header.Header.Time = header.GetTime().Add(-time.Hour) + }, + true, + }, + { + "next consensus state exists and header time is after next consensus state time", + func() { + header, ok := clientMessage.(*ibctm.Header) + suite.Require().True(ok) + + // commit block and update client, adding a new consensus state + suite.coordinator.CommitBlock(suite.chainB) + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + // increase timestamp of current header + header.Header.Time = header.Header.Time.Add(time.Hour) + }, + true, + }, + { + "valid fork misbehaviour returns true", + func() { + header1, err := path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) + suite.Require().NoError(err) + + // commit block and update client + suite.coordinator.CommitBlock(suite.chainB) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + header2, err := path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) + suite.Require().NoError(err) + + // assign the same height, each header will have a different commit hash + header1.Header.Height = header2.Header.Height + + clientMessage = &ibctm.Misbehaviour{ + Header1: header1, + Header2: header2, + ClientId: path.EndpointA.ClientID, + } + }, + true, + }, + { + "valid time misbehaviour: not monotonically increasing time", func() { + trustedHeight := path.EndpointA.GetClientState().GetLatestHeight().(clienttypes.Height) + + trustedVals, found := suite.chainB.GetValsAtHeight(int64(trustedHeight.RevisionHeight) + 1) + suite.Require().True(found) + + clientMessage = &ibctm.Misbehaviour{ + Header2: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height+3, trustedHeight, suite.chainB.CurrentHeader.Time.Add(time.Minute), suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + Header1: suite.chainB.CreateTMClientHeader(suite.chainB.ChainID, suite.chainB.CurrentHeader.Height, trustedHeight, suite.chainB.CurrentHeader.Time, suite.chainB.Vals, suite.chainB.NextVals, trustedVals, suite.chainB.Signers), + } + }, true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + // reset suite to create fresh application state + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + err := path.EndpointA.CreateClient() + suite.Require().NoError(err) + + // ensure counterparty state is committed + suite.coordinator.CommitBlock(suite.chainB) + clientMessage, err = path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) + suite.Require().NoError(err) + + tc.malleate() + + clientState := path.EndpointA.GetClientState() + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + + foundMisbehaviour := clientState.CheckForMisbehaviour( + suite.chainA.GetContext(), + suite.chainA.App.AppCodec(), + clientStore, // pass in clientID prefixed clientStore + clientMessage, + ) + + if tc.expPass { + suite.Require().True(foundMisbehaviour) + } else { + suite.Require().False(foundMisbehaviour) + } + }) + } +} + +func (suite *TendermintTestSuite) TestUpdateStateOnMisbehaviour() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + // reset suite to create fresh application state + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + err := path.EndpointA.CreateClient() + suite.Require().NoError(err) + + tc.malleate() + + clientState := path.EndpointA.GetClientState() + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) + + clientState.UpdateStateOnMisbehaviour(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, nil) + + if tc.expPass { + clientStateBz := clientStore.Get(host.ClientStateKey()) + suite.Require().NotEmpty(clientStateBz) + + newClientState := clienttypes.MustUnmarshalClientState(suite.chainA.Codec, clientStateBz) + suite.Require().Equal(frozenHeight, newClientState.(*ibctm.ClientState).FrozenHeight) + } + }) + } +} diff --git a/modules/light-clients/07-tendermint/types/upgrade.go b/modules/light-clients/07-tendermint/upgrade.go similarity index 70% rename from modules/light-clients/07-tendermint/types/upgrade.go rename to modules/light-clients/07-tendermint/upgrade.go index b5b5ebe40f4..abbeca91b90 100644 --- a/modules/light-clients/07-tendermint/types/upgrade.go +++ b/modules/light-clients/07-tendermint/upgrade.go @@ -1,43 +1,44 @@ -package types +package tendermint import ( "fmt" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // VerifyUpgradeAndUpdateState checks if the upgraded client has been committed by the current client -// It will zero out all client-specific fields (e.g. TrustingPeriod and verify all data +// It will zero out all client-specific fields (e.g. TrustingPeriod) and verify all data // in client state that must be the same across all valid Tendermint clients for the new chain. // VerifyUpgrade will return an error if: // - the upgradedClient is not a Tendermint ClientState -// - the lastest height of the client state does not have the same revision number or has a greater +// - the latest height of the client state does not have the same revision number or has a greater // height than the committed client. -// - the height of upgraded client is not greater than that of current client -// - the latest height of the new client does not match or is greater than the height in committed client -// - any Tendermint chain specified parameter in upgraded client such as ChainID, UnbondingPeriod, -// and ProofSpecs do not match parameters set by committed client +// - the height of upgraded client is not greater than that of current client +// - the latest height of the new client does not match or is greater than the height in committed client +// - any Tendermint chain specified parameter in upgraded client such as ChainID, UnbondingPeriod, +// and ProofSpecs do not match parameters set by committed client func (cs ClientState) VerifyUpgradeAndUpdateState( ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, upgradedClient exported.ClientState, upgradedConsState exported.ConsensusState, proofUpgradeClient, proofUpgradeConsState []byte, -) (exported.ClientState, exported.ConsensusState, error) { +) error { if len(cs.UpgradePath) == 0 { - return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade client, no upgrade path set") + return errorsmod.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade client, no upgrade path set") } // last height of current counterparty chain must be client's latest height lastHeight := cs.GetLatestHeight() if !upgradedClient.GetLatestHeight().GT(lastHeight) { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "upgraded client height %s must be at greater than current client height %s", + return errorsmod.Wrapf(ibcerrors.ErrInvalidHeight, "upgraded client height %s must be at greater than current client height %s", upgradedClient.GetLatestHeight(), lastHeight) } @@ -46,52 +47,52 @@ func (cs ClientState) VerifyUpgradeAndUpdateState( // counterparty must also commit to the upgraded consensus state at a sub-path under the upgrade path specified tmUpgradeClient, ok := upgradedClient.(*ClientState) if !ok { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "upgraded client must be Tendermint client. expected: %T got: %T", + return errorsmod.Wrapf(clienttypes.ErrInvalidClientType, "upgraded client must be Tendermint client. expected: %T got: %T", &ClientState{}, upgradedClient) } tmUpgradeConsState, ok := upgradedConsState.(*ConsensusState) if !ok { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "upgraded consensus state must be Tendermint consensus state. expected %T, got: %T", + return errorsmod.Wrapf(clienttypes.ErrInvalidConsensus, "upgraded consensus state must be Tendermint consensus state. expected %T, got: %T", &ConsensusState{}, upgradedConsState) } // unmarshal proofs var merkleProofClient, merkleProofConsState commitmenttypes.MerkleProof if err := cdc.Unmarshal(proofUpgradeClient, &merkleProofClient); err != nil { - return nil, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal client merkle proof: %v", err) + return errorsmod.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal client merkle proof: %v", err) } if err := cdc.Unmarshal(proofUpgradeConsState, &merkleProofConsState); err != nil { - return nil, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal consensus state merkle proof: %v", err) + return errorsmod.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal consensus state merkle proof: %v", err) } // Must prove against latest consensus state to ensure we are verifying against latest upgrade plan // This verifies that upgrade is intended for the provided revision, since committed client must exist // at this consensus state - consState, err := GetConsensusState(clientStore, cdc, lastHeight) - if err != nil { - return nil, nil, sdkerrors.Wrap(err, "could not retrieve consensus state for lastHeight") + consState, found := GetConsensusState(clientStore, cdc, lastHeight) + if !found { + return errorsmod.Wrap(clienttypes.ErrConsensusStateNotFound, "could not retrieve consensus state for lastHeight") } // Verify client proof - bz, err := cdc.MarshalInterface(upgradedClient) + bz, err := cdc.MarshalInterface(upgradedClient.ZeroCustomFields()) if err != nil { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "could not marshal client state: %v", err) + return errorsmod.Wrapf(clienttypes.ErrInvalidClient, "could not marshal client state: %v", err) } // construct clientState Merkle path upgradeClientPath := constructUpgradeClientMerklePath(cs.UpgradePath, lastHeight) if err := merkleProofClient.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradeClientPath, bz); err != nil { - return nil, nil, sdkerrors.Wrapf(err, "client state proof failed. Path: %s", upgradeClientPath.Pretty()) + return errorsmod.Wrapf(err, "client state proof failed. Path: %s", upgradeClientPath.Pretty()) } // Verify consensus state proof bz, err = cdc.MarshalInterface(upgradedConsState) if err != nil { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "could not marshal consensus state: %v", err) + return errorsmod.Wrapf(clienttypes.ErrInvalidConsensus, "could not marshal consensus state: %v", err) } // construct consensus state Merkle path upgradeConsStatePath := constructUpgradeConsStateMerklePath(cs.UpgradePath, lastHeight) if err := merkleProofConsState.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradeConsStatePath, bz); err != nil { - return nil, nil, sdkerrors.Wrapf(err, "consensus state proof failed. Path: %s", upgradeConsStatePath.Pretty()) + return errorsmod.Wrapf(err, "consensus state proof failed. Path: %s", upgradeConsStatePath.Pretty()) } // Construct new client state and consensus state @@ -101,11 +102,10 @@ func (cs ClientState) VerifyUpgradeAndUpdateState( newClientState := NewClientState( tmUpgradeClient.ChainId, cs.TrustLevel, cs.TrustingPeriod, tmUpgradeClient.UnbondingPeriod, cs.MaxClockDrift, tmUpgradeClient.LatestHeight, tmUpgradeClient.ProofSpecs, tmUpgradeClient.UpgradePath, - cs.AllowUpdateAfterExpiry, cs.AllowUpdateAfterMisbehaviour, ) if err := newClientState.Validate(); err != nil { - return nil, nil, sdkerrors.Wrap(err, "updated client state failed basic validation") + return errorsmod.Wrap(err, "updated client state failed basic validation") } // The new consensus state is merely used as a trusted kernel against which headers on the new @@ -119,10 +119,11 @@ func (cs ClientState) VerifyUpgradeAndUpdateState( tmUpgradeConsState.Timestamp, commitmenttypes.NewMerkleRoot([]byte(SentinelRoot)), tmUpgradeConsState.NextValidatorsHash, ) - // set metadata for this consensus state + setClientState(clientStore, cdc, newClientState) + setConsensusState(clientStore, cdc, newConsState, newClientState.LatestHeight) setConsensusMetadata(ctx, clientStore, tmUpgradeClient.LatestHeight) - return newClientState, newConsState, nil + return nil } // construct MerklePath for the committed client from upgradePath diff --git a/modules/light-clients/07-tendermint/types/upgrade_test.go b/modules/light-clients/07-tendermint/upgrade_test.go similarity index 85% rename from modules/light-clients/07-tendermint/types/upgrade_test.go rename to modules/light-clients/07-tendermint/upgrade_test.go index c5f1216e8b8..52c2b7841b8 100644 --- a/modules/light-clients/07-tendermint/types/upgrade_test.go +++ b/modules/light-clients/07-tendermint/upgrade_test.go @@ -1,19 +1,18 @@ -package types_test +package tendermint_test import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + 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/ibc-go/v7/testing" ) -var newChainId = "newChainId-1" - func (suite *TendermintTestSuite) TestVerifyUpgrade() { var ( + newChainID string upgradedClient exported.ClientState upgradedConsState exported.ConsensusState lastHeight clienttypes.Height @@ -35,8 +34,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test // commit upgrade store changes and update clients @@ -55,9 +54,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "successful upgrade to same revision", setup: func() { - upgradedHeight := clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+2)) - // don't use -1 suffix in chain id - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradedHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedClient = ibctm.NewClientState(suite.chainB.ChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, clienttypes.NewHeight(clienttypes.ParseChainID(suite.chainB.ChainID), upgradedClient.GetLatestHeight().GetRevisionHeight()+10), commitmenttypes.GetSDKSpecs(), upgradePath) upgradedClient = upgradedClient.ZeroCustomFields() upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) suite.Require().NoError(err) @@ -66,8 +63,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test // commit upgrade store changes and update clients @@ -91,8 +88,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+10)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test // commit upgrade store changes and update clients @@ -112,7 +109,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { name: "unsuccessful upgrade: committed client does not have zeroed custom fields", setup: func() { // non-zeroed upgrade client - upgradedClient = types.NewClientState(newChainId, types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedClient = ibctm.NewClientState(newChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath) upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) suite.Require().NoError(err) @@ -120,8 +117,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test // commit upgrade store changes and update clients @@ -144,11 +141,11 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test // change upgradedClient client-specified parameters - upgradedClient = types.NewClientState("wrongchainID", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, true) + upgradedClient = ibctm.NewClientState("wrongchainID", ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath) suite.coordinator.CommitBlock(suite.chainB) err := path.EndpointA.UpdateClient() @@ -166,11 +163,11 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { name: "unsuccessful upgrade: client-specified parameters do not match previous client", setup: func() { // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test // change upgradedClient client-specified parameters - upgradedClient = types.NewClientState(newChainId, types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) + upgradedClient = ibctm.NewClientState(newChainID, ibctm.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath) suite.coordinator.CommitBlock(suite.chainB) err := path.EndpointA.UpdateClient() @@ -191,11 +188,11 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test // change submitted upgradedConsensusState - upgradedConsState = &types.ConsensusState{ + upgradedConsState = &ibctm.ConsensusState{ NextValidatorsHash: []byte("maliciousValidators"), } @@ -216,7 +213,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: client proof unmarshal failed", setup: func() { - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test cs, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID) suite.Require().True(found) @@ -230,7 +227,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { { name: "unsuccessful upgrade: consensus state proof unmarshal failed", setup: func() { - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test cs, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID) suite.Require().True(found) @@ -249,7 +246,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for test cs, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID) suite.Require().True(found) @@ -267,7 +264,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test cs, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID) suite.Require().True(found) @@ -284,7 +281,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test // commit upgrade store changes and update clients @@ -299,7 +296,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) // SetClientState with empty upgrade path - tmClient, _ := cs.(*types.ClientState) + tmClient, _ := cs.(*ibctm.ClientState) tmClient.UpgradePath = []string{""} suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID, tmClient) }, @@ -312,7 +309,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test // commit upgrade store changes and update clients @@ -335,7 +332,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+100)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for // commit upgrade store changes and update clients @@ -355,7 +352,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { name: "unsuccessful upgrade: client is expired", setup: func() { // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test // commit upgrade store changes and update clients @@ -381,7 +378,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for test // commit upgrade store changes and update clients @@ -401,7 +398,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { name: "unsuccessful upgrade: final client is not valid", setup: func() { // new client has smaller unbonding period such that old trusting period is no longer valid - upgradedClient = types.NewClientState(newChainId, types.DefaultTrustLevel, trustingPeriod, trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedClient = ibctm.NewClientState(newChainID, ibctm.DefaultTrustLevel, trustingPeriod, trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath) upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) suite.Require().NoError(err) @@ -409,8 +406,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) - suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClientBz) //nolint:errcheck // ignore error for testing + suite.chainB.GetSimApp().UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsStateBz) //nolint:errcheck // ignore error for testing // commit upgrade store changes and update clients @@ -436,12 +433,20 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { path = ibctesting.NewPath(suite.chainA, suite.chainB) suite.coordinator.SetupClients(path) - upgradedClient = types.NewClientState(newChainId, types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + + clientState := path.EndpointA.GetClientState().(*ibctm.ClientState) + revisionNumber := clienttypes.ParseChainID(clientState.ChainId) + + var err error + newChainID, err = clienttypes.SetRevisionNumber(clientState.ChainId, revisionNumber+1) + suite.Require().NoError(err) + + upgradedClient = ibctm.NewClientState(newChainID, ibctm.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, clienttypes.NewHeight(revisionNumber+1, clientState.GetLatestHeight().GetRevisionHeight()+1), commitmenttypes.GetSDKSpecs(), upgradePath) upgradedClient = upgradedClient.ZeroCustomFields() upgradedClientBz, err = clienttypes.MarshalClientState(suite.chainA.App.AppCodec(), upgradedClient) suite.Require().NoError(err) - upgradedConsState = &types.ConsensusState{ + upgradedConsState = &ibctm.ConsensusState{ NextValidatorsHash: []byte("nextValsHash"), } upgradedConsStateBz, err = clienttypes.MarshalConsensusState(suite.chainA.App.AppCodec(), upgradedConsState) @@ -455,7 +460,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient upgradedClient = upgradedClient.ZeroCustomFields() - clientState, consensusState, err := cs.VerifyUpgradeAndUpdateState( + err = cs.VerifyUpgradeAndUpdateState( suite.chainA.GetContext(), suite.cdc, clientStore, @@ -467,14 +472,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { if tc.expPass { suite.Require().NoError(err, "verify upgrade failed on valid case: %s", tc.name) + + clientState := suite.chainA.GetClientState(path.EndpointA.ClientID) suite.Require().NotNil(clientState, "verify upgrade failed on valid case: %s", tc.name) + + consensusState, found := suite.chainA.GetConsensusState(path.EndpointA.ClientID, clientState.GetLatestHeight()) suite.Require().NotNil(consensusState, "verify upgrade failed on valid case: %s", tc.name) + suite.Require().True(found) } else { suite.Require().Error(err, "verify upgrade passed on invalid case: %s", tc.name) - suite.Require().Nil(clientState, "verify upgrade passed on invalid case: %s", tc.name) - - suite.Require().Nil(consensusState, "verify upgrade passed on invalid case: %s", tc.name) - } } } diff --git a/modules/light-clients/09-localhost/doc.go b/modules/light-clients/09-localhost/doc.go deleted file mode 100644 index 40a0f060867..00000000000 --- a/modules/light-clients/09-localhost/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -/* -Package localhost implements a concrete `ConsensusState`, `Header`, -`Misbehaviour` and `Equivocation` types for the loop-back client. -*/ -package localhost diff --git a/modules/light-clients/09-localhost/module.go b/modules/light-clients/09-localhost/module.go deleted file mode 100644 index fd77e2e62b5..00000000000 --- a/modules/light-clients/09-localhost/module.go +++ /dev/null @@ -1,10 +0,0 @@ -package localhost - -import ( - "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" -) - -// Name returns the IBC client name -func Name() string { - return types.SubModuleName -} diff --git a/modules/light-clients/09-localhost/types/client_state.go b/modules/light-clients/09-localhost/types/client_state.go deleted file mode 100644 index d75690bee7c..00000000000 --- a/modules/light-clients/09-localhost/types/client_state.go +++ /dev/null @@ -1,340 +0,0 @@ -package types - -import ( - "bytes" - "encoding/binary" - "reflect" - "strings" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -var _ exported.ClientState = (*ClientState)(nil) - -// NewClientState creates a new ClientState instance -func NewClientState(chainID string, height clienttypes.Height) *ClientState { - return &ClientState{ - ChainId: chainID, - Height: height, - } -} - -// GetChainID returns an empty string -func (cs ClientState) GetChainID() string { - return cs.ChainId -} - -// ClientType is localhost. -func (cs ClientState) ClientType() string { - return exported.Localhost -} - -// GetLatestHeight returns the latest height stored. -func (cs ClientState) GetLatestHeight() exported.Height { - return cs.Height -} - -// Status always returns Active. The localhost status cannot be changed. -func (cs ClientState) Status(_ sdk.Context, _ sdk.KVStore, _ codec.BinaryCodec, -) exported.Status { - return exported.Active -} - -// Validate performs a basic validation of the client state fields. -func (cs ClientState) Validate() error { - if strings.TrimSpace(cs.ChainId) == "" { - return sdkerrors.Wrap(sdkerrors.ErrInvalidChainID, "chain id cannot be blank") - } - if cs.Height.RevisionHeight == 0 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "local revision height cannot be zero") - } - return nil -} - -// ZeroCustomFields returns the same client state since there are no custom fields in localhost -func (cs ClientState) ZeroCustomFields() exported.ClientState { - return &cs -} - -// Initialize ensures that initial consensus state for localhost is nil -func (cs ClientState) Initialize(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, consState exported.ConsensusState) error { - if consState != nil { - return sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "initial consensus state for localhost must be nil.") - } - return nil -} - -// ExportMetadata is a no-op for localhost client -func (cs ClientState) ExportMetadata(_ sdk.KVStore) []exported.GenesisMetadata { - return nil -} - -// CheckHeaderAndUpdateState updates the localhost client. It only needs access to the context -func (cs *ClientState) CheckHeaderAndUpdateState( - ctx sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.Header, -) (exported.ClientState, exported.ConsensusState, error) { - // use the chain ID from context since the localhost client is from the running chain (i.e self). - cs.ChainId = ctx.ChainID() - revision := clienttypes.ParseChainID(cs.ChainId) - cs.Height = clienttypes.NewHeight(revision, uint64(ctx.BlockHeight())) - return cs, nil, nil -} - -// CheckMisbehaviourAndUpdateState implements ClientState -// Since localhost is the client of the running chain, misbehaviour cannot be submitted to it -// Thus, CheckMisbehaviourAndUpdateState returns an error for localhost -func (cs ClientState) CheckMisbehaviourAndUpdateState( - _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.Misbehaviour, -) (exported.ClientState, error) { - return nil, sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "cannot submit misbehaviour to localhost client") -} - -// CheckSubstituteAndUpdateState returns an error. The localhost cannot be modified by -// proposals. -func (cs ClientState) CheckSubstituteAndUpdateState( - ctx sdk.Context, _ codec.BinaryCodec, _, _ sdk.KVStore, - _ exported.ClientState, -) (exported.ClientState, error) { - return nil, sdkerrors.Wrap(clienttypes.ErrUpdateClientFailed, "cannot update localhost client with a proposal") -} - -// VerifyUpgradeAndUpdateState returns an error since localhost cannot be upgraded -func (cs ClientState) VerifyUpgradeAndUpdateState( - _ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, - _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, -) (exported.ClientState, exported.ConsensusState, error) { - return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade localhost client") -} - -// VerifyClientState verifies that the localhost client state is stored locally -func (cs ClientState) VerifyClientState( - store sdk.KVStore, cdc codec.BinaryCodec, - _ exported.Height, _ exported.Prefix, _ string, _ []byte, clientState exported.ClientState, -) error { - path := host.KeyClientState - bz := store.Get([]byte(path)) - if bz == nil { - return sdkerrors.Wrapf(clienttypes.ErrFailedClientStateVerification, - "not found for path: %s", path) - } - - selfClient := clienttypes.MustUnmarshalClientState(cdc, bz) - - if !reflect.DeepEqual(selfClient, clientState) { - return sdkerrors.Wrapf(clienttypes.ErrFailedClientStateVerification, - "stored clientState != provided clientState: \n%v\n≠\n%v", - selfClient, clientState, - ) - } - return nil -} - -// VerifyClientConsensusState returns nil since a local host client does not store consensus -// states. -func (cs ClientState) VerifyClientConsensusState( - sdk.KVStore, codec.BinaryCodec, - exported.Height, string, exported.Height, exported.Prefix, - []byte, exported.ConsensusState, -) error { - return nil -} - -// VerifyConnectionState verifies a proof of the connection state of the -// specified connection end stored locally. -func (cs ClientState) VerifyConnectionState( - store sdk.KVStore, - cdc codec.BinaryCodec, - _ exported.Height, - _ exported.Prefix, - _ []byte, - connectionID string, - connectionEnd exported.ConnectionI, -) error { - path := host.ConnectionKey(connectionID) - bz := store.Get(path) - if bz == nil { - return sdkerrors.Wrapf(clienttypes.ErrFailedConnectionStateVerification, "not found for path %s", path) - } - - var prevConnection connectiontypes.ConnectionEnd - err := cdc.Unmarshal(bz, &prevConnection) - if err != nil { - return err - } - - if !reflect.DeepEqual(&prevConnection, connectionEnd) { - return sdkerrors.Wrapf( - clienttypes.ErrFailedConnectionStateVerification, - "connection end ≠ previous stored connection: \n%v\n≠\n%v", connectionEnd, prevConnection, - ) - } - - return nil -} - -// VerifyChannelState verifies a proof of the channel state of the specified -// channel end, under the specified port, stored on the local machine. -func (cs ClientState) VerifyChannelState( - store sdk.KVStore, - cdc codec.BinaryCodec, - _ exported.Height, - prefix exported.Prefix, - _ []byte, - portID, - channelID string, - channel exported.ChannelI, -) error { - path := host.ChannelKey(portID, channelID) - bz := store.Get(path) - if bz == nil { - return sdkerrors.Wrapf(clienttypes.ErrFailedChannelStateVerification, "not found for path %s", path) - } - - var prevChannel channeltypes.Channel - err := cdc.Unmarshal(bz, &prevChannel) - if err != nil { - return err - } - - if !reflect.DeepEqual(&prevChannel, channel) { - return sdkerrors.Wrapf( - clienttypes.ErrFailedChannelStateVerification, - "channel end ≠ previous stored channel: \n%v\n≠\n%v", channel, prevChannel, - ) - } - - return nil -} - -// VerifyPacketCommitment verifies a proof of an outgoing packet commitment at -// the specified port, specified channel, and specified sequence. -func (cs ClientState) VerifyPacketCommitment( - ctx sdk.Context, - store sdk.KVStore, - _ codec.BinaryCodec, - _ exported.Height, - _ uint64, - _ uint64, - _ exported.Prefix, - _ []byte, - portID, - channelID string, - sequence uint64, - commitmentBytes []byte, -) error { - path := host.PacketCommitmentKey(portID, channelID, sequence) - - data := store.Get(path) - if len(data) == 0 { - return sdkerrors.Wrapf(clienttypes.ErrFailedPacketCommitmentVerification, "not found for path %s", path) - } - - if !bytes.Equal(data, commitmentBytes) { - return sdkerrors.Wrapf( - clienttypes.ErrFailedPacketCommitmentVerification, - "commitment ≠ previous commitment: \n%X\n≠\n%X", commitmentBytes, data, - ) - } - - return nil -} - -// VerifyPacketAcknowledgement verifies a proof of an incoming packet -// acknowledgement at the specified port, specified channel, and specified sequence. -func (cs ClientState) VerifyPacketAcknowledgement( - ctx sdk.Context, - store sdk.KVStore, - _ codec.BinaryCodec, - _ exported.Height, - _ uint64, - _ uint64, - _ exported.Prefix, - _ []byte, - portID, - channelID string, - sequence uint64, - acknowledgement []byte, -) error { - path := host.PacketAcknowledgementKey(portID, channelID, sequence) - - data := store.Get(path) - if len(data) == 0 { - return sdkerrors.Wrapf(clienttypes.ErrFailedPacketAckVerification, "not found for path %s", path) - } - - if !bytes.Equal(data, acknowledgement) { - return sdkerrors.Wrapf( - clienttypes.ErrFailedPacketAckVerification, - "ak bytes ≠ previous ack: \n%X\n≠\n%X", acknowledgement, data, - ) - } - - return nil -} - -// VerifyPacketReceiptAbsence verifies a proof of the absence of an -// incoming packet receipt at the specified port, specified channel, and -// specified sequence. -func (cs ClientState) VerifyPacketReceiptAbsence( - ctx sdk.Context, - store sdk.KVStore, - _ codec.BinaryCodec, - _ exported.Height, - _ uint64, - _ uint64, - _ exported.Prefix, - _ []byte, - portID, - channelID string, - sequence uint64, -) error { - path := host.PacketReceiptKey(portID, channelID, sequence) - - data := store.Get(path) - if data != nil { - return sdkerrors.Wrap(clienttypes.ErrFailedPacketReceiptVerification, "expected no packet receipt") - } - - return nil -} - -// VerifyNextSequenceRecv verifies a proof of the next sequence number to be -// received of the specified channel at the specified port. -func (cs ClientState) VerifyNextSequenceRecv( - ctx sdk.Context, - store sdk.KVStore, - _ codec.BinaryCodec, - _ exported.Height, - _ uint64, - _ uint64, - _ exported.Prefix, - _ []byte, - portID, - channelID string, - nextSequenceRecv uint64, -) error { - path := host.NextSequenceRecvKey(portID, channelID) - - data := store.Get(path) - if len(data) == 0 { - return sdkerrors.Wrapf(clienttypes.ErrFailedNextSeqRecvVerification, "not found for path %s", path) - } - - prevSequenceRecv := binary.BigEndian.Uint64(data) - if prevSequenceRecv != nextSequenceRecv { - return sdkerrors.Wrapf( - clienttypes.ErrFailedNextSeqRecvVerification, - "next sequence receive ≠ previous stored sequence (%d ≠ %d)", nextSequenceRecv, prevSequenceRecv, - ) - } - - return nil -} diff --git a/modules/light-clients/09-localhost/types/client_state_test.go b/modules/light-clients/09-localhost/types/client_state_test.go deleted file mode 100644 index 75d827f3ae8..00000000000 --- a/modules/light-clients/09-localhost/types/client_state_test.go +++ /dev/null @@ -1,526 +0,0 @@ -package types_test - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types" -) - -const ( - testConnectionID = "connectionid" - testPortID = "testportid" - testChannelID = "testchannelid" - testSequence = 1 -) - -func (suite *LocalhostTestSuite) TestStatus() { - clientState := types.NewClientState("chainID", clienttypes.NewHeight(3, 10)) - - // localhost should always return active - status := clientState.Status(suite.ctx, nil, nil) - suite.Require().Equal(exported.Active, status) -} - -func (suite *LocalhostTestSuite) TestValidate() { - testCases := []struct { - name string - clientState *types.ClientState - expPass bool - }{ - { - name: "valid client", - clientState: types.NewClientState("chainID", clienttypes.NewHeight(3, 10)), - expPass: true, - }, - { - name: "invalid chain id", - clientState: types.NewClientState(" ", clienttypes.NewHeight(3, 10)), - expPass: false, - }, - { - name: "invalid height", - clientState: types.NewClientState("chainID", clienttypes.ZeroHeight()), - expPass: false, - }, - } - - for _, tc := range testCases { - err := tc.clientState.Validate() - if tc.expPass { - suite.Require().NoError(err, tc.name) - } else { - suite.Require().Error(err, tc.name) - } - } -} - -func (suite *LocalhostTestSuite) TestInitialize() { - testCases := []struct { - name string - consState exported.ConsensusState - expPass bool - }{ - { - "valid initialization", - nil, - true, - }, - { - "invalid consenus state", - &ibctmtypes.ConsensusState{}, - false, - }, - } - - clientState := types.NewClientState("chainID", clienttypes.NewHeight(3, 10)) - - for _, tc := range testCases { - err := clientState.Initialize(suite.ctx, suite.cdc, suite.store, tc.consState) - - if tc.expPass { - suite.Require().NoError(err, "valid testcase: %s failed", tc.name) - } else { - suite.Require().Error(err, "invalid testcase: %s passed", tc.name) - } - } -} - -func (suite *LocalhostTestSuite) TestVerifyClientState() { - clientState := types.NewClientState("chainID", clientHeight) - invalidClient := types.NewClientState("chainID", clienttypes.NewHeight(0, 12)) - - testCases := []struct { - name string - clientState *types.ClientState - malleate func() - counterparty *types.ClientState - expPass bool - }{ - { - name: "proof verification success", - clientState: clientState, - malleate: func() { - bz := clienttypes.MustMarshalClientState(suite.cdc, clientState) - suite.store.Set(host.ClientStateKey(), bz) - }, - counterparty: clientState, - expPass: true, - }, - { - name: "proof verification failed: invalid client", - clientState: clientState, - malleate: func() { - bz := clienttypes.MustMarshalClientState(suite.cdc, clientState) - suite.store.Set(host.ClientStateKey(), bz) - }, - counterparty: invalidClient, - expPass: false, - }, - { - name: "proof verification failed: client not stored", - clientState: clientState, - malleate: func() {}, - counterparty: clientState, - expPass: false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() - tc.malleate() - - err := tc.clientState.VerifyClientState( - suite.store, suite.cdc, clienttypes.NewHeight(0, 10), nil, "", []byte{}, tc.counterparty, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *LocalhostTestSuite) TestVerifyClientConsensusState() { - clientState := types.NewClientState("chainID", clientHeight) - err := clientState.VerifyClientConsensusState( - nil, nil, nil, "", nil, nil, nil, nil, - ) - suite.Require().NoError(err) -} - -func (suite *LocalhostTestSuite) TestCheckHeaderAndUpdateState() { - clientState := types.NewClientState("chainID", clientHeight) - cs, _, err := clientState.CheckHeaderAndUpdateState(suite.ctx, nil, nil, nil) - suite.Require().NoError(err) - suite.Require().Equal(uint64(0), cs.GetLatestHeight().GetRevisionNumber()) - suite.Require().Equal(suite.ctx.BlockHeight(), int64(cs.GetLatestHeight().GetRevisionHeight())) - suite.Require().Equal(suite.ctx.BlockHeader().ChainID, clientState.ChainId) -} - -func (suite *LocalhostTestSuite) TestMisbehaviourAndUpdateState() { - clientState := types.NewClientState("chainID", clientHeight) - cs, err := clientState.CheckMisbehaviourAndUpdateState(suite.ctx, nil, nil, nil) - suite.Require().Error(err) - suite.Require().Nil(cs) -} - -func (suite *LocalhostTestSuite) TestProposedHeaderAndUpdateState() { - clientState := types.NewClientState("chainID", clientHeight) - cs, err := clientState.CheckSubstituteAndUpdateState(suite.ctx, nil, nil, nil, nil) - suite.Require().Error(err) - suite.Require().Nil(cs) -} - -func (suite *LocalhostTestSuite) TestVerifyConnectionState() { - counterparty := connectiontypes.NewCounterparty("clientB", testConnectionID, commitmenttypes.NewMerklePrefix([]byte("ibc"))) - conn1 := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, []*connectiontypes.Version{connectiontypes.NewVersion("1", nil)}, 0) - conn2 := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "clientA", counterparty, []*connectiontypes.Version{connectiontypes.NewVersion("2", nil)}, 0) - - testCases := []struct { - name string - clientState *types.ClientState - malleate func() - connection connectiontypes.ConnectionEnd - expPass bool - }{ - { - name: "proof verification success", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - bz, err := suite.cdc.Marshal(&conn1) - suite.Require().NoError(err) - suite.store.Set(host.ConnectionKey(testConnectionID), bz) - }, - connection: conn1, - expPass: true, - }, - { - name: "proof verification failed: connection not stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() {}, - connection: conn1, - expPass: false, - }, - { - name: "proof verification failed: unmarshal error", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - suite.store.Set(host.ConnectionKey(testConnectionID), []byte("connection")) - }, - connection: conn1, - expPass: false, - }, - { - name: "proof verification failed: different connection stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - bz, err := suite.cdc.Marshal(&conn2) - suite.Require().NoError(err) - suite.store.Set(host.ConnectionKey(testConnectionID), bz) - }, - connection: conn1, - expPass: false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() - tc.malleate() - - err := tc.clientState.VerifyConnectionState( - suite.store, suite.cdc, clientHeight, nil, []byte{}, testConnectionID, &tc.connection, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *LocalhostTestSuite) TestVerifyChannelState() { - counterparty := channeltypes.NewCounterparty(testPortID, testChannelID) - ch1 := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, counterparty, []string{testConnectionID}, "1.0.0") - ch2 := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, counterparty, []string{testConnectionID}, "2.0.0") - - testCases := []struct { - name string - clientState *types.ClientState - malleate func() - channel channeltypes.Channel - expPass bool - }{ - { - name: "proof verification success", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - bz, err := suite.cdc.Marshal(&ch1) - suite.Require().NoError(err) - suite.store.Set(host.ChannelKey(testPortID, testChannelID), bz) - }, - channel: ch1, - expPass: true, - }, - { - name: "proof verification failed: channel not stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() {}, - channel: ch1, - expPass: false, - }, - { - name: "proof verification failed: unmarshal failed", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - suite.store.Set(host.ChannelKey(testPortID, testChannelID), []byte("channel")) - }, - channel: ch1, - expPass: false, - }, - { - name: "proof verification failed: different channel stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - bz, err := suite.cdc.Marshal(&ch2) - suite.Require().NoError(err) - suite.store.Set(host.ChannelKey(testPortID, testChannelID), bz) - }, - channel: ch1, - expPass: false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() - tc.malleate() - - err := tc.clientState.VerifyChannelState( - suite.store, suite.cdc, clientHeight, nil, []byte{}, testPortID, testChannelID, &tc.channel, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *LocalhostTestSuite) TestVerifyPacketCommitment() { - testCases := []struct { - name string - clientState *types.ClientState - malleate func() - commitment []byte - expPass bool - }{ - { - name: "proof verification success", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - suite.store.Set( - host.PacketCommitmentKey(testPortID, testChannelID, testSequence), []byte("commitment"), - ) - }, - commitment: []byte("commitment"), - expPass: true, - }, - { - name: "proof verification failed: different commitment stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - suite.store.Set( - host.PacketCommitmentKey(testPortID, testChannelID, testSequence), []byte("different"), - ) - }, - commitment: []byte("commitment"), - expPass: false, - }, - { - name: "proof verification failed: no commitment stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() {}, - commitment: []byte{}, - expPass: false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() - tc.malleate() - - err := tc.clientState.VerifyPacketCommitment( - suite.ctx, suite.store, suite.cdc, clientHeight, 0, 0, nil, []byte{}, testPortID, testChannelID, testSequence, tc.commitment, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *LocalhostTestSuite) TestVerifyPacketAcknowledgement() { - testCases := []struct { - name string - clientState *types.ClientState - malleate func() - ack []byte - expPass bool - }{ - { - name: "proof verification success", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - suite.store.Set( - host.PacketAcknowledgementKey(testPortID, testChannelID, testSequence), []byte("acknowledgement"), - ) - }, - ack: []byte("acknowledgement"), - expPass: true, - }, - { - name: "proof verification failed: different ack stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - suite.store.Set( - host.PacketAcknowledgementKey(testPortID, testChannelID, testSequence), []byte("different"), - ) - }, - ack: []byte("acknowledgement"), - expPass: false, - }, - { - name: "proof verification failed: no commitment stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() {}, - ack: []byte{}, - expPass: false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() - tc.malleate() - - err := tc.clientState.VerifyPacketAcknowledgement( - suite.ctx, suite.store, suite.cdc, clientHeight, 0, 0, nil, []byte{}, testPortID, testChannelID, testSequence, tc.ack, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} - -func (suite *LocalhostTestSuite) TestVerifyPacketReceiptAbsence() { - clientState := types.NewClientState("chainID", clientHeight) - - err := clientState.VerifyPacketReceiptAbsence( - suite.ctx, suite.store, suite.cdc, clientHeight, 0, 0, nil, nil, testPortID, testChannelID, testSequence, - ) - - suite.Require().NoError(err, "receipt absence failed") - - suite.store.Set(host.PacketReceiptKey(testPortID, testChannelID, testSequence), []byte("receipt")) - - err = clientState.VerifyPacketReceiptAbsence( - suite.ctx, suite.store, suite.cdc, clientHeight, 0, 0, nil, nil, testPortID, testChannelID, testSequence, - ) - suite.Require().Error(err, "receipt exists in store") -} - -func (suite *LocalhostTestSuite) TestVerifyNextSeqRecv() { - nextSeqRecv := uint64(5) - - testCases := []struct { - name string - clientState *types.ClientState - malleate func() - nextSeqRecv uint64 - expPass bool - }{ - { - name: "proof verification success", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - suite.store.Set( - host.NextSequenceRecvKey(testPortID, testChannelID), - sdk.Uint64ToBigEndian(nextSeqRecv), - ) - }, - nextSeqRecv: nextSeqRecv, - expPass: true, - }, - { - name: "proof verification failed: different nextSeqRecv stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() { - suite.store.Set( - host.NextSequenceRecvKey(testPortID, testChannelID), - sdk.Uint64ToBigEndian(3), - ) - }, - nextSeqRecv: nextSeqRecv, - expPass: false, - }, - { - name: "proof verification failed: no nextSeqRecv stored", - clientState: types.NewClientState("chainID", clientHeight), - malleate: func() {}, - nextSeqRecv: nextSeqRecv, - expPass: false, - }, - } - - for _, tc := range testCases { - tc := tc - - suite.Run(tc.name, func() { - suite.SetupTest() - tc.malleate() - - err := tc.clientState.VerifyNextSequenceRecv( - suite.ctx, suite.store, suite.cdc, clientHeight, 0, 0, nil, []byte{}, testPortID, testChannelID, nextSeqRecv, - ) - - if tc.expPass { - suite.Require().NoError(err) - } else { - suite.Require().Error(err) - } - }) - } -} diff --git a/modules/light-clients/09-localhost/types/codec.go b/modules/light-clients/09-localhost/types/codec.go deleted file mode 100644 index 96e414a95c4..00000000000 --- a/modules/light-clients/09-localhost/types/codec.go +++ /dev/null @@ -1,16 +0,0 @@ -package types - -import ( - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - - "github.com/cosmos/ibc-go/v4/modules/core/exported" -) - -// RegisterInterfaces register the ibc interfaces submodule implementations to protobuf -// Any. -func RegisterInterfaces(registry codectypes.InterfaceRegistry) { - registry.RegisterImplementations( - (*exported.ClientState)(nil), - &ClientState{}, - ) -} diff --git a/modules/light-clients/09-localhost/types/errors.go b/modules/light-clients/09-localhost/types/errors.go deleted file mode 100644 index 57ad7c1f6a6..00000000000 --- a/modules/light-clients/09-localhost/types/errors.go +++ /dev/null @@ -1,10 +0,0 @@ -package types - -import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// Localhost sentinel errors -var ( - ErrConsensusStatesNotStored = sdkerrors.Register(SubModuleName, 2, "localhost does not store consensus states") -) diff --git a/modules/light-clients/09-localhost/types/keys.go b/modules/light-clients/09-localhost/types/keys.go deleted file mode 100644 index 2fe7c7e48f5..00000000000 --- a/modules/light-clients/09-localhost/types/keys.go +++ /dev/null @@ -1,6 +0,0 @@ -package types - -const ( - // SubModuleName for the localhost (loopback) client - SubModuleName = "localhost" -) diff --git a/modules/light-clients/09-localhost/types/localhost.pb.go b/modules/light-clients/09-localhost/types/localhost.pb.go deleted file mode 100644 index 15ef33136e9..00000000000 --- a/modules/light-clients/09-localhost/types/localhost.pb.go +++ /dev/null @@ -1,369 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: ibc/lightclients/localhost/v1/localhost.proto - -package types - -import ( - fmt "fmt" - types "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// ClientState defines a loopback (localhost) client. It requires (read-only) -// access to keys outside the client prefix. -type ClientState struct { - // self chain ID - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty" yaml:"chain_id"` - // self latest block height - Height types.Height `protobuf:"bytes,2,opt,name=height,proto3" json:"height"` -} - -func (m *ClientState) Reset() { *m = ClientState{} } -func (m *ClientState) String() string { return proto.CompactTextString(m) } -func (*ClientState) ProtoMessage() {} -func (*ClientState) Descriptor() ([]byte, []int) { - return fileDescriptor_acd9f5b22d41bf6d, []int{0} -} -func (m *ClientState) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ClientState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ClientState.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 *ClientState) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClientState.Merge(m, src) -} -func (m *ClientState) XXX_Size() int { - return m.Size() -} -func (m *ClientState) XXX_DiscardUnknown() { - xxx_messageInfo_ClientState.DiscardUnknown(m) -} - -var xxx_messageInfo_ClientState proto.InternalMessageInfo - -func init() { - proto.RegisterType((*ClientState)(nil), "ibc.lightclients.localhost.v1.ClientState") -} - -func init() { - proto.RegisterFile("ibc/lightclients/localhost/v1/localhost.proto", fileDescriptor_acd9f5b22d41bf6d) -} - -var fileDescriptor_acd9f5b22d41bf6d = []byte{ - // 288 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xcd, 0x4c, 0x4a, 0xd6, - 0xcf, 0xc9, 0x4c, 0xcf, 0x28, 0x49, 0xce, 0xc9, 0x4c, 0xcd, 0x2b, 0x29, 0xd6, 0xcf, 0xc9, 0x4f, - 0x4e, 0xcc, 0xc9, 0xc8, 0x2f, 0x2e, 0xd1, 0x2f, 0x33, 0x44, 0x70, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, - 0xf2, 0x85, 0x64, 0x33, 0x93, 0x92, 0xf5, 0x90, 0x95, 0xeb, 0x21, 0x54, 0x94, 0x19, 0x4a, 0x89, - 0xa4, 0xe7, 0xa7, 0xe7, 0x83, 0x55, 0xea, 0x83, 0x58, 0x10, 0x4d, 0x52, 0xf2, 0x20, 0x3b, 0x92, - 0xf3, 0x8b, 0x52, 0xf5, 0x21, 0x9a, 0x40, 0x06, 0x43, 0x58, 0x10, 0x05, 0x4a, 0xb5, 0x5c, 0xdc, - 0xce, 0x60, 0x7e, 0x70, 0x49, 0x62, 0x49, 0xaa, 0x90, 0x1e, 0x17, 0x47, 0x72, 0x46, 0x62, 0x66, - 0x5e, 0x7c, 0x66, 0x8a, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xa7, 0x93, 0xf0, 0xa7, 0x7b, 0xf2, 0xfc, - 0x95, 0x89, 0xb9, 0x39, 0x56, 0x4a, 0x30, 0x19, 0xa5, 0x20, 0x76, 0x30, 0xd3, 0x33, 0x45, 0xc8, - 0x82, 0x8b, 0x2d, 0x23, 0x15, 0xe4, 0x26, 0x09, 0x26, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x29, 0x3d, - 0x90, 0x2b, 0x41, 0x16, 0xea, 0x41, 0xad, 0x29, 0x33, 0xd4, 0xf3, 0x00, 0xab, 0x70, 0x62, 0x39, - 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0xde, 0x8a, 0xa5, 0x63, 0x81, 0x3c, 0x83, 0x53, 0xdc, 0x89, - 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, - 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0xb9, 0xa4, 0x67, 0x96, 0x64, 0x94, 0x26, - 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x27, 0xe7, 0x17, 0xe7, 0xe6, 0x17, 0xeb, 0x67, 0x26, 0x25, 0xeb, - 0xa6, 0xe7, 0xeb, 0x97, 0x99, 0xe8, 0xe7, 0xe6, 0xa7, 0x94, 0xe6, 0xa4, 0x16, 0x43, 0x42, 0x4f, - 0x17, 0x16, 0x7c, 0x06, 0x96, 0xba, 0x88, 0x10, 0x2c, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, - 0xfb, 0xd2, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x84, 0xfe, 0x1f, 0x95, 0x6c, 0x01, 0x00, 0x00, -} - -func (m *ClientState) 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 *ClientState) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Height.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintLocalhost(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintLocalhost(dAtA, i, uint64(len(m.ChainId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintLocalhost(dAtA []byte, offset int, v uint64) int { - offset -= sovLocalhost(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *ClientState) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovLocalhost(uint64(l)) - } - l = m.Height.Size() - n += 1 + l + sovLocalhost(uint64(l)) - return n -} - -func sovLocalhost(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozLocalhost(x uint64) (n int) { - return sovLocalhost(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *ClientState) 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 ErrIntOverflowLocalhost - } - 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: ClientState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ClientState: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowLocalhost - } - 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 ErrInvalidLengthLocalhost - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthLocalhost - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ChainId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowLocalhost - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthLocalhost - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthLocalhost - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Height.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipLocalhost(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthLocalhost - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipLocalhost(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowLocalhost - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowLocalhost - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowLocalhost - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthLocalhost - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupLocalhost - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthLocalhost - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthLocalhost = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowLocalhost = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupLocalhost = fmt.Errorf("proto: unexpected end of group") -) diff --git a/modules/light-clients/09-localhost/types/localhost_test.go b/modules/light-clients/09-localhost/types/localhost_test.go deleted file mode 100644 index 56bf9379fbe..00000000000 --- a/modules/light-clients/09-localhost/types/localhost_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package types_test - -import ( - "testing" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/suite" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/testing/simapp" -) - -const ( - height = 4 -) - -var clientHeight = clienttypes.NewHeight(0, 10) - -type LocalhostTestSuite struct { - suite.Suite - - cdc codec.Codec - ctx sdk.Context - store sdk.KVStore -} - -func (suite *LocalhostTestSuite) SetupTest() { - isCheckTx := false - app := simapp.Setup(isCheckTx) - - suite.cdc = app.AppCodec() - suite.ctx = app.BaseApp.NewContext(isCheckTx, tmproto.Header{Height: 1, ChainID: "ibc-chain"}) - suite.store = app.IBCKeeper.ClientKeeper.ClientStore(suite.ctx, exported.Localhost) -} - -func TestLocalhostTestSuite(t *testing.T) { - suite.Run(t, new(LocalhostTestSuite)) -} diff --git a/proto/buf.gen.gogo.yaml b/proto/buf.gen.gogo.yaml new file mode 100644 index 00000000000..9c8ba0a4b1f --- /dev/null +++ b/proto/buf.gen.gogo.yaml @@ -0,0 +1,8 @@ +version: v1 +plugins: + - name: gocosmos + out: .. + opt: plugins=grpc,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types + - name: grpc-gateway + out: .. + opt: logtostderr=true,allow_colon_final_segments=true diff --git a/proto/buf.gen.swagger.yaml b/proto/buf.gen.swagger.yaml new file mode 100644 index 00000000000..d0f7535b1a4 --- /dev/null +++ b/proto/buf.gen.swagger.yaml @@ -0,0 +1,5 @@ +version: v1 +plugins: + - name: swagger + out: ../tmp-swagger-gen + opt: logtostderr=true,fqn_for_swagger_name=true,simple_operation_ids=true diff --git a/proto/buf.lock b/proto/buf.lock new file mode 100644 index 00000000000..f36df5f2658 --- /dev/null +++ b/proto/buf.lock @@ -0,0 +1,23 @@ +# Generated by buf. DO NOT EDIT. +version: v1 +deps: + - remote: buf.build + owner: cosmos + repository: cosmos-proto + commit: 1935555c206d4afb9e94615dfd0fad31 + - remote: buf.build + owner: cosmos + repository: cosmos-sdk + commit: 8c515ebc07ee4514aabcaf3a584a1d1a + - remote: buf.build + owner: cosmos + repository: gogo-proto + commit: 34d970b699f84aa382f3c29773a60836 + - remote: buf.build + owner: cosmos + repository: ics23 + commit: 55085f7c710a45f58fa09947208eb70b + - remote: buf.build + owner: googleapis + repository: googleapis + commit: 8d7204855ec14631a499bd7393ce1970 diff --git a/proto/buf.yaml b/proto/buf.yaml index aae636f0a14..79a7bf0012f 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -1,9 +1,13 @@ -# Generated by "buf config migrate-v1beta1". Edit as necessary, and -# remove this comment when you're finished. -# -# This module represents the "proto" root found in -# the previous configuration. version: v1 +name: buf.build/cosmos/ibc +deps: + # TODO: update sdk buf dependency when v0.47.0 is tagged and pushed to BSR + # see: (https://github.com/cosmos/cosmos-sdk/tree/main/proto#sdk-x-buf) + - buf.build/cosmos/cosmos-sdk:8c515ebc07ee4514aabcaf3a584a1d1a + - buf.build/cosmos/cosmos-proto:1935555c206d4afb9e94615dfd0fad31 + - buf.build/cosmos/gogo-proto:a14993478f40695898ed8a86931094b6656e8a5d + - buf.build/googleapis/googleapis:8d7204855ec14631a499bd7393ce1970 + - buf.build/cosmos/ics23:b1abd8678aab07165efd453c96796a179eb3131f breaking: use: - FILE diff --git a/proto/ibc/applications/fee/v1/ack.proto b/proto/ibc/applications/fee/v1/ack.proto index b6c20acf74e..ec1342bbf23 100644 --- a/proto/ibc/applications/fee/v1/ack.proto +++ b/proto/ibc/applications/fee/v1/ack.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.fee.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/fee/v1/fee.proto b/proto/ibc/applications/fee/v1/fee.proto index d85ebcfeb31..1a025ddca1c 100644 --- a/proto/ibc/applications/fee/v1/fee.proto +++ b/proto/ibc/applications/fee/v1/fee.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.fee.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types"; import "cosmos/base/v1beta1/coin.proto"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/fee/v1/genesis.proto b/proto/ibc/applications/fee/v1/genesis.proto index 9bce6ac599b..6bba6cff632 100644 --- a/proto/ibc/applications/fee/v1/genesis.proto +++ b/proto/ibc/applications/fee/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.fee.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types"; import "gogoproto/gogo.proto"; import "ibc/applications/fee/v1/fee.proto"; diff --git a/proto/ibc/applications/fee/v1/metadata.proto b/proto/ibc/applications/fee/v1/metadata.proto index e1ec1b12bfd..0c0a72c9ca5 100644 --- a/proto/ibc/applications/fee/v1/metadata.proto +++ b/proto/ibc/applications/fee/v1/metadata.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.fee.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/fee/v1/query.proto b/proto/ibc/applications/fee/v1/query.proto index 41b8c6ba5b6..bcf6622b34b 100644 --- a/proto/ibc/applications/fee/v1/query.proto +++ b/proto/ibc/applications/fee/v1/query.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.fee.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types"; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; @@ -83,6 +83,8 @@ message QueryIncentivizedPacketsRequest { message QueryIncentivizedPacketsResponse { // list of identified fees for incentivized packets repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1 [(gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; } // QueryIncentivizedPacketRequest defines the request type for the IncentivizedPacket rpc @@ -114,6 +116,8 @@ message QueryIncentivizedPacketsForChannelRequest { message QueryIncentivizedPacketsForChannelResponse { // Map of all incentivized_packets repeated ibc.applications.fee.v1.IdentifiedPacketFees incentivized_packets = 1; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; } // QueryTotalRecvFeesRequest defines the request type for the TotalRecvFees rpc @@ -205,6 +209,8 @@ message QueryFeeEnabledChannelsResponse { // list of fee enabled channels repeated ibc.applications.fee.v1.FeeEnabledChannel fee_enabled_channels = 1 [(gogoproto.moretags) = "yaml:\"fee_enabled_channels\"", (gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; } // QueryFeeEnabledChannelRequest defines the request type for the FeeEnabledChannel rpc diff --git a/proto/ibc/applications/fee/v1/tx.proto b/proto/ibc/applications/fee/v1/tx.proto index 8d6fca58fbb..3a46de74ebe 100644 --- a/proto/ibc/applications/fee/v1/tx.proto +++ b/proto/ibc/applications/fee/v1/tx.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.fee.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types"; import "gogoproto/gogo.proto"; import "ibc/applications/fee/v1/fee.proto"; diff --git a/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto b/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto index c7abd9f3372..a505b4637ef 100644 --- a/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto +++ b/proto/ibc/applications/interchain_accounts/controller/v1/controller.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.interchain_accounts.controller.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/interchain_accounts/controller/v1/query.proto b/proto/ibc/applications/interchain_accounts/controller/v1/query.proto index 6ccc0456731..8c237a1525f 100644 --- a/proto/ibc/applications/interchain_accounts/controller/v1/query.proto +++ b/proto/ibc/applications/interchain_accounts/controller/v1/query.proto @@ -2,19 +2,37 @@ syntax = "proto3"; package ibc.applications.interchain_accounts.controller.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"; import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; +import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; // Query provides defines the gRPC querier service. service Query { + // InterchainAccount returns the interchain account address for a given owner address on a given connection + rpc InterchainAccount(QueryInterchainAccountRequest) returns (QueryInterchainAccountResponse) { + option (google.api.http).get = + "/ibc/apps/interchain_accounts/controller/v1/owners/{owner}/connections/{connection_id}"; + } + // Params queries all parameters of the ICA controller submodule. rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/ibc/apps/interchain_accounts/controller/v1/params"; } } +// QueryInterchainAccountRequest is the request type for the Query/InterchainAccount RPC method. +message QueryInterchainAccountRequest { + string owner = 1; + string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; +} + +// QueryInterchainAccountResponse the response type for the Query/InterchainAccount RPC method. +message QueryInterchainAccountResponse { + string address = 1; +} + // QueryParamsRequest is the request type for the Query/Params RPC method. message QueryParamsRequest {} diff --git a/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto b/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto new file mode 100644 index 00000000000..284ffe70576 --- /dev/null +++ b/proto/ibc/applications/interchain_accounts/controller/v1/tx.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.controller.v1; + +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"; + +import "gogoproto/gogo.proto"; +import "ibc/applications/interchain_accounts/v1/packet.proto"; + +// Msg defines the 27-interchain-accounts/controller Msg service. +service Msg { + // RegisterInterchainAccount defines a rpc handler for MsgRegisterInterchainAccount. + rpc RegisterInterchainAccount(MsgRegisterInterchainAccount) returns (MsgRegisterInterchainAccountResponse); + // SendTx defines a rpc handler for MsgSendTx. + rpc SendTx(MsgSendTx) returns (MsgSendTxResponse); +} + +// MsgRegisterInterchainAccount defines the payload for Msg/RegisterAccount +message MsgRegisterInterchainAccount { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string owner = 1; + string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string version = 3; +} + +// MsgRegisterInterchainAccountResponse defines the response for Msg/RegisterAccount +message MsgRegisterInterchainAccountResponse { + string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string port_id = 2 [(gogoproto.moretags) = "yaml:\"port_id\""]; +} + +// MsgSendTx defines the payload for Msg/SendTx +message MsgSendTx { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string owner = 1; + string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + ibc.applications.interchain_accounts.v1.InterchainAccountPacketData packet_data = 3 + [(gogoproto.moretags) = "yaml:\"packet_data\"", (gogoproto.nullable) = false]; + // Relative timeout timestamp provided will be added to the current block time during transaction execution. + // The timeout timestamp must be non-zero. + uint64 relative_timeout = 4 [(gogoproto.moretags) = "yaml:\"relative_timeout\""]; +} + +// MsgSendTxResponse defines the response for MsgSendTx +message MsgSendTxResponse { + uint64 sequence = 1; +} diff --git a/proto/ibc/applications/interchain_accounts/v1/genesis.proto b/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto similarity index 78% rename from proto/ibc/applications/interchain_accounts/v1/genesis.proto rename to proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto index a92b6a0f17a..2fed3763ff3 100644 --- a/proto/ibc/applications/interchain_accounts/v1/genesis.proto +++ b/proto/ibc/applications/interchain_accounts/genesis/v1/genesis.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package ibc.applications.interchain_accounts.v1; +package ibc.applications.interchain_accounts.genesis.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/genesis/types"; import "gogoproto/gogo.proto"; import "ibc/applications/interchain_accounts/controller/v1/controller.proto"; @@ -36,11 +36,13 @@ message HostGenesisState { ibc.applications.interchain_accounts.host.v1.Params params = 4 [(gogoproto.nullable) = false]; } -// ActiveChannel contains a connection ID, port ID and associated active channel ID +// ActiveChannel contains a connection ID, port ID and associated active channel ID, as well as a boolean flag to +// indicate if the channel is middleware enabled message ActiveChannel { - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - string port_id = 2 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 3 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string port_id = 2 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 3 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + bool is_middleware_enabled = 4 [(gogoproto.moretags) = "yaml:\"is_middleware_enabled\""]; } // RegisteredInterchainAccount contains a connection ID, port ID and associated interchain account address diff --git a/proto/ibc/applications/interchain_accounts/host/v1/host.proto b/proto/ibc/applications/interchain_accounts/host/v1/host.proto index e73510e57f1..18cc1d13da3 100644 --- a/proto/ibc/applications/interchain_accounts/host/v1/host.proto +++ b/proto/ibc/applications/interchain_accounts/host/v1/host.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.interchain_accounts.host.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/interchain_accounts/host/v1/query.proto b/proto/ibc/applications/interchain_accounts/host/v1/query.proto index 02d17d314a7..b89ed8ed871 100644 --- a/proto/ibc/applications/interchain_accounts/host/v1/query.proto +++ b/proto/ibc/applications/interchain_accounts/host/v1/query.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.interchain_accounts.host.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types"; import "google/api/annotations.proto"; import "ibc/applications/interchain_accounts/host/v1/host.proto"; diff --git a/proto/ibc/applications/interchain_accounts/v1/account.proto b/proto/ibc/applications/interchain_accounts/v1/account.proto index 2748b935778..d60c27a9c29 100644 --- a/proto/ibc/applications/interchain_accounts/v1/account.proto +++ b/proto/ibc/applications/interchain_accounts/v1/account.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.interchain_accounts.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"; import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; @@ -12,7 +12,7 @@ import "cosmos/auth/v1beta1/auth.proto"; message InterchainAccount { option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = false; - option (cosmos_proto.implements_interface) = "InterchainAccountI"; + option (cosmos_proto.implements_interface) = "ibc.applications.interchain_accounts.v1.InterchainAccountI"; cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""]; diff --git a/proto/ibc/applications/interchain_accounts/v1/metadata.proto b/proto/ibc/applications/interchain_accounts/v1/metadata.proto index 6a4b4abe57e..9ea7eeca337 100644 --- a/proto/ibc/applications/interchain_accounts/v1/metadata.proto +++ b/proto/ibc/applications/interchain_accounts/v1/metadata.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.interchain_accounts.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/interchain_accounts/v1/packet.proto b/proto/ibc/applications/interchain_accounts/v1/packet.proto index 8e09a9d670c..d2dcf518eab 100644 --- a/proto/ibc/applications/interchain_accounts/v1/packet.proto +++ b/proto/ibc/applications/interchain_accounts/v1/packet.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.interchain_accounts.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"; import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/transfer/v1/authz.proto b/proto/ibc/applications/transfer/v1/authz.proto new file mode 100644 index 00000000000..8b27ac9cf7d --- /dev/null +++ b/proto/ibc/applications/transfer/v1/authz.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// Allocation defines the spend limit for a particular port and channel +message Allocation { + // the port on which the packet will be sent + string source_port = 1 [(gogoproto.moretags) = "yaml:\"source_port\""]; + // the channel by which the packet will be sent + string source_channel = 2 [(gogoproto.moretags) = "yaml:\"source_channel\""]; + // spend limitation on the channel + repeated cosmos.base.v1beta1.Coin spend_limit = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + // allow list of receivers, an empty allow list permits any receiver address + repeated string allow_list = 4; +} + +// TransferAuthorization allows the grantee to spend up to spend_limit coins from +// the granter's account for ibc transfer on a specific channel +message TransferAuthorization { + option (cosmos_proto.implements_interface) = "cosmos.authz.v1beta1.Authorization"; + + // port and channel amounts + repeated Allocation allocations = 1 [(gogoproto.nullable) = false]; +} diff --git a/proto/ibc/applications/transfer/v1/genesis.proto b/proto/ibc/applications/transfer/v1/genesis.proto index 34672fdebfb..5e09a34ab07 100644 --- a/proto/ibc/applications/transfer/v1/genesis.proto +++ b/proto/ibc/applications/transfer/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.transfer.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"; import "ibc/applications/transfer/v1/transfer.proto"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/transfer/v1/query.proto b/proto/ibc/applications/transfer/v1/query.proto index 075c0001c8a..89b70309f15 100644 --- a/proto/ibc/applications/transfer/v1/query.proto +++ b/proto/ibc/applications/transfer/v1/query.proto @@ -7,13 +7,13 @@ import "cosmos/base/query/v1beta1/pagination.proto"; import "ibc/applications/transfer/v1/transfer.proto"; import "google/api/annotations.proto"; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"; // Query provides defines the gRPC querier service. service Query { // DenomTrace queries a denomination trace information. rpc DenomTrace(QueryDenomTraceRequest) returns (QueryDenomTraceResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces/{hash}"; + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces/{hash=**}"; } // DenomTraces queries all denomination traces. @@ -28,7 +28,7 @@ service Query { // DenomHash queries a denomination hash information. rpc DenomHash(QueryDenomHashRequest) returns (QueryDenomHashResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denom_hashes/{trace}"; + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_hashes/{trace=**}"; } // EscrowAddress returns the escrow address for a particular port and channel id. diff --git a/proto/ibc/applications/transfer/v1/transfer.proto b/proto/ibc/applications/transfer/v1/transfer.proto index 1f92e81a627..2171074799a 100644 --- a/proto/ibc/applications/transfer/v1/transfer.proto +++ b/proto/ibc/applications/transfer/v1/transfer.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.transfer.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/applications/transfer/v1/tx.proto b/proto/ibc/applications/transfer/v1/tx.proto index 5befdf2fbc3..1c67aafb937 100644 --- a/proto/ibc/applications/transfer/v1/tx.proto +++ b/proto/ibc/applications/transfer/v1/tx.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.transfer.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; @@ -38,7 +38,12 @@ message MsgTransfer { // Timeout timestamp in absolute nanoseconds since unix epoch. // The timeout is disabled when set to 0. uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; + // optional memo + string memo = 8; } // MsgTransferResponse defines the Msg/Transfer response type. -message MsgTransferResponse {} +message MsgTransferResponse { + // sequence number of the transfer packet sent + uint64 sequence = 1; +} diff --git a/proto/ibc/applications/transfer/v2/packet.proto b/proto/ibc/applications/transfer/v2/packet.proto index acae83530f6..7dc31347af1 100644 --- a/proto/ibc/applications/transfer/v2/packet.proto +++ b/proto/ibc/applications/transfer/v2/packet.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.applications.transfer.v2; -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"; // FungibleTokenPacketData defines a struct for the packet payload // See FungibleTokenPacketData spec: @@ -16,4 +16,6 @@ message FungibleTokenPacketData { string sender = 3; // the recipient address on the destination chain string receiver = 4; + // optional memo + string memo = 5; } diff --git a/proto/ibc/core/channel/v1/channel.proto b/proto/ibc/core/channel/v1/channel.proto index feaf6d43503..287830ef437 100644 --- a/proto/ibc/core/channel/v1/channel.proto +++ b/proto/ibc/core/channel/v1/channel.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.channel.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"; import "gogoproto/gogo.proto"; import "ibc/core/client/v1/client.proto"; diff --git a/proto/ibc/core/channel/v1/genesis.proto b/proto/ibc/core/channel/v1/genesis.proto index 1c0ff6ee883..65cc928aa2a 100644 --- a/proto/ibc/core/channel/v1/genesis.proto +++ b/proto/ibc/core/channel/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.channel.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"; import "gogoproto/gogo.proto"; import "ibc/core/channel/v1/channel.proto"; diff --git a/proto/ibc/core/channel/v1/query.proto b/proto/ibc/core/channel/v1/query.proto index 986633173cc..2d5bdb2fc8c 100644 --- a/proto/ibc/core/channel/v1/query.proto +++ b/proto/ibc/core/channel/v1/query.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.channel.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"; import "ibc/core/client/v1/client.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; diff --git a/proto/ibc/core/channel/v1/tx.proto b/proto/ibc/core/channel/v1/tx.proto index 10e2ac29286..d81257eae80 100644 --- a/proto/ibc/core/channel/v1/tx.proto +++ b/proto/ibc/core/channel/v1/tx.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.channel.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"; import "gogoproto/gogo.proto"; import "ibc/core/client/v1/client.proto"; @@ -111,7 +111,8 @@ message MsgChannelOpenTry { // MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. message MsgChannelOpenTryResponse { - string version = 1; + string version = 1; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; } // MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge diff --git a/proto/ibc/core/channel/v1/upgrade.proto b/proto/ibc/core/channel/v1/upgrade.proto index 753487ce432..f143a99f8f8 100644 --- a/proto/ibc/core/channel/v1/upgrade.proto +++ b/proto/ibc/core/channel/v1/upgrade.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.channel.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"; import "gogoproto/gogo.proto"; import "ibc/core/client/v1/client.proto"; diff --git a/proto/ibc/core/client/v1/client.proto b/proto/ibc/core/client/v1/client.proto index 9d386592fa9..266649ba01c 100644 --- a/proto/ibc/core/client/v1/client.proto +++ b/proto/ibc/core/client/v1/client.proto @@ -2,11 +2,12 @@ syntax = "proto3"; package ibc.core.client.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; import "cosmos/upgrade/v1beta1/upgrade.proto"; +import "cosmos_proto/cosmos.proto"; // IdentifiedClientState defines a client state with an additional client // identifier field. @@ -41,7 +42,8 @@ message ClientConsensusStates { // handler may fail if the subject and the substitute do not match in client and // chain parameters (with exception to latest height, frozen height, and chain-id). message ClientUpdateProposal { - option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_getters) = false; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; // the title of the update proposal string title = 1; // the description of the proposal @@ -56,9 +58,10 @@ message ClientUpdateProposal { // UpgradeProposal is a gov Content type for initiating an IBC breaking // upgrade. message UpgradeProposal { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.equal) = true; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = true; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; string title = 1; string description = 2; diff --git a/proto/ibc/core/client/v1/genesis.proto b/proto/ibc/core/client/v1/genesis.proto index b2930c48418..78821244169 100644 --- a/proto/ibc/core/client/v1/genesis.proto +++ b/proto/ibc/core/client/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.client.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"; import "ibc/core/client/v1/client.proto"; import "gogoproto/gogo.proto"; diff --git a/proto/ibc/core/client/v1/query.proto b/proto/ibc/core/client/v1/query.proto index 2c9618bc801..0d26cf62e6d 100644 --- a/proto/ibc/core/client/v1/query.proto +++ b/proto/ibc/core/client/v1/query.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.client.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"; import "cosmos/base/query/v1beta1/pagination.proto"; import "ibc/core/client/v1/client.proto"; @@ -46,9 +46,9 @@ service Query { option (google.api.http).get = "/ibc/core/client/v1/client_status/{client_id}"; } - // ClientParams queries all parameters of the ibc client. + // ClientParams queries all parameters of the ibc client submodule. rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) { - option (google.api.http).get = "/ibc/client/v1/params"; + option (google.api.http).get = "/ibc/core/client/v1/params"; } // UpgradedClientState queries an Upgraded IBC light client. diff --git a/proto/ibc/core/client/v1/tx.proto b/proto/ibc/core/client/v1/tx.proto index 11dfdadeaa6..23302d5e3aa 100644 --- a/proto/ibc/core/client/v1/tx.proto +++ b/proto/ibc/core/client/v1/tx.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.client.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; @@ -40,15 +40,15 @@ message MsgCreateClient { message MsgCreateClientResponse {} // MsgUpdateClient defines an sdk.Msg to update a IBC client state using -// the given header. +// the given client message. message MsgUpdateClient { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; // client unique identifier string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // header to update the light client - google.protobuf.Any header = 2; + // client message to update the light client + google.protobuf.Any client_message = 2; // signer address string signer = 3; } @@ -82,16 +82,17 @@ message MsgUpgradeClientResponse {} // MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for // light client misbehaviour. +// Warning: DEPRECATED message MsgSubmitMisbehaviour { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; // client unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\"", deprecated = true]; // misbehaviour used for freezing the light client - google.protobuf.Any misbehaviour = 2; + google.protobuf.Any misbehaviour = 2 [deprecated = true]; // signer address - string signer = 3; + string signer = 3 [deprecated = true]; } // MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response diff --git a/proto/ibc/core/commitment/v1/commitment.proto b/proto/ibc/core/commitment/v1/commitment.proto index b6a68a99fb7..4840ff3e067 100644 --- a/proto/ibc/core/commitment/v1/commitment.proto +++ b/proto/ibc/core/commitment/v1/commitment.proto @@ -2,10 +2,10 @@ syntax = "proto3"; package ibc.core.commitment.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types"; import "gogoproto/gogo.proto"; -import "proofs.proto"; +import "cosmos/ics23/v1/proofs.proto"; // MerkleRoot defines a merkle root hash. // In the Cosmos SDK, the AppHash of a block header becomes the root. @@ -37,5 +37,5 @@ message MerklePath { // should be succinct. // MerkleProofs are ordered from leaf-to-root message MerkleProof { - repeated ics23.CommitmentProof proofs = 1; + repeated cosmos.ics23.v1.CommitmentProof proofs = 1; } diff --git a/proto/ibc/core/connection/v1/connection.proto b/proto/ibc/core/connection/v1/connection.proto index 8360af98883..ba367c14d20 100644 --- a/proto/ibc/core/connection/v1/connection.proto +++ b/proto/ibc/core/connection/v1/connection.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.connection.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"; import "gogoproto/gogo.proto"; import "ibc/core/commitment/v1/commitment.proto"; diff --git a/proto/ibc/core/connection/v1/genesis.proto b/proto/ibc/core/connection/v1/genesis.proto index f616ae67e0d..122c5a4652d 100644 --- a/proto/ibc/core/connection/v1/genesis.proto +++ b/proto/ibc/core/connection/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.connection.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"; import "gogoproto/gogo.proto"; import "ibc/core/connection/v1/connection.proto"; diff --git a/proto/ibc/core/connection/v1/query.proto b/proto/ibc/core/connection/v1/query.proto index 129f30a71a8..3c76b238910 100644 --- a/proto/ibc/core/connection/v1/query.proto +++ b/proto/ibc/core/connection/v1/query.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.connection.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"; import "gogoproto/gogo.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; @@ -41,6 +41,11 @@ service Query { option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/consensus_state/" "revision/{revision_number}/height/{revision_height}"; } + + // ConnectionParams queries all parameters of the ibc connection submodule. + rpc ConnectionParams(QueryConnectionParamsRequest) returns (QueryConnectionParamsResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/params"; + } } // QueryConnectionRequest is the request type for the Query/Connection RPC @@ -136,3 +141,12 @@ message QueryConnectionConsensusStateResponse { // height at which the proof was retrieved ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; } + +// QueryConnectionParamsRequest is the request type for the Query/ConnectionParams RPC method. +message QueryConnectionParamsRequest {} + +// QueryConnectionParamsResponse is the response type for the Query/ConnectionParams RPC method. +message QueryConnectionParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} \ No newline at end of file diff --git a/proto/ibc/core/connection/v1/tx.proto b/proto/ibc/core/connection/v1/tx.proto index b2fea632c36..af8f505c461 100644 --- a/proto/ibc/core/connection/v1/tx.proto +++ b/proto/ibc/core/connection/v1/tx.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.connection.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; @@ -67,6 +67,8 @@ message MsgConnectionOpenTry { ibc.core.client.v1.Height consensus_height = 11 [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; string signer = 12; + // optional proof data for host state machines that are unable to introspect their own consensus state + bytes host_consensus_state_proof = 13; } // MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. @@ -94,6 +96,8 @@ message MsgConnectionOpenAck { ibc.core.client.v1.Height consensus_height = 9 [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; string signer = 10; + // optional proof data for host state machines that are unable to introspect their own consensus state + bytes host_consensus_state_proof = 11; } // MsgConnectionOpenAckResponse defines the Msg/ConnectionOpenAck response type. diff --git a/proto/ibc/core/types/v1/genesis.proto b/proto/ibc/core/types/v1/genesis.proto index 4cc931d32f7..4e07551f823 100644 --- a/proto/ibc/core/types/v1/genesis.proto +++ b/proto/ibc/core/types/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.core.types.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/types"; import "gogoproto/gogo.proto"; import "ibc/core/client/v1/genesis.proto"; diff --git a/proto/ibc/lightclients/localhost/v1/localhost.proto b/proto/ibc/lightclients/localhost/v1/localhost.proto deleted file mode 100644 index 9eda835ebb1..00000000000 --- a/proto/ibc/lightclients/localhost/v1/localhost.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.localhost.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/client.proto"; - -// ClientState defines a loopback (localhost) client. It requires (read-only) -// access to keys outside the client prefix. -message ClientState { - option (gogoproto.goproto_getters) = false; - // self chain ID - string chain_id = 1 [(gogoproto.moretags) = "yaml:\"chain_id\""]; - // self latest block height - ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; -} diff --git a/proto/ibc/lightclients/solomachine/v1/solomachine.proto b/proto/ibc/lightclients/solomachine/v1/solomachine.proto deleted file mode 100644 index 37bd81e923a..00000000000 --- a/proto/ibc/lightclients/solomachine/v1/solomachine.proto +++ /dev/null @@ -1,189 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.solomachine.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100"; - -import "ibc/core/connection/v1/connection.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// ClientState defines a solo machine client that tracks the current consensus -// state and if the client is frozen. -message ClientState { - option (gogoproto.goproto_getters) = false; - // latest sequence of the client state - uint64 sequence = 1; - // frozen sequence of the solo machine - uint64 frozen_sequence = 2 [(gogoproto.moretags) = "yaml:\"frozen_sequence\""]; - ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; - // when set to true, will allow governance to update a solo machine client. - // The client will be unfrozen if it is frozen. - bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; -} - -// ConsensusState defines a solo machine consensus state. The sequence of a -// consensus state is contained in the "height" key used in storing the -// consensus state. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // public key of the solo machine - google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; - // diversifier allows the same public key to be re-used across different solo - // machine clients (potentially on different chains) without being considered - // misbehaviour. - string diversifier = 2; - uint64 timestamp = 3; -} - -// Header defines a solo machine consensus header -message Header { - option (gogoproto.goproto_getters) = false; - // sequence to update solo machine public key at - uint64 sequence = 1; - uint64 timestamp = 2; - bytes signature = 3; - google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; - string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; -} - -// Misbehaviour defines misbehaviour for a solo machine which consists -// of a sequence and two signatures over different messages at that sequence. -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - uint64 sequence = 2; - SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; - SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; -} - -// SignatureAndData contains a signature and the data signed over to create that -// signature. -message SignatureAndData { - option (gogoproto.goproto_getters) = false; - bytes signature = 1; - DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; - bytes data = 3; - uint64 timestamp = 4; -} - -// TimestampedSignatureData contains the signature data and the timestamp of the -// signature. -message TimestampedSignatureData { - option (gogoproto.goproto_getters) = false; - bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; - uint64 timestamp = 2; -} - -// SignBytes defines the signed bytes used for signature verification. -message SignBytes { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - uint64 timestamp = 2; - string diversifier = 3; - // type of the data used - DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; - // marshaled data - bytes data = 5; -} - -// DataType defines the type of solo machine proof being created. This is done -// to preserve uniqueness of different data sign byte encodings. -enum DataType { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // Data type for client state verification - DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; - // Data type for consensus state verification - DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; - // Data type for connection state verification - DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; - // Data type for channel state verification - DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; - // Data type for packet commitment verification - DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; - // Data type for packet acknowledgement verification - DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; - // Data type for packet receipt absence verification - DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; - // Data type for next sequence recv verification - DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; - // Data type for header verification - DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; -} - -// HeaderData returns the SignBytes data for update verification. -message HeaderData { - option (gogoproto.goproto_getters) = false; - - // header public key - google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; - // header diversifier - string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; -} - -// ClientStateData returns the SignBytes data for client state verification. -message ClientStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; -} - -// ConsensusStateData returns the SignBytes data for consensus state -// verification. -message ConsensusStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; -} - -// ConnectionStateData returns the SignBytes data for connection state -// verification. -message ConnectionStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.connection.v1.ConnectionEnd connection = 2; -} - -// ChannelStateData returns the SignBytes data for channel state -// verification. -message ChannelStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.channel.v1.Channel channel = 2; -} - -// PacketCommitmentData returns the SignBytes data for packet commitment -// verification. -message PacketCommitmentData { - bytes path = 1; - bytes commitment = 2; -} - -// PacketAcknowledgementData returns the SignBytes data for acknowledgement -// verification. -message PacketAcknowledgementData { - bytes path = 1; - bytes acknowledgement = 2; -} - -// PacketReceiptAbsenceData returns the SignBytes data for -// packet receipt absence verification. -message PacketReceiptAbsenceData { - bytes path = 1; -} - -// NextSequenceRecvData returns the SignBytes data for verification of the next -// sequence to be received. -message NextSequenceRecvData { - bytes path = 1; - uint64 next_seq_recv = 2 [(gogoproto.moretags) = "yaml:\"next_seq_recv\""]; -} diff --git a/proto/ibc/lightclients/solomachine/v2/solomachine.proto b/proto/ibc/lightclients/solomachine/v2/solomachine.proto index c735fddddf9..250313319b4 100644 --- a/proto/ibc/lightclients/solomachine/v2/solomachine.proto +++ b/proto/ibc/lightclients/solomachine/v2/solomachine.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package ibc.lightclients.solomachine.v2; -option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/core/02-client/migrations/v7"; import "ibc/core/connection/v1/connection.proto"; import "ibc/core/channel/v1/channel.proto"; diff --git a/proto/ibc/lightclients/solomachine/v3/solomachine.proto b/proto/ibc/lightclients/solomachine/v3/solomachine.proto new file mode 100644 index 00000000000..40e76b722e7 --- /dev/null +++ b/proto/ibc/lightclients/solomachine/v3/solomachine.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; + +package ibc.lightclients.solomachine.v3; + +option go_package = "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine;solomachine"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// ClientState defines a solo machine client that tracks the current consensus +// state and if the client is frozen. +message ClientState { + option (gogoproto.goproto_getters) = false; + // latest sequence of the client state + uint64 sequence = 1; + // frozen sequence of the solo machine + bool is_frozen = 2 [(gogoproto.moretags) = "yaml:\"is_frozen\""]; + ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; +} + +// ConsensusState defines a solo machine consensus state. The sequence of a +// consensus state is contained in the "height" key used in storing the +// consensus state. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // public key of the solo machine + google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; + // diversifier allows the same public key to be re-used across different solo + // machine clients (potentially on different chains) without being considered + // misbehaviour. + string diversifier = 2; + uint64 timestamp = 3; +} + +// Header defines a solo machine consensus header +message Header { + option (gogoproto.goproto_getters) = false; + + uint64 timestamp = 1; + bytes signature = 2; + google.protobuf.Any new_public_key = 3 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; + string new_diversifier = 4 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// Misbehaviour defines misbehaviour for a solo machine which consists +// of a sequence and two signatures over different messages at that sequence. +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + SignatureAndData signature_one = 2 [(gogoproto.moretags) = "yaml:\"signature_one\""]; + SignatureAndData signature_two = 3 [(gogoproto.moretags) = "yaml:\"signature_two\""]; +} + +// SignatureAndData contains a signature and the data signed over to create that +// signature. +message SignatureAndData { + option (gogoproto.goproto_getters) = false; + + bytes signature = 1; + bytes path = 2; + bytes data = 3; + uint64 timestamp = 4; +} + +// TimestampedSignatureData contains the signature data and the timestamp of the +// signature. +message TimestampedSignatureData { + option (gogoproto.goproto_getters) = false; + + bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; + uint64 timestamp = 2; +} + +// SignBytes defines the signed bytes used for signature verification. +message SignBytes { + option (gogoproto.goproto_getters) = false; + + // the sequence number + uint64 sequence = 1; + // the proof timestamp + uint64 timestamp = 2; + // the public key diversifier + string diversifier = 3; + // the standardised path bytes + bytes path = 4; + // the marshaled data bytes + bytes data = 5; +} + +// HeaderData returns the SignBytes data for update verification. +message HeaderData { + option (gogoproto.goproto_getters) = false; + + // header public key + google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; + // header diversifier + string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} diff --git a/proto/ibc/lightclients/tendermint/v1/tendermint.proto b/proto/ibc/lightclients/tendermint/v1/tendermint.proto index 55a4e06906d..79713e5a253 100644 --- a/proto/ibc/lightclients/tendermint/v1/tendermint.proto +++ b/proto/ibc/lightclients/tendermint/v1/tendermint.proto @@ -2,11 +2,11 @@ syntax = "proto3"; package ibc.lightclients.tendermint.v1; -option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types"; +option go_package = "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint;tendermint"; import "tendermint/types/validator.proto"; import "tendermint/types/types.proto"; -import "proofs.proto"; +import "cosmos/ics23/v1/proofs.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; import "ibc/core/client/v1/client.proto"; @@ -41,7 +41,7 @@ message ClientState { [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"latest_height\""]; // Proof specifications used in verifying counterparty state - repeated ics23.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; + repeated cosmos.ics23.v1.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; // Path at which next upgraded client will be committed. // Each element corresponds to the key for a single CommitmentProof in the @@ -79,7 +79,8 @@ message ConsensusState { message Misbehaviour { option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // ClientID is deprecated + string client_id = 1 [deprecated = true, (gogoproto.moretags) = "yaml:\"client_id\""]; Header header_1 = 2 [(gogoproto.customname) = "Header1", (gogoproto.moretags) = "yaml:\"header_1\""]; Header header_2 = 3 [(gogoproto.customname) = "Header2", (gogoproto.moretags) = "yaml:\"header_2\""]; } diff --git a/scripts/linting/lint-changed-go-files.sh b/scripts/linting/lint-changed-go-files.sh new file mode 100755 index 00000000000..286c4b772d0 --- /dev/null +++ b/scripts/linting/lint-changed-go-files.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# lint_modified_go_files runs the linter only if changes have been made to any go files. +function lint_modified_go_files() { + local go_files="$(git diff --name-only | grep \.go$)" + for f in $go_files; do + local dir_name="$(dirname $f)" + golangci-lint run "${dir_name}" --fix --out-format=tab --issues-exit-code=0 + done +} + +lint_modified_go_files diff --git a/scripts/linting/lint-changed-md-files.sh b/scripts/linting/lint-changed-md-files.sh new file mode 100755 index 00000000000..214ec70f622 --- /dev/null +++ b/scripts/linting/lint-changed-md-files.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# lint_modified_markdown_files runs the linter only if changes have been made to any md files. +function lint_modified_markdown_files() { + local markdown_files="$(git diff --name-only | grep \.md$)" + for f in $markdown_files; do + markdownlint "${f}" --fix + done +} + +lint_modified_markdown_files diff --git a/scripts/protoc-swagger-gen.sh b/scripts/protoc-swagger-gen.sh index aab3e65f6f4..fc58c14ef68 100755 --- a/scripts/protoc-swagger-gen.sh +++ b/scripts/protoc-swagger-gen.sh @@ -3,25 +3,22 @@ set -eo pipefail mkdir -p ./tmp-swagger-gen -proto_dirs=$(find ./proto -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) +cd proto +proto_dirs=$(find ./ -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) for dir in $proto_dirs; do - # generate swagger files (filter query files) query_file=$(find "${dir}" -maxdepth 1 \( -name 'query.proto' -o -name 'service.proto' \)) if [[ ! -z "$query_file" ]]; then - buf protoc \ - -I "proto" \ - -I "third_party/proto" \ - "$query_file" \ - --swagger_out=./tmp-swagger-gen \ - --swagger_opt=logtostderr=true --swagger_opt=fqn_for_swagger_name=true --swagger_opt=simple_operation_ids=true + buf generate --template buf.gen.swagger.yaml $query_file fi done +cd .. + # combine swagger files # uses nodejs package `swagger-combine`. # all the individual swagger files need to be configured in `config.json` for merging swagger-combine ./docs/client/config.json -o ./docs/client/swagger-ui/swagger.yaml -f yaml --continueOnConflictingPaths true --includeDefinitions true # clean swagger files -rm -rf ./tmp-swagger-gen +rm -rf ./tmp-swagger-gen \ No newline at end of file diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index 4736b47540b..06a576bfdd0 100755 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -2,38 +2,15 @@ set -eo pipefail -protoc_gen_gocosmos() { - if ! grep "github.com/gogo/protobuf => github.com/regen-network/protobuf" go.mod &>/dev/null ; then - echo -e "\tPlease run this command from somewhere inside the ibc-go folder." - return 1 - fi +echo "Generating gogo proto code" +cd proto - go get github.com/regen-network/cosmos-proto/protoc-gen-gocosmos@latest 2>/dev/null -} +buf generate --template buf.gen.gogo.yaml $file -protoc_gen_gocosmos - -proto_dirs=$(find ./proto -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) -for dir in $proto_dirs; do - buf protoc \ - -I "proto" \ - -I "third_party/proto" \ - --gocosmos_out=plugins=interfacetype+grpc,\ -Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types:. \ - --grpc-gateway_out=logtostderr=true:. \ - $(find "${dir}" -maxdepth 1 -name '*.proto') - -done - -# command to generate docs using protoc-gen-doc -buf protoc \ - -I "proto" \ - -I "third_party/proto" \ - --doc_out=./docs/ibc \ - --doc_opt=./docs/protodoc-markdown.tmpl,proto-docs.md \ - $(find "$(pwd)/proto" -maxdepth 7 -name '*.proto') -go mod tidy +cd .. # move proto files to the right places cp -r github.com/cosmos/ibc-go/v*/modules/* modules/ rm -rf github.com + +go mod tidy diff --git a/testing/README.md b/testing/README.md index c682ba9ed8e..8eb95321d46 100644 --- a/testing/README.md +++ b/testing/README.md @@ -1,39 +1,42 @@ -# IBC Testing Package +# IBC Testing Package ## Components The testing package comprises of four parts constructed as a stack. + - coordinator - chain - path - endpoint A coordinator sits at the highest level and contains all the chains which have been initialized. -It also stores and updates the current global time. The time is manually incremented by a `TimeIncrement`. +It also stores and updates the current global time. The time is manually incremented by a `TimeIncrement`. This allows all the chains to remain in synchrony avoiding the issue of a counterparty being perceived to be in the future. The coordinator also contains functions to do basic setup of clients, connections, and channels -between two chains. +between two chains. A chain is an SDK application (as represented by an app.go file). Inside the chain is an `TestingApp` which allows the chain to simulate block production and transaction processing. The chain contains by default a single tendermint validator. A chain is used to process SDK messages. -A path connects two channel endpoints. It contains all the information needed to relay between two endpoints. +A path connects two channel endpoints. It contains all the information needed to relay between two endpoints. An endpoint represents a channel (and its associated client and connections) on some specific chain. It contains references to the chain it is on and the counterparty endpoint it is connected to. The endpoint contains functions -to interact with initialization and updates of its associated clients, connections, and channels. It can send, receive, +to interact with initialization and updates of its associated clients, connections, and channels. It can send, receive, and acknowledge packets. In general: + - endpoints are used for initialization and execution of IBC logic on one side of an IBC connection - paths are used to relay packets - chains are used to commit SDK messages -- coordinator is used to setup a path between two chains +- coordinator is used to setup a path between two chains ## Integration To integrate the testing package into your tests, you will need to define: + - a testing application - a function to initialize the testing application @@ -44,21 +47,21 @@ will need to be extended to fulfill the `TestingApp` interface. ```go type TestingApp interface { - abci.Application + abci.Application - // ibc-go additions - GetBaseApp() *baseapp.BaseApp - GetStakingKeeper() stakingkeeper.Keeper - GetIBCKeeper() *keeper.Keeper - GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper - GetTxConfig() client.TxConfig + // ibc-go additions + GetBaseApp() *baseapp.BaseApp + GetStakingKeeper() ibctestingtypes.StakingKeeper + GetIBCKeeper() *keeper.Keeper + GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper + GetTxConfig() client.TxConfig - // Implemented by SimApp - AppCodec() codec.Codec + // Implemented by SimApp + AppCodec() codec.Codec - // Implemented by BaseApp - LastCommitID() sdk.CommitID - LastBlockHeight() int64 + // Implemented by BaseApp + LastCommitID() sdk.CommitID + LastBlockHeight() int64 } ``` @@ -70,27 +73,27 @@ To begin, you will need to extend your application by adding the following funct // GetBaseApp implements the TestingApp interface. func (app *SimApp) GetBaseApp() *baseapp.BaseApp { - return app.BaseApp + return app.BaseApp } // GetStakingKeeper implements the TestingApp interface. -func (app *SimApp) GetStakingKeeper() stakingkeeper.Keeper { - return app.StakingKeeper +func (app *SimApp) GetStakingKeeper() ibctestingtypes.Keeper { + return app.StakingKeeper } // GetIBCKeeper implements the TestingApp interface. func (app *SimApp) GetIBCKeeper() *ibckeeper.Keeper { - return app.IBCKeeper + return app.IBCKeeper } // GetScopedIBCKeeper implements the TestingApp interface. func (app *SimApp) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper { - return app.ScopedIBCKeeper + return app.ScopedIBCKeeper } // GetTxConfig implements the TestingApp interface. func (app *SimApp) GetTxConfig() client.TxConfig { - return MakeTestEncodingConfig().TxConfig + return MakeTestEncodingConfig().TxConfig } ``` @@ -103,7 +106,7 @@ Your application may need to define `AppCodec()` if it does not already exist: // 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 *SimApp) AppCodec() codec.Codec { - return app.appCodec + return app.appCodec } ``` @@ -115,19 +118,20 @@ The testing package requires that you provide a function to initialize your Test ```go func SetupTestingApp() (TestingApp, map[string]json.RawMessage) { - db := dbm.NewMemDB() - encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) - return app, simapp.NewDefaultGenesisState(encCdc.Marshaler) + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + return app, simapp.NewDefaultGenesisState(encCdc.Marshaler) } ``` This function returns the TestingApp and the default genesis state used to initialize the testing app. Change the value of `DefaultTestingAppInit` to use your function: + ```go func init() { - ibctesting.DefaultTestingAppInit = MySetupTestingAppFunction + ibctesting.DefaultTestingAppInit = MySetupTestingAppFunction } ``` @@ -135,69 +139,71 @@ func init() { ## Example Here is an example of how to setup your testing environment in every package you are testing: + ```go // KeeperTestSuite is a testing suite to test keeper functions. type KeeperTestSuite struct { - suite.Suite + suite.Suite - coordinator *ibctesting.Coordinator + coordinator *ibctesting.Coordinator - // testing chains used for convenience and readability - chainA *ibctesting.TestChain - chainB *ibctesting.TestChain + // testing chains used for convenience and readability + chainA *ibctesting.TestChain + chainB *ibctesting.TestChain } // TestKeeperTestSuite runs all the tests within this package. func TestKeeperTestSuite(t *testing.T) { - suite.Run(t, new(KeeperTestSuite)) + suite.Run(t, new(KeeperTestSuite)) } // SetupTest creates a coordinator with 2 test chains. func (suite *KeeperTestSuite) SetupTest() { - suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) // initializes 2 test chains - suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) // convenience and readability - suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) // convenience and readability + suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2) // initializes 2 test chains + suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1)) // convenience and readability + suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2)) // convenience and readability } ``` -To create interaction between chainA and chainB, we need to contruct a `Path` these chains will use. +To create interaction between chainA and chainB, we need to contruct a `Path` these chains will use. A path contains two endpoints, `EndpointA` and `EndpointB` (corresponding to the order of the chains passed -into the `NewPath` function). A path is a pointer and its values will be filled in as necessary during the -setup portion of testing. +into the `NewPath` function). A path is a pointer and its values will be filled in as necessary during the +setup portion of testing. Endpoint Struct: + ```go // Endpoint is a which represents a channel endpoint and its associated // client and connections. It contains client, connection, and channel // configuration parameters. Endpoint functions will utilize the parameters // set in the configuration structs when executing IBC messages. type Endpoint struct { - Chain *TestChain - Counterparty *Endpoint - ClientID string - ConnectionID string - ChannelID string - - ClientConfig ClientConfig - ConnectionConfig *ConnectionConfig - ChannelConfig *ChannelConfig + Chain *TestChain + Counterparty *Endpoint + ClientID string + ConnectionID string + ChannelID string + + ClientConfig ClientConfig + ConnectionConfig *ConnectionConfig + ChannelConfig *ChannelConfig } ``` The fields empty after `NewPath` is called are `ClientID`, `ConnectionID` and `ChannelID` as the clients, connections, and channels for these endpoints have not yet been created. The -`ClientConfig`, `ConnectionConfig` and `ChannelConfig` contain all the necessary information for clients, +`ClientConfig`, `ConnectionConfig` and `ChannelConfig` contain all the necessary information for clients, connections, and channels to be initialized. If you would like to use endpoints which are intitialized to use your Port IDs, you might add a helper function similar to the one found in transfer: ```go func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { - path := ibctesting.NewPath(chainA, chainB) - path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort - path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort + path := ibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort + path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort - return path + return pa``th } ``` @@ -205,41 +211,41 @@ func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { Path configurations should be set to the desired values before calling any `Setup` coordinator functions. To initialize the clients, connections, and channels for a path we can call the Setup functions of the coordinator: + - Setup() -> setup clients, connections, channels - SetupClients() -> setup clients only - SetupConnections() -> setup clients and connections only - Here is a basic example of the testing package being used to simulate IBC functionality: ```go - path := ibctesting.NewPath(suite.chainA, suite.chainB) // clientID, connectionID, channelID empty - suite.coordinator.Setup(path) // clientID, connectionID, channelID filled - suite.Require().Equal("07-tendermint-0", path.EndpointA.ClientID) - suite.Require().Equal("connection-0", path.EndpointA.ClientID) - suite.Require().Equal("channel-0", path.EndpointA.ClientID) + path := ibctesting.NewPath(suite.chainA, suite.chainB) // clientID, connectionID, channelID empty + suite.coordinator.Setup(path) // clientID, connectionID, channelID filled + suite.Require().Equal("07-tendermint-0", path.EndpointA.ClientID) + suite.Require().Equal("connection-0", path.EndpointA.ClientID) + suite.Require().Equal("channel-0", path.EndpointA.ClientID) - // create packet 1 - packet1 := NewPacket() // NewPacket would construct your packet + // send on endpointA + sequence, err := path.EndpointA.SendPacket(timeoutHeight1, timeoutTimestamp1, packet1Data) - // send on endpointA - path.EndpointA.SendPacket(packet1) + // create packet 1 + packet1 := NewPacket() // NewPacket would construct your packet - // receive on endpointB - path.EndpointB.RecvPacket(packet1) + // receive on endpointB + path.EndpointB.RecvPacket(packet1) - // acknowledge the receipt of the packet - path.EndpointA.AcknowledgePacket(packet1, ack) + // acknowledge the receipt of the packet + path.EndpointA.AcknowledgePacket(packet1, ack) - // we can also relay - packet2 := NewPacket() + // we can also relay + sequence, err := path.EndpointA.SendPacket(timeoutHeight2, timeoutTimestamp2, packet2Data) - path.EndpointA.SendPacket(packet2) + packet2 := NewPacket() - path.Relay(packet2, expectedAck) + path.Relay(packet2, expectedAck) - // if needed we can update our clients - path.EndpointB.UpdateClient() + // if needed we can update our clients + path.EndpointB.UpdateClient() ``` ### Transfer Testing Example @@ -250,71 +256,74 @@ If ICS 20 had its own simapp, its testing setup might include a `testing/app.go` package transfertesting import ( - "encoding/json" + "encoding/json" - "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" + "github.com/tendermint/tendermint/libs/log" + dbm "github.com/tendermint/tm-db" - "github.com/cosmos/ibc-go/v4/modules/apps/transfer/simapp" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + "github.com/cosmos/ibc-go/v7/modules/apps/transfer/simapp" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func SetupTransferTestingApp() (ibctesting.TestingApp, map[string]json.RawMessage) { - db := dbm.NewMemDB() - encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) - return app, simapp.NewDefaultGenesisState(encCdc.Marshaler) + db := dbm.NewMemDB() + encCdc := simapp.MakeTestEncodingConfig() + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + return app, simapp.NewDefaultGenesisState(encCdc.Marshaler) } func init() { - ibctesting.DefaultTestingAppInit = SetupTransferTestingApp + ibctesting.DefaultTestingAppInit = SetupTransferTestingApp } func NewTransferPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { - path := ibctesting.NewPath(chainA, chainB) - path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort - path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort + path := ibctesting.NewPath(chainA, chainB) + path.EndpointA.ChannelConfig.PortID = ibctesting.TransferPort + path.EndpointB.ChannelConfig.PortID = ibctesting.TransferPort - return path + return path } func GetTransferSimApp(chain *ibctesting.TestChain) *simapp.SimApp { - app, ok := chain.App.(*simapp.SimApp) - if !ok { - panic("not transfer app") - } + app, ok := chain.App.(*simapp.SimApp) + if !ok { + panic("not transfer app") + } - return app + return app } ``` ### Middleware Testing -When writing IBC applications acting as middleware, it might be desirable to test integration points. +When writing IBC applications acting as middleware, it might be desirable to test integration points. This can be done by wiring a middleware stack in the app.go file using existing applications as middleware and IBC base applications. -The mock module may also be leveraged to act as a base application in the instance that such an application is not available for testing or causes dependency concerns. +The mock module may also be leveraged to act as a base application in the instance that such an application is not available for testing or causes dependency concerns. -The mock IBC module contains a `MockIBCApp`. This struct contains a function field for every IBC App Module callback. -Each of these functions can be individually set to mock expected behaviour of a base application. +The mock IBC module contains a `MockIBCApp`. This struct contains a function field for every IBC App Module callback. +Each of these functions can be individually set to mock expected behaviour of a base application. The portID and scoped keeper for the `MockIBCApp` should be set within `MockIBCApp` before calling `NewIBCModule`. For example, if one wanted to test that the base application cannot affect the outcome of the `OnChanOpenTry` callback, the mock module base application callback could be updated as such: + ```go - mockModule.IBCApp.OnChanOpenTry = func(ctx sdk.Context, portID, channelID, version string) error { - return fmt.Errorf("mock base app must not be called for OnChanOpenTry") - } +mockModule.IBCApp.OnChanOpenTry = func(ctx sdk.Context, portID, channelID, version string) error { + return fmt.Errorf("mock base app must not be called for OnChanOpenTry") +} ``` -Using a mock module as a base application in a middleware stack may require adding the module to your `SimApp`. +Using a mock module as a base application in a middleware stack may require adding the module to your `SimApp`. This is because IBC will route to the top level IBC module of a middleware stack, so a module which never sits at the top of middleware stack will need to be accessed via a public field in `SimApp` This might look like: + ```go - suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanOpenInit = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string, - portID, channelID string, chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, version string, - ) error { - return fmt.Errorf("mock ica auth fails") - } +suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanOpenInit = func( + ctx sdk.Context, order channeltypes.Order, connectionHops []string, + portID, channelID string, chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, version string, +) error { + return fmt.Errorf("mock ica auth fails") +} ``` diff --git a/testing/app.go b/testing/app.go index 9392c42424c..fea0ed503b4 100644 --- a/testing/app.go +++ b/testing/app.go @@ -5,16 +5,18 @@ import ( "testing" "time" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -23,18 +25,19 @@ import ( tmtypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tm-db" - "github.com/cosmos/ibc-go/v4/modules/core/keeper" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/modules/core/keeper" + "github.com/cosmos/ibc-go/v7/testing/simapp" + ibctestingtypes "github.com/cosmos/ibc-go/v7/testing/types" ) -var DefaultTestingAppInit func() (TestingApp, map[string]json.RawMessage) = SetupTestingApp +var DefaultTestingAppInit = SetupTestingApp type TestingApp interface { abci.Application // ibc-go additions GetBaseApp() *baseapp.BaseApp - GetStakingKeeper() stakingkeeper.Keeper + GetStakingKeeper() ibctestingtypes.StakingKeeper GetIBCKeeper() *keeper.Keeper GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper GetTxConfig() client.TxConfig @@ -43,14 +46,14 @@ type TestingApp interface { AppCodec() codec.Codec // Implemented by BaseApp - LastCommitID() sdk.CommitID + LastCommitID() storetypes.CommitID LastBlockHeight() int64 } func SetupTestingApp() (TestingApp, map[string]json.RawMessage) { db := dbm.NewMemDB() encCdc := simapp.MakeTestEncodingConfig() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simtestutil.EmptyAppOptions{}) return app, simapp.NewDefaultGenesisState(encCdc.Marshaler) } @@ -58,7 +61,7 @@ func SetupTestingApp() (TestingApp, map[string]json.RawMessage) { // that also act as delegators. For simplicity, each validator is bonded with a delegation // of one consensus engine unit (10^6) in the default token of the simapp from first genesis // account. A Nop logger is set in SimApp. -func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, powerReduction sdk.Int, balances ...banktypes.Balance) TestingApp { +func SetupWithGenesisValSet(t testing.TB, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, powerReduction math.Int, balances ...banktypes.Balance) TestingApp { app, genesisState := DefaultTestingAppInit() // set genesis accounts @@ -110,7 +113,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(&stakingGenesis) // update total supply - bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, sdk.NewCoins(), []banktypes.Metadata{}) + bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, sdk.NewCoins(), []banktypes.Metadata{}, []banktypes.SendEnabled{}) genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) stateBytes, err := json.MarshalIndent(genesisState, "", " ") @@ -119,10 +122,9 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs // init chain will set the validator set and initialize the genesis accounts app.InitChain( abci.RequestInitChain{ - ChainId: chainID, - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: simapp.DefaultConsensusParams, - AppStateBytes: stateBytes, + ChainId: chainID, + Validators: []abci.ValidatorUpdate{}, + AppStateBytes: stateBytes, }, ) diff --git a/testing/chain.go b/testing/chain.go index 038d20c4c54..b82e2cd9823 100644 --- a/testing/chain.go +++ b/testing/chain.go @@ -5,17 +5,17 @@ import ( "testing" "time" + errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/cosmos/cosmos-sdk/x/staking/teststaking" + "github.com/cosmos/cosmos-sdk/x/staking/testutil" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -25,14 +25,14 @@ import ( tmtypes "github.com/tendermint/tendermint/types" tmversion "github.com/tendermint/tendermint/version" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - "github.com/cosmos/ibc-go/v4/modules/core/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - "github.com/cosmos/ibc-go/v4/testing/mock" - "github.com/cosmos/ibc-go/v4/testing/simapp" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + "github.com/cosmos/ibc-go/v7/modules/core/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "github.com/cosmos/ibc-go/v7/testing/mock" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) var MaxAccounts = 10 @@ -48,13 +48,13 @@ type SenderAccount struct { // is used for delivering transactions through the application state. // NOTE: the actual application uses an empty chain-id for ease of testing. type TestChain struct { - *testing.T + testing.TB Coordinator *Coordinator App TestingApp ChainID string - LastHeader *ibctmtypes.Header // header for last block height committed - CurrentHeader tmproto.Header // header for current block height + LastHeader *ibctm.Header // header for last block height committed + CurrentHeader tmproto.Header // header for current block height QueryServer types.QueryServer TxConfig client.TxConfig Codec codec.BinaryCodec @@ -91,7 +91,7 @@ type TestChain struct { // // CONTRACT: Validator array must be provided in the order expected by Tendermint. // i.e. sorted first by power and then lexicographically by address. -func NewTestChainWithValSet(t *testing.T, coord *Coordinator, chainID string, valSet *tmtypes.ValidatorSet, signers map[string]tmtypes.PrivValidator) *TestChain { +func NewTestChainWithValSet(tb testing.TB, coord *Coordinator, chainID string, valSet *tmtypes.ValidatorSet, signers map[string]tmtypes.PrivValidator) *TestChain { genAccs := []authtypes.GenesisAccount{} genBals := []banktypes.Balance{} senderAccs := []SenderAccount{} @@ -101,8 +101,9 @@ func NewTestChainWithValSet(t *testing.T, coord *Coordinator, chainID string, va senderPrivKey := secp256k1.GenPrivKey() acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), uint64(i), 0) amount, ok := sdk.NewIntFromString("10000000000000000000") - require.True(t, ok) + require.True(tb, ok) + // add sender account balance := banktypes.Balance{ Address: acc.GetAddress().String(), Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), @@ -119,7 +120,7 @@ func NewTestChainWithValSet(t *testing.T, coord *Coordinator, chainID string, va senderAccs = append(senderAccs, senderAcc) } - app := SetupWithGenesisValSet(t, valSet, genAccs, chainID, sdk.DefaultPowerReduction, genBals...) + app := SetupWithGenesisValSet(tb, valSet, genAccs, chainID, sdk.DefaultPowerReduction, genBals...) // create current header and call begin block header := tmproto.Header{ @@ -132,7 +133,7 @@ func NewTestChainWithValSet(t *testing.T, coord *Coordinator, chainID string, va // create an account to send transactions from chain := &TestChain{ - T: t, + TB: tb, Coordinator: coord, ChainID: chainID, App: app, @@ -189,7 +190,7 @@ func (chain *TestChain) GetContext() sdk.Context { // their own SimApp. func (chain *TestChain) GetSimApp() *simapp.SimApp { app, ok := chain.App.(*simapp.SimApp) - require.True(chain.T, ok) + require.True(chain.TB, ok) return app } @@ -200,21 +201,28 @@ func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) { return chain.QueryProofAtHeight(key, chain.App.LastBlockHeight()) } -// QueryProof performs an abci query with the given key and returns the proto encoded merkle proof -// for the query and the height at which the proof will succeed on a tendermint verifier. +// QueryProofAtHeight performs an abci query with the given key and returns the proto encoded merkle proof +// for the query and the height at which the proof will succeed on a tendermint verifier. Only the IBC +// store is supported func (chain *TestChain) QueryProofAtHeight(key []byte, height int64) ([]byte, clienttypes.Height) { + return chain.QueryProofForStore(exported.StoreKey, key, height) +} + +// QueryProofForStore performs an abci query with the given key and returns the proto encoded merkle proof +// for the query and the height at which the proof will succeed on a tendermint verifier. +func (chain *TestChain) QueryProofForStore(storeKey string, key []byte, height int64) ([]byte, clienttypes.Height) { res := chain.App.Query(abci.RequestQuery{ - Path: fmt.Sprintf("store/%s/key", host.StoreKey), + Path: fmt.Sprintf("store/%s/key", storeKey), Height: height - 1, Data: key, Prove: true, }) merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) proof, err := chain.App.AppCodec().Marshal(&merkleProof) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) revision := clienttypes.ParseChainID(chain.ChainID) @@ -235,10 +243,10 @@ func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, cl }) merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) proof, err := chain.App.AppCodec().Marshal(&merkleProof) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) revision := clienttypes.ParseChainID(chain.ChainID) @@ -278,7 +286,7 @@ func (chain *TestChain) NextBlock() { // val set changes returned from previous block get applied to the next validators // of this block. See tendermint spec for details. chain.Vals = chain.NextVals - chain.NextVals = ApplyValSetChanges(chain.T, chain.Vals, res.ValidatorUpdates) + chain.NextVals = ApplyValSetChanges(chain.TB, chain.Vals, res.ValidatorUpdates) // increment the current header chain.CurrentHeader = tmproto.Header{ @@ -290,6 +298,7 @@ func (chain *TestChain) NextBlock() { Time: chain.CurrentHeader.Time, ValidatorsHash: chain.Vals.Hash(), NextValidatorsHash: chain.NextVals.Hash(), + ProposerAddress: chain.CurrentHeader.ProposerAddress, } chain.App.BeginBlock(abci.RequestBeginBlock{Header: chain.CurrentHeader}) @@ -309,15 +318,14 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { chain.Coordinator.UpdateTimeForChain(chain) _, r, err := simapp.SignAndDeliver( - chain.T, + chain.TB, chain.TxConfig, chain.App.GetBaseApp(), - chain.GetContext().BlockHeader(), msgs, chain.ChainID, []uint64{chain.SenderAccount.GetAccountNumber()}, []uint64{chain.SenderAccount.GetSequence()}, - true, true, chain.SenderPrivKey, + true, chain.SenderPrivKey, ) if err != nil { return nil, err @@ -327,7 +335,10 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { chain.NextBlock() // increment sequence for successful transaction execution - chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) + err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) + if err != nil { + return nil, err + } chain.Coordinator.IncrementTime() @@ -338,7 +349,7 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) { // expected to exist otherwise testing will fail. func (chain *TestChain) GetClientState(clientID string) exported.ClientState { clientState, found := chain.App.GetIBCKeeper().ClientKeeper.GetClientState(chain.GetContext(), clientID) - require.True(chain.T, found) + require.True(chain.TB, found) return clientState } @@ -359,7 +370,7 @@ func (chain *TestChain) GetValsAtHeight(height int64) (*tmtypes.ValidatorSet, bo valSet := stakingtypes.Validators(histInfo.Valset) - tmValidators, err := teststaking.ToTmValidators(valSet, sdk.DefaultPowerReduction) + tmValidators, err := testutil.ToTmValidators(valSet, sdk.DefaultPowerReduction) if err != nil { panic(err) } @@ -370,7 +381,7 @@ func (chain *TestChain) GetValsAtHeight(height int64) (*tmtypes.ValidatorSet, bo // acknowledgement does not exist then testing will fail. func (chain *TestChain) GetAcknowledgement(packet exported.PacketI) []byte { ack, found := chain.App.GetIBCKeeper().ChannelKeeper.GetPacketAcknowledgement(chain.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) - require.True(chain.T, found) + require.True(chain.TB, found) return ack } @@ -382,13 +393,13 @@ func (chain *TestChain) GetPrefix() commitmenttypes.MerklePrefix { // ConstructUpdateTMClientHeader will construct a valid 07-tendermint Header to update the // light client on the source chain. -func (chain *TestChain) ConstructUpdateTMClientHeader(counterparty *TestChain, clientID string) (*ibctmtypes.Header, error) { +func (chain *TestChain) ConstructUpdateTMClientHeader(counterparty *TestChain, clientID string) (*ibctm.Header, error) { return chain.ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty, clientID, clienttypes.ZeroHeight()) } // ConstructUpdateTMClientHeader will construct a valid 07-tendermint Header to update the // light client on the source chain. -func (chain *TestChain) ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty *TestChain, clientID string, trustedHeight clienttypes.Height) (*ibctmtypes.Header, error) { +func (chain *TestChain) ConstructUpdateTMClientHeaderWithTrustedHeight(counterparty *TestChain, clientID string, trustedHeight clienttypes.Height) (*ibctm.Header, error) { header := counterparty.LastHeader // Relayer must query for LatestHeight on client to get TrustedHeight if the trusted height is not set if trustedHeight.IsZero() { @@ -410,7 +421,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(ibctm.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) } } // inject trusted fields into last header @@ -434,18 +445,18 @@ func (chain *TestChain) ExpireClient(amount time.Duration) { // CurrentTMClientHeader creates a TM header using the current header parameters // on the chain. The trusted fields in the header are set to nil. -func (chain *TestChain) CurrentTMClientHeader() *ibctmtypes.Header { +func (chain *TestChain) CurrentTMClientHeader() *ibctm.Header { return chain.CreateTMClientHeader(chain.ChainID, chain.CurrentHeader.Height, clienttypes.Height{}, chain.CurrentHeader.Time, chain.Vals, chain.NextVals, nil, chain.Signers) } // CreateTMClientHeader creates a TM header to update the TM client. Args are passed in to allow // caller flexibility to use params that differ from the chain. -func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, nextVals, tmTrustedVals *tmtypes.ValidatorSet, signers map[string]tmtypes.PrivValidator) *ibctmtypes.Header { +func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, trustedHeight clienttypes.Height, timestamp time.Time, tmValSet, nextVals, tmTrustedVals *tmtypes.ValidatorSet, signers map[string]tmtypes.PrivValidator) *ibctm.Header { var ( valSet *tmproto.ValidatorSet trustedVals *tmproto.ValidatorSet ) - require.NotNil(chain.T, tmValSet) + require.NotNil(chain.TB, tmValSet) vsetHash := tmValSet.Hash() nextValHash := nextVals.Hash() @@ -474,32 +485,32 @@ func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, // MakeCommit expects a signer array in the same order as the validator array. // Thus we iterate over the ordered validator set and construct a signer array // from the signer map in the same order. - var signerArr []tmtypes.PrivValidator - for _, v := range tmValSet.Validators { + var signerArr []tmtypes.PrivValidator //nolint:prealloc // using prealloc here would be needlessly complex + for _, v := range tmValSet.Validators { //nolint:staticcheck // need to check for nil validator set signerArr = append(signerArr, signers[v.Address.String()]) } commit, err := tmtypes.MakeCommit(blockID, blockHeight, 1, voteSet, signerArr, timestamp) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) signedHeader := &tmproto.SignedHeader{ Header: tmHeader.ToProto(), Commit: commit.ToProto(), } - if tmValSet != nil { + if tmValSet != nil { //nolint:staticcheck valSet, err = tmValSet.ToProto() - require.NoError(chain.T, err) + require.NoError(chain.TB, err) } if tmTrustedVals != nil { trustedVals, err = tmTrustedVals.ToProto() - require.NoError(chain.T, err) + require.NoError(chain.TB, err) } // The trusted fields may be nil. They may be filled before relaying messages to a client. // The relayer is responsible for querying client and injecting appropriate trusted fields. - return &ibctmtypes.Header{ + return &ibctm.Header{ SignedHeader: signedHeader, ValidatorSet: valSet, TrustedHeight: trustedHeight, @@ -528,11 +539,11 @@ func (chain *TestChain) CreatePortCapability(scopedKeeper capabilitykeeper.Scope if !ok { // create capability using the IBC capability keeper cap, err := chain.App.GetScopedIBCKeeper().NewCapability(chain.GetContext(), host.PortPath(portID)) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) // claim capability using the scopedKeeper err = scopedKeeper.ClaimCapability(chain.GetContext(), cap, host.PortPath(portID)) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) } chain.NextBlock() @@ -542,7 +553,7 @@ func (chain *TestChain) CreatePortCapability(scopedKeeper capabilitykeeper.Scope // exist, otherwise testing will fail. func (chain *TestChain) GetPortCapability(portID string) *capabilitytypes.Capability { cap, ok := chain.App.GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.PortPath(portID)) - require.True(chain.T, ok) + require.True(chain.TB, ok) return cap } @@ -556,9 +567,9 @@ func (chain *TestChain) CreateChannelCapability(scopedKeeper capabilitykeeper.Sc _, ok := chain.App.GetScopedIBCKeeper().GetCapability(chain.GetContext(), capName) if !ok { cap, err := chain.App.GetScopedIBCKeeper().NewCapability(chain.GetContext(), capName) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) err = scopedKeeper.ClaimCapability(chain.GetContext(), cap, capName) - require.NoError(chain.T, err) + require.NoError(chain.TB, err) } chain.NextBlock() @@ -568,7 +579,13 @@ func (chain *TestChain) CreateChannelCapability(scopedKeeper capabilitykeeper.Sc // The capability must exist, otherwise testing will fail. func (chain *TestChain) GetChannelCapability(portID, channelID string) *capabilitytypes.Capability { cap, ok := chain.App.GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.ChannelCapabilityPath(portID, channelID)) - require.True(chain.T, ok) + require.True(chain.TB, ok) return cap } + +// GetTimeoutHeight is a convenience function which returns a IBC packet timeout height +// to be used for testing. It returns the current IBC height + 100 blocks +func (chain *TestChain) GetTimeoutHeight() clienttypes.Height { + return clienttypes.NewHeight(clienttypes.ParseChainID(chain.ChainID), uint64(chain.GetContext().BlockHeight())+100) +} diff --git a/testing/chain_test.go b/testing/chain_test.go index 5edb189c2f8..4f1f4e4a118 100644 --- a/testing/chain_test.go +++ b/testing/chain_test.go @@ -3,12 +3,11 @@ package ibctesting_test import ( "testing" - "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" - ibctesting "github.com/cosmos/ibc-go/v4/testing" + ibctesting "github.com/cosmos/ibc-go/v7/testing" ) func TestChangeValSet(t *testing.T) { @@ -24,16 +23,18 @@ func TestChangeValSet(t *testing.T) { amount2, ok := sdk.NewIntFromString("30000000000000000000") require.True(t, ok) - val := chainA.App.GetStakingKeeper().GetValidators(chainA.GetContext(), 4) + val := chainA.GetSimApp().StakingKeeper.GetValidators(chainA.GetContext(), 4) - chainA.App.GetStakingKeeper().Delegate(chainA.GetContext(), chainA.SenderAccounts[1].SenderAccount.GetAddress(), + chainA.GetSimApp().StakingKeeper.Delegate(chainA.GetContext(), chainA.SenderAccounts[1].SenderAccount.GetAddress(), //nolint:errcheck // ignore error for test amount, types.Unbonded, val[1], true) - chainA.App.GetStakingKeeper().Delegate(chainA.GetContext(), chainA.SenderAccounts[3].SenderAccount.GetAddress(), + chainA.GetSimApp().StakingKeeper.Delegate(chainA.GetContext(), chainA.SenderAccounts[3].SenderAccount.GetAddress(), //nolint:errcheck // ignore error for test amount2, types.Unbonded, val[3], true) coord.CommitBlock(chainA) // verify that update clients works even after validator update goes into effect - path.EndpointB.UpdateClient() - path.EndpointB.UpdateClient() + err := path.EndpointB.UpdateClient() + require.NoError(t, err) + err = path.EndpointB.UpdateClient() + require.NoError(t, err) } diff --git a/testing/config.go b/testing/config.go index b75ecc8d918..9a6ace904ba 100644 --- a/testing/config.go +++ b/testing/config.go @@ -3,11 +3,11 @@ package ibctesting import ( "time" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - "github.com/cosmos/ibc-go/v4/testing/mock" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "github.com/cosmos/ibc-go/v7/testing/mock" ) type ClientConfig interface { @@ -15,22 +15,18 @@ type ClientConfig interface { } type TendermintConfig struct { - TrustLevel ibctmtypes.Fraction - TrustingPeriod time.Duration - UnbondingPeriod time.Duration - MaxClockDrift time.Duration - AllowUpdateAfterExpiry bool - AllowUpdateAfterMisbehaviour bool + TrustLevel ibctm.Fraction + TrustingPeriod time.Duration + UnbondingPeriod time.Duration + MaxClockDrift time.Duration } func NewTendermintConfig() *TendermintConfig { return &TendermintConfig{ - TrustLevel: DefaultTrustLevel, - TrustingPeriod: TrustingPeriod, - UnbondingPeriod: UnbondingPeriod, - MaxClockDrift: MaxClockDrift, - AllowUpdateAfterExpiry: false, - AllowUpdateAfterMisbehaviour: false, + TrustLevel: DefaultTrustLevel, + TrustingPeriod: TrustingPeriod, + UnbondingPeriod: UnbondingPeriod, + MaxClockDrift: MaxClockDrift, } } diff --git a/testing/coordinator.go b/testing/coordinator.go index f2cc49f9a91..6374a17b170 100644 --- a/testing/coordinator.go +++ b/testing/coordinator.go @@ -11,7 +11,9 @@ import ( ) var ( - ChainIDPrefix = "testchain" + ChainIDPrefix = "testchain" + // to disable revision format, set ChainIDSuffix to "" + ChainIDSuffix = "-1" globalStartTime = time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC) TimeIncrement = time.Second * 5 ) @@ -173,7 +175,7 @@ func (coord *Coordinator) GetChain(chainID string) *TestChain { // GetChainID returns the chainID used for the provided index. func GetChainID(index int) string { - return ChainIDPrefix + strconv.Itoa(index) + return ChainIDPrefix + strconv.Itoa(index) + ChainIDSuffix } // CommitBlock commits a block on the provided indexes and then increments the global time. diff --git a/testing/endpoint.go b/testing/endpoint.go index ce8895ebb51..b30c1534fc7 100644 --- a/testing/endpoint.go +++ b/testing/endpoint.go @@ -2,17 +2,18 @@ package ibctesting import ( "fmt" + "strings" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ) // Endpoint is a which represents a channel endpoint and its associated @@ -88,17 +89,16 @@ func (endpoint *Endpoint) CreateClient() (err error) { switch endpoint.ClientConfig.GetClientType() { case exported.Tendermint: tmConfig, ok := endpoint.ClientConfig.(*TendermintConfig) - require.True(endpoint.Chain.T, ok) + require.True(endpoint.Chain.TB, ok) height := endpoint.Counterparty.Chain.LastHeader.GetHeight().(clienttypes.Height) - clientState = ibctmtypes.NewClientState( + clientState = ibctm.NewClientState( endpoint.Counterparty.Chain.ChainID, tmConfig.TrustLevel, tmConfig.TrustingPeriod, tmConfig.UnbondingPeriod, tmConfig.MaxClockDrift, - height, commitmenttypes.GetSDKSpecs(), UpgradePath, tmConfig.AllowUpdateAfterExpiry, tmConfig.AllowUpdateAfterMisbehaviour, - ) + height, commitmenttypes.GetSDKSpecs(), UpgradePath) consensusState = endpoint.Counterparty.Chain.LastHeader.ConsensusState() case exported.Solomachine: // TODO - // solo := NewSolomachine(endpoint.Chain.T, endpoint.Chain.Codec, clientID, "", 1) + // solo := NewSolomachine(endpoint.Chain.TB, endpoint.Chain.Codec, clientID, "", 1) // clientState = solo.ClientState() // consensusState = solo.ConsensusState() @@ -113,7 +113,7 @@ func (endpoint *Endpoint) CreateClient() (err error) { msg, err := clienttypes.NewMsgCreateClient( clientState, consensusState, endpoint.Chain.SenderAccount.GetAddress().String(), ) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) res, err := endpoint.Chain.SendMsgs(msg) if err != nil { @@ -121,7 +121,7 @@ func (endpoint *Endpoint) CreateClient() (err error) { } endpoint.ClientID, err = ParseClientIDFromEvents(res.GetEvents()) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) return nil } @@ -131,7 +131,7 @@ func (endpoint *Endpoint) UpdateClient() (err error) { // ensure counterparty has committed state endpoint.Chain.Coordinator.CommitBlock(endpoint.Counterparty.Chain) - var header exported.Header + var header exported.ClientMessage switch endpoint.ClientConfig.GetClientType() { case exported.Tendermint: @@ -149,11 +149,64 @@ func (endpoint *Endpoint) UpdateClient() (err error) { endpoint.ClientID, header, endpoint.Chain.SenderAccount.GetAddress().String(), ) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) return endpoint.Chain.sendMsgs(msg) } +// UpgradeChain will upgrade a chain's chainID to the next revision number. +// It will also update the counterparty client. +// TODO: implement actual upgrade chain functionality via scheduling an upgrade +// and upgrading the client via MsgUpgradeClient +// see reference https://github.com/cosmos/ibc-go/pull/1169 +func (endpoint *Endpoint) UpgradeChain() error { + if strings.TrimSpace(endpoint.Counterparty.ClientID) == "" { + return fmt.Errorf("cannot upgrade chain if there is no counterparty client") + } + + clientState := endpoint.Counterparty.GetClientState().(*ibctm.ClientState) + + // increment revision number in chainID + + oldChainID := clientState.ChainId + if !clienttypes.IsRevisionFormat(oldChainID) { + return fmt.Errorf("cannot upgrade chain which is not of revision format: %s", oldChainID) + } + + revisionNumber := clienttypes.ParseChainID(oldChainID) + newChainID, err := clienttypes.SetRevisionNumber(oldChainID, revisionNumber+1) + if err != nil { + return err + } + + // update chain + endpoint.Chain.ChainID = newChainID + endpoint.Chain.CurrentHeader.ChainID = newChainID + endpoint.Chain.NextBlock() // commit changes + + // update counterparty client manually + clientState.ChainId = newChainID + clientState.LatestHeight = clienttypes.NewHeight(revisionNumber+1, clientState.LatestHeight.GetRevisionHeight()+1) + endpoint.Counterparty.SetClientState(clientState) + + consensusState := &ibctm.ConsensusState{ + Timestamp: endpoint.Chain.LastHeader.GetTime(), + Root: commitmenttypes.NewMerkleRoot(endpoint.Chain.LastHeader.Header.GetAppHash()), + NextValidatorsHash: endpoint.Chain.LastHeader.Header.NextValidatorsHash, + } + endpoint.Counterparty.SetConsensusState(consensusState, clientState.GetLatestHeight()) + + // ensure the next update isn't identical to the one set in state + endpoint.Chain.Coordinator.IncrementTime() + endpoint.Chain.NextBlock() + + if err = endpoint.Counterparty.UpdateClient(); err != nil { + return err + } + + return nil +} + // ConnOpenInit will construct and execute a MsgConnectionOpenInit on the associated endpoint. func (endpoint *Endpoint) ConnOpenInit() error { msg := connectiontypes.NewMsgConnectionOpenInit( @@ -168,7 +221,7 @@ func (endpoint *Endpoint) ConnOpenInit() error { } endpoint.ConnectionID, err = ParseConnectionIDFromEvents(res.GetEvents()) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) return nil } @@ -176,13 +229,12 @@ func (endpoint *Endpoint) ConnOpenInit() error { // ConnOpenTry will construct and execute a MsgConnectionOpenTry on the associated endpoint. func (endpoint *Endpoint) ConnOpenTry() error { err := endpoint.UpdateClient() - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) counterpartyClient, proofClient, proofConsensus, consensusHeight, proofInit, proofHeight := endpoint.QueryConnectionHandshakeProof() msg := connectiontypes.NewMsgConnectionOpenTry( - "", endpoint.ClientID, // does not support handshake continuation - endpoint.Counterparty.ConnectionID, endpoint.Counterparty.ClientID, + endpoint.ClientID, endpoint.Counterparty.ConnectionID, endpoint.Counterparty.ClientID, counterpartyClient, endpoint.Counterparty.Chain.GetPrefix(), []*connectiontypes.Version{ConnectionVersion}, endpoint.ConnectionConfig.DelayPeriod, proofInit, proofClient, proofConsensus, proofHeight, consensusHeight, @@ -195,7 +247,7 @@ func (endpoint *Endpoint) ConnOpenTry() error { if endpoint.ConnectionID == "" { endpoint.ConnectionID, err = ParseConnectionIDFromEvents(res.GetEvents()) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) } return nil @@ -204,7 +256,7 @@ func (endpoint *Endpoint) ConnOpenTry() error { // ConnOpenAck will construct and execute a MsgConnectionOpenAck on the associated endpoint. func (endpoint *Endpoint) ConnOpenAck() error { err := endpoint.UpdateClient() - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) counterpartyClient, proofClient, proofConsensus, consensusHeight, proofTry, proofHeight := endpoint.QueryConnectionHandshakeProof() @@ -221,7 +273,7 @@ func (endpoint *Endpoint) ConnOpenAck() error { // ConnOpenConfirm will construct and execute a MsgConnectionOpenConfirm on the associated endpoint. func (endpoint *Endpoint) ConnOpenConfirm() error { err := endpoint.UpdateClient() - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) connectionKey := host.ConnectionKey(endpoint.Counterparty.ConnectionID) proof, height := endpoint.Counterparty.Chain.QueryProof(connectionKey) @@ -277,7 +329,7 @@ func (endpoint *Endpoint) ChanOpenInit() error { } endpoint.ChannelID, err = ParseChannelIDFromEvents(res.GetEvents()) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) // update version to selected app version // NOTE: this update must be performed after SendMsgs() @@ -289,13 +341,13 @@ func (endpoint *Endpoint) ChanOpenInit() error { // ChanOpenTry will construct and execute a MsgChannelOpenTry on the associated endpoint. func (endpoint *Endpoint) ChanOpenTry() error { err := endpoint.UpdateClient() - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) channelKey := host.ChannelKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) proof, height := endpoint.Counterparty.Chain.QueryProof(channelKey) msg := channeltypes.NewMsgChannelOpenTry( - endpoint.ChannelConfig.PortID, "", // does not support handshake continuation + endpoint.ChannelConfig.PortID, endpoint.ChannelConfig.Version, endpoint.ChannelConfig.Order, []string{endpoint.ConnectionID}, endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID, endpoint.Counterparty.ChannelConfig.Version, proof, height, @@ -308,7 +360,7 @@ func (endpoint *Endpoint) ChanOpenTry() error { if endpoint.ChannelID == "" { endpoint.ChannelID, err = ParseChannelIDFromEvents(res.GetEvents()) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) } // update version to selected app version @@ -321,7 +373,7 @@ func (endpoint *Endpoint) ChanOpenTry() error { // ChanOpenAck will construct and execute a MsgChannelOpenAck on the associated endpoint. func (endpoint *Endpoint) ChanOpenAck() error { err := endpoint.UpdateClient() - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) channelKey := host.ChannelKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) proof, height := endpoint.Counterparty.Chain.QueryProof(channelKey) @@ -345,7 +397,7 @@ func (endpoint *Endpoint) ChanOpenAck() error { // ChanOpenConfirm will construct and execute a MsgChannelOpenConfirm on the associated endpoint. func (endpoint *Endpoint) ChanOpenConfirm() error { err := endpoint.UpdateClient() - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) channelKey := host.ChannelKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) proof, height := endpoint.Counterparty.Chain.QueryProof(channelKey) @@ -371,19 +423,30 @@ func (endpoint *Endpoint) ChanCloseInit() error { // SendPacket sends a packet through the channel keeper using the associated endpoint // The counterparty client is updated so proofs can be sent to the counterparty chain. -func (endpoint *Endpoint) SendPacket(packet exported.PacketI) error { - channelCap := endpoint.Chain.GetChannelCapability(packet.GetSourcePort(), packet.GetSourceChannel()) +// The packet sequence generated for the packet to be sent is returned. An error +// is returned if one occurs. +func (endpoint *Endpoint) SendPacket( + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, +) (uint64, error) { + channelCap := endpoint.Chain.GetChannelCapability(endpoint.ChannelConfig.PortID, endpoint.ChannelID) // no need to send message, acting as a module - err := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.SendPacket(endpoint.Chain.GetContext(), channelCap, packet) + sequence, err := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.SendPacket(endpoint.Chain.GetContext(), channelCap, endpoint.ChannelConfig.PortID, endpoint.ChannelID, timeoutHeight, timeoutTimestamp, data) if err != nil { - return err + return 0, err } // commit changes since no message was sent endpoint.Chain.Coordinator.CommitBlock(endpoint.Chain) - return endpoint.Counterparty.UpdateClient() + err = endpoint.Counterparty.UpdateClient() + if err != nil { + return 0, err + } + + return sequence, nil } // RecvPacket receives a packet on the associated endpoint. @@ -463,7 +526,7 @@ func (endpoint *Endpoint) TimeoutPacket(packet channeltypes.Packet) error { proof, proofHeight := endpoint.Counterparty.QueryProof(packetKey) nextSeqRecv, found := endpoint.Counterparty.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextSequenceRecv(endpoint.Counterparty.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) - require.True(endpoint.Chain.T, found) + require.True(endpoint.Chain.TB, found) timeoutMsg := channeltypes.NewMsgTimeout( packet, nextSeqRecv, @@ -493,7 +556,7 @@ func (endpoint *Endpoint) TimeoutOnClose(packet channeltypes.Packet) error { proofClosed, _ := endpoint.Counterparty.QueryProof(channelKey) nextSeqRecv, found := endpoint.Counterparty.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextSequenceRecv(endpoint.Counterparty.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) - require.True(endpoint.Chain.T, found) + require.True(endpoint.Chain.TB, found) timeoutOnCloseMsg := channeltypes.NewMsgTimeoutOnClose( packet, nextSeqRecv, @@ -503,11 +566,11 @@ func (endpoint *Endpoint) TimeoutOnClose(packet channeltypes.Packet) error { return endpoint.Chain.sendMsgs(timeoutOnCloseMsg) } -// SetChannelClosed sets a channel state to CLOSED. -func (endpoint *Endpoint) SetChannelClosed() error { +// SetChannelState sets a channel state +func (endpoint *Endpoint) SetChannelState(state channeltypes.State) error { channel := endpoint.GetChannel() - channel.State = channeltypes.CLOSED + channel.State = state endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.SetChannel(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID, channel) endpoint.Chain.Coordinator.CommitBlock(endpoint.Chain) @@ -530,7 +593,7 @@ func (endpoint *Endpoint) SetClientState(clientState exported.ClientState) { // The consensus state is expected to exist otherwise testing will fail. func (endpoint *Endpoint) GetConsensusState(height exported.Height) exported.ConsensusState { consensusState, found := endpoint.Chain.GetConsensusState(endpoint.ClientID, height) - require.True(endpoint.Chain.T, found) + require.True(endpoint.Chain.TB, found) return consensusState } @@ -544,7 +607,7 @@ func (endpoint *Endpoint) SetConsensusState(consensusState exported.ConsensusSta // connection is expected to exist otherwise testing will fail. func (endpoint *Endpoint) GetConnection() connectiontypes.ConnectionEnd { connection, found := endpoint.Chain.App.GetIBCKeeper().ConnectionKeeper.GetConnection(endpoint.Chain.GetContext(), endpoint.ConnectionID) - require.True(endpoint.Chain.T, found) + require.True(endpoint.Chain.TB, found) return connection } @@ -558,7 +621,7 @@ func (endpoint *Endpoint) SetConnection(connection connectiontypes.ConnectionEnd // is expected to exist otherwise testing will fail. func (endpoint *Endpoint) GetChannel() channeltypes.Channel { channel, found := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetChannel(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) - require.True(endpoint.Chain.T, found) + require.True(endpoint.Chain.TB, found) return channel } diff --git a/testing/events.go b/testing/events.go index 18169d30818..ac1fdd71954 100644 --- a/testing/events.go +++ b/testing/events.go @@ -5,20 +5,23 @@ import ( "strconv" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) +type EventsMap map[string]map[string]string + // ParseClientIDFromEvents parses events emitted from a MsgCreateClient and returns the // client identifier. func ParseClientIDFromEvents(events sdk.Events) (string, error) { for _, ev := range events { if ev.Type == clienttypes.EventTypeCreateClient { for _, attr := range ev.Attributes { - if string(attr.Key) == clienttypes.AttributeKeyClientID { - return string(attr.Value), nil + if attr.Key == clienttypes.AttributeKeyClientID { + return attr.Value, nil } } } @@ -33,8 +36,8 @@ func ParseConnectionIDFromEvents(events sdk.Events) (string, error) { if ev.Type == connectiontypes.EventTypeConnectionOpenInit || ev.Type == connectiontypes.EventTypeConnectionOpenTry { for _, attr := range ev.Attributes { - if string(attr.Key) == connectiontypes.AttributeKeyConnectionID { - return string(attr.Value), nil + if attr.Key == connectiontypes.AttributeKeyConnectionID { + return attr.Value, nil } } } @@ -48,8 +51,8 @@ func ParseChannelIDFromEvents(events sdk.Events) (string, error) { for _, ev := range events { if ev.Type == channeltypes.EventTypeChannelOpenInit || ev.Type == channeltypes.EventTypeChannelOpenTry { for _, attr := range ev.Attributes { - if string(attr.Key) == channeltypes.AttributeKeyChannelID { - return string(attr.Value), nil + if attr.Key == channeltypes.AttributeKeyChannelID { + return attr.Value, nil } } } @@ -64,12 +67,12 @@ func ParsePacketFromEvents(events sdk.Events) (channeltypes.Packet, error) { if ev.Type == channeltypes.EventTypeSendPacket { packet := channeltypes.Packet{} for _, attr := range ev.Attributes { - switch string(attr.Key) { - case channeltypes.AttributeKeyData: - packet.Data = attr.Value + switch attr.Key { + case channeltypes.AttributeKeyData: //nolint:staticcheck // DEPRECATED + packet.Data = []byte(attr.Value) case channeltypes.AttributeKeySequence: - seq, err := strconv.ParseUint(string(attr.Value), 10, 64) + seq, err := strconv.ParseUint(attr.Value, 10, 64) if err != nil { return channeltypes.Packet{}, err } @@ -77,19 +80,19 @@ func ParsePacketFromEvents(events sdk.Events) (channeltypes.Packet, error) { packet.Sequence = seq case channeltypes.AttributeKeySrcPort: - packet.SourcePort = string(attr.Value) + packet.SourcePort = attr.Value case channeltypes.AttributeKeySrcChannel: - packet.SourceChannel = string(attr.Value) + packet.SourceChannel = attr.Value case channeltypes.AttributeKeyDstPort: - packet.DestinationPort = string(attr.Value) + packet.DestinationPort = attr.Value case channeltypes.AttributeKeyDstChannel: - packet.DestinationChannel = string(attr.Value) + packet.DestinationChannel = attr.Value case channeltypes.AttributeKeyTimeoutHeight: - height, err := clienttypes.ParseHeight(string(attr.Value)) + height, err := clienttypes.ParseHeight(attr.Value) if err != nil { return channeltypes.Packet{}, err } @@ -97,7 +100,7 @@ func ParsePacketFromEvents(events sdk.Events) (channeltypes.Packet, error) { packet.TimeoutHeight = height case channeltypes.AttributeKeyTimeoutTimestamp: - timestamp, err := strconv.ParseUint(string(attr.Value), 10, 64) + timestamp, err := strconv.ParseUint(attr.Value, 10, 64) if err != nil { return channeltypes.Packet{}, err } @@ -121,11 +124,41 @@ func ParseAckFromEvents(events sdk.Events) ([]byte, error) { for _, ev := range events { if ev.Type == channeltypes.EventTypeWriteAck { for _, attr := range ev.Attributes { - if string(attr.Key) == channeltypes.AttributeKeyAck { - return attr.Value, nil + if attr.Key == channeltypes.AttributeKeyAck { //nolint:staticcheck // DEPRECATED + return []byte(attr.Value), nil } } } } return nil, fmt.Errorf("acknowledgement event attribute not found") } + +// AssertEvents asserts that expected events are present in the actual events. +// Expected map needs to be a subset of actual events to pass. +func AssertEvents( + suite *suite.Suite, + expected EventsMap, + actual sdk.Events, +) { + hasEvents := make(map[string]bool) + for eventType := range expected { + hasEvents[eventType] = false + } + + for _, event := range actual { + expEvent, eventFound := expected[event.Type] + if eventFound { + hasEvents[event.Type] = true + suite.Require().Len(event.Attributes, len(expEvent)) + for _, attr := range event.Attributes { + expValue, found := expEvent[attr.Key] + suite.Require().True(found) + suite.Require().Equal(expValue, attr.Value) + } + } + } + + for eventName, hasEvent := range hasEvents { + suite.Require().True(hasEvent, "event: %s was not found in events", eventName) + } +} diff --git a/testing/mock/README.md b/testing/mock/README.md index 5da403f9c34..71c170a357f 100644 --- a/testing/mock/README.md +++ b/testing/mock/README.md @@ -1,4 +1,4 @@ -This package is only intended to be used for testing core IBC. In order to maintain secure +This package is only intended to be used for testing core IBC. In order to maintain secure testing, we need to do message passing and execution which requires connecting an IBC application module that fulfills all the callbacks. We cannot connect to ibc-transfer which does not support all channel types so instead we create a mock application module which does nothing. It simply diff --git a/testing/mock/ack.go b/testing/mock/ack.go index c25176a02da..280e848b3be 100644 --- a/testing/mock/ack.go +++ b/testing/mock/ack.go @@ -1,23 +1,23 @@ package mock -// MockEmptyAcknowledgement implements the exported.Acknowledgement interface and always returns an empty byte string as Response -type MockEmptyAcknowledgement struct { +// EmptyAcknowledgement implements the exported.Acknowledgement interface and always returns an empty byte string as Response +type EmptyAcknowledgement struct { Response []byte } -// NewMockEmptyAcknowledgement returns a new instance of MockEmptyAcknowledgement -func NewMockEmptyAcknowledgement() MockEmptyAcknowledgement { - return MockEmptyAcknowledgement{ +// NewEmptyAcknowledgement returns a new instance of EmptyAcknowledgement +func NewEmptyAcknowledgement() EmptyAcknowledgement { + return EmptyAcknowledgement{ Response: []byte{}, } } // Success implements the Acknowledgement interface -func (ack MockEmptyAcknowledgement) Success() bool { +func (ack EmptyAcknowledgement) Success() bool { return true } // Acknowledgement implements the Acknowledgement interface -func (ack MockEmptyAcknowledgement) Acknowledgement() []byte { +func (ack EmptyAcknowledgement) Acknowledgement() []byte { return []byte{} } diff --git a/testing/mock/ibc_app.go b/testing/mock/ibc_app.go index 47f39deb5ce..d3bac8889a2 100644 --- a/testing/mock/ibc_app.go +++ b/testing/mock/ibc_app.go @@ -5,12 +5,12 @@ import ( capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) -// MockIBCApp contains IBC application module callbacks as defined in 05-port. -type MockIBCApp struct { +// IBCApp contains IBC application module callbacks as defined in 05-port. +type IBCApp struct { PortID string ScopedKeeper capabilitykeeper.ScopedKeeper @@ -87,9 +87,9 @@ type MockIBCApp struct { ) error } -// NewMockIBCApp returns a MockIBCApp. An empty PortID indicates the mock app doesn't bind/claim ports. -func NewMockIBCApp(portID string, scopedKeeper capabilitykeeper.ScopedKeeper) *MockIBCApp { - return &MockIBCApp{ +// NewIBCApp returns a IBCApp. An empty PortID indicates the mock app doesn't bind/claim ports. +func NewIBCApp(portID string, scopedKeeper capabilitykeeper.ScopedKeeper) *IBCApp { + return &IBCApp{ PortID: portID, ScopedKeeper: scopedKeeper, } diff --git a/testing/mock/ibc_module.go b/testing/mock/ibc_module.go index 12d35564005..b1afd1087c1 100644 --- a/testing/mock/ibc_module.go +++ b/testing/mock/ibc_module.go @@ -9,19 +9,19 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" + 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/ibc-go/v7/modules/core/exported" ) // IBCModule implements the ICS26 callbacks for testing/mock. type IBCModule struct { appModule *AppModule - IBCApp *MockIBCApp // base application of an IBC middleware stack + IBCApp *IBCApp // base application of an IBC middleware stack } // NewIBCModule creates a new IBCModule given the underlying mock IBC application and scopedKeeper. -func NewIBCModule(appModule *AppModule, app *MockIBCApp) IBCModule { +func NewIBCModule(appModule *AppModule, app *IBCApp) IBCModule { appModule.ibcApps = append(appModule.ibcApps, app) return IBCModule{ appModule: appModule, @@ -42,9 +42,11 @@ func (im IBCModule) OnChanOpenInit( return im.IBCApp.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version) } - // Claim channel capability passed back by IBC module - if err := im.IBCApp.ScopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return "", err + if chanCap != nil { + // Claim channel capability passed back by IBC module + if err := im.IBCApp.ScopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return "", err + } } return version, nil @@ -59,9 +61,11 @@ func (im IBCModule) OnChanOpenTry( return im.IBCApp.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, counterpartyVersion) } - // Claim channel capability passed back by IBC module - if err := im.IBCApp.ScopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return "", err + if chanCap != nil { + // Claim channel capability passed back by IBC module + if err := im.IBCApp.ScopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { + return "", err + } } return Version, nil diff --git a/testing/mock/ibc_module_test.go b/testing/mock/ibc_module_test.go index e790f6e39e7..6eec0c11db9 100644 --- a/testing/mock/ibc_module_test.go +++ b/testing/mock/ibc_module_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/require" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - "github.com/cosmos/ibc-go/v4/testing/mock" + 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/testing/mock" ) func TestCreateCapabilityName(t *testing.T) { diff --git a/testing/mock/mock.go b/testing/mock/mock.go index 3ee9e1dec89..2c4b536fa26 100644 --- a/testing/mock/mock.go +++ b/testing/mock/mock.go @@ -10,14 +10,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" + 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" + "github.com/cosmos/ibc-go/v7/modules/core/exported" ) const ( @@ -71,9 +71,6 @@ func (AppModuleBasic) ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, return nil } -// RegisterRESTRoutes implements AppModuleBasic interface. -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} - // RegisterGRPCGatewayRoutes implements AppModuleBasic interface. func (a AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {} @@ -90,7 +87,7 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { // AppModule represents the AppModule for the mock module. type AppModule struct { AppModuleBasic - ibcApps []*MockIBCApp + ibcApps []*IBCApp portKeeper PortKeeper } @@ -104,21 +101,6 @@ func NewAppModule(pk PortKeeper) AppModule { // RegisterInvariants implements the AppModule interface. func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} -// Route implements the AppModule interface. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(ModuleName, nil) -} - -// QuerierRoute implements the AppModule interface. -func (AppModule) QuerierRoute() string { - return "" -} - -// LegacyQuerierHandler implements the AppModule interface. -func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { - return nil -} - // RegisterServices implements the AppModule interface. func (am AppModule) RegisterServices(module.Configurator) {} @@ -128,7 +110,10 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json. if ibcApp.PortID != "" && !am.portKeeper.IsBound(ctx, ibcApp.PortID) { // bind mock portID cap := am.portKeeper.BindPort(ctx, ibcApp.PortID) - ibcApp.ScopedKeeper.ClaimCapability(ctx, cap, host.PortPath(ibcApp.PortID)) + err := ibcApp.ScopedKeeper.ClaimCapability(ctx, cap, host.PortPath(ibcApp.PortID)) + if err != nil { + panic(err) + } } } @@ -151,3 +136,18 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } + +var _ exported.Path = KeyPath{} + +// KeyPath defines a placeholder struct which implements the exported.Path interface +type KeyPath struct{} + +// String implements the exported.Path interface +func (KeyPath) String() string { + return "" +} + +// Empty implements the exported.Path interface +func (KeyPath) Empty() bool { + return false +} diff --git a/testing/mock/privval_test.go b/testing/mock/privval_test.go index 8fbabd90729..7b40f7b7130 100644 --- a/testing/mock/privval_test.go +++ b/testing/mock/privval_test.go @@ -7,7 +7,7 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/ibc-go/v4/testing/mock" + "github.com/cosmos/ibc-go/v7/testing/mock" ) const chainID = "testChain" @@ -24,7 +24,8 @@ func TestSignVote(t *testing.T) { pk, _ := pv.GetPubKey() vote := &tmproto.Vote{Height: 2} - pv.SignVote(chainID, vote) + err := pv.SignVote(chainID, vote) + require.NoError(t, err) msg := tmtypes.VoteSignBytes(chainID, vote) ok := pk.VerifySignature(msg, vote.Signature) @@ -36,7 +37,8 @@ func TestSignProposal(t *testing.T) { pk, _ := pv.GetPubKey() proposal := &tmproto.Proposal{Round: 2} - pv.SignProposal(chainID, proposal) + err := pv.SignProposal(chainID, proposal) + require.NoError(t, err) msg := tmtypes.ProposalSignBytes(chainID, proposal) ok := pk.VerifySignature(msg, proposal.Signature) diff --git a/testing/path.go b/testing/path.go index bfec2c803f2..d3b84a96ca7 100644 --- a/testing/path.go +++ b/testing/path.go @@ -4,7 +4,7 @@ import ( "bytes" "fmt" - channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ) // Path contains two endpoints representing two chains connected over IBC diff --git a/testing/sdk_test.go b/testing/sdk_test.go deleted file mode 100644 index a56dae3b73e..00000000000 --- a/testing/sdk_test.go +++ /dev/null @@ -1,279 +0,0 @@ -package ibctesting_test - -import ( - "fmt" - "testing" - "time" - - "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - servertypes "github.com/cosmos/cosmos-sdk/server/types" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/rest" - txtypes "github.com/cosmos/cosmos-sdk/types/tx" - authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" - authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/spf13/cobra" - "github.com/stretchr/testify/suite" - tmrand "github.com/tendermint/tendermint/libs/rand" - dbm "github.com/tendermint/tm-db" - - ibcclientcli "github.com/cosmos/ibc-go/v4/modules/core/02-client/client/cli" - "github.com/cosmos/ibc-go/v4/testing/simapp" - "github.com/cosmos/ibc-go/v4/testing/simapp/params" -) - -/* - This file contains tests from the SDK which had to deleted during the migration of - the IBC module from the SDK into this repository. https://github.com/cosmos/cosmos-sdk/pull/8735 - - They can be removed once the SDK deprecates amino. -*/ - -type IntegrationTestSuite struct { - suite.Suite - - cfg network.Config - network *network.Network -} - -func (s *IntegrationTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - cfg := DefaultConfig() - - cfg.NumValidators = 2 - - s.cfg = cfg - s.network = network.New(s.T(), cfg) - - kb := s.network.Validators[0].ClientCtx.Keyring - _, _, err := kb.NewMnemonic("newAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - - account1, _, err := kb.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - - account2, _, err := kb.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - - multi := kmultisig.NewLegacyAminoPubKey(2, []cryptotypes.PubKey{account1.GetPubKey(), account2.GetPubKey()}) - _, err = kb.SaveMultisig("multi", multi) - s.Require().NoError(err) - - _, err = s.network.WaitForHeight(1) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) -} - -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} - -// NewAppConstructor returns a new simapp AppConstructor -func NewAppConstructor(encodingCfg params.EncodingConfig) network.AppConstructor { - return func(val network.Validator) servertypes.Application { - return simapp.NewSimApp( - val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0, - encodingCfg, - simapp.EmptyAppOptions{}, - baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)), - baseapp.SetMinGasPrices(val.AppConfig.MinGasPrices), - ) - } -} - -// DefaultConfig returns a sane default configuration suitable for nearly all -// testing requirements. -func DefaultConfig() network.Config { - encCfg := simapp.MakeTestEncodingConfig() - - return network.Config{ - Codec: encCfg.Marshaler, - TxConfig: encCfg.TxConfig, - LegacyAmino: encCfg.Amino, - InterfaceRegistry: encCfg.InterfaceRegistry, - AccountRetriever: authtypes.AccountRetriever{}, - AppConstructor: NewAppConstructor(encCfg), - GenesisState: simapp.ModuleBasics.DefaultGenesis(encCfg.Marshaler), - TimeoutCommit: 2 * time.Second, - ChainID: "chain-" + tmrand.NewRand().Str(6), - NumValidators: 4, - BondDenom: sdk.DefaultBondDenom, - MinGasPrices: fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), - AccountTokens: sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction), - StakingTokens: sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction), - BondedTokens: sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction), - PruningStrategy: storetypes.PruningOptionNothing, - CleanupDir: true, - SigningAlgo: string(hd.Secp256k1Type), - KeyringOptions: []keyring.Option{}, - } -} - -func (s *IntegrationTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -// TestLegacyRestErrMessages creates two IBC txs, one that fails, one that -// succeeds, and make sure we cannot query any of them (with pretty error msg). -// Our intension is to test the error message of querying a message which is -// signed with proto, since IBC won't support legacy amino at all we are -// considering a message from IBC module. -func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { - val := s.network.Validators[0] - - // Write client state json to temp file, used for an IBC message. - // Generated by printing the result of cdc.MarshalIntefaceJSON on - // a solo machine client state - clientStateJSON := testutil.WriteToNewTempFile( - s.T(), - `{"@type":"/ibc.lightclients.solomachine.v2.ClientState","sequence":"1","is_frozen":false,"consensus_state":{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"testing","timestamp":"10"},"allow_update_after_proposal":false}`, - ) - - badClientStateJSON := testutil.WriteToNewTempFile( - s.T(), - `{"@type":"/ibc.lightclients.solomachine.v2.ClientState","sequence":"1","is_frozen":false,"consensus_state":{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"DIFFERENT","timestamp":"10"},"allow_update_after_proposal":false}`, - ) - - // Write consensus json to temp file, used for an IBC message. - // Generated by printing the result of cdc.MarshalIntefaceJSON on - // a solo machine consensus state - consensusJSON := testutil.WriteToNewTempFile( - s.T(), - `{"@type":"/ibc.lightclients.solomachine.v2.ConsensusState","public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AtK50+5pJOoaa04qqAqrnyAqsYrwrR/INnA6UPIaYZlp"},"diversifier":"testing","timestamp":"10"}`, - ) - - testCases := []struct { - desc string - cmd *cobra.Command - args []string - code uint32 - }{ - { - "Failing IBC message", - ibcclientcli.NewCreateClientCmd(), - []string{ - badClientStateJSON.Name(), // path to client state json - consensusJSON.Name(), // path to consensus json, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=foobar", flags.FlagNote), - }, - uint32(8), - }, - { - "Successful IBC message", - ibcclientcli.NewCreateClientCmd(), - []string{ - clientStateJSON.Name(), // path to client state json - consensusJSON.Name(), // path to consensus json, - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=foobar", flags.FlagNote), - }, - uint32(0), - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.desc), func() { - out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, tc.cmd, tc.args) - s.Require().NoError(err) - var txRes sdk.TxResponse - s.Require().NoError(val.ClientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), &txRes)) - s.Require().Equal(tc.code, txRes.Code) - - s.Require().NoError(s.network.WaitForNextBlock()) - - s.testQueryIBCTx(txRes, tc.cmd, tc.args) - }) - } -} - -// testQueryIBCTx is a helper function to test querying txs which: -// - show an error message on legacy REST endpoints -// - succeed using gRPC -// In practice, we call this function on IBC txs. -func (s *IntegrationTestSuite) testQueryIBCTx(txRes sdk.TxResponse, cmd *cobra.Command, args []string) { - val := s.network.Validators[0] - - errMsg := "this transaction cannot be displayed via legacy REST endpoints, because it does not support" + - " Amino serialization. Please either use CLI, gRPC, gRPC-gateway, or directly query the Tendermint RPC" + - " endpoint to query this transaction. The new REST endpoint (via gRPC-gateway) is " - - // Test that legacy endpoint return the above error message on IBC txs. - testCases := []struct { - desc string - url string - }{ - { - "Query by hash", - fmt.Sprintf("%s/txs/%s", val.APIAddress, txRes.TxHash), - }, - { - "Query by height", - fmt.Sprintf("%s/txs?tx.height=%d", val.APIAddress, txRes.Height), - }, - } - - for _, tc := range testCases { - s.Run(fmt.Sprintf("Case %s", tc.desc), func() { - txJSON, err := rest.GetRequest(tc.url) - s.Require().NoError(err) - - var errResp rest.ErrorResponse - s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(txJSON, &errResp)) - - s.Require().Contains(errResp.Error, errMsg) - }) - } - - // try fetching the txn using gRPC req, it will fetch info since it has proto codec. - grpcJSON, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", val.APIAddress, txRes.TxHash)) - s.Require().NoError(err) - - var getTxRes txtypes.GetTxResponse - s.Require().NoError(val.ClientCtx.JSONCodec.UnmarshalJSON(grpcJSON, &getTxRes)) - s.Require().Equal(getTxRes.Tx.Body.Memo, "foobar") - - // generate broadcast only txn. - args = append(args, fmt.Sprintf("--%s=true", flags.FlagGenerateOnly)) - out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) - s.Require().NoError(err) - - txFile := testutil.WriteToNewTempFile(s.T(), string(out.Bytes())) - txFileName := txFile.Name() - - // encode the generated txn. - out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, authcli.GetEncodeCommand(), []string{txFileName}) - s.Require().NoError(err) - - bz, err := val.ClientCtx.LegacyAmino.MarshalJSON(authrest.DecodeReq{Tx: string(out.Bytes())}) - s.Require().NoError(err) - - // try to decode the txn using legacy rest, it fails. - res, err := rest.PostRequest(fmt.Sprintf("%s/txs/decode", val.APIAddress), "application/json", bz) - s.Require().NoError(err) - - var errResp rest.ErrorResponse - s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(res, &errResp)) - s.Require().Contains(errResp.Error, errMsg) -} diff --git a/testing/simapp/README.md b/testing/simapp/README.md index fc449f7f2d0..412ef054eaf 100644 --- a/testing/simapp/README.md +++ b/testing/simapp/README.md @@ -4,48 +4,48 @@ order: false # simapp -simapp is an application built using the Cosmos SDK for testing and educational purposes. +simapp is an application built using the Cosmos SDK for testing and educational purposes. -## Running testnets with `simd` +## Running testnets with `simd` -If you want to spin up a quick testnet with your friends, you can follow these steps. +If you want to spin up a quick testnet with your friends, you can follow these steps. Unless otherwise noted, every step must be done by everyone who wants to participate in this testnet. -1. `$ make build`. This will build the `simd` binary and install it in your Cosmos SDK repo, - inside a new `build` directory. The following instructions are run from inside - that directory. +1. `$ make build`. This will build the `simd` binary and install it in your Cosmos SDK repo, + inside a new `build` directory. The following instructions are run from inside + that directory. 2. If you've run `simd` before, you may need to reset your database before starting a new - testnet: `$ ./simd unsafe-reset-all` -3. `$ ./simd init [moniker]`. This will initialize a new working directory, by default at + testnet: `$ ./simd unsafe-reset-all` +3. `$ ./simd init [moniker]`. This will initialize a new working directory, by default at `~/.simapp`. You need a provide a "moniker," but it doesn't matter what it is. -4. `$ ./simd keys add [key_name]`. This will create a new key, with a name of your choosing. +4. `$ ./simd keys add [key_name]`. This will create a new key, with a name of your choosing. Save the output of this command somewhere; you'll need the address generated here later. 5. `$ ./simd add-genesis-account $(simd keys show [key_name] -a) [amount]`, where `key_name` is the same key name as before; and `amount` is something like `10000000000000000000000000stake`. 6. `$ ./simd gentx [key_name] [amount] --chain-id [chain-id]`. This will create the - genesis transaction for your new chain. -7. Now, one person needs to create the genesis file `genesis.json` using the genesis transactions + genesis transaction for your new chain. +7. Now, one person needs to create the genesis file `genesis.json` using the genesis transactions from every participant, by gathering all the genesis transactions under `config/gentx` and then calling `./simd collect-gentxs`. This will create a new `genesis.json` file that includes data from all the validators (we sometimes call it the "super genesis file" to distinguish it from - single-validator genesis files). -8. Once you've received the super genesis file, overwrite your original `genesis.json` file with - the new super `genesis.json`. + single-validator genesis files). +8. Once you've received the super genesis file, overwrite your original `genesis.json` file with + the new super `genesis.json`. 9. Modify your `config/config.toml` (in the simapp working directory) to include the other participants as persistent peers: - ``` + ```text # Comma separated list of nodes to keep persistent connections to persistent_peers = "[validator address]@[ip address]:[port],[validator address]@[ip address]:[port]" ``` You can find `validator address` by running `./simd tendermint show-node-id`. (It will be hex-encoded.) By default, `port` is 26656. -10. Now you can start your nodes: `$ ./simd start`. +10. Now you can start your nodes: `$ ./simd start`. -Now you have a small testnet that you can use to try out changes to the Cosmos SDK or Tendermint! +Now you have a small testnet that you can use to try out changes to the Cosmos SDK or Tendermint! NOTE: Sometimes creating the network through the `collect-gentxs` will fail, and validators will start in a funny state (and then panic). If this happens, you can try to create and start the network first -with a single validator and then add additional validators using a `create-validator` transaction. \ No newline at end of file +with a single validator and then add additional validators using a `create-validator` transaction. diff --git a/testing/simapp/ante_handler.go b/testing/simapp/ante_handler.go index 5f8a6265399..1fee5a3a529 100644 --- a/testing/simapp/ante_handler.go +++ b/testing/simapp/ante_handler.go @@ -1,12 +1,13 @@ package simapp 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/v4/modules/core/ante" - "github.com/cosmos/ibc-go/v4/modules/core/keeper" + ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors" + ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" + "github.com/cosmos/ibc-go/v7/modules/core/keeper" ) // HandlerOptions extend the SDK's AnteHandler options by requiring the IBC keeper. @@ -19,36 +20,29 @@ type HandlerOptions struct { // NewAnteHandler creates a new ante handler func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if options.AccountKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler") + return nil, errorsmod.Wrap(ibcerrors.ErrLogic, "account keeper is required for AnteHandler") } if options.BankKeeper == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") + return nil, errorsmod.Wrap(ibcerrors.ErrLogic, "bank keeper is required for AnteHandler") } if options.SignModeHandler == nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") - } - - sigGasConsumer := options.SigGasConsumer - if sigGasConsumer == nil { - sigGasConsumer = ante.DefaultSigVerificationGasConsumer + return nil, errorsmod.Wrap(ibcerrors.ErrLogic, "sign mode handler is required for AnteHandler") } anteDecorators := []sdk.AnteDecorator{ - ante.NewSetUpContextDecorator(), - ante.NewRejectExtensionOptionsDecorator(), - ante.NewMempoolFeeDecorator(), + ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), ante.NewValidateMemoDecorator(options.AccountKeeper), ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), - ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), - // SetPubKeyDecorator must be called before all signature verification decorators - ante.NewSetPubKeyDecorator(options.AccountKeeper), + ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), + ante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewValidateSigCountDecorator(options.AccountKeeper), - ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), + ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer), ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), ante.NewIncrementSequenceDecorator(options.AccountKeeper), - ibcante.NewAnteDecorator(options.IBCKeeper), + ibcante.NewRedundantRelayDecorator(options.IBCKeeper), } return sdk.ChainAnteDecorators(anteDecorators...), nil diff --git a/testing/simapp/app.go b/testing/simapp/app.go index 312de2eb624..78b72ad6c6e 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -2,53 +2,54 @@ package simapp import ( "encoding/json" + "fmt" "io" "net/http" "os" "path/filepath" - "github.com/gorilla/mux" - "github.com/rakyll/statik/fs" - "github.com/spf13/cast" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/log" - tmos "github.com/tendermint/tendermint/libs/os" - dbm "github.com/tendermint/tm-db" - + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" + _ "github.com/cosmos/cosmos-sdk/client/docs/statik" // this is used for serving docs + nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" - "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" + runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" "github.com/cosmos/cosmos-sdk/server/api" "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" 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" - authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" 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" + authz "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" - + "github.com/cosmos/cosmos-sdk/x/consensus" + consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" "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" distr "github.com/cosmos/cosmos-sdk/x/distribution" - distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/evidence" @@ -60,8 +61,13 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "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" + "github.com/cosmos/cosmos-sdk/x/group" + groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper" + groupmodule "github.com/cosmos/cosmos-sdk/x/group/module" "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" @@ -80,37 +86,43 @@ import ( upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/gorilla/mux" + "github.com/rakyll/statik/fs" + "github.com/spf13/cast" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" + tmos "github.com/tendermint/tendermint/libs/os" + dbm "github.com/tendermint/tm-db" - ica "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts" - icacontroller "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller" - icacontrollerkeeper "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/keeper" - icacontrollertypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types" - icahost "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host" - icahostkeeper "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/keeper" - icahosttypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/host/types" - icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types" - ibcfee "github.com/cosmos/ibc-go/v4/modules/apps/29-fee" - ibcfeekeeper "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/keeper" - ibcfeetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types" - transfer "github.com/cosmos/ibc-go/v4/modules/apps/transfer" - ibctransferkeeper "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v4/modules/core" - ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client" - ibcclientclient "github.com/cosmos/ibc-go/v4/modules/core/02-client/client" - ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" - ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper" - ibcmock "github.com/cosmos/ibc-go/v4/testing/mock" - simappparams "github.com/cosmos/ibc-go/v4/testing/simapp/params" - - authz "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" - - // unnamed import of statik for swagger UI support - _ "github.com/cosmos/cosmos-sdk/client/docs/statik" + ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts" + icacontroller "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller" + icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper" + icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types" + icahost "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host" + icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper" + icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types" + icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" + ibcfee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee" + ibcfeekeeper "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/keeper" + ibcfeetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types" + transfer "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" + ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" + ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client" + ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibcmock "github.com/cosmos/ibc-go/v7/testing/mock" + simappparams "github.com/cosmos/ibc-go/v7/testing/simapp/params" + simappupgrades "github.com/cosmos/ibc-go/v7/testing/simapp/upgrades" + v6 "github.com/cosmos/ibc-go/v7/testing/simapp/upgrades/v6" + v7 "github.com/cosmos/ibc-go/v7/testing/simapp/upgrades/v7" + ibctestingtypes "github.com/cosmos/ibc-go/v7/testing/types" ) const appName = "SimApp" @@ -129,20 +141,28 @@ var ( // and genesis verification. ModuleBasics = module.NewBasicManager( auth.AppModuleBasic{}, - genutil.AppModuleBasic{}, + genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), bank.AppModuleBasic{}, capability.AppModuleBasic{}, staking.AppModuleBasic{}, mint.AppModuleBasic{}, distr.AppModuleBasic{}, gov.NewAppModuleBasic( - paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, - ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, + []govclient.ProposalHandler{ + paramsclient.ProposalHandler, + upgradeclient.LegacyProposalHandler, + upgradeclient.LegacyCancelProposalHandler, + ibcclientclient.UpdateClientProposalHandler, + ibcclientclient.UpgradeProposalHandler, + }, ), + groupmodule.AppModuleBasic{}, params.AppModuleBasic{}, crisis.AppModuleBasic{}, slashing.AppModuleBasic{}, ibc.AppModuleBasic{}, + ibctm.AppModuleBasic{}, + solomachine.AppModuleBasic{}, feegrantmodule.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, @@ -152,6 +172,7 @@ var ( authzmodule.AppModuleBasic{}, vesting.AppModuleBasic{}, ibcfee.AppModuleBasic{}, + consensus.AppModuleBasic{}, ) // module account permissions @@ -182,39 +203,41 @@ type SimApp struct { legacyAmino *codec.LegacyAmino appCodec codec.Codec interfaceRegistry types.InterfaceRegistry + txConfig client.TxConfig invCheckPeriod uint // keys to access the substores - keys map[string]*sdk.KVStoreKey - tkeys map[string]*sdk.TransientStoreKey - memKeys map[string]*sdk.MemoryStoreKey + 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 - GovKeeper govkeeper.Keeper - CrisisKeeper crisiskeeper.Keeper - UpgradeKeeper upgradekeeper.Keeper - ParamsKeeper paramskeeper.Keeper - AuthzKeeper authzkeeper.Keeper - IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly - IBCFeeKeeper ibcfeekeeper.Keeper - ICAControllerKeeper icacontrollerkeeper.Keeper - ICAHostKeeper icahostkeeper.Keeper - EvidenceKeeper evidencekeeper.Keeper - TransferKeeper ibctransferkeeper.Keeper - FeeGrantKeeper feegrantkeeper.Keeper + AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.Keeper + CapabilityKeeper *capabilitykeeper.Keeper + StakingKeeper *stakingkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + MintKeeper mintkeeper.Keeper + DistrKeeper distrkeeper.Keeper + GovKeeper govkeeper.Keeper + GroupKeeper groupkeeper.Keeper + CrisisKeeper *crisiskeeper.Keeper + UpgradeKeeper *upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + AuthzKeeper authzkeeper.Keeper + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + IBCFeeKeeper ibcfeekeeper.Keeper + ICAControllerKeeper icacontrollerkeeper.Keeper + ICAHostKeeper icahostkeeper.Keeper + EvidenceKeeper evidencekeeper.Keeper + TransferKeeper ibctransferkeeper.Keeper + FeeGrantKeeper feegrantkeeper.Keeper + ConsensusParamsKeeper consensusparamkeeper.Keeper // make scoped keepers public for test purposes ScopedIBCKeeper capabilitykeeper.ScopedKeeper ScopedTransferKeeper capabilitykeeper.ScopedKeeper - ScopedIBCFeeKeeper capabilitykeeper.ScopedKeeper ScopedFeeMockKeeper capabilitykeeper.ScopedKeeper ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper ScopedICAHostKeeper capabilitykeeper.ScopedKeeper @@ -261,11 +284,11 @@ func NewSimApp( bApp.SetInterfaceRegistry(interfaceRegistry) keys := sdk.NewKVStoreKeys( - authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, + authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, + govtypes.StoreKey, group.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, capabilitytypes.StoreKey, - authzkeeper.StoreKey, ibcfeetypes.StoreKey, + authzkeeper.StoreKey, ibcfeetypes.StoreKey, consensusparamtypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -279,16 +302,18 @@ func NewSimApp( keys: keys, tkeys: tkeys, memKeys: memKeys, + txConfig: encodingConfig.TxConfig, } app.ParamsKeeper = initParamsKeeper(appCodec, legacyAmino, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey]) // set the BaseApp's parameter store - bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramskeeper.ConsensusParamsKeyTable())) + app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[consensusparamtypes.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) + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) @@ -304,62 +329,89 @@ func NewSimApp( // SDK module keepers - app.AccountKeeper = authkeeper.NewAccountKeeper( - appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms, - ) + app.AccountKeeper = authkeeper.NewAccountKeeper(appCodec, keys[authtypes.StoreKey], authtypes.ProtoBaseAccount, maccPerms, sdk.GetConfig().GetBech32AccountAddrPrefix(), authtypes.NewModuleAddress(govtypes.ModuleName).String()) + app.BankKeeper = bankkeeper.NewBaseKeeper( - appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.ModuleAccountAddrs(), + appCodec, + keys[banktypes.StoreKey], + app.AccountKeeper, + BlockedAddresses(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - stakingKeeper := stakingkeeper.NewKeeper( - appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName), + + // register the staking hooks + // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks + 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.GetSubspace(minttypes.ModuleName), &stakingKeeper, - app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, - ) - app.DistrKeeper = distrkeeper.NewKeeper( - appCodec, keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper, - &stakingKeeper, authtypes.FeeCollectorName, app.ModuleAccountAddrs(), + appCodec, keys[minttypes.StoreKey], app.StakingKeeper, + app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, 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()) + app.SlashingKeeper = slashingkeeper.NewKeeper( - appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName), + appCodec, legacyAmino, keys[slashingtypes.StoreKey], app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - app.CrisisKeeper = crisiskeeper.NewKeeper( - app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, - ) - - app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper) - app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp) // register the staking hooks // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks - app.StakingKeeper = *stakingKeeper.SetHooks( + app.StakingKeeper.SetHooks( stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) - app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.BaseApp.MsgServiceRouter()) + app.CrisisKeeper = crisiskeeper.NewKeeper(appCodec, keys[crisistypes.StoreKey], invCheckPeriod, + app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + + app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper) + app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + + app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.MsgServiceRouter(), app.AccountKeeper) // IBC Keepers app.IBCKeeper = ibckeeper.NewKeeper( - appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, + appCodec, keys[ibcexported.StoreKey], app.GetSubspace(ibcexported.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, ) // register the proposal types - govRouter := govtypes.NewRouter() - govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler). + govRouter := govv1beta1.NewRouter() + govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). - AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) - app.GovKeeper = govkeeper.NewKeeper( - appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, - &stakingKeeper, govRouter, + + govConfig := govtypes.DefaultConfig() + /* + Example of setting gov params: + govConfig.MaxMetadataLen = 10000 + */ + govKeeper := govkeeper.NewKeeper( + appCodec, keys[govtypes.StoreKey], app.AccountKeeper, app.BankKeeper, + app.StakingKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // Set legacy router for backwards compatibility with gov v1beta1 + govKeeper.SetLegacyRouter(govRouter) + + app.GovKeeper = *govKeeper.SetHooks( + govtypes.NewMultiGovHooks( + // register the governance hooks + ), ) + groupConfig := group.DefaultConfig() + /* + Example of setting group params: + groupConfig.MaxMetadataLen = 1000 + */ + app.GroupKeeper = groupkeeper.NewKeeper(keys[group.StoreKey], appCodec, app.MsgServiceRouter(), app.AccountKeeper, groupConfig) + // IBC Fee Module keeper app.IBCFeeKeeper = ibcfeekeeper.NewKeeper( - appCodec, keys[ibcfeetypes.StoreKey], app.GetSubspace(ibcfeetypes.ModuleName), + appCodec, keys[ibcfeetypes.StoreKey], app.IBCKeeper.ChannelKeeper, // may be replaced with IBC middleware app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, @@ -376,6 +428,7 @@ func NewSimApp( // ICA Host keeper app.ICAHostKeeper = icahostkeeper.NewKeeper( appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName), + app.IBCFeeKeeper, // use ics29 fee as ics4Wrapper in middleware stack app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(), ) @@ -402,7 +455,7 @@ func NewSimApp( mockModule := ibcmock.NewAppModule(&app.IBCKeeper.PortKeeper) // The mock module is used for testing IBC - mockIBCModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewMockIBCApp(ibcmock.ModuleName, scopedIBCMockKeeper)) + mockIBCModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewIBCApp(ibcmock.ModuleName, scopedIBCMockKeeper)) ibcRouter.AddRoute(ibcmock.ModuleName, mockIBCModule) // Create Transfer Stack @@ -430,7 +483,7 @@ func NewSimApp( // initialize ICA module with mock module as the authentication module on the controller side var icaControllerStack porttypes.IBCModule - icaControllerStack = ibcmock.NewIBCModule(&mockModule, ibcmock.NewMockIBCApp("", scopedICAMockKeeper)) + icaControllerStack = ibcmock.NewIBCModule(&mockModule, ibcmock.NewIBCApp("", scopedICAMockKeeper)) app.ICAAuthModule = icaControllerStack.(ibcmock.IBCModule) icaControllerStack = icacontroller.NewIBCMiddleware(icaControllerStack, app.ICAControllerKeeper) icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) @@ -462,7 +515,7 @@ func NewSimApp( // mockModule.OnAcknowledgementPacket -> fee.OnAcknowledgementPacket -> channel.OnAcknowledgementPacket // create fee wrapped mock module - feeMockModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewMockIBCApp(MockFeePort, scopedFeeMockKeeper)) + feeMockModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewIBCApp(MockFeePort, scopedFeeMockKeeper)) app.FeeMockModule = feeMockModule feeWithMockModule := ibcfee.NewIBCMiddleware(feeMockModule, app.IBCFeeKeeper) ibcRouter.AddRoute(MockFeePort, feeWithMockModule) @@ -472,7 +525,7 @@ func NewSimApp( // create evidence keeper with router evidenceKeeper := evidencekeeper.NewKeeper( - appCodec, keys[evidencetypes.StoreKey], &app.StakingKeeper, app.SlashingKeeper, + appCodec, keys[evidencetypes.StoreKey], app.StakingKeeper, app.SlashingKeeper, ) // If evidence needs to be handled for the app, set routes in router here and seal app.EvidenceKeeper = *evidenceKeeper @@ -491,24 +544,26 @@ func NewSimApp( app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx, encodingConfig.TxConfig, ), - auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts), + auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), - bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), - capability.NewAppModule(appCodec, *app.CapabilityKeeper), - crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), + 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), - gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), - distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), - staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), + gov.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)), + distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), + staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), upgrade.NewAppModule(app.UpgradeKeeper), evidence.NewAppModule(app.EvidenceKeeper), - ibc.NewAppModule(app.IBCKeeper), params.NewAppModule(app.ParamsKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), + consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), // IBC modules + ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ibcfee.NewAppModule(app.IBCFeeKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), @@ -522,15 +577,15 @@ func NewSimApp( // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) app.mm.SetOrderBeginBlockers( upgradetypes.ModuleName, capabilitytypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName, - evidencetypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName, ibctransfertypes.ModuleName, authtypes.ModuleName, + evidencetypes.ModuleName, stakingtypes.ModuleName, ibcexported.ModuleName, ibctransfertypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, govtypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, authz.ModuleName, feegrant.ModuleName, - paramstypes.ModuleName, vestingtypes.ModuleName, icatypes.ModuleName, ibcfeetypes.ModuleName, ibcmock.ModuleName, + paramstypes.ModuleName, vestingtypes.ModuleName, icatypes.ModuleName, ibcfeetypes.ModuleName, ibcmock.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, ) app.mm.SetOrderEndBlockers( - crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName, ibctransfertypes.ModuleName, + crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, ibcexported.ModuleName, ibctransfertypes.ModuleName, capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName, minttypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, - upgradetypes.ModuleName, vestingtypes.ModuleName, icatypes.ModuleName, ibcfeetypes.ModuleName, ibcmock.ModuleName, + upgradetypes.ModuleName, vestingtypes.ModuleName, icatypes.ModuleName, ibcfeetypes.ModuleName, ibcmock.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, ) // NOTE: The genutils module must occur after staking so that pools are @@ -541,15 +596,23 @@ func NewSimApp( app.mm.SetOrderInitGenesis( capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName, - ibchost.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName, - icatypes.ModuleName, ibcfeetypes.ModuleName, ibcmock.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName, + ibcexported.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName, + icatypes.ModuleName, ibcfeetypes.ModuleName, ibcmock.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, + vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, ) - app.mm.RegisterInvariants(&app.CrisisKeeper) - app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino) + app.mm.RegisterInvariants(app.CrisisKeeper) app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) app.mm.RegisterServices(app.configurator) + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.mm.Modules)) + + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + // add test gRPC service for testing gRPC queries in isolation testdata.RegisterQueryServer(app.GRPCQueryRouter(), testdata.QueryImpl{}) @@ -558,20 +621,21 @@ func NewSimApp( // NOTE: this is not required apps that don't use the simulator for fuzz testing // transactions app.sm = module.NewSimulationManager( - auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts), - bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), - capability.NewAppModule(appCodec, *app.CapabilityKeeper), + auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), + bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), + capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), - gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper), - staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), - distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), + gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), + mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), + staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), params.NewAppModule(app.ParamsKeeper), evidence.NewAppModule(app.EvidenceKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), + ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), ) app.sm.RegisterStoreDecoders() @@ -604,6 +668,9 @@ func NewSimApp( app.SetEndBlocker(app.EndBlocker) + app.setupUpgradeHandlers() + app.setupUpgradeStoreLoaders() + if loadLatest { if err := app.LoadLatestVersion(); err != nil { tmos.Exit(err.Error()) @@ -656,7 +723,7 @@ func (app *SimApp) LoadHeight(height int64) error { func (app *SimApp) ModuleAccountAddrs() map[string]bool { modAccAddrs := make(map[string]bool) for acc := range maccPerms { - // do not add mock module to blocked addresses + // do not add the following modules to blocked addresses // this is only used for testing if acc == ibcmock.ModuleName { continue @@ -698,21 +765,21 @@ func (app *SimApp) InterfaceRegistry() types.InterfaceRegistry { // GetKey returns the KVStoreKey for the provided store key. // // NOTE: This is solely to be used for testing purposes. -func (app *SimApp) GetKey(storeKey string) *sdk.KVStoreKey { +func (app *SimApp) 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 *SimApp) GetTKey(storeKey string) *sdk.TransientStoreKey { +func (app *SimApp) 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 *SimApp) GetMemKey(storeKey string) *sdk.MemoryStoreKey { +func (app *SimApp) GetMemKey(storeKey string) *storetypes.MemoryStoreKey { return app.memKeys[storeKey] } @@ -732,7 +799,7 @@ func (app *SimApp) GetBaseApp() *baseapp.BaseApp { } // GetStakingKeeper implements the TestingApp interface. -func (app *SimApp) GetStakingKeeper() stakingkeeper.Keeper { +func (app *SimApp) GetStakingKeeper() ibctestingtypes.StakingKeeper { return app.StakingKeeper } @@ -748,7 +815,7 @@ func (app *SimApp) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper { // GetTxConfig implements the TestingApp interface. func (app *SimApp) GetTxConfig() client.TxConfig { - return MakeTestEncodingConfig().TxConfig + return app.txConfig } // SimulationManager implements the SimulationApp interface @@ -760,18 +827,17 @@ func (app *SimApp) SimulationManager() *module.SimulationManager { // API server. func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { clientCtx := apiSvr.ClientCtx - rpc.RegisterRoutes(clientCtx, apiSvr.Router) - // Register legacy tx routes. - authrest.RegisterTxRoutes(clientCtx, apiSvr.Router) // 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 legacy and grpc-gateway routes for all modules. - ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router) ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + // Register nodeservice grpc-gateway routes. + nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + // register swagger API from root so that other applications can override easily if apiConfig.Swagger { RegisterSwaggerAPI(clientCtx, apiSvr.Router) @@ -785,7 +851,16 @@ func (app *SimApp) RegisterTxService(clientCtx client.Context) { // RegisterTendermintService implements the Application.RegisterTendermintService method. func (app *SimApp) RegisterTendermintService(clientCtx client.Context) { - tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry) + tmservice.RegisterTendermintService( + clientCtx, + app.BaseApp.GRPCQueryRouter(), + app.interfaceRegistry, + app.Query, + ) +} + +func (app *SimApp) RegisterNodeService(clientCtx client.Context) { + nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter()) } // RegisterSwaggerAPI registers swagger route with API Server @@ -808,22 +883,91 @@ func GetMaccPerms() map[string][]string { return dupMaccPerms } +// ModuleAccountAddrsLegacy returns all the app's module account addresses. +func ModuleAccountAddrsLegacy() map[string]bool { + modAccAddrs := make(map[string]bool) + for acc := range GetMaccPerms() { + modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true + } + + return modAccAddrs +} + +func BlockedAddresses() map[string]bool { + modAccAddrs := ModuleAccountAddrsLegacy() + + // allow the following addresses to receive funds + delete(modAccAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + delete(modAccAddrs, authtypes.NewModuleAddress(ibcmock.ModuleName).String()) + + return modAccAddrs +} + // initParamsKeeper init params keeper and its subspaces -func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper { +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(govtypes.ParamKeyTable()) - paramsKeeper.Subspace(crisistypes.ModuleName) + // TODO: ibc module subspaces can be removed after migration of params + // https://github.com/cosmos/ibc-go/issues/2010 paramsKeeper.Subspace(ibctransfertypes.ModuleName) - paramsKeeper.Subspace(ibchost.ModuleName) + paramsKeeper.Subspace(ibcexported.ModuleName) paramsKeeper.Subspace(icacontrollertypes.SubModuleName) paramsKeeper.Subspace(icahosttypes.SubModuleName) return paramsKeeper } + +// setupUpgradeHandlers sets all necessary upgrade handlers for testing purposes +func (app *SimApp) setupUpgradeHandlers() { + app.UpgradeKeeper.SetUpgradeHandler( + simappupgrades.DefaultUpgradeName, + simappupgrades.CreateDefaultUpgradeHandler(app.mm, app.configurator), + ) + + // NOTE: The moduleName arg of v6.CreateUpgradeHandler refers to the auth module ScopedKeeper name to which the channel capability should be migrated from. + // This should be the same string value provided upon instantiation of the ScopedKeeper with app.CapabilityKeeper.ScopeToModule() + // See: https://github.com/cosmos/ibc-go/blob/v6.1.0/testing/simapp/app.go#L310 + app.UpgradeKeeper.SetUpgradeHandler( + v6.UpgradeName, + v6.CreateUpgradeHandler( + app.mm, + app.configurator, + app.appCodec, + app.keys[capabilitytypes.ModuleName], + app.CapabilityKeeper, + ibcmock.ModuleName+icacontrollertypes.SubModuleName, + ), + ) + + app.UpgradeKeeper.SetUpgradeHandler( + v7.UpgradeName, + v7.CreateUpgradeHandler( + app.mm, + app.configurator, + app.appCodec, + app.IBCKeeper.ClientKeeper, + app.ConsensusParamsKeeper, + app.ParamsKeeper, + ), + ) +} + +// setupUpgradeStoreLoaders sets all necessary store loaders required by upgrades. +func (app *SimApp) setupUpgradeStoreLoaders() { + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() + if err != nil { + tmos.Exit(fmt.Sprintf("failed to read upgrade info from disk %s", err)) + } + + if upgradeInfo.Name == v7.UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + storeUpgrades := storetypes.StoreUpgrades{ + Added: []string{ + consensusparamtypes.StoreKey, + crisistypes.StoreKey, + }, + } + + // configure store loader that checks if version == upgradeHeight and applies store upgrades + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + } +} diff --git a/testing/simapp/encoding.go b/testing/simapp/encoding.go index c13124c5c7b..ff03bcd5ed6 100644 --- a/testing/simapp/encoding.go +++ b/testing/simapp/encoding.go @@ -3,7 +3,7 @@ package simapp import ( "github.com/cosmos/cosmos-sdk/std" - simappparams "github.com/cosmos/ibc-go/v4/testing/simapp/params" + simappparams "github.com/cosmos/ibc-go/v7/testing/simapp/params" ) // MakeTestEncodingConfig creates an EncodingConfig for testing. This function diff --git a/testing/simapp/export.go b/testing/simapp/export.go index fba37920697..3d436bc4b6d 100644 --- a/testing/simapp/export.go +++ b/testing/simapp/export.go @@ -45,7 +45,7 @@ func (app *SimApp) ExportAppStateAndValidators( // 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 +// in favour of export at a block height func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) { applyAllowedAddrs := false @@ -108,8 +108,8 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [] feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) app.DistrKeeper.SetFeePool(ctx, feePool) - app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) - return false + err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) + return err != nil }) // reinitialize all delegations @@ -122,8 +122,14 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [] if err != nil { panic(err) } - app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr) - app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr) + err = app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr) + if err != nil { + panic(err) + } + err = app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr) + if err != nil { + panic(err) + } } // reset context height diff --git a/testing/simapp/genesis_account_test.go b/testing/simapp/genesis_account_test.go index f4595c0fdf0..3f88fd435c5 100644 --- a/testing/simapp/genesis_account_test.go +++ b/testing/simapp/genesis_account_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" - "github.com/cosmos/ibc-go/v4/testing/simapp" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) func TestSimGenesisAccountValidate(t *testing.T) { diff --git a/testing/simapp/helpers/test_helpers.go b/testing/simapp/helpers/test_helpers.go deleted file mode 100644 index 9ccecbd976c..00000000000 --- a/testing/simapp/helpers/test_helpers.go +++ /dev/null @@ -1,80 +0,0 @@ -package helpers - -import ( - "math/rand" - "time" - - "github.com/cosmos/cosmos-sdk/client" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/simulation" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" -) - -// SimAppChainID hardcoded chainID for simulation -const ( - DefaultGenTxGas = 1000000 - SimAppChainID = "simulation-app" -) - -// GenTx generates a signed mock transaction. -func GenTx(gen client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, gas uint64, chainID string, accNums, accSeqs []uint64, priv ...cryptotypes.PrivKey) (sdk.Tx, error) { - sigs := make([]signing.SignatureV2, len(priv)) - - // create a random length memo - r := rand.New(rand.NewSource(time.Now().UnixNano())) - - memo := simulation.RandStringOfLength(r, simulation.RandIntBetween(r, 0, 100)) - - signMode := gen.SignModeHandler().DefaultMode() - - // 1st round: set SignatureV2 with empty signatures, to set correct - // signer infos. - for i, p := range priv { - sigs[i] = signing.SignatureV2{ - PubKey: p.PubKey(), - Data: &signing.SingleSignatureData{ - SignMode: signMode, - }, - Sequence: accSeqs[i], - } - } - - tx := gen.NewTxBuilder() - err := tx.SetMsgs(msgs...) - if err != nil { - return nil, err - } - err = tx.SetSignatures(sigs...) - if err != nil { - return nil, err - } - tx.SetMemo(memo) - tx.SetFeeAmount(feeAmt) - tx.SetGasLimit(gas) - - // 2nd round: once all signer infos are set, every signer can sign. - for i, p := range priv { - signerData := authsign.SignerData{ - ChainID: chainID, - AccountNumber: accNums[i], - Sequence: accSeqs[i], - } - signBytes, err := gen.SignModeHandler().GetSignBytes(signMode, signerData, tx.GetTx()) - if err != nil { - panic(err) - } - sig, err := p.Sign(signBytes) - if err != nil { - panic(err) - } - sigs[i].Data.(*signing.SingleSignatureData).Signature = sig - err = tx.SetSignatures(sigs...) - if err != nil { - panic(err) - } - } - - return tx.GetTx(), nil -} diff --git a/testing/simapp/params/amino.go b/testing/simapp/params/amino.go index 0d43dd1eb8f..d603987dd5f 100644 --- a/testing/simapp/params/amino.go +++ b/testing/simapp/params/amino.go @@ -6,7 +6,7 @@ package params import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" + "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" ) // MakeTestEncodingConfig creates an EncodingConfig for an amino based test configuration. diff --git a/testing/simapp/params/doc.go b/testing/simapp/params/doc.go index 1c721342a9c..bef67c83b3d 100644 --- a/testing/simapp/params/doc.go +++ b/testing/simapp/params/doc.go @@ -13,7 +13,7 @@ file with the weights defined for each of the transaction operations: "op_weight_msg_delegate": 100, } -In the example above, the `MsgSend` has 60% chance to be simulated, while the -`MsgDelegate` will always be simulated. +In the example above, the MsgSend has 60% chance to be simulated, while the +MsgDelegate will always be simulated. */ package params diff --git a/testing/simapp/sim_bench_test.go b/testing/simapp/sim_bench_test.go index 26c2223c543..8cdecd5c331 100644 --- a/testing/simapp/sim_bench_test.go +++ b/testing/simapp/sim_bench_test.go @@ -5,13 +5,14 @@ import ( "os" "testing" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) // Profile with: -// /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/ibc-go/v4/testing/simapp -bench ^BenchmarkFullAppSimulation$ -Commit=true -cpuprofile cpu.out +// /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/ibc-go/v7/testing/simapp -bench ^BenchmarkFullAppSimulation$ -Commit=true -cpuprofile cpu.out func BenchmarkFullAppSimulation(b *testing.B) { b.ReportAllocs() config, db, dir, logger, _, err := SetupSimulation("goleveldb-app-sim", "Simulation") @@ -27,7 +28,7 @@ func BenchmarkFullAppSimulation(b *testing.B) { } }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( @@ -73,7 +74,7 @@ func BenchmarkInvariants(b *testing.B) { } }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( diff --git a/testing/simapp/sim_test.go b/testing/simapp/sim_test.go index 7935213c9b3..5c9dc1cddde 100644 --- a/testing/simapp/sim_test.go +++ b/testing/simapp/sim_test.go @@ -9,6 +9,8 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/store" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -29,9 +31,8 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/testing/simapp/helpers" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // Get flags every time the simulator is run @@ -40,8 +41,8 @@ func init() { } type StoreKeysPrefixes struct { - A sdk.StoreKey - B sdk.StoreKey + A storetypes.StoreKey + B storetypes.StoreKey Prefixes [][]byte } @@ -69,7 +70,7 @@ func TestFullAppSimulation(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // run randomized simulation @@ -107,7 +108,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // Run randomized simulation @@ -147,7 +148,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", newApp.Name()) var genesisState GenesisState @@ -178,7 +179,7 @@ func TestAppImportExport(t *testing.T) { {app.keys[govtypes.StoreKey], newApp.keys[govtypes.StoreKey], [][]byte{}}, {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}}, {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}}, - {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}}, + {app.keys[ibcexported.StoreKey], newApp.keys[ibcexported.StoreKey], [][]byte{}}, {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}}, {app.keys[authzkeeper.StoreKey], newApp.keys[authzkeeper.StoreKey], [][]byte{}}, } @@ -207,7 +208,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // Run randomized simulation @@ -252,7 +253,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, fauxMerkleModeOpt) + newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}, fauxMerkleModeOpt) require.Equal(t, "SimApp", newApp.Name()) newApp.InitChain(abci.RequestInitChain{ @@ -285,7 +286,7 @@ func TestAppStateDeterminism(t *testing.T) { config.ExportParamsPath = "" config.OnOperation = false config.AllInvariants = false - config.ChainID = helpers.SimAppChainID + config.ChainID = "simulation-app" numSeeds := 3 numTimesToRunPerSeed := 5 @@ -303,7 +304,7 @@ func TestAppStateDeterminism(t *testing.T) { } db := dbm.NewMemDB() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), EmptyAppOptions{}, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, MakeTestEncodingConfig(), simtestutil.EmptyAppOptions{}, interBlockCacheOpt()) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", diff --git a/testing/simapp/simd/cmd/cmd_test.go b/testing/simapp/simd/cmd/cmd_test.go index 5108d3c0a2e..4ac8843035a 100644 --- a/testing/simapp/simd/cmd/cmd_test.go +++ b/testing/simapp/simd/cmd/cmd_test.go @@ -8,8 +8,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v4/testing/simapp" - "github.com/cosmos/ibc-go/v4/testing/simapp/simd/cmd" + "github.com/cosmos/ibc-go/v7/testing/simapp" + "github.com/cosmos/ibc-go/v7/testing/simapp/simd/cmd" ) func TestInitCmd(t *testing.T) { @@ -20,5 +20,5 @@ func TestInitCmd(t *testing.T) { fmt.Sprintf("--%s=%s", cli.FlagOverwrite, "true"), // Overwrite genesis.json, in case it already exists }) - require.NoError(t, svrcmd.Execute(rootCmd, simapp.DefaultNodeHome)) + require.NoError(t, svrcmd.Execute(rootCmd, "simd", simapp.DefaultNodeHome)) } diff --git a/testing/simapp/simd/cmd/genaccounts.go b/testing/simapp/simd/cmd/genaccounts.go index b31b1c20fb4..0b25662d093 100644 --- a/testing/simapp/simd/cmd/genaccounts.go +++ b/testing/simapp/simd/cmd/genaccounts.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" @@ -39,31 +38,36 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) - depCdc := clientCtx.JSONCodec - cdc := depCdc.(codec.Codec) - serverCtx := server.GetServerContextFromCmd(cmd) config := serverCtx.Config config.SetRoot(clientCtx.HomeDir) + var kr keyring.Keyring addr, err := sdk.AccAddressFromBech32(args[0]) if err != nil { inBuf := bufio.NewReader(cmd.InOrStdin()) keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) - // attempt to lookup address from Keybase if no address was provided - kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf) - if err != nil { - return err + if keyringBackend != "" && clientCtx.Keyring == nil { + var err error + kr, err = keyring.New(sdk.KeyringServiceName(), keyringBackend, clientCtx.HomeDir, inBuf, clientCtx.Codec) + if err != nil { + return err + } + } else { + kr = clientCtx.Keyring } - info, err := kb.Key(args[0]) + k, err := kr.Key(args[0]) if err != nil { - return fmt.Errorf("failed to get address from Keybase: %w", err) + return fmt.Errorf("failed to get address from Keyring: %w", err) } - addr = info.GetAddress() + addr, err = k.GetAddress() + if err != nil { + return err + } } coins, err := sdk.ParseCoinsNormalized(args[1]) @@ -118,7 +122,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa return fmt.Errorf("failed to unmarshal genesis state: %w", err) } - authGenState := authtypes.GetGenesisStateFromAppState(cdc, appState) + authGenState := authtypes.GetGenesisStateFromAppState(clientCtx.Codec, appState) accs, err := authtypes.UnpackAccounts(authGenState.Accounts) if err != nil { @@ -140,19 +144,19 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa } authGenState.Accounts = genAccs - authGenStateBz, err := cdc.MarshalJSON(&authGenState) + authGenStateBz, err := clientCtx.Codec.MarshalJSON(&authGenState) if err != nil { return fmt.Errorf("failed to marshal auth genesis state: %w", err) } appState[authtypes.ModuleName] = authGenStateBz - bankGenState := banktypes.GetGenesisStateFromAppState(depCdc, appState) + bankGenState := banktypes.GetGenesisStateFromAppState(clientCtx.Codec, appState) bankGenState.Balances = append(bankGenState.Balances, balances) bankGenState.Balances = banktypes.SanitizeGenesisBalances(bankGenState.Balances) bankGenState.Supply = bankGenState.Supply.Add(balances.Coins...) - bankGenStateBz, err := cdc.MarshalJSON(bankGenState) + bankGenStateBz, err := clientCtx.Codec.MarshalJSON(bankGenState) if err != nil { return fmt.Errorf("failed to marshal bank genesis state: %w", err) } diff --git a/testing/simapp/simd/cmd/genaccounts_test.go b/testing/simapp/simd/cmd/genaccounts_test.go index b22f956d4d2..f643174707a 100644 --- a/testing/simapp/simd/cmd/genaccounts_test.go +++ b/testing/simapp/simd/cmd/genaccounts_test.go @@ -16,8 +16,8 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" - "github.com/cosmos/ibc-go/v4/testing/simapp" - simcmd "github.com/cosmos/ibc-go/v4/testing/simapp/simd/cmd" + "github.com/cosmos/ibc-go/v7/testing/simapp" + simcmd "github.com/cosmos/ibc-go/v7/testing/simapp/simd/cmd" ) var testMbm = module.NewBasicManager(genutil.AppModuleBasic{}) @@ -63,7 +63,7 @@ func TestAddGenesisAccountCmd(t *testing.T) { require.NoError(t, err) serverCtx := server.NewContext(viper.New(), cfg, logger) - clientCtx := client.Context{}.WithJSONCodec(appCodec).WithHomeDir(home) + clientCtx := client.Context{}.WithCodec(appCodec).WithHomeDir(home) ctx := context.Background() ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) diff --git a/testing/simapp/simd/cmd/root.go b/testing/simapp/simd/cmd/root.go index 219091ea09a..10a43fbb5d2 100644 --- a/testing/simapp/simd/cmd/root.go +++ b/testing/simapp/simd/cmd/root.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" + sdkcmd "cosmossdk.io/simapp/simd/cmd" + rosettaCmd "cosmossdk.io/tools/rosetta/cmd" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" @@ -17,21 +19,25 @@ import ( serverconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/snapshots" + snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" "github.com/cosmos/cosmos-sdk/store" 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" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/crisis" + "github.com/cosmos/cosmos-sdk/x/genutil" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/spf13/cast" "github.com/spf13/cobra" + tmcfg "github.com/tendermint/tendermint/config" tmcli "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" - "github.com/cosmos/ibc-go/v4/testing/simapp" - "github.com/cosmos/ibc-go/v4/testing/simapp/params" + "github.com/cosmos/ibc-go/v7/testing/simapp" + "github.com/cosmos/ibc-go/v7/testing/simapp/params" ) // NewRootCmd creates a new root command for simd. It is called once in the @@ -71,8 +77,9 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { } customAppTemplate, customAppConfig := initAppConfig() + customTMConfig := initTendermintConfig() - return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig) + return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig) }, } @@ -81,6 +88,18 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { return rootCmd, encodingConfig } +// 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 +} + // initAppConfig helps to override default appConfig template and configs. // return "", nil if no custom configuration is required for the application. func initAppConfig() (string, interface{}) { @@ -140,16 +159,17 @@ lru_size = 0` func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { cfg := sdk.GetConfig() cfg.Seal() + gentxModule := simapp.ModuleBasics[genutiltypes.ModuleName].(genutil.AppModuleBasic) rootCmd.AddCommand( genutilcli.InitCmd(simapp.ModuleBasics, simapp.DefaultNodeHome), - genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome), + genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome, gentxModule.GenTxValidator), genutilcli.MigrateGenesisCmd(), genutilcli.GenTxCmd(simapp.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome), genutilcli.ValidateGenesisCmd(simapp.ModuleBasics), AddGenesisAccountCmd(simapp.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), - testnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}), + sdkcmd.NewTestnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}), debug.Cmd(), config.Cmd(), ) @@ -166,7 +186,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { ) // add rosetta - rootCmd.AddCommand(server.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler)) + rootCmd.AddCommand(rosettaCmd.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler)) } func addModuleInitFlags(startCmd *cobra.Command) { @@ -246,7 +266,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a } snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") - snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir) + snapshotDB, err := dbm.NewDB("metadata", server.GetAppDBBackend(appOpts), snapshotDir) if err != nil { panic(err) } @@ -255,6 +275,11 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a panic(err) } + snapshotOptions := snapshottypes.NewSnapshotOptions( + cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval)), + cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent)), + ) + return simapp.NewSimApp( logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), @@ -269,9 +294,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a baseapp.SetInterBlockCache(cache), baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))), baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))), - baseapp.SetSnapshotStore(snapshotStore), - baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval))), - baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent))), + baseapp.SetSnapshot(snapshotStore, snapshotOptions), ) } @@ -279,7 +302,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a // and exports state. func (a appCreator) appExport( logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, - appOpts servertypes.AppOptions, + appOpts servertypes.AppOptions, modulesToExport []string, ) (servertypes.ExportedApp, error) { var simApp *simapp.SimApp homePath, ok := appOpts.Get(flags.FlagHome).(string) diff --git a/testing/simapp/simd/cmd/testnet.go b/testing/simapp/simd/cmd/testnet.go deleted file mode 100644 index 657393fa915..00000000000 --- a/testing/simapp/simd/cmd/testnet.go +++ /dev/null @@ -1,396 +0,0 @@ -package cmd - -// DONTCOVER - -import ( - "bufio" - "encoding/json" - "fmt" - "net" - "os" - "path/filepath" - - "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/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/server" - srvconfig "github.com/cosmos/cosmos-sdk/server/config" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/genutil" - genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/spf13/cobra" - tmconfig "github.com/tendermint/tendermint/config" - tmos "github.com/tendermint/tendermint/libs/os" - tmrand "github.com/tendermint/tendermint/libs/rand" - "github.com/tendermint/tendermint/types" - tmtime "github.com/tendermint/tendermint/types/time" -) - -var ( - flagNodeDirPrefix = "node-dir-prefix" - flagNumValidators = "v" - flagOutputDir = "output-dir" - flagNodeDaemonHome = "node-daemon-home" - flagStartingIPAddress = "starting-ip-address" -) - -// get cmd to initialize all files for tendermint testnet and application -func testnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command { - cmd := &cobra.Command{ - Use: "testnet", - Short: "Initialize files for a simapp testnet", - Long: `testnet will create "v" number of directories and populate each with -necessary files (private validator, genesis, config, etc.). - -Note, strict routability for addresses is turned off in the config file. - -Example: - simd testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2 - `, - RunE: func(cmd *cobra.Command, _ []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - serverCtx := server.GetServerContextFromCmd(cmd) - config := serverCtx.Config - - outputDir, _ := cmd.Flags().GetString(flagOutputDir) - keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) - chainID, _ := cmd.Flags().GetString(flags.FlagChainID) - minGasPrices, _ := cmd.Flags().GetString(server.FlagMinGasPrices) - nodeDirPrefix, _ := cmd.Flags().GetString(flagNodeDirPrefix) - nodeDaemonHome, _ := cmd.Flags().GetString(flagNodeDaemonHome) - startingIPAddress, _ := cmd.Flags().GetString(flagStartingIPAddress) - numValidators, _ := cmd.Flags().GetInt(flagNumValidators) - algo, _ := cmd.Flags().GetString(flags.FlagKeyAlgorithm) - - return InitTestnet( - clientCtx, cmd, config, mbm, genBalIterator, outputDir, chainID, minGasPrices, - nodeDirPrefix, nodeDaemonHome, startingIPAddress, keyringBackend, algo, numValidators, - ) - }, - } - - cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with") - cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet") - cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)") - cmd.Flags().String(flagNodeDaemonHome, "simd", "Home directory of the node's daemon configuration") - cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") - cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") - cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)") - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") - cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for") - - return cmd -} - -const nodeDirPerm = 0o755 - -// Initialize the testnet -func InitTestnet( - clientCtx client.Context, - cmd *cobra.Command, - nodeConfig *tmconfig.Config, - mbm module.BasicManager, - genBalIterator banktypes.GenesisBalancesIterator, - outputDir, - chainID, - minGasPrices, - nodeDirPrefix, - nodeDaemonHome, - startingIPAddress, - keyringBackend, - algoStr string, - numValidators int, -) error { - if chainID == "" { - chainID = "chain-" + tmrand.NewRand().Str(6) - } - - nodeIDs := make([]string, numValidators) - valPubKeys := make([]cryptotypes.PubKey, numValidators) - - simappConfig := srvconfig.DefaultConfig() - simappConfig.MinGasPrices = minGasPrices - simappConfig.API.Enable = true - simappConfig.Telemetry.Enabled = true - simappConfig.Telemetry.PrometheusRetentionTime = 60 - simappConfig.Telemetry.EnableHostnameLabel = false - simappConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", chainID}} - - var ( - genAccounts []authtypes.GenesisAccount - genBalances []banktypes.Balance - genFiles []string - ) - - inBuf := bufio.NewReader(cmd.InOrStdin()) - // generate private keys, node IDs, and initial transactions - for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) - nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) - gentxsDir := filepath.Join(outputDir, "gentxs") - - nodeConfig.SetRoot(nodeDir) - nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657" - - if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - nodeConfig.Moniker = nodeDirName - - ip, err := getIP(i, startingIPAddress) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) - genFiles = append(genFiles, nodeConfig.GenesisFile()) - - kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, nodeDir, inBuf) - if err != nil { - return err - } - - keyringAlgos, _ := kb.SupportedAlgorithms() - algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos) - if err != nil { - return err - } - - addr, secret, err := server.GenerateSaveCoinKey(kb, nodeDirName, true, algo) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - info := map[string]string{"secret": secret} - - cliPrint, err := json.Marshal(info) - if err != nil { - return err - } - - // save private key seed words - if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil { - return err - } - - accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction) - accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction) - coins := sdk.Coins{ - sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens), - sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens), - } - - genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()}) - genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0)) - - valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction) - createValMsg, err := stakingtypes.NewMsgCreateValidator( - sdk.ValAddress(addr), - valPubKeys[i], - sdk.NewCoin(sdk.DefaultBondDenom, valTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), - stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()), - sdk.OneInt(), - ) - if err != nil { - return err - } - - txBuilder := clientCtx.TxConfig.NewTxBuilder() - if err := txBuilder.SetMsgs(createValMsg); err != nil { - return err - } - - txBuilder.SetMemo(memo) - - txFactory := tx.Factory{} - txFactory = txFactory. - WithChainID(chainID). - WithMemo(memo). - WithKeybase(kb). - WithTxConfig(clientCtx.TxConfig) - - if err := tx.Sign(txFactory, nodeDirName, txBuilder, true); err != nil { - return err - } - - txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) - if err != nil { - return err - } - - if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil { - return err - } - - srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), simappConfig) - } - - if err := initGenFiles(clientCtx, mbm, chainID, genAccounts, genBalances, genFiles, numValidators); err != nil { - return err - } - - err := collectGenFiles( - clientCtx, nodeConfig, chainID, nodeIDs, valPubKeys, numValidators, - outputDir, nodeDirPrefix, nodeDaemonHome, genBalIterator, - ) - if err != nil { - return err - } - - cmd.PrintErrf("Successfully initialized %d node directories\n", numValidators) - return nil -} - -func initGenFiles( - clientCtx client.Context, mbm module.BasicManager, chainID string, - genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance, - genFiles []string, numValidators int, -) error { - appGenState := mbm.DefaultGenesis(clientCtx.JSONCodec) - - // set the accounts in the genesis state - var authGenState authtypes.GenesisState - clientCtx.JSONCodec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState) - - accounts, err := authtypes.PackAccounts(genAccounts) - if err != nil { - return err - } - - authGenState.Accounts = accounts - appGenState[authtypes.ModuleName] = clientCtx.JSONCodec.MustMarshalJSON(&authGenState) - - // set the balances in the genesis state - var bankGenState banktypes.GenesisState - clientCtx.JSONCodec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState) - - bankGenState.Balances = genBalances - appGenState[banktypes.ModuleName] = clientCtx.JSONCodec.MustMarshalJSON(&bankGenState) - - appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ") - if err != nil { - return err - } - - genDoc := types.GenesisDoc{ - ChainID: chainID, - AppState: appGenStateJSON, - Validators: nil, - } - - // generate empty genesis files for each validator and save - for i := 0; i < numValidators; i++ { - if err := genDoc.SaveAs(genFiles[i]); err != nil { - return err - } - } - return nil -} - -func collectGenFiles( - clientCtx client.Context, nodeConfig *tmconfig.Config, chainID string, - nodeIDs []string, valPubKeys []cryptotypes.PubKey, numValidators int, - outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator, -) error { - var appState json.RawMessage - genTime := tmtime.Now() - - for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) - nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) - gentxsDir := filepath.Join(outputDir, "gentxs") - nodeConfig.Moniker = nodeDirName - - nodeConfig.SetRoot(nodeDir) - - nodeID, valPubKey := nodeIDs[i], valPubKeys[i] - initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey) - - genDoc, err := types.GenesisDocFromFile(nodeConfig.GenesisFile()) - if err != nil { - return err - } - - nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.JSONCodec, clientCtx.TxConfig, nodeConfig, initCfg, *genDoc, genBalIterator) - if err != nil { - return err - } - - if appState == nil { - // set the canonical application state (they should not differ) - appState = nodeAppState - } - - genFile := nodeConfig.GenesisFile() - - // overwrite each validator's genesis file to have a canonical genesis time - if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil { - return err - } - } - - return nil -} - -func getIP(i int, startingIPAddr string) (ip string, err error) { - if len(startingIPAddr) == 0 { - ip, err = server.ExternalIP() - if err != nil { - return "", err - } - return ip, nil - } - return calculateIP(startingIPAddr, i) -} - -func calculateIP(ip string, i int) (string, error) { - ipv4 := net.ParseIP(ip).To4() - if ipv4 == nil { - return "", fmt.Errorf("%v: non ipv4 address", ip) - } - - for j := 0; j < i; j++ { - ipv4[3]++ - } - - return ipv4.String(), nil -} - -func writeFile(name string, dir string, contents []byte) error { - writePath := filepath.Join(dir) - file := filepath.Join(writePath, name) - - err := tmos.EnsureDir(writePath, 0o755) - if err != nil { - return err - } - - err = tmos.WriteFile(file, contents, 0o644) - if err != nil { - return err - } - - return nil -} diff --git a/testing/simapp/simd/main.go b/testing/simapp/simd/main.go index c6450c79f58..07b2ab96848 100644 --- a/testing/simapp/simd/main.go +++ b/testing/simapp/simd/main.go @@ -6,14 +6,14 @@ import ( "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - "github.com/cosmos/ibc-go/v4/testing/simapp" - "github.com/cosmos/ibc-go/v4/testing/simapp/simd/cmd" + "github.com/cosmos/ibc-go/v7/testing/simapp" + "github.com/cosmos/ibc-go/v7/testing/simapp/simd/cmd" ) func main() { rootCmd, _ := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, simapp.DefaultNodeHome); err != nil { + if err := svrcmd.Execute(rootCmd, "simd", simapp.DefaultNodeHome); err != nil { switch e := err.(type) { case server.ErrorCode: os.Exit(e.Code) diff --git a/testing/simapp/state.go b/testing/simapp/state.go index 0b1830d7c4b..3e8707d40c1 100644 --- a/testing/simapp/state.go +++ b/testing/simapp/state.go @@ -4,10 +4,11 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "math/rand" + "os" "time" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" @@ -19,7 +20,7 @@ import ( tmjson "github.com/tendermint/tendermint/libs/json" tmtypes "github.com/tendermint/tendermint/types" - simappparams "github.com/cosmos/ibc-go/v4/testing/simapp/params" + simappparams "github.com/cosmos/ibc-go/v7/testing/simapp/params" ) // AppStateFn returns the initial application state using a genesis or the simulation parameters. @@ -54,7 +55,7 @@ func AppStateFn(cdc codec.JSONCodec, simManager *module.SimulationManager) simty case config.ParamsFile != "": appParams := make(simtypes.AppParams) - bz, err := ioutil.ReadFile(config.ParamsFile) + bz, err := os.ReadFile(config.ParamsFile) if err != nil { panic(err) } @@ -165,7 +166,7 @@ func AppStateRandomizedFn( Rand: r, GenState: genesisState, Accounts: accs, - InitialStake: initialStake, + InitialStake: math.NewInt(initialStake), NumBonded: numInitiallyBonded, GenTimestamp: genesisTimestamp, } @@ -183,7 +184,7 @@ func AppStateRandomizedFn( // AppStateFromGenesisFileFn util function to generate the genesis AppState // from a genesis.json file. func AppStateFromGenesisFileFn(r io.Reader, cdc codec.JSONCodec, genesisFile string) (tmtypes.GenesisDoc, []simtypes.Account) { - bytes, err := ioutil.ReadFile(genesisFile) + bytes, err := os.ReadFile(genesisFile) if err != nil { panic(err) } diff --git a/testing/simapp/test_helpers.go b/testing/simapp/test_helpers.go index 58e1ac2eb23..3a6ff204a87 100644 --- a/testing/simapp/test_helpers.go +++ b/testing/simapp/test_helpers.go @@ -1,23 +1,22 @@ package simapp import ( - "bytes" - "encoding/hex" "encoding/json" - "fmt" - "strconv" + "math/rand" "testing" "time" bam "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" @@ -25,13 +24,13 @@ import ( tmtypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tm-db" - "github.com/cosmos/ibc-go/v4/testing/simapp/helpers" + "github.com/cosmos/ibc-go/v7/testing/mock" ) // DefaultConsensusParams defines the default Tendermint consensus params used in // SimApp testing. -var DefaultConsensusParams = &abci.ConsensusParams{ - Block: &abci.BlockParams{ +var DefaultConsensusParams = &tmproto.ConsensusParams{ + Block: &tmproto.BlockParams{ MaxBytes: 200000, MaxGas: 2000000, }, @@ -50,7 +49,7 @@ var DefaultConsensusParams = &abci.ConsensusParams{ func setup(withGenesis bool, invCheckPeriod uint) (*SimApp, GenesisState) { db := dbm.NewMemDB() encCdc := MakeTestEncodingConfig() - app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, EmptyAppOptions{}) + app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, encCdc, simtestutil.EmptyAppOptions{}) if withGenesis { return app, NewDefaultGenesisState(encCdc.Marshaler) } @@ -59,47 +58,37 @@ func setup(withGenesis bool, invCheckPeriod uint) (*SimApp, GenesisState) { // Setup initializes a new SimApp. A Nop logger is set in SimApp. func Setup(isCheckTx bool) *SimApp { - app, genesisState := setup(!isCheckTx, 5) - if !isCheckTx { - // init chain must be called to stop deliverState from being nil - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - if err != nil { - panic(err) - } + privVal := mock.NewPV() + pubKey, _ := privVal.GetPubKey() + + // create validator set with single validator + validator := tmtypes.NewValidator(pubKey, 1) + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - // Initialize the chain - app.InitChain( - abci.RequestInitChain{ - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: DefaultConsensusParams, - AppStateBytes: stateBytes, - }, - ) + // generate genesis account + senderPrivKey := secp256k1.GenPrivKey() + acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0) + balance := banktypes.Balance{ + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))), } + app := SetupWithGenesisValSet(valSet, []authtypes.GenesisAccount{acc}, balance) + return app } -// SetupWithGenesisAccounts initializes a new SimApp with the provided genesis -// accounts and possible balances. -func SetupWithGenesisAccounts(genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp { - app, genesisState := setup(true, 0) - authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) - genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) - - totalSupply := sdk.NewCoins() - for _, b := range balances { - totalSupply = totalSupply.Add(b.Coins...) - } - - bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}) - genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) +// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts +// that also act as delegators. For simplicity, each validator is bonded with a delegation +// of one consensus engine unit in the default token of the simapp from first genesis +// account. A Nop logger is set in SimApp. +func SetupWithGenesisValSet(valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp { + app, genesisState := setup(true, 5) + genesisState = genesisStateWithValSet(app, genesisState, valSet, genAccs, balances...) - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - if err != nil { - panic(err) - } + stateBytes, _ := json.MarshalIndent(genesisState, "", " ") + // init chain will set the validator set and initialize the genesis accounts app.InitChain( abci.RequestInitChain{ Validators: []abci.ValidatorUpdate{}, @@ -108,128 +97,111 @@ func SetupWithGenesisAccounts(genAccs []authtypes.GenesisAccount, balances ...ba }, ) + // commit genesis changes app.Commit() - app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1}}) + app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{ + Height: app.LastBlockHeight() + 1, + AppHash: app.LastCommitID().Hash, + ValidatorsHash: valSet.Hash(), + NextValidatorsHash: valSet.Hash(), + }}) return app } -type GenerateAccountStrategy func(int) []sdk.AccAddress - -// createRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order. -func createRandomAccounts(accNum int) []sdk.AccAddress { - testAddrs := make([]sdk.AccAddress, accNum) - for i := 0; i < accNum; i++ { - pk := ed25519.GenPrivKey().PubKey() - testAddrs[i] = sdk.AccAddress(pk.Address()) - } - - return testAddrs -} - -// createIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order. -func createIncrementalAccounts(accNum int) []sdk.AccAddress { - var addresses []sdk.AccAddress - var buffer bytes.Buffer - - // start at 100 so we can make up to 999 test addresses with valid test addresses - for i := 100; i < (accNum + 100); i++ { - numString := strconv.Itoa(i) - buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") // base address string +func genesisStateWithValSet(app *SimApp, genesisState GenesisState, + valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, + balances ...banktypes.Balance, +) GenesisState { + // set genesis accounts + authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) + genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) - buffer.WriteString(numString) // adding on final two digits to make addresses unique - res, _ := sdk.AccAddressFromHex(buffer.String()) - bech := res.String() - addr, _ := TestAddr(buffer.String(), bech) + validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) + delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) + + bondAmt := sdk.DefaultPowerReduction + + for _, val := range valSet.Validators { + pk, _ := cryptocodec.FromTmPubKeyInterface(val.PubKey) + pkAny, _ := codectypes.NewAnyWithValue(pk) + validator := stakingtypes.Validator{ + OperatorAddress: sdk.ValAddress(val.Address).String(), + ConsensusPubkey: pkAny, + Jailed: false, + Status: stakingtypes.Bonded, + Tokens: bondAmt, + DelegatorShares: sdk.OneDec(), + Description: stakingtypes.Description{}, + UnbondingHeight: int64(0), + UnbondingTime: time.Unix(0, 0).UTC(), + Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), + MinSelfDelegation: sdk.ZeroInt(), + } + validators = append(validators, validator) + delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec())) - addresses = append(addresses, addr) - buffer.Reset() } + // set validators and delegations + stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations) + genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis) - return addresses -} - -// AddTestAddrsFromPubKeys adds the addresses into the SimApp providing only the public keys. -func AddTestAddrsFromPubKeys(app *SimApp, ctx sdk.Context, pubKeys []cryptotypes.PubKey, accAmt sdk.Int) { - initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt)) - - for _, pk := range pubKeys { - initAccountWithCoins(app, ctx, sdk.AccAddress(pk.Address()), initCoins) + totalSupply := sdk.NewCoins() + for _, b := range balances { + // add genesis acc tokens to total supply + totalSupply = totalSupply.Add(b.Coins...) } -} - -// AddTestAddrs constructs and returns accNum amount of accounts with an -// initial balance of accAmt in random order -func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { - return addTestAddrs(app, ctx, accNum, accAmt, createRandomAccounts) -} -// AddTestAddrs constructs and returns accNum amount of accounts with an -// initial balance of accAmt in random order -func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { - return addTestAddrs(app, ctx, accNum, accAmt, createIncrementalAccounts) -} - -func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, strategy GenerateAccountStrategy) []sdk.AccAddress { - testAddrs := strategy(accNum) - - initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt)) - - for _, addr := range testAddrs { - initAccountWithCoins(app, ctx, addr, initCoins) + for range delegations { + // add delegated tokens to total supply + totalSupply = totalSupply.Add(sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)) } - return testAddrs -} + // add bonded amount to bonded pool module account + balances = append(balances, banktypes.Balance{ + Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), + Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt)}, + }) -func initAccountWithCoins(app *SimApp, ctx sdk.Context, addr sdk.AccAddress, coins sdk.Coins) { - err := app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, coins) - if err != nil { - panic(err) - } + // update total supply + bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{}) + genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) - err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, coins) - if err != nil { - panic(err) - } + return genesisState } -// ConvertAddrsToValAddrs converts the provided addresses to ValAddress. -func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress { - valAddrs := make([]sdk.ValAddress, len(addrs)) +// SetupWithGenesisAccounts initializes a new SimApp with the provided genesis +// accounts and possible balances. +func SetupWithGenesisAccounts(genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *SimApp { + app, genesisState := setup(true, 0) + authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) + genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) - for i, addr := range addrs { - valAddrs[i] = sdk.ValAddress(addr) + totalSupply := sdk.NewCoins() + for _, b := range balances { + totalSupply = totalSupply.Add(b.Coins...) } - return valAddrs -} + bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{}) + genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) -func TestAddr(addr string, bech string) (sdk.AccAddress, error) { - res, err := sdk.AccAddressFromHex(addr) + stateBytes, err := json.MarshalIndent(genesisState, "", " ") if err != nil { - return nil, err - } - bechexpected := res.String() - if bech != bechexpected { - return nil, fmt.Errorf("bech encoding doesn't match reference") + panic(err) } - bechres, err := sdk.AccAddressFromBech32(bech) - if err != nil { - return nil, err - } - if !bytes.Equal(bechres, res) { - return nil, err - } + app.InitChain( + abci.RequestInitChain{ + Validators: []abci.ValidatorUpdate{}, + ConsensusParams: DefaultConsensusParams, + AppStateBytes: stateBytes, + }, + ) - return res, nil -} + app.Commit() + app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: app.LastBlockHeight() + 1}}) -// CheckBalance checks the balance of an account. -func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) { - ctxCheck := app.BaseApp.NewContext(true, tmproto.Header{}) - require.True(t, balances.IsEqual(app.BankKeeper.GetAllBalances(ctxCheck, addr))) + return app } // SignAndDeliver signs and delivers a transaction. No simulation occurs as the @@ -237,110 +209,32 @@ func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.C // // CONTRACT: BeginBlock must be called before this function. func SignAndDeliver( - t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, header tmproto.Header, msgs []sdk.Msg, - chainID string, accNums, accSeqs []uint64, expSimPass, expPass bool, priv ...cryptotypes.PrivKey, + tb testing.TB, txCfg client.TxConfig, app *bam.BaseApp, msgs []sdk.Msg, + chainID string, accNums, accSeqs []uint64, expPass bool, priv ...cryptotypes.PrivKey, ) (sdk.GasInfo, *sdk.Result, error) { - tx, err := helpers.GenTx( + tx, err := simtestutil.GenSignedMockTx( + rand.New(rand.NewSource(time.Now().UnixNano())), txCfg, msgs, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, - helpers.DefaultGenTxGas, + simtestutil.DefaultGenTxGas, chainID, accNums, accSeqs, priv..., ) - require.NoError(t, err) + require.NoError(tb, err) // Simulate a sending a transaction - gInfo, res, err := app.Deliver(txCfg.TxEncoder(), tx) + gInfo, res, err := app.SimDeliver(txCfg.TxEncoder(), tx) if expPass { - require.NoError(t, err) - require.NotNil(t, res) + require.NoError(tb, err) + require.NotNil(tb, res) } else { - require.Error(t, err) - require.Nil(t, res) + require.Error(tb, err) + require.Nil(tb, res) } return gInfo, res, err } - -// GenSequenceOfTxs generates a set of signed transactions of messages, such -// that they differ only by having the sequence numbers incremented between -// every transaction. -func GenSequenceOfTxs(txGen client.TxConfig, msgs []sdk.Msg, accNums []uint64, initSeqNums []uint64, numToGenerate int, priv ...cryptotypes.PrivKey) ([]sdk.Tx, error) { - txs := make([]sdk.Tx, numToGenerate) - var err error - for i := 0; i < numToGenerate; i++ { - txs[i], err = helpers.GenTx( - txGen, - msgs, - sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)}, - helpers.DefaultGenTxGas, - "", - accNums, - initSeqNums, - priv..., - ) - if err != nil { - break - } - incrementAllSequenceNumbers(initSeqNums) - } - - return txs, err -} - -func incrementAllSequenceNumbers(initSeqNums []uint64) { - for i := 0; i < len(initSeqNums); i++ { - initSeqNums[i]++ - } -} - -// CreateTestPubKeys returns a total of numPubKeys public keys in ascending order. -func CreateTestPubKeys(numPubKeys int) []cryptotypes.PubKey { - var publicKeys []cryptotypes.PubKey - var buffer bytes.Buffer - - // start at 10 to avoid changing 1 to 01, 2 to 02, etc - for i := 100; i < (numPubKeys + 100); i++ { - numString := strconv.Itoa(i) - buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") // base pubkey string - buffer.WriteString(numString) // adding on final two digits to make pubkeys unique - publicKeys = append(publicKeys, NewPubKeyFromHex(buffer.String())) - buffer.Reset() - } - - return publicKeys -} - -// NewPubKeyFromHex returns a PubKey from a hex string. -func NewPubKeyFromHex(pk string) (res cryptotypes.PubKey) { - pkBytes, err := hex.DecodeString(pk) - if err != nil { - panic(err) - } - if len(pkBytes) != ed25519.PubKeySize { - panic(errors.Wrap(errors.ErrInvalidPubKey, "invalid pubkey size")) - } - return &ed25519.PubKey{Key: pkBytes} -} - -// EmptyAppOptions is a stub implementing AppOptions -type EmptyAppOptions struct{} - -// Get implements AppOptions -func (ao EmptyAppOptions) Get(o string) interface{} { - return nil -} - -// FundAccount is a utility function that funds an account by minting and sending the coins to the address -// TODO(fdymylja): instead of using the mint module account, which has the permission of minting, create a "faucet" account -func FundAccount(app *SimApp, ctx sdk.Context, addr sdk.AccAddress, amounts sdk.Coins) error { - err := app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, amounts) - if err != nil { - return err - } - return app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, addr, amounts) -} diff --git a/testing/simapp/upgrades/upgrades.go b/testing/simapp/upgrades/upgrades.go new file mode 100644 index 00000000000..adc81349bdd --- /dev/null +++ b/testing/simapp/upgrades/upgrades.go @@ -0,0 +1,23 @@ +package upgrades + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" +) + +const ( + // DefaultUpgradeName is the default upgrade name used for upgrade tests which do not require special handling. + DefaultUpgradeName = "normal upgrade" +) + +// CreateDefaultUpgradeHandler creates an upgrade handler which can be used for regular upgrade tests +// that do not require special logic +func CreateDefaultUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + return mm.RunMigrations(ctx, configurator, vm) + } +} diff --git a/testing/simapp/upgrades/v6/upgrades.go b/testing/simapp/upgrades/v6/upgrades.go new file mode 100644 index 00000000000..953bccf37e9 --- /dev/null +++ b/testing/simapp/upgrades/v6/upgrades.go @@ -0,0 +1,36 @@ +package v6 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + v6 "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/migrations/v6" +) + +const ( + // UpgradeName defines the on-chain upgrade name for the SimApp v6 upgrade. + UpgradeName = "v6" +) + +// CreateUpgradeHandler creates an upgrade handler for the v6 SimApp upgrade. +// NOTE: The v6.MigrateICS27ChannelCapabiliity function can be omitted if chains do not yet implement an ICS27 controller module +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + cdc codec.BinaryCodec, + capabilityStoreKey *storetypes.KVStoreKey, + capabilityKeeper *capabilitykeeper.Keeper, + moduleName string, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + if err := v6.MigrateICS27ChannelCapability(ctx, cdc, capabilityStoreKey, capabilityKeeper, moduleName); err != nil { + return nil, err + } + + return mm.RunMigrations(ctx, configurator, vm) + } +} diff --git a/testing/simapp/upgrades/v7/upgrades.go b/testing/simapp/upgrades/v7/upgrades.go new file mode 100644 index 00000000000..4621c06339b --- /dev/null +++ b/testing/simapp/upgrades/v7/upgrades.go @@ -0,0 +1,42 @@ +package v7 + +import ( + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + consensusparamskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + clientkeeper "github.com/cosmos/ibc-go/v7/modules/core/02-client/keeper" + ibctmmigrations "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint/migrations" +) + +const ( + // UpgradeName defines the on-chain upgrade name for the SimApp v7 upgrade. + UpgradeName = "v7" +) + +// CreateUpgradeHandler creates an upgrade handler for the v7 SimApp upgrade. +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + cdc codec.BinaryCodec, + clientKeeper clientkeeper.Keeper, + consensusParamsKeeper consensusparamskeeper.Keeper, + paramsKeeper paramskeeper.Keeper, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + // OPTIONAL: prune expired tendermint consensus states to save storage space + if _, err := ibctmmigrations.PruneExpiredConsensusStates(ctx, cdc, clientKeeper); err != nil { + return nil, err + } + + legacyBaseAppSubspace := paramsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramstypes.ConsensusParamsKeyTable()) + baseapp.MigrateParams(ctx, legacyBaseAppSubspace, &consensusParamsKeeper) + + return mm.RunMigrations(ctx, configurator, vm) + } +} diff --git a/testing/simapp/utils.go b/testing/simapp/utils.go index 668feb3f7f6..313d334408a 100644 --- a/testing/simapp/utils.go +++ b/testing/simapp/utils.go @@ -3,7 +3,7 @@ package simapp import ( "encoding/json" "fmt" - "io/ioutil" + "os" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -12,8 +12,6 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" - - "github.com/cosmos/ibc-go/v4/testing/simapp/helpers" ) // SetupSimulation creates the config, db (levelDB), temporary directory and logger for @@ -25,7 +23,7 @@ func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, } config := NewConfigFromFlags() - config.ChainID = helpers.SimAppChainID + config.ChainID = "simulation-app" var logger log.Logger if FlagVerboseValue { @@ -34,12 +32,12 @@ func SetupSimulation(dirPrefix, dbName string) (simtypes.Config, dbm.DB, string, logger = log.NewNopLogger() } - dir, err := ioutil.TempDir("", dirPrefix) + dir, err := os.MkdirTemp("", dirPrefix) if err != nil { return simtypes.Config{}, nil, "", nil, false, err } - db, err := sdk.NewLevelDB(dbName, dir) + db, err := dbm.NewDB(dbName, dbm.BackendType(config.DBBackend), dir) if err != nil { return simtypes.Config{}, nil, "", nil, false, err } @@ -56,7 +54,7 @@ func SimulationOperations(app App, cdc codec.JSONCodec, config simtypes.Config) } if config.ParamsFile != "" { - bz, err := ioutil.ReadFile(config.ParamsFile) + bz, err := os.ReadFile(config.ParamsFile) if err != nil { panic(err) } @@ -67,8 +65,8 @@ func SimulationOperations(app App, cdc codec.JSONCodec, config simtypes.Config) } } - simState.ParamChanges = app.SimulationManager().GenerateParamChanges(config.Seed) - simState.Contents = app.SimulationManager().GetProposalContents(simState) + //nolint: staticcheck // SA1019: app.SimulationManager().GetProposalContents is deprecated: Use GetProposalMsgs instead. GetProposalContents returns each module's proposal content generator function with their default operation weight and key. + simState.LegacyProposalContents = app.SimulationManager().GetProposalContents(simState) return app.SimulationManager().WeightedOperations(simState) } @@ -84,7 +82,7 @@ func CheckExportSimulation( return err } - if err := ioutil.WriteFile(config.ExportStatePath, []byte(exported.AppState), 0o600); err != nil { + if err := os.WriteFile(config.ExportStatePath, []byte(exported.AppState), 0o600); err != nil { return err } } @@ -96,7 +94,7 @@ func CheckExportSimulation( return err } - if err := ioutil.WriteFile(config.ExportParamsPath, paramsBz, 0o600); err != nil { + if err := os.WriteFile(config.ExportParamsPath, paramsBz, 0o600); err != nil { return err } } diff --git a/testing/solomachine.go b/testing/solomachine.go index a97f63c3919..e63b04ab51b 100644 --- a/testing/solomachine.go +++ b/testing/solomachine.go @@ -2,6 +2,7 @@ package ibctesting import ( "testing" + "time" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -9,14 +10,25 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/stretchr/testify/require" - clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - host "github.com/cosmos/ibc-go/v4/modules/core/24-host" - "github.com/cosmos/ibc-go/v4/modules/core/exported" - solomachinetypes "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types" + transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "github.com/cosmos/ibc-go/v7/modules/core/exported" + solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" +) + +var ( + clientIDSolomachine = "client-on-solomachine" // clientID generated on solo machine side + connectionIDSolomachine = "connection-on-solomachine" // connectionID generated on solo machine side + channelIDSolomachine = "channel-on-solomachine" // channelID generated on solo machine side ) // Solomachine is a testing helper used to simulate a counterparty @@ -82,18 +94,17 @@ func GenerateKeys(t *testing.T, n uint64) ([]cryptotypes.PrivKey, []cryptotypes. return privKeys, pubKeys, pk } -// ClientState returns a new solo machine ClientState instance. Default usage does not allow update -// after governance proposal -func (solo *Solomachine) ClientState() *solomachinetypes.ClientState { - return solomachinetypes.NewClientState(solo.Sequence, solo.ConsensusState(), false) +// ClientState returns a new solo machine ClientState instance. +func (solo *Solomachine) ClientState() *solomachine.ClientState { + return solomachine.NewClientState(solo.Sequence, solo.ConsensusState()) } // ConsensusState returns a new solo machine ConsensusState instance -func (solo *Solomachine) ConsensusState() *solomachinetypes.ConsensusState { +func (solo *Solomachine) ConsensusState() *solomachine.ConsensusState { publicKey, err := codectypes.NewAnyWithValue(solo.PublicKey) require.NoError(solo.t, err) - return &solomachinetypes.ConsensusState{ + return &solomachine.ConsensusState{ PublicKey: publicKey, Diversifier: solo.Diversifier, Timestamp: solo.Time, @@ -105,28 +116,55 @@ func (solo *Solomachine) GetHeight() exported.Height { return clienttypes.NewHeight(0, solo.Sequence) } +// CreateClient creates an on-chain client on the provided chain. +func (solo *Solomachine) CreateClient(chain *TestChain) string { + msgCreateClient, err := clienttypes.NewMsgCreateClient(solo.ClientState(), solo.ConsensusState(), chain.SenderAccount.GetAddress().String()) + require.NoError(solo.t, err) + + res, err := chain.SendMsgs(msgCreateClient) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) + + clientID, err := ParseClientIDFromEvents(res.GetEvents()) + require.NoError(solo.t, err) + + return clientID +} + +// UpdateClient sends a MsgUpdateClient to the provided chain and updates the given clientID. +func (solo *Solomachine) UpdateClient(chain *TestChain, clientID string) { + smHeader := solo.CreateHeader(solo.Diversifier) + msgUpdateClient, err := clienttypes.NewMsgUpdateClient(clientID, smHeader, chain.SenderAccount.GetAddress().String()) + require.NoError(solo.t, err) + + res, err := chain.SendMsgs(msgUpdateClient) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) +} + // CreateHeader generates a new private/public key pair and creates the // necessary signature to construct a valid solo machine header. -func (solo *Solomachine) CreateHeader() *solomachinetypes.Header { +// A new diversifier will be used as well +func (solo *Solomachine) CreateHeader(newDiversifier string) *solomachine.Header { // generate new private keys and signature for header newPrivKeys, newPubKeys, newPubKey := GenerateKeys(solo.t, uint64(len(solo.PrivateKeys))) publicKey, err := codectypes.NewAnyWithValue(newPubKey) require.NoError(solo.t, err) - data := &solomachinetypes.HeaderData{ + data := &solomachine.HeaderData{ NewPubKey: publicKey, - NewDiversifier: solo.Diversifier, + NewDiversifier: newDiversifier, } dataBz, err := solo.cdc.Marshal(data) require.NoError(solo.t, err) - signBytes := &solomachinetypes.SignBytes{ + signBytes := &solomachine.SignBytes{ Sequence: solo.Sequence, Timestamp: solo.Time, Diversifier: solo.Diversifier, - DataType: solomachinetypes.HEADER, + Path: []byte(solomachine.SentinelHeaderPath), Data: dataBz, } @@ -135,83 +173,282 @@ func (solo *Solomachine) CreateHeader() *solomachinetypes.Header { sig := solo.GenerateSignature(bz) - header := &solomachinetypes.Header{ - Sequence: solo.Sequence, + header := &solomachine.Header{ Timestamp: solo.Time, Signature: sig, NewPublicKey: publicKey, - NewDiversifier: solo.Diversifier, + NewDiversifier: newDiversifier, } // assumes successful header update solo.Sequence++ + solo.Time++ solo.PrivateKeys = newPrivKeys solo.PublicKeys = newPubKeys solo.PublicKey = newPubKey + solo.Diversifier = newDiversifier return header } // CreateMisbehaviour constructs testing misbehaviour for the solo machine client // by signing over two different data bytes at the same sequence. -func (solo *Solomachine) CreateMisbehaviour() *solomachinetypes.Misbehaviour { - path := solo.GetClientStatePath("counterparty") - dataOne, err := solomachinetypes.ClientStateDataBytes(solo.cdc, path, solo.ClientState()) +func (solo *Solomachine) CreateMisbehaviour() *solomachine.Misbehaviour { + merklePath := solo.GetClientStatePath("counterparty") + path, err := solo.cdc.Marshal(&merklePath) require.NoError(solo.t, err) - path = solo.GetConsensusStatePath("counterparty", clienttypes.NewHeight(0, 1)) - dataTwo, err := solomachinetypes.ConsensusStateDataBytes(solo.cdc, path, solo.ConsensusState()) + data, err := solo.cdc.Marshal(solo.ClientState()) require.NoError(solo.t, err) - signBytes := &solomachinetypes.SignBytes{ + signBytes := &solomachine.SignBytes{ Sequence: solo.Sequence, Timestamp: solo.Time, Diversifier: solo.Diversifier, - DataType: solomachinetypes.CLIENT, - Data: dataOne, + Path: path, + Data: data, } bz, err := solo.cdc.Marshal(signBytes) require.NoError(solo.t, err) sig := solo.GenerateSignature(bz) - signatureOne := solomachinetypes.SignatureAndData{ + signatureOne := solomachine.SignatureAndData{ Signature: sig, - DataType: solomachinetypes.CLIENT, - Data: dataOne, + Path: path, + Data: data, Timestamp: solo.Time, } // misbehaviour signaturess can have different timestamps solo.Time++ - signBytes = &solomachinetypes.SignBytes{ + merklePath = solo.GetConsensusStatePath("counterparty", clienttypes.NewHeight(0, 1)) + path, err = solo.cdc.Marshal(&merklePath) + require.NoError(solo.t, err) + + data, err = solo.cdc.Marshal(solo.ConsensusState()) + require.NoError(solo.t, err) + + signBytes = &solomachine.SignBytes{ Sequence: solo.Sequence, Timestamp: solo.Time, Diversifier: solo.Diversifier, - DataType: solomachinetypes.CONSENSUS, - Data: dataTwo, + Path: path, + Data: data, } bz, err = solo.cdc.Marshal(signBytes) require.NoError(solo.t, err) sig = solo.GenerateSignature(bz) - signatureTwo := solomachinetypes.SignatureAndData{ + signatureTwo := solomachine.SignatureAndData{ Signature: sig, - DataType: solomachinetypes.CONSENSUS, - Data: dataTwo, + Path: path, + Data: data, Timestamp: solo.Time, } - return &solomachinetypes.Misbehaviour{ - ClientId: solo.ClientID, + return &solomachine.Misbehaviour{ Sequence: solo.Sequence, SignatureOne: &signatureOne, SignatureTwo: &signatureTwo, } } +// ConnOpenInit initializes a connection on the provided chain given a solo machine clientID. +func (solo *Solomachine) ConnOpenInit(chain *TestChain, clientID string) string { + msgConnOpenInit := connectiontypes.NewMsgConnectionOpenInit( + clientID, + clientIDSolomachine, // clientID generated on solo machine side + chain.GetPrefix(), DefaultOpenInitVersion, DefaultDelayPeriod, + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgConnOpenInit) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) + + connectionID, err := ParseConnectionIDFromEvents(res.GetEvents()) + require.NoError(solo.t, err) + + return connectionID +} + +// ConnOpenAck performs the connection open ack handshake step on the tendermint chain for the associated +// solo machine client. +func (solo *Solomachine) ConnOpenAck(chain *TestChain, clientID, connectionID string) { + proofTry := solo.GenerateConnOpenTryProof(clientID, connectionID) + + clientState := ibctm.NewClientState(chain.ChainID, DefaultTrustLevel, TrustingPeriod, UnbondingPeriod, MaxClockDrift, chain.LastHeader.GetHeight().(clienttypes.Height), commitmenttypes.GetSDKSpecs(), UpgradePath) + proofClient := solo.GenerateClientStateProof(clientState) + + consensusState := chain.LastHeader.ConsensusState() + consensusHeight := chain.LastHeader.GetHeight() + proofConsensus := solo.GenerateConsensusStateProof(consensusState, consensusHeight) + + msgConnOpenAck := connectiontypes.NewMsgConnectionOpenAck( + connectionID, connectionIDSolomachine, clientState, + proofTry, proofClient, proofConsensus, + clienttypes.ZeroHeight(), clientState.GetLatestHeight().(clienttypes.Height), + ConnectionVersion, + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgConnOpenAck) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) +} + +// ChanOpenInit initializes a channel on the provided chain given a solo machine connectionID. +func (solo *Solomachine) ChanOpenInit(chain *TestChain, connectionID string) string { + msgChanOpenInit := channeltypes.NewMsgChannelOpenInit( + transfertypes.PortID, + transfertypes.Version, + channeltypes.UNORDERED, + []string{connectionID}, + transfertypes.PortID, + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgChanOpenInit) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) + + if res, ok := res.MsgResponses[0].GetCachedValue().(*channeltypes.MsgChannelOpenInitResponse); ok { + return res.ChannelId + } + + return "" +} + +// ChanOpenAck performs the channel open ack handshake step on the tendermint chain for the associated +// solo machine client. +func (solo *Solomachine) ChanOpenAck(chain *TestChain, channelID string) { + proofTry := solo.GenerateChanOpenTryProof(transfertypes.PortID, transfertypes.Version, channelID) + msgChanOpenAck := channeltypes.NewMsgChannelOpenAck( + transfertypes.PortID, + channelID, + channelIDSolomachine, + transfertypes.Version, + proofTry, + clienttypes.ZeroHeight(), + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgChanOpenAck) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) +} + +// ChanCloseConfirm performs the channel close confirm handshake step on the tendermint chain for the associated +// solo machine client. +func (solo *Solomachine) ChanCloseConfirm(chain *TestChain, portID, channelID string) { + proofInit := solo.GenerateChanClosedProof(portID, transfertypes.Version, channelID) + msgChanCloseConfirm := channeltypes.NewMsgChannelCloseConfirm( + portID, + channelID, + proofInit, + clienttypes.ZeroHeight(), + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgChanCloseConfirm) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) +} + +// SendTransfer constructs a MsgTransfer and sends the message to the given chain. Any number of optional +// functions can be provided which will modify the MsgTransfer before SendMsgs is called. +func (solo *Solomachine) SendTransfer(chain *TestChain, portID, channelID string, fns ...func(*transfertypes.MsgTransfer)) channeltypes.Packet { + msgTransfer := transfertypes.MsgTransfer{ + SourcePort: portID, + SourceChannel: channelID, + Token: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)), + Sender: chain.SenderAccount.GetAddress().String(), + Receiver: chain.SenderAccount.GetAddress().String(), + TimeoutHeight: clienttypes.ZeroHeight(), + TimeoutTimestamp: uint64(chain.GetContext().BlockTime().Add(time.Hour).UnixNano()), + } + + for _, fn := range fns { + fn(&msgTransfer) + } + + res, err := chain.SendMsgs(&msgTransfer) + require.NoError(solo.t, err) + + packet, err := ParsePacketFromEvents(res.GetEvents()) + require.NoError(solo.t, err) + + return packet +} + +// RecvPacket creates a commitment proof and broadcasts a new MsgRecvPacket. +func (solo *Solomachine) RecvPacket(chain *TestChain, packet channeltypes.Packet) { + proofCommitment := solo.GenerateCommitmentProof(packet) + msgRecvPacket := channeltypes.NewMsgRecvPacket( + packet, + proofCommitment, + clienttypes.ZeroHeight(), + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgRecvPacket) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) +} + +// AcknowledgePacket creates an acknowledgement proof and broadcasts a MsgAcknowledgement. +func (solo *Solomachine) AcknowledgePacket(chain *TestChain, packet channeltypes.Packet) { + proofAck := solo.GenerateAcknowledgementProof(packet) + transferAck := channeltypes.NewResultAcknowledgement([]byte{byte(1)}).Acknowledgement() + msgAcknowledgement := channeltypes.NewMsgAcknowledgement( + packet, transferAck, + proofAck, + clienttypes.ZeroHeight(), + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgAcknowledgement) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) +} + +// TimeoutPacket creates a unreceived packet proof and broadcasts a MsgTimeout. +func (solo *Solomachine) TimeoutPacket(chain *TestChain, packet channeltypes.Packet) { + proofUnreceived := solo.GenerateReceiptAbsenceProof(packet) + msgTimeout := channeltypes.NewMsgTimeout( + packet, + 1, // nextSequenceRecv is unused for UNORDERED channels + proofUnreceived, + clienttypes.ZeroHeight(), + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgTimeout) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) +} + +// TimeoutPacket creates a channel closed and unreceived packet proof and broadcasts a MsgTimeoutOnClose. +func (solo *Solomachine) TimeoutPacketOnClose(chain *TestChain, packet channeltypes.Packet, channelID string) { + proofClosed := solo.GenerateChanClosedProof(transfertypes.PortID, transfertypes.Version, channelID) + proofUnreceived := solo.GenerateReceiptAbsenceProof(packet) + msgTimeout := channeltypes.NewMsgTimeoutOnClose( + packet, + 1, // nextSequenceRecv is unused for UNORDERED channels + proofUnreceived, + proofClosed, + clienttypes.ZeroHeight(), + chain.SenderAccount.GetAddress().String(), + ) + + res, err := chain.SendMsgs(msgTimeout) + require.NoError(solo.t, err) + require.NotNil(solo.t, res) +} + // GenerateSignature uses the stored private keys to generate a signature // over the sign bytes with each key. If the amount of keys is greater than // 1 then a multisig data type is returned. @@ -247,6 +484,160 @@ func (solo *Solomachine) GenerateSignature(signBytes []byte) []byte { return bz } +// GenerateProof takes in solo machine sign bytes, generates a signature and marshals it as a proof. +// The solo machine sequence is incremented. +func (solo *Solomachine) GenerateProof(signBytes *solomachine.SignBytes) []byte { + bz, err := solo.cdc.Marshal(signBytes) + require.NoError(solo.t, err) + + sig := solo.GenerateSignature(bz) + signatureDoc := &solomachine.TimestampedSignatureData{ + SignatureData: sig, + Timestamp: solo.Time, + } + proof, err := solo.cdc.Marshal(signatureDoc) + require.NoError(solo.t, err) + + solo.Sequence++ + + return proof +} + +// GenerateClientStateProof generates the proof of the client state required for the connection open try and ack handshake steps. +// The client state should be the self client states of the tendermint chain. +func (solo *Solomachine) GenerateClientStateProof(clientState exported.ClientState) []byte { + data, err := clienttypes.MarshalClientState(solo.cdc, clientState) + require.NoError(solo.t, err) + + signBytes := &solomachine.SignBytes{ + Sequence: solo.Sequence, + Timestamp: solo.Time, + Diversifier: solo.Diversifier, + Path: []byte(solo.GetClientStatePath(clientIDSolomachine).String()), + Data: data, + } + + return solo.GenerateProof(signBytes) +} + +// GenerateConsensusStateProof generates the proof of the consensus state required for the connection open try and ack handshake steps. +// The consensus state should be the self consensus states of the tendermint chain. +func (solo *Solomachine) GenerateConsensusStateProof(consensusState exported.ConsensusState, consensusHeight exported.Height) []byte { + data, err := clienttypes.MarshalConsensusState(solo.cdc, consensusState) + require.NoError(solo.t, err) + + signBytes := &solomachine.SignBytes{ + Sequence: solo.Sequence, + Timestamp: solo.Time, + Diversifier: solo.Diversifier, + Path: []byte(solo.GetConsensusStatePath(clientIDSolomachine, consensusHeight).String()), + Data: data, + } + + return solo.GenerateProof(signBytes) +} + +// GenerateConnOpenTryProof generates the proofTry required for the connection open ack handshake step. +// The clientID, connectionID provided represent the clientID and connectionID created on the counterparty chain, that is the tendermint chain. +func (solo *Solomachine) GenerateConnOpenTryProof(counterpartyClientID, counterpartyConnectionID string) []byte { + counterparty := connectiontypes.NewCounterparty(counterpartyClientID, counterpartyConnectionID, prefix) + connection := connectiontypes.NewConnectionEnd(connectiontypes.TRYOPEN, clientIDSolomachine, counterparty, []*connectiontypes.Version{ConnectionVersion}, DefaultDelayPeriod) + + data, err := solo.cdc.Marshal(&connection) + require.NoError(solo.t, err) + + signBytes := &solomachine.SignBytes{ + Sequence: solo.Sequence, + Timestamp: solo.Time, + Diversifier: solo.Diversifier, + Path: []byte(solo.GetConnectionStatePath(connectionIDSolomachine).String()), + Data: data, + } + + return solo.GenerateProof(signBytes) +} + +// GenerateChanOpenTryProof generates the proofTry required for the channel open ack handshake step. +// The channelID provided represents the channelID created on the counterparty chain, that is the tendermint chain. +func (solo *Solomachine) GenerateChanOpenTryProof(portID, version, counterpartyChannelID string) []byte { + counterparty := channeltypes.NewCounterparty(portID, counterpartyChannelID) + channel := channeltypes.NewChannel(channeltypes.TRYOPEN, channeltypes.UNORDERED, counterparty, []string{connectionIDSolomachine}, version) + + data, err := solo.cdc.Marshal(&channel) + require.NoError(solo.t, err) + + signBytes := &solomachine.SignBytes{ + Sequence: solo.Sequence, + Timestamp: solo.Time, + Diversifier: solo.Diversifier, + Path: []byte(solo.GetChannelStatePath(portID, channelIDSolomachine).String()), + Data: data, + } + + return solo.GenerateProof(signBytes) +} + +// GenerateChanClosedProof generates a channel closed proof. +// The channelID provided represents the channelID created on the counterparty chain, that is the tendermint chain. +func (solo *Solomachine) GenerateChanClosedProof(portID, version, counterpartyChannelID string) []byte { + counterparty := channeltypes.NewCounterparty(portID, counterpartyChannelID) + channel := channeltypes.NewChannel(channeltypes.CLOSED, channeltypes.UNORDERED, counterparty, []string{connectionIDSolomachine}, version) + + data, err := solo.cdc.Marshal(&channel) + require.NoError(solo.t, err) + + signBytes := &solomachine.SignBytes{ + Sequence: solo.Sequence, + Timestamp: solo.Time, + Diversifier: solo.Diversifier, + Path: []byte(solo.GetChannelStatePath(portID, channelIDSolomachine).String()), + Data: data, + } + + return solo.GenerateProof(signBytes) +} + +// GenerateCommitmentProof generates a commitment proof for the provided packet. +func (solo *Solomachine) GenerateCommitmentProof(packet channeltypes.Packet) []byte { + commitment := channeltypes.CommitPacket(solo.cdc, packet) + + signBytes := &solomachine.SignBytes{ + Sequence: solo.Sequence, + Timestamp: solo.Time, + Diversifier: solo.Diversifier, + Path: []byte(solo.GetPacketCommitmentPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()).String()), + Data: commitment, + } + + return solo.GenerateProof(signBytes) +} + +// GenerateAcknowledgementProof generates an acknowledgement proof. +func (solo *Solomachine) GenerateAcknowledgementProof(packet channeltypes.Packet) []byte { + transferAck := channeltypes.NewResultAcknowledgement([]byte{byte(1)}).Acknowledgement() + signBytes := &solomachine.SignBytes{ + Sequence: solo.Sequence, + Timestamp: solo.Time, + Diversifier: solo.Diversifier, + Path: []byte(solo.GetPacketAcknowledgementPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()).String()), + Data: channeltypes.CommitAcknowledgement(transferAck), + } + + return solo.GenerateProof(signBytes) +} + +// GenerateReceiptAbsenceProof generates a receipt absence proof for the provided packet. +func (solo *Solomachine) GenerateReceiptAbsenceProof(packet channeltypes.Packet) []byte { + signBytes := &solomachine.SignBytes{ + Sequence: solo.Sequence, + Timestamp: solo.Time, + Diversifier: solo.Diversifier, + Path: []byte(solo.GetPacketReceiptPath(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()).String()), + Data: nil, + } + return solo.GenerateProof(signBytes) +} + // GetClientStatePath returns the commitment path for the client state. func (solo *Solomachine) GetClientStatePath(counterpartyClientIdentifier string) commitmenttypes.MerklePath { path, err := commitmenttypes.ApplyPrefix(prefix, commitmenttypes.NewMerklePath(host.FullClientStatePath(counterpartyClientIdentifier))) @@ -282,8 +673,8 @@ func (solo *Solomachine) GetChannelStatePath(portID, channelID string) commitmen } // GetPacketCommitmentPath returns the commitment path for a packet commitment. -func (solo *Solomachine) GetPacketCommitmentPath(portID, channelID string) commitmenttypes.MerklePath { - commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, solo.Sequence)) +func (solo *Solomachine) GetPacketCommitmentPath(portID, channelID string, sequence uint64) commitmenttypes.MerklePath { + commitmentPath := commitmenttypes.NewMerklePath(host.PacketCommitmentPath(portID, channelID, sequence)) path, err := commitmenttypes.ApplyPrefix(prefix, commitmentPath) require.NoError(solo.t, err) @@ -291,8 +682,8 @@ func (solo *Solomachine) GetPacketCommitmentPath(portID, channelID string) commi } // GetPacketAcknowledgementPath returns the commitment path for a packet acknowledgement. -func (solo *Solomachine) GetPacketAcknowledgementPath(portID, channelID string) commitmenttypes.MerklePath { - ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, solo.Sequence)) +func (solo *Solomachine) GetPacketAcknowledgementPath(portID, channelID string, sequence uint64) commitmenttypes.MerklePath { + ackPath := commitmenttypes.NewMerklePath(host.PacketAcknowledgementPath(portID, channelID, sequence)) path, err := commitmenttypes.ApplyPrefix(prefix, ackPath) require.NoError(solo.t, err) @@ -301,8 +692,8 @@ func (solo *Solomachine) GetPacketAcknowledgementPath(portID, channelID string) // GetPacketReceiptPath returns the commitment path for a packet receipt // and an absent receipts. -func (solo *Solomachine) GetPacketReceiptPath(portID, channelID string) commitmenttypes.MerklePath { - receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, solo.Sequence)) +func (solo *Solomachine) GetPacketReceiptPath(portID, channelID string, sequence uint64) commitmenttypes.MerklePath { + receiptPath := commitmenttypes.NewMerklePath(host.PacketReceiptPath(portID, channelID, sequence)) path, err := commitmenttypes.ApplyPrefix(prefix, receiptPath) require.NoError(solo.t, err) diff --git a/testing/types/expected_keepers.go b/testing/types/expected_keepers.go new file mode 100644 index 00000000000..07034b57a25 --- /dev/null +++ b/testing/types/expected_keepers.go @@ -0,0 +1,12 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// StakingKeeper defines the expected staking keeper interface used in the +// IBC testing package +type StakingKeeper interface { + GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool) +} diff --git a/testing/utils.go b/testing/utils.go index f9f64bf72bd..b0d810b4cad 100644 --- a/testing/utils.go +++ b/testing/utils.go @@ -10,14 +10,14 @@ import ( // ApplyValSetChanges takes in tmtypes.ValidatorSet and []abci.ValidatorUpdate and will return a new tmtypes.ValidatorSet which has the // provided validator updates applied to the provided validator set. -func ApplyValSetChanges(t *testing.T, valSet *tmtypes.ValidatorSet, valUpdates []abci.ValidatorUpdate) *tmtypes.ValidatorSet { +func ApplyValSetChanges(tb testing.TB, valSet *tmtypes.ValidatorSet, valUpdates []abci.ValidatorUpdate) *tmtypes.ValidatorSet { updates, err := tmtypes.PB2TM.ValidatorUpdates(valUpdates) - require.NoError(t, err) + require.NoError(tb, err) // must copy since validator set will mutate with UpdateWithChangeSet newVals := valSet.Copy() err = newVals.UpdateWithChangeSet(updates) - require.NoError(t, err) + require.NoError(tb, err) return newVals } diff --git a/testing/values.go b/testing/values.go index 481db7915e8..fa69c502069 100644 --- a/testing/values.go +++ b/testing/values.go @@ -1,6 +1,6 @@ /* - This file contains the variables, constants, and default values - used in the testing package and commonly defined in tests. +This file contains the variables, constants, and default values +used in the testing package and commonly defined in tests. */ package ibctesting @@ -9,12 +9,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types" - connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types" - commitmenttypes "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types" - "github.com/cosmos/ibc-go/v4/testing/mock" - "github.com/cosmos/ibc-go/v4/testing/simapp" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" + ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "github.com/cosmos/ibc-go/v7/testing/mock" + "github.com/cosmos/ibc-go/v7/testing/simapp" ) const ( @@ -46,9 +46,12 @@ const ( var ( DefaultOpenInitVersion *connectiontypes.Version - // Default params variables used to create a TM client - DefaultTrustLevel ibctmtypes.Fraction = ibctmtypes.DefaultTrustLevel - TestCoin = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) + // DefaultTrustLevel sets params variables used to create a TM client + DefaultTrustLevel = ibctm.DefaultTrustLevel + + TestAccAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + TestCoin = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) + TestCoins = sdk.NewCoins(TestCoin) UpgradePath = []string{"upgrade", "upgradedIBCState"} diff --git a/third_party/proto/buf.yaml b/third_party/proto/buf.yaml deleted file mode 100644 index b111c46ba08..00000000000 --- a/third_party/proto/buf.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by "buf config migrate-v1beta1". Edit as necessary, and -# remove this comment when you're finished. -# -# This module represents the "third_party/proto" root found in -# the previous configuration. -version: v1 -build: - excludes: - - google/protobuf -breaking: - use: - - FILE - ignore: - - proofs.proto # confio/ics23 - - gogoproto - - google - - tendermint -lint: - use: - - DEFAULT - - COMMENTS - - FILE_LOWER_SNAKE_CASE - except: - - UNARY_RPC - - COMMENT_FIELD - - SERVICE_SUFFIX - - PACKAGE_VERSION_SUFFIX - - RPC_REQUEST_STANDARD_NAME - ignore: - - proofs.proto # confio/ics23 - - gogoproto - - google - - tendermint \ No newline at end of file diff --git a/third_party/proto/cosmos/auth/v1beta1/auth.proto b/third_party/proto/cosmos/auth/v1beta1/auth.proto deleted file mode 100644 index 79071456f6e..00000000000 --- a/third_party/proto/cosmos/auth/v1beta1/auth.proto +++ /dev/null @@ -1,51 +0,0 @@ -syntax = "proto3"; -package cosmos.auth.v1beta1; - -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; - -// BaseAccount defines a base account type. It contains all the necessary fields -// for basic account functionality. Any custom account type should extend this -// type for additional functionality (e.g. vesting). -message BaseAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.equal) = false; - - option (cosmos_proto.implements_interface) = "AccountI"; - - string address = 1; - google.protobuf.Any pub_key = 2 - [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""]; - uint64 account_number = 3 [(gogoproto.moretags) = "yaml:\"account_number\""]; - uint64 sequence = 4; -} - -// ModuleAccount defines an account for modules that holds coins on a pool. -message ModuleAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (cosmos_proto.implements_interface) = "ModuleAccountI"; - - BaseAccount base_account = 1 [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""]; - string name = 2; - repeated string permissions = 3; -} - -// Params defines the parameters for the auth module. -message Params { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - uint64 max_memo_characters = 1 [(gogoproto.moretags) = "yaml:\"max_memo_characters\""]; - uint64 tx_sig_limit = 2 [(gogoproto.moretags) = "yaml:\"tx_sig_limit\""]; - uint64 tx_size_cost_per_byte = 3 [(gogoproto.moretags) = "yaml:\"tx_size_cost_per_byte\""]; - uint64 sig_verify_cost_ed25519 = 4 - [(gogoproto.customname) = "SigVerifyCostED25519", (gogoproto.moretags) = "yaml:\"sig_verify_cost_ed25519\""]; - uint64 sig_verify_cost_secp256k1 = 5 - [(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""]; -} - diff --git a/third_party/proto/cosmos/auth/v1beta1/genesis.proto b/third_party/proto/cosmos/auth/v1beta1/genesis.proto deleted file mode 100644 index 5d6823e6b35..00000000000 --- a/third_party/proto/cosmos/auth/v1beta1/genesis.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; -package cosmos.auth.v1beta1; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/auth/v1beta1/auth.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; - -// GenesisState defines the auth module's genesis state. -message GenesisState { - // params defines all the paramaters of the module. - Params params = 1 [(gogoproto.nullable) = false]; - - // accounts are the accounts present at genesis. - repeated google.protobuf.Any accounts = 2; -} - diff --git a/third_party/proto/cosmos/auth/v1beta1/query.proto b/third_party/proto/cosmos/auth/v1beta1/query.proto deleted file mode 100644 index 2c438c7b5ed..00000000000 --- a/third_party/proto/cosmos/auth/v1beta1/query.proto +++ /dev/null @@ -1,48 +0,0 @@ -syntax = "proto3"; -package cosmos.auth.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; -import "cosmos/auth/v1beta1/auth.proto"; -import "cosmos_proto/cosmos.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; - -// Query defines the gRPC querier service. -service Query { - // Account returns account details based on address. - rpc Account(QueryAccountRequest) returns (QueryAccountResponse) { - option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}"; - } - - // Params queries all parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/auth/v1beta1/params"; - } -} - -// QueryAccountRequest is the request type for the Query/Account RPC method. -message QueryAccountRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // address defines the address to query for. - string address = 1; -} - -// QueryAccountResponse is the response type for the Query/Account RPC method. -message QueryAccountResponse { - // account defines the account of the corresponding address. - google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1 [(gogoproto.nullable) = false]; -} - diff --git a/third_party/proto/cosmos/base/query/v1beta1/pagination.proto b/third_party/proto/cosmos/base/query/v1beta1/pagination.proto deleted file mode 100644 index 2a8cbccedd8..00000000000 --- a/third_party/proto/cosmos/base/query/v1beta1/pagination.proto +++ /dev/null @@ -1,50 +0,0 @@ -syntax = "proto3"; -package cosmos.base.query.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/types/query"; - -// PageRequest is to be embedded in gRPC request messages for efficient -// pagination. Ex: -// -// message SomeRequest { -// Foo some_parameter = 1; -// PageRequest pagination = 2; -// } -message PageRequest { - // key is a value returned in PageResponse.next_key to begin - // querying the next page most efficiently. Only one of offset or key - // should be set. - bytes key = 1; - - // offset is a numeric offset that can be used when key is unavailable. - // It is less efficient than using key. Only one of offset or key should - // be set. - uint64 offset = 2; - - // limit is the total number of results to be returned in the result page. - // If left empty it will default to a value to be set by each app. - uint64 limit = 3; - - // count_total is set to true to indicate that the result set should include - // a count of the total number of items available for pagination in UIs. - // count_total is only respected when offset is used. It is ignored when key - // is set. - bool count_total = 4; -} - -// PageResponse is to be embedded in gRPC response messages where the -// corresponding request message has used PageRequest. -// -// message SomeResponse { -// repeated Bar results = 1; -// PageResponse page = 2; -// } -message PageResponse { - // next_key is the key to be passed to PageRequest.key to - // query the next page most efficiently - bytes next_key = 1; - - // total is total number of results available if PageRequest.count_total - // was set, its value is undefined otherwise - uint64 total = 2; -} diff --git a/third_party/proto/cosmos/base/v1beta1/coin.proto b/third_party/proto/cosmos/base/v1beta1/coin.proto deleted file mode 100644 index fab75284b7f..00000000000 --- a/third_party/proto/cosmos/base/v1beta1/coin.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto3"; -package cosmos.base.v1beta1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/types"; -option (gogoproto.goproto_stringer_all) = false; -option (gogoproto.stringer_all) = false; - -// Coin defines a token with a denomination and an amount. -// -// NOTE: The amount field is an Int which implements the custom method -// signatures required by gogoproto. -message Coin { - option (gogoproto.equal) = true; - - string denom = 1; - string amount = 2 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; -} - -// DecCoin defines a token with a denomination and a decimal amount. -// -// NOTE: The amount field is an Dec which implements the custom method -// signatures required by gogoproto. -message DecCoin { - option (gogoproto.equal) = true; - - string denom = 1; - string amount = 2 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; -} - -// IntProto defines a Protobuf wrapper around an Int object. -message IntProto { - string int = 1 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; -} - -// DecProto defines a Protobuf wrapper around a Dec object. -message DecProto { - string dec = 1 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; -} diff --git a/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto b/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto deleted file mode 100644 index d322dedc30d..00000000000 --- a/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto +++ /dev/null @@ -1,59 +0,0 @@ -syntax = "proto3"; -package cosmos.upgrade.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; -option (gogoproto.goproto_stringer_all) = false; -option (gogoproto.goproto_getters_all) = false; - -// Plan specifies information about a planned upgrade and when it should occur. -message Plan { - option (gogoproto.equal) = true; - - // Sets the name for the upgrade. This name will be used by the upgraded - // version of the software to apply any special "on-upgrade" commands during - // the first BeginBlock method after the upgrade is applied. It is also used - // to detect whether a software version can handle a given upgrade. If no - // upgrade handler with this name has been set in the software, it will be - // assumed that the software is out-of-date when the upgrade Time or Height is - // reached and the software will exit. - string name = 1; - - // The time after which the upgrade must be performed. - // Leave set to its zero value to use a pre-defined Height instead. - google.protobuf.Timestamp time = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; - - // The height at which the upgrade must be performed. - // Only used if Time is not set. - int64 height = 3; - - // Any application specific upgrade info to be included on-chain - // such as a git commit that validators could automatically upgrade to - string info = 4; - - // UpgradedClientState field has been deprecated. IBC upgrade logic has been - // moved to the IBC module in the sub module 02-client. - reserved 5; - reserved "option"; -} - -// SoftwareUpgradeProposal is a gov Content type for initiating a software -// upgrade. -message SoftwareUpgradeProposal { - option (gogoproto.equal) = true; - - string title = 1; - string description = 2; - Plan plan = 3 [(gogoproto.nullable) = false]; -} - -// CancelSoftwareUpgradeProposal is a gov Content type for cancelling a software -// upgrade. -message CancelSoftwareUpgradeProposal { - option (gogoproto.equal) = true; - - string title = 1; - string description = 2; -} diff --git a/third_party/proto/cosmos_proto/cosmos.proto b/third_party/proto/cosmos_proto/cosmos.proto deleted file mode 100644 index 167b170757b..00000000000 --- a/third_party/proto/cosmos_proto/cosmos.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; -package cosmos_proto; - -import "google/protobuf/descriptor.proto"; - -option go_package = "github.com/regen-network/cosmos-proto"; - -extend google.protobuf.MessageOptions { - string interface_type = 93001; - - string implements_interface = 93002; -} - -extend google.protobuf.FieldOptions { - string accepts_interface = 93001; -} diff --git a/third_party/proto/gogoproto/gogo.proto b/third_party/proto/gogoproto/gogo.proto deleted file mode 100644 index 49e78f99fe5..00000000000 --- a/third_party/proto/gogoproto/gogo.proto +++ /dev/null @@ -1,145 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto2"; -package gogoproto; - -import "google/protobuf/descriptor.proto"; - -option java_package = "com.google.protobuf"; -option java_outer_classname = "GoGoProtos"; -option go_package = "github.com/gogo/protobuf/gogoproto"; - -extend google.protobuf.EnumOptions { - optional bool goproto_enum_prefix = 62001; - optional bool goproto_enum_stringer = 62021; - optional bool enum_stringer = 62022; - optional string enum_customname = 62023; - optional bool enumdecl = 62024; -} - -extend google.protobuf.EnumValueOptions { - optional string enumvalue_customname = 66001; -} - -extend google.protobuf.FileOptions { - optional bool goproto_getters_all = 63001; - optional bool goproto_enum_prefix_all = 63002; - optional bool goproto_stringer_all = 63003; - optional bool verbose_equal_all = 63004; - optional bool face_all = 63005; - optional bool gostring_all = 63006; - optional bool populate_all = 63007; - optional bool stringer_all = 63008; - optional bool onlyone_all = 63009; - - optional bool equal_all = 63013; - optional bool description_all = 63014; - optional bool testgen_all = 63015; - optional bool benchgen_all = 63016; - optional bool marshaler_all = 63017; - optional bool unmarshaler_all = 63018; - optional bool stable_marshaler_all = 63019; - - optional bool sizer_all = 63020; - - optional bool goproto_enum_stringer_all = 63021; - optional bool enum_stringer_all = 63022; - - optional bool unsafe_marshaler_all = 63023; - optional bool unsafe_unmarshaler_all = 63024; - - optional bool goproto_extensions_map_all = 63025; - optional bool goproto_unrecognized_all = 63026; - optional bool gogoproto_import = 63027; - optional bool protosizer_all = 63028; - optional bool compare_all = 63029; - optional bool typedecl_all = 63030; - optional bool enumdecl_all = 63031; - - optional bool goproto_registration = 63032; - optional bool messagename_all = 63033; - - optional bool goproto_sizecache_all = 63034; - optional bool goproto_unkeyed_all = 63035; -} - -extend google.protobuf.MessageOptions { - optional bool goproto_getters = 64001; - optional bool goproto_stringer = 64003; - optional bool verbose_equal = 64004; - optional bool face = 64005; - optional bool gostring = 64006; - optional bool populate = 64007; - optional bool stringer = 67008; - optional bool onlyone = 64009; - - optional bool equal = 64013; - optional bool description = 64014; - optional bool testgen = 64015; - optional bool benchgen = 64016; - optional bool marshaler = 64017; - optional bool unmarshaler = 64018; - optional bool stable_marshaler = 64019; - - optional bool sizer = 64020; - - optional bool unsafe_marshaler = 64023; - optional bool unsafe_unmarshaler = 64024; - - optional bool goproto_extensions_map = 64025; - optional bool goproto_unrecognized = 64026; - - optional bool protosizer = 64028; - optional bool compare = 64029; - - optional bool typedecl = 64030; - - optional bool messagename = 64033; - - optional bool goproto_sizecache = 64034; - optional bool goproto_unkeyed = 64035; -} - -extend google.protobuf.FieldOptions { - optional bool nullable = 65001; - optional bool embed = 65002; - optional string customtype = 65003; - optional string customname = 65004; - optional string jsontag = 65005; - optional string moretags = 65006; - optional string casttype = 65007; - optional string castkey = 65008; - optional string castvalue = 65009; - - optional bool stdtime = 65010; - optional bool stdduration = 65011; - optional bool wktpointer = 65012; - - optional string castrepeated = 65013; -} diff --git a/third_party/proto/google/api/annotations.proto b/third_party/proto/google/api/annotations.proto deleted file mode 100644 index 85c361b47fe..00000000000 --- a/third_party/proto/google/api/annotations.proto +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/http.proto"; -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "AnnotationsProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.MethodOptions { - // See `HttpRule`. - HttpRule http = 72295728; -} diff --git a/third_party/proto/google/api/http.proto b/third_party/proto/google/api/http.proto deleted file mode 100644 index 2bd3a19bfa5..00000000000 --- a/third_party/proto/google/api/http.proto +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option cc_enable_arenas = true; -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "HttpProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - - -// Defines the HTTP configuration for an API service. It contains a list of -// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method -// to one or more HTTP REST API methods. -message Http { - // A list of HTTP configuration rules that apply to individual API methods. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated HttpRule rules = 1; - - // When set to true, URL path parmeters will be fully URI-decoded except in - // cases of single segment matches in reserved expansion, where "%2F" will be - // left encoded. - // - // The default behavior is to not decode RFC 6570 reserved characters in multi - // segment matches. - bool fully_decode_reserved_expansion = 2; -} - -// `HttpRule` defines the mapping of an RPC method to one or more HTTP -// REST API methods. The mapping specifies how different portions of the RPC -// request message are mapped to URL path, URL query parameters, and -// HTTP request body. The mapping is typically specified as an -// `google.api.http` annotation on the RPC method, -// see "google/api/annotations.proto" for details. -// -// The mapping consists of a field specifying the path template and -// method kind. The path template can refer to fields in the request -// message, as in the example below which describes a REST GET -// operation on a resource collection of messages: -// -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; -// } -// } -// message GetMessageRequest { -// message SubMessage { -// string subfield = 1; -// } -// string message_id = 1; // mapped to the URL -// SubMessage sub = 2; // `sub.subfield` is url-mapped -// } -// message Message { -// string text = 1; // content of the resource -// } -// -// The same http annotation can alternatively be expressed inside the -// `GRPC API Configuration` YAML file. -// -// http: -// rules: -// - selector: .Messaging.GetMessage -// get: /v1/messages/{message_id}/{sub.subfield} -// -// This definition enables an automatic, bidrectional mapping of HTTP -// JSON to RPC. Example: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` -// -// In general, not only fields but also field paths can be referenced -// from a path pattern. Fields mapped to the path pattern cannot be -// repeated and must have a primitive (non-message) type. -// -// Any fields in the request message which are not bound by the path -// pattern automatically become (optional) HTTP query -// parameters. Assume the following definition of the request message: -// -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http).get = "/v1/messages/{message_id}"; -// } -// } -// message GetMessageRequest { -// message SubMessage { -// string subfield = 1; -// } -// string message_id = 1; // mapped to the URL -// int64 revision = 2; // becomes a parameter -// SubMessage sub = 3; // `sub.subfield` becomes a parameter -// } -// -// -// This enables a HTTP JSON to RPC mapping as below: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` -// -// Note that fields which are mapped to HTTP parameters must have a -// primitive type or a repeated primitive type. Message types are not -// allowed. In the case of a repeated type, the parameter can be -// repeated in the URL, as in `...?param=A¶m=B`. -// -// For HTTP method kinds which allow a request body, the `body` field -// specifies the mapping. Consider a REST update method on the -// message resource collection: -// -// -// service Messaging { -// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { -// option (google.api.http) = { -// put: "/v1/messages/{message_id}" -// body: "message" -// }; -// } -// } -// message UpdateMessageRequest { -// string message_id = 1; // mapped to the URL -// Message message = 2; // mapped to the body -// } -// -// -// The following HTTP JSON to RPC mapping is enabled, where the -// representation of the JSON in the request body is determined by -// protos JSON encoding: -// -// HTTP | RPC -// -----|----- -// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` -// -// The special name `*` can be used in the body mapping to define that -// every field not bound by the path template should be mapped to the -// request body. This enables the following alternative definition of -// the update method: -// -// service Messaging { -// rpc UpdateMessage(Message) returns (Message) { -// option (google.api.http) = { -// put: "/v1/messages/{message_id}" -// body: "*" -// }; -// } -// } -// message Message { -// string message_id = 1; -// string text = 2; -// } -// -// -// The following HTTP JSON to RPC mapping is enabled: -// -// HTTP | RPC -// -----|----- -// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` -// -// Note that when using `*` in the body mapping, it is not possible to -// have HTTP parameters, as all fields not bound by the path end in -// the body. This makes this option more rarely used in practice of -// defining REST APIs. The common usage of `*` is in custom methods -// which don't use the URL at all for transferring data. -// -// It is possible to define multiple HTTP methods for one RPC by using -// the `additional_bindings` option. Example: -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get: "/v1/messages/{message_id}" -// additional_bindings { -// get: "/v1/users/{user_id}/messages/{message_id}" -// } -// }; -// } -// } -// message GetMessageRequest { -// string message_id = 1; -// string user_id = 2; -// } -// -// -// This enables the following two alternative HTTP JSON to RPC -// mappings: -// -// HTTP | RPC -// -----|----- -// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` -// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` -// -// # Rules for HTTP mapping -// -// The rules for mapping HTTP path, query parameters, and body fields -// to the request message are as follows: -// -// 1. The `body` field specifies either `*` or a field path, or is -// omitted. If omitted, it indicates there is no HTTP request body. -// 2. Leaf fields (recursive expansion of nested messages in the -// request) can be classified into three types: -// (a) Matched in the URL template. -// (b) Covered by body (if body is `*`, everything except (a) fields; -// else everything under the body field) -// (c) All other fields. -// 3. URL query parameters found in the HTTP request are mapped to (c) fields. -// 4. Any body sent with an HTTP request can contain only (b) fields. -// -// The syntax of the path template is as follows: -// -// Template = "/" Segments [ Verb ] ; -// Segments = Segment { "/" Segment } ; -// Segment = "*" | "**" | LITERAL | Variable ; -// Variable = "{" FieldPath [ "=" Segments ] "}" ; -// FieldPath = IDENT { "." IDENT } ; -// Verb = ":" LITERAL ; -// -// The syntax `*` matches a single path segment. The syntax `**` matches zero -// or more path segments, which must be the last part of the path except the -// `Verb`. The syntax `LITERAL` matches literal text in the path. -// -// The syntax `Variable` matches part of the URL path as specified by its -// template. A variable template must not contain other variables. If a variable -// matches a single path segment, its template may be omitted, e.g. `{var}` -// is equivalent to `{var=*}`. -// -// If a variable contains exactly one path segment, such as `"{var}"` or -// `"{var=*}"`, when such a variable is expanded into a URL path, all characters -// except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the -// Discovery Document as `{var}`. -// -// If a variable contains one or more path segments, such as `"{var=foo/*}"` -// or `"{var=**}"`, when such a variable is expanded into a URL path, all -// characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables -// show up in the Discovery Document as `{+var}`. -// -// NOTE: While the single segment variable matches the semantics of -// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 -// Simple String Expansion, the multi segment variable **does not** match -// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion -// does not expand special characters like `?` and `#`, which would lead -// to invalid URLs. -// -// NOTE: the field paths in variables and in the `body` must not refer to -// repeated fields or map fields. -message HttpRule { - // Selects methods to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. - string selector = 1; - - // Determines the URL pattern is matched by this rules. This pattern can be - // used with any of the {get|put|post|delete|patch} methods. A custom method - // can be defined using the 'custom' field. - oneof pattern { - // Used for listing and getting information about resources. - string get = 2; - - // Used for updating a resource. - string put = 3; - - // Used for creating a resource. - string post = 4; - - // Used for deleting a resource. - string delete = 5; - - // Used for updating a resource. - string patch = 6; - - // The custom pattern is used for specifying an HTTP method that is not - // included in the `pattern` field, such as HEAD, or "*" to leave the - // HTTP method unspecified for this rule. The wild-card rule is useful - // for services that provide content to Web (HTML) clients. - CustomHttpPattern custom = 8; - } - - // The name of the request field whose value is mapped to the HTTP body, or - // `*` for mapping all fields not captured by the path pattern to the HTTP - // body. NOTE: the referred field must not be a repeated field and must be - // present at the top-level of request message type. - string body = 7; - - // Optional. The name of the response field whose value is mapped to the HTTP - // body of response. Other response fields are ignored. When - // not set, the response message will be used as HTTP body of response. - string response_body = 12; - - // Additional HTTP bindings for the selector. Nested bindings must - // not contain an `additional_bindings` field themselves (that is, - // the nesting may only be one level deep). - repeated HttpRule additional_bindings = 11; -} - -// A custom pattern is used for defining custom HTTP verb. -message CustomHttpPattern { - // The name of this custom HTTP verb. - string kind = 1; - - // The path matched by this custom verb. - string path = 2; -} diff --git a/third_party/proto/google/protobuf/any.proto b/third_party/proto/google/protobuf/any.proto deleted file mode 100644 index 1431810ea45..00000000000 --- a/third_party/proto/google/protobuf/any.proto +++ /dev/null @@ -1,161 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package google.protobuf; - -import "gogoproto/gogo.proto"; - -option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option go_package = "types"; -option java_package = "com.google.protobuf"; -option java_outer_classname = "AnyProto"; -option java_multiple_files = true; -option objc_class_prefix = "GPB"; - -// `Any` contains an arbitrary serialized protocol buffer message along with a -// URL that describes the type of the serialized message. -// -// Protobuf library provides support to pack/unpack Any values in the form -// of utility functions or additional generated methods of the Any type. -// -// Example 1: Pack and unpack a message in C++. -// -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } -// -// Example 2: Pack and unpack a message in Java. -// -// Foo foo = ...; -// Any any = Any.pack(foo); -// ... -// if (any.is(Foo.class)) { -// foo = any.unpack(Foo.class); -// } -// -// Example 3: Pack and unpack a message in Python. -// -// foo = Foo(...) -// any = Any() -// any.Pack(foo) -// ... -// if any.Is(Foo.DESCRIPTOR): -// any.Unpack(foo) -// ... -// -// Example 4: Pack and unpack a message in Go -// -// foo := &pb.Foo{...} -// any, err := ptypes.MarshalAny(foo) -// ... -// foo := &pb.Foo{} -// if err := ptypes.UnmarshalAny(any, foo); err != nil { -// ... -// } -// -// The pack methods provided by protobuf library will by default use -// 'type.googleapis.com/full.type.name' as the type URL and the unpack -// methods only use the fully qualified type name after the last '/' -// in the type URL, for example "foo.bar.com/x/y.z" will yield type -// name "y.z". -// -// -// JSON -// ==== -// The JSON representation of an `Any` value uses the regular -// representation of the deserialized, embedded message, with an -// additional field `@type` which contains the type URL. Example: -// -// package google.profile; -// message Person { -// string first_name = 1; -// string last_name = 2; -// } -// -// { -// "@type": "type.googleapis.com/google.profile.Person", -// "firstName": , -// "lastName": -// } -// -// If the embedded message type is well-known and has a custom JSON -// representation, that representation will be embedded adding a field -// `value` which holds the custom JSON in addition to the `@type` -// field. Example (for message [google.protobuf.Duration][]): -// -// { -// "@type": "type.googleapis.com/google.protobuf.Duration", -// "value": "1.212s" -// } -// -message Any { - // A URL/resource name that uniquely identifies the type of the serialized - // protocol buffer message. This string must contain at least - // one "/" character. The last segment of the URL's path must represent - // the fully qualified name of the type (as in - // `path/google.protobuf.Duration`). The name should be in a canonical form - // (e.g., leading "." is not accepted). - // - // In practice, teams usually precompile into the binary all types that they - // expect it to use in the context of Any. However, for URLs which use the - // scheme `http`, `https`, or no scheme, one can optionally set up a type - // server that maps type URLs to message definitions as follows: - // - // * If no scheme is provided, `https` is assumed. - // * An HTTP GET on the URL must yield a [google.protobuf.Type][] - // value in binary format, or produce an error. - // * Applications are allowed to cache lookup results based on the - // URL, or have them precompiled into a binary to avoid any - // lookup. Therefore, binary compatibility needs to be preserved - // on changes to types. (Use versioned type names to manage - // breaking changes.) - // - // Note: this functionality is not currently available in the official - // protobuf release, and it is not used for type URLs beginning with - // type.googleapis.com. - // - // Schemes other than `http`, `https` (or the empty scheme) might be - // used with implementation specific semantics. - // - string type_url = 1; - - // Must be a valid serialized protocol buffer of the above specified type. - bytes value = 2; - - option (gogoproto.typedecl) = false; -} - -option (gogoproto.goproto_registration) = false; diff --git a/third_party/proto/proofs.proto b/third_party/proto/proofs.proto deleted file mode 100644 index da43503ecbd..00000000000 --- a/third_party/proto/proofs.proto +++ /dev/null @@ -1,234 +0,0 @@ -syntax = "proto3"; - -package ics23; -option go_package = "github.com/confio/ics23/go"; - -enum HashOp { - // NO_HASH is the default if no data passed. Note this is an illegal argument some places. - NO_HASH = 0; - SHA256 = 1; - SHA512 = 2; - KECCAK = 3; - RIPEMD160 = 4; - BITCOIN = 5; // ripemd160(sha256(x)) -} - -/** -LengthOp defines how to process the key and value of the LeafOp -to include length information. After encoding the length with the given -algorithm, the length will be prepended to the key and value bytes. -(Each one with it's own encoded length) -*/ -enum LengthOp { - // NO_PREFIX don't include any length info - NO_PREFIX = 0; - // VAR_PROTO uses protobuf (and go-amino) varint encoding of the length - VAR_PROTO = 1; - // VAR_RLP uses rlp int encoding of the length - VAR_RLP = 2; - // FIXED32_BIG uses big-endian encoding of the length as a 32 bit integer - FIXED32_BIG = 3; - // FIXED32_LITTLE uses little-endian encoding of the length as a 32 bit integer - FIXED32_LITTLE = 4; - // FIXED64_BIG uses big-endian encoding of the length as a 64 bit integer - FIXED64_BIG = 5; - // FIXED64_LITTLE uses little-endian encoding of the length as a 64 bit integer - FIXED64_LITTLE = 6; - // REQUIRE_32_BYTES is like NONE, but will fail if the input is not exactly 32 bytes (sha256 output) - REQUIRE_32_BYTES = 7; - // REQUIRE_64_BYTES is like NONE, but will fail if the input is not exactly 64 bytes (sha512 output) - REQUIRE_64_BYTES = 8; -} - -/** -ExistenceProof takes a key and a value and a set of steps to perform on it. -The result of peforming all these steps will provide a "root hash", which can -be compared to the value in a header. - -Since it is computationally infeasible to produce a hash collission for any of the used -cryptographic hash functions, if someone can provide a series of operations to transform -a given key and value into a root hash that matches some trusted root, these key and values -must be in the referenced merkle tree. - -The only possible issue is maliablity in LeafOp, such as providing extra prefix data, -which should be controlled by a spec. Eg. with lengthOp as NONE, - prefix = FOO, key = BAR, value = CHOICE -and - prefix = F, key = OOBAR, value = CHOICE -would produce the same value. - -With LengthOp this is tricker but not impossible. Which is why the "leafPrefixEqual" field -in the ProofSpec is valuable to prevent this mutability. And why all trees should -length-prefix the data before hashing it. -*/ -message ExistenceProof { - bytes key = 1; - bytes value = 2; - LeafOp leaf = 3; - repeated InnerOp path = 4; -} - -/* -NonExistenceProof takes a proof of two neighbors, one left of the desired key, -one right of the desired key. If both proofs are valid AND they are neighbors, -then there is no valid proof for the given key. -*/ -message NonExistenceProof { - bytes key = 1; // TODO: remove this as unnecessary??? we prove a range - ExistenceProof left = 2; - ExistenceProof right = 3; -} - -/* -CommitmentProof is either an ExistenceProof or a NonExistenceProof, or a Batch of such messages -*/ -message CommitmentProof { - oneof proof { - ExistenceProof exist = 1; - NonExistenceProof nonexist = 2; - BatchProof batch = 3; - CompressedBatchProof compressed = 4; - } -} - -/** -LeafOp represents the raw key-value data we wish to prove, and -must be flexible to represent the internal transformation from -the original key-value pairs into the basis hash, for many existing -merkle trees. - -key and value are passed in. So that the signature of this operation is: - leafOp(key, value) -> output - -To process this, first prehash the keys and values if needed (ANY means no hash in this case): - hkey = prehashKey(key) - hvalue = prehashValue(value) - -Then combine the bytes, and hash it - output = hash(prefix || length(hkey) || hkey || length(hvalue) || hvalue) -*/ -message LeafOp { - HashOp hash = 1; - HashOp prehash_key = 2; - HashOp prehash_value = 3; - LengthOp length = 4; - // prefix is a fixed bytes that may optionally be included at the beginning to differentiate - // a leaf node from an inner node. - bytes prefix = 5; -} - -/** -InnerOp represents a merkle-proof step that is not a leaf. -It represents concatenating two children and hashing them to provide the next result. - -The result of the previous step is passed in, so the signature of this op is: - innerOp(child) -> output - -The result of applying InnerOp should be: - output = op.hash(op.prefix || child || op.suffix) - - where the || operator is concatenation of binary data, -and child is the result of hashing all the tree below this step. - -Any special data, like prepending child with the length, or prepending the entire operation with -some value to differentiate from leaf nodes, should be included in prefix and suffix. -If either of prefix or suffix is empty, we just treat it as an empty string -*/ -message InnerOp { - HashOp hash = 1; - bytes prefix = 2; - bytes suffix = 3; -} - - -/** -ProofSpec defines what the expected parameters are for a given proof type. -This can be stored in the client and used to validate any incoming proofs. - - verify(ProofSpec, Proof) -> Proof | Error - -As demonstrated in tests, if we don't fix the algorithm used to calculate the -LeafHash for a given tree, there are many possible key-value pairs that can -generate a given hash (by interpretting the preimage differently). -We need this for proper security, requires client knows a priori what -tree format server uses. But not in code, rather a configuration object. -*/ -message ProofSpec { - // any field in the ExistenceProof must be the same as in this spec. - // except Prefix, which is just the first bytes of prefix (spec can be longer) - LeafOp leaf_spec = 1; - InnerSpec inner_spec = 2; - // max_depth (if > 0) is the maximum number of InnerOps allowed (mainly for fixed-depth tries) - int32 max_depth = 3; - // min_depth (if > 0) is the minimum number of InnerOps allowed (mainly for fixed-depth tries) - int32 min_depth = 4; -} - -/* -InnerSpec contains all store-specific structure info to determine if two proofs from a -given store are neighbors. - -This enables: - - isLeftMost(spec: InnerSpec, op: InnerOp) - isRightMost(spec: InnerSpec, op: InnerOp) - isLeftNeighbor(spec: InnerSpec, left: InnerOp, right: InnerOp) -*/ -message InnerSpec { - // Child order is the ordering of the children node, must count from 0 - // iavl tree is [0, 1] (left then right) - // merk is [0, 2, 1] (left, right, here) - repeated int32 child_order = 1; - int32 child_size = 2; - int32 min_prefix_length = 3; - int32 max_prefix_length = 4; - // empty child is the prehash image that is used when one child is nil (eg. 20 bytes of 0) - bytes empty_child = 5; - // hash is the algorithm that must be used for each InnerOp - HashOp hash = 6; -} - -/* -BatchProof is a group of multiple proof types than can be compressed -*/ -message BatchProof { - repeated BatchEntry entries = 1; -} - -// Use BatchEntry not CommitmentProof, to avoid recursion -message BatchEntry { - oneof proof { - ExistenceProof exist = 1; - NonExistenceProof nonexist = 2; - } -} - - -/****** all items here are compressed forms *******/ - -message CompressedBatchProof { - repeated CompressedBatchEntry entries = 1; - repeated InnerOp lookup_inners = 2; -} - -// Use BatchEntry not CommitmentProof, to avoid recursion -message CompressedBatchEntry { - oneof proof { - CompressedExistenceProof exist = 1; - CompressedNonExistenceProof nonexist = 2; - } -} - -message CompressedExistenceProof { - bytes key = 1; - bytes value = 2; - LeafOp leaf = 3; - // these are indexes into the lookup_inners table in CompressedBatchProof - repeated int32 path = 4; -} - -message CompressedNonExistenceProof { - bytes key = 1; // TODO: remove this as unnecessary??? we prove a range - CompressedExistenceProof left = 2; - CompressedExistenceProof right = 3; -} diff --git a/third_party/proto/tendermint/crypto/keys.proto b/third_party/proto/tendermint/crypto/keys.proto deleted file mode 100644 index 16fd7adf3ee..00000000000 --- a/third_party/proto/tendermint/crypto/keys.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package tendermint.crypto; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; - -import "gogoproto/gogo.proto"; - -// PublicKey defines the keys available for use with Tendermint Validators -message PublicKey { - option (gogoproto.compare) = true; - option (gogoproto.equal) = true; - - oneof sum { - bytes ed25519 = 1; - bytes secp256k1 = 2; - } -} diff --git a/third_party/proto/tendermint/crypto/proof.proto b/third_party/proto/tendermint/crypto/proof.proto deleted file mode 100644 index 975df768539..00000000000 --- a/third_party/proto/tendermint/crypto/proof.proto +++ /dev/null @@ -1,41 +0,0 @@ -syntax = "proto3"; -package tendermint.crypto; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; - -import "gogoproto/gogo.proto"; - -message Proof { - int64 total = 1; - int64 index = 2; - bytes leaf_hash = 3; - repeated bytes aunts = 4; -} - -message ValueOp { - // Encoded in ProofOp.Key. - bytes key = 1; - - // To encode in ProofOp.Data - Proof proof = 2; -} - -message DominoOp { - string key = 1; - string input = 2; - string output = 3; -} - -// ProofOp defines an operation used for calculating Merkle root -// The data could be arbitrary format, providing nessecary data -// for example neighbouring node hash -message ProofOp { - string type = 1; - bytes key = 2; - bytes data = 3; -} - -// ProofOps is Merkle proof defined by the list of ProofOps -message ProofOps { - repeated ProofOp ops = 1 [(gogoproto.nullable) = false]; -} diff --git a/third_party/proto/tendermint/libs/bits/types.proto b/third_party/proto/tendermint/libs/bits/types.proto deleted file mode 100644 index 3111d113a5b..00000000000 --- a/third_party/proto/tendermint/libs/bits/types.proto +++ /dev/null @@ -1,9 +0,0 @@ -syntax = "proto3"; -package tendermint.libs.bits; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/libs/bits"; - -message BitArray { - int64 bits = 1; - repeated uint64 elems = 2; -} diff --git a/third_party/proto/tendermint/types/types.proto b/third_party/proto/tendermint/types/types.proto deleted file mode 100644 index 7f7ea74cac2..00000000000 --- a/third_party/proto/tendermint/types/types.proto +++ /dev/null @@ -1,157 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "tendermint/crypto/proof.proto"; -import "tendermint/version/types.proto"; -import "tendermint/types/validator.proto"; - -// BlockIdFlag indicates which BlcokID the signature is for -enum BlockIDFlag { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; - BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; - BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; - BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; -} - -// SignedMsgType is a type of signed message in the consensus. -enum SignedMsgType { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - SIGNED_MSG_TYPE_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "UnknownType"]; - // Votes - SIGNED_MSG_TYPE_PREVOTE = 1 [(gogoproto.enumvalue_customname) = "PrevoteType"]; - SIGNED_MSG_TYPE_PRECOMMIT = 2 [(gogoproto.enumvalue_customname) = "PrecommitType"]; - - // Proposals - SIGNED_MSG_TYPE_PROPOSAL = 32 [(gogoproto.enumvalue_customname) = "ProposalType"]; -} - -// PartsetHeader -message PartSetHeader { - uint32 total = 1; - bytes hash = 2; -} - -message Part { - uint32 index = 1; - bytes bytes = 2; - tendermint.crypto.Proof proof = 3 [(gogoproto.nullable) = false]; -} - -// BlockID -message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; -} - -// -------------------------------- - -// Header defines the structure of a Tendermint block header. -message Header { - // basic block info - tendermint.version.Consensus version = 1 [(gogoproto.nullable) = false]; - string chain_id = 2 [(gogoproto.customname) = "ChainID"]; - int64 height = 3; - google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - - // prev block info - BlockID last_block_id = 5 [(gogoproto.nullable) = false]; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block -} - -// Data contains the set of transactions included in the block -message Data { - // Txs that will be applied by state @ block.Height+1. - // NOTE: not all txs here are valid. We're just agreeing on the order first. - // This means that block.AppHash does not include these txs. - repeated bytes txs = 1; -} - -// Vote represents a prevote, precommit, or commit vote from validators for -// consensus. -message Vote { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - BlockID block_id = 4 - [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; // zero if vote is nil. - google.protobuf.Timestamp timestamp = 5 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes validator_address = 6; - int32 validator_index = 7; - bytes signature = 8; -} - -// Commit contains the evidence that a block was committed by a set of validators. -message Commit { - int64 height = 1; - int32 round = 2; - BlockID block_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; - repeated CommitSig signatures = 4 [(gogoproto.nullable) = false]; -} - -// CommitSig is a part of the Vote included in a Commit. -message CommitSig { - BlockIDFlag block_id_flag = 1; - bytes validator_address = 2; - google.protobuf.Timestamp timestamp = 3 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 4; -} - -message Proposal { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - int32 pol_round = 4; - BlockID block_id = 5 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - google.protobuf.Timestamp timestamp = 6 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 7; -} - -message SignedHeader { - Header header = 1; - Commit commit = 2; -} - -message LightBlock { - SignedHeader signed_header = 1; - tendermint.types.ValidatorSet validator_set = 2; -} - -message BlockMeta { - BlockID block_id = 1 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - int64 block_size = 2; - Header header = 3 [(gogoproto.nullable) = false]; - int64 num_txs = 4; -} - -// TxProof represents a Merkle proof of the presence of a transaction in the Merkle tree. -message TxProof { - bytes root_hash = 1; - bytes data = 2; - tendermint.crypto.Proof proof = 3; -} diff --git a/third_party/proto/tendermint/types/validator.proto b/third_party/proto/tendermint/types/validator.proto deleted file mode 100644 index 49860b96d6b..00000000000 --- a/third_party/proto/tendermint/types/validator.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "tendermint/crypto/keys.proto"; - -message ValidatorSet { - repeated Validator validators = 1; - Validator proposer = 2; - int64 total_voting_power = 3; -} - -message Validator { - bytes address = 1; - tendermint.crypto.PublicKey pub_key = 2 [(gogoproto.nullable) = false]; - int64 voting_power = 3; - int64 proposer_priority = 4; -} - -message SimpleValidator { - tendermint.crypto.PublicKey pub_key = 1; - int64 voting_power = 2; -} diff --git a/third_party/proto/tendermint/version/types.proto b/third_party/proto/tendermint/version/types.proto deleted file mode 100644 index 6061868bd43..00000000000 --- a/third_party/proto/tendermint/version/types.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; -package tendermint.version; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/version"; - -import "gogoproto/gogo.proto"; - -// App includes the protocol and software version for the application. -// This information is included in ResponseInfo. The App.Protocol can be -// updated in ResponseEndBlock. -message App { - uint64 protocol = 1; - string software = 2; -} - -// Consensus captures the consensus rules for processing a block in the blockchain, -// including all blockchain data structures and the rules of the application's -// state transition machine. -message Consensus { - option (gogoproto.equal) = true; - - uint64 block = 1; - uint64 app = 2; -}