diff --git a/.github/mergify.yml b/.github/mergify.yml index d5228ffd826..54110ab1c91 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -16,8 +16,8 @@ pull_request_rules: name: default method: squash commit_message_template: | - {{ title }} (#{{ number }}) - {{ body }} + {{ title }} (#{{ number }}) + {{ body }} - name: backport patches to v1.0.x capability branch conditions: - base=main diff --git a/.github/workflows/golangci-feature.yml b/.github/workflows/golangci-feature.yml new file mode 100644 index 00000000000..2237a2ea736 --- /dev/null +++ b/.github/workflows/golangci-feature.yml @@ -0,0 +1,31 @@ +# golangci-feature runs on pull requests from branches that do not target main. +# +# Working on feature branches (PRs where the PR base-ref != main) is a common +# workflow used, in order to make the merging of PRs easier certain lints are excluded +# when it makes sense. Currently, unused lints are excluded since many PRs will add +# unused code that will be used in a later PR. +name: golangci-lint feature branch +on: + pull_request: + # Ignore if the target is main. (Negation of golanci-lint.yml) + branches-ignore: + - main +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@v4 + with: + go-version: '1.21' + - uses: actions/checkout@v4 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3.7.0 + with: + version: v1.54.2 + args: --timeout 10m \ No newline at end of file diff --git a/README.md b/README.md index 794211505e9..bb933781a34 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ This IBC implementation in Golang is built as a Cosmos SDK module. To understand ## Roadmap -For an overview of upcoming changes to ibc-go take a look at the [roadmap](./docs/docs/01-ibc/09-roadmap.md). +For an overview of upcoming changes to ibc-go take a look at the [roadmap](./docs/docs/01-ibc/10-roadmap.md). This roadmap is also available as a [project board](https://github.com/orgs/cosmos/projects/7/views/25). @@ -92,7 +92,7 @@ To report a security vulnerability, see our [Coordinated Vulnerability Disclosur The following audits have been performed on the `ibc-go` source code: -- [ICS27 Interchain Accounts](https://github.com/cosmos/ibc-go/blob/main/docs/audits/Trail%20of%20Bits%20audit%20-%20Final%20Report.pdf) by Trail of Bits +- [ICS27 Interchain Accounts](https://github.com/cosmos/ibc-go/blob/main/docs/audits/27-interchain-accounts/Trail%20of%20Bits%20audit%20-%20Final%20Report.pdf) by Trail of Bits ## Quick Navigation diff --git a/docs/client/swagger-ui/swagger.yaml b/docs/client/swagger-ui/swagger.yaml index 1a6b9d8f140..a40c2d3b353 100644 --- a/docs/client/swagger-ui/swagger.yaml +++ b/docs/client/swagger-ui/swagger.yaml @@ -698,6 +698,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -737,7 +741,6 @@ paths: name "y.z". - JSON @@ -1041,6 +1044,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -1080,7 +1087,6 @@ paths: name "y.z". - JSON @@ -1325,6 +1331,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -1364,7 +1374,6 @@ paths: name "y.z". - JSON @@ -1545,6 +1554,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -1584,7 +1597,6 @@ paths: name "y.z". - JSON @@ -1866,6 +1878,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -1905,7 +1921,6 @@ paths: name "y.z". - JSON @@ -2115,6 +2130,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -2154,7 +2173,6 @@ paths: name "y.z". - JSON @@ -2358,6 +2376,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -2397,7 +2419,6 @@ paths: name "y.z". - JSON @@ -2601,6 +2622,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -2640,7 +2665,6 @@ paths: name "y.z". - JSON @@ -2858,6 +2882,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -2897,7 +2925,6 @@ paths: name "y.z". - JSON @@ -3255,6 +3282,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -3294,7 +3325,6 @@ paths: name "y.z". - JSON @@ -3516,6 +3546,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -3555,7 +3589,6 @@ paths: name "y.z". - JSON @@ -3749,6 +3782,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -3788,7 +3825,6 @@ paths: name "y.z". - JSON @@ -3994,6 +4030,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -4033,7 +4073,6 @@ paths: name "y.z". - JSON @@ -4224,6 +4263,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -4263,7 +4306,6 @@ paths: name "y.z". - JSON @@ -4440,6 +4482,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -4479,7 +4525,6 @@ paths: name "y.z". - JSON @@ -4671,6 +4716,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -4710,7 +4759,6 @@ paths: name "y.z". - JSON @@ -4903,6 +4951,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -4942,7 +4994,6 @@ paths: name "y.z". - JSON @@ -5240,6 +5291,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -5279,7 +5334,6 @@ paths: name "y.z". - JSON @@ -5494,6 +5548,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -5533,7 +5591,6 @@ paths: name "y.z". - JSON @@ -5729,6 +5786,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -5768,7 +5829,6 @@ paths: name "y.z". - JSON @@ -5981,6 +6041,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6020,7 +6084,6 @@ paths: name "y.z". - JSON @@ -6169,6 +6232,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6208,7 +6275,6 @@ paths: name "y.z". - JSON @@ -6361,6 +6427,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6400,7 +6470,6 @@ paths: name "y.z". - JSON @@ -6549,6 +6618,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6588,7 +6661,6 @@ paths: name "y.z". - JSON @@ -6741,6 +6813,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -6780,7 +6856,6 @@ paths: name "y.z". - JSON @@ -6987,6 +7062,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -7026,7 +7105,6 @@ paths: name "y.z". - JSON @@ -7346,6 +7424,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -7385,7 +7467,6 @@ paths: name "y.z". - JSON @@ -7740,6 +7821,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -7779,7 +7864,6 @@ paths: name "y.z". - JSON @@ -7944,6 +8028,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -7983,7 +8071,6 @@ paths: name "y.z". - JSON @@ -8177,6 +8264,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -8216,7 +8307,6 @@ paths: name "y.z". - JSON @@ -8373,6 +8463,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -8412,7 +8506,6 @@ paths: name "y.z". - JSON @@ -8601,6 +8694,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -8640,7 +8737,6 @@ paths: name "y.z". - JSON @@ -8839,6 +8935,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -8878,7 +8978,6 @@ paths: name "y.z". - JSON @@ -8943,12 +9042,15 @@ paths: - STATE_TRYOPEN - STATE_OPEN - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE default: STATE_UNINITIALIZED_UNSPECIFIED description: >- State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or + UNINITIALIZED. - STATE_UNINITIALIZED_UNSPECIFIED: Default State - STATE_INIT: A channel has just started the opening handshake. @@ -8957,6 +9059,8 @@ paths: ready to send and receive packets. - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. ordering: title: whether the channel is ordered or unordered type: string @@ -9003,6 +9107,15 @@ paths: channel_id: type: string title: channel identifier + upgrade_sequence: + type: string + format: uint64 + title: >- + upgrade sequence indicates the latest upgrade attempt + performed by this channel + + the value of 0 indicates the channel has never been + upgraded description: >- IdentifiedChannel defines a channel with additional port and channel @@ -9183,6 +9296,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -9222,7 +9339,6 @@ paths: name "y.z". - JSON @@ -9343,12 +9459,15 @@ paths: - STATE_TRYOPEN - STATE_OPEN - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE default: STATE_UNINITIALIZED_UNSPECIFIED description: >- State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or + UNINITIALIZED. - STATE_UNINITIALIZED_UNSPECIFIED: Default State - STATE_INIT: A channel has just started the opening handshake. @@ -9357,6 +9476,8 @@ paths: ready to send and receive packets. - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. ordering: title: whether the channel is ordered or unordered type: string @@ -9396,6 +9517,15 @@ paths: title: >- opaque channel version, which is agreed upon during the handshake + upgrade_sequence: + type: string + format: uint64 + title: >- + upgrade sequence indicates the latest upgrade attempt + performed by this channel + + the value of 0 indicates the channel has never been + upgraded description: >- Channel defines pipeline for exactly-once packet delivery between specific @@ -9558,6 +9688,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -9597,7 +9731,6 @@ paths: name "y.z". - JSON @@ -9769,6 +9902,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -9808,7 +9945,6 @@ paths: name "y.z". - JSON @@ -10002,6 +10138,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -10041,7 +10181,6 @@ paths: name "y.z". - JSON @@ -10203,6 +10342,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -10242,7 +10385,6 @@ paths: name "y.z". - JSON @@ -10431,6 +10573,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -10470,7 +10616,6 @@ paths: name "y.z". - JSON @@ -10584,7 +10729,7 @@ paths: gets reset title: |- - QuerySequenceResponse is the request type for the + QuerySequenceResponse is the response type for the Query/QueryNextSequenceReceiveResponse RPC method default: description: An unexpected error response. @@ -10699,6 +10844,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -10738,7 +10887,6 @@ paths: name "y.z". - JSON @@ -10953,6 +11101,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -10992,7 +11144,6 @@ paths: name "y.z". - JSON @@ -11261,6 +11412,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -11300,7 +11455,6 @@ paths: name "y.z". - JSON @@ -11584,6 +11738,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -11623,7 +11781,6 @@ paths: name "y.z". - JSON @@ -11896,6 +12053,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -11935,7 +12096,6 @@ paths: name "y.z". - JSON @@ -12208,6 +12368,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -12247,7 +12411,6 @@ paths: name "y.z". - JSON @@ -12474,6 +12637,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -12513,7 +12680,6 @@ paths: name "y.z". - JSON @@ -12743,6 +12909,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -12782,7 +12952,6 @@ paths: name "y.z". - JSON @@ -13011,6 +13180,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -13050,7 +13223,6 @@ paths: name "y.z". - JSON @@ -13108,129 +13280,120 @@ paths: format: uint64 tags: - Query - /ibc/core/channel/v1/connections/{connection}/channels: + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/upgrade: get: - summary: |- - ConnectionChannels queries all the channels associated with a connection - end. - operationId: ConnectionChannels + summary: Upgrade returns the upgrade for a given port and channel id. + operationId: Upgrade responses: '200': description: A successful response. schema: type: object properties: - channels: - type: array - items: - type: object - properties: - state: - title: current state of the channel end - type: string - enum: - - STATE_UNINITIALIZED_UNSPECIFIED - - STATE_INIT - - STATE_TRYOPEN - - STATE_OPEN - - STATE_CLOSED - default: STATE_UNINITIALIZED_UNSPECIFIED - description: >- - State defines if a channel is in one of the following - states: + upgrade: + type: object + properties: + fields: + type: object + properties: + ordering: + type: string + enum: + - ORDER_NONE_UNSPECIFIED + - ORDER_UNORDERED + - ORDER_ORDERED + default: ORDER_NONE_UNSPECIFIED + description: >- + - ORDER_NONE_UNSPECIFIED: zero-value for channel + ordering + - ORDER_UNORDERED: packets can be delivered in any order, which may differ from the order in + which they were sent. + - ORDER_ORDERED: packets are delivered exactly in the order which they were sent + title: Order defines if a channel is ORDERED or UNORDERED + connection_hops: + type: array + items: + type: string + version: + type: string + description: >- + UpgradeFields are the fields in a channel end which may be + changed - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + during a channel upgrade. + timeout: + type: object + properties: + height: + title: >- + block height after which the packet or upgrade times + out + 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 - - STATE_UNINITIALIZED_UNSPECIFIED: Default State - - STATE_INIT: A channel has just started the opening handshake. - - STATE_TRYOPEN: A channel has acknowledged the handshake step on the counterparty chain. - - STATE_OPEN: A channel has completed the handshake. Open channels are - ready to send and receive packets. - - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive - packets. - ordering: - title: whether the channel is ordered or unordered - type: string - enum: - - ORDER_NONE_UNSPECIFIED - - ORDER_UNORDERED - - ORDER_ORDERED - default: ORDER_NONE_UNSPECIFIED - description: >- - - ORDER_NONE_UNSPECIFIED: zero-value for channel - ordering - - ORDER_UNORDERED: packets can be delivered in any order, which may differ from the order in - which they were sent. - - ORDER_ORDERED: packets are delivered exactly in the order which they were sent - counterparty: - title: counterparty channel end - type: object - properties: - port_id: - type: string - description: >- - port on the counterparty chain which owns the other - end of the channel. - channel_id: - type: string - title: channel end on the counterparty chain - connection_hops: - type: array - items: + 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 + timestamp: type: string - title: >- - list of connection identifiers, in order, along which - packets sent on + format: uint64 + title: >- + block timestamp (in nanoseconds) after which the + packet or upgrade times out + description: >- + Timeout defines an execution deadline structure for + 04-channel handlers. - this channel will travel - version: - type: string - title: >- - opaque channel version, which is agreed upon during the - handshake - port_id: - type: string - title: port identifier - channel_id: - type: string - title: channel identifier - description: >- - IdentifiedChannel defines a channel with additional port and - channel + This includes packet lifecycle handlers as well as the + upgrade handshake handlers. - identifier fields. - description: list of channels associated with a connection. - pagination: - title: pagination response - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: + A valid Timeout contains either one or both of a timestamp + and block height (sequence). + next_sequence_send: type: string format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise description: >- - PageResponse is to be embedded in gRPC response messages where - the + Upgrade is a verifiable type which contains the relevant + information - corresponding request message has used PageRequest. + for an attempted upgrade. It provides the proposed changes to + the channel - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } - height: - title: query block height + end, the timeout for this upgrade attempt and the next packet + sequence + + which allows the counterparty to efficiently know the highest + sequence it has received. + + The next sequence send is used for pruning and upgrading from + unordered to ordered channels. + 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: @@ -13258,9 +13421,9 @@ paths: RevisionHeight gets reset - title: |- - QueryConnectionChannelsResponse is the Response type for the - Query/QueryConnectionChannels RPC method + title: >- + QueryUpgradeResponse is the response type for the + QueryUpgradeResponse RPC method default: description: An unexpected error response. schema: @@ -13374,6 +13537,10 @@ paths: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -13413,7 +13580,6 @@ paths: name "y.z". - JSON @@ -13453,15 +13619,656 @@ paths: "value": "1.212s" } parameters: - - name: connection - description: connection unique identifier + - name: channel_id in: path required: true type: string - - name: pagination.key - description: |- - key is a value returned in PageResponse.next_key to begin - querying the next page most efficiently. Only one of offset or key + - name: port_id + in: path + required: true + type: string + tags: + - Query + /ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/upgrade_error: + get: + summary: UpgradeError returns the error receipt if the upgrade handshake failed. + operationId: UpgradeError + responses: + '200': + description: A successful response. + schema: + type: object + properties: + error_receipt: + type: object + properties: + sequence: + type: string + format: uint64 + title: the channel upgrade sequence + message: + type: string + title: the error message detailing the cause of failure + description: >- + 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. + 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: >- + QueryUpgradeErrorResponse is the response type for the + Query/QueryUpgradeError 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); + } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } + + 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" + } + parameters: + - name: channel_id + in: path + required: true + type: string + - name: port_id + in: path + required: true + type: string + tags: + - Query + /ibc/core/channel/v1/connections/{connection}/channels: + get: + summary: |- + ConnectionChannels queries all the channels associated with a connection + end. + operationId: ConnectionChannels + responses: + '200': + description: A successful response. + schema: + type: object + properties: + channels: + type: array + items: + type: object + properties: + state: + title: current state of the channel end + type: string + enum: + - STATE_UNINITIALIZED_UNSPECIFIED + - STATE_INIT + - STATE_TRYOPEN + - STATE_OPEN + - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE + default: STATE_UNINITIALIZED_UNSPECIFIED + description: >- + State defines if a channel is in one of the following + states: + + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or + UNINITIALIZED. + + - STATE_UNINITIALIZED_UNSPECIFIED: Default State + - STATE_INIT: A channel has just started the opening handshake. + - STATE_TRYOPEN: A channel has acknowledged the handshake step on the counterparty chain. + - STATE_OPEN: A channel has completed the handshake. Open channels are + ready to send and receive packets. + - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive + packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. + ordering: + title: whether the channel is ordered or unordered + type: string + enum: + - ORDER_NONE_UNSPECIFIED + - ORDER_UNORDERED + - ORDER_ORDERED + default: ORDER_NONE_UNSPECIFIED + description: >- + - ORDER_NONE_UNSPECIFIED: zero-value for channel + ordering + - ORDER_UNORDERED: packets can be delivered in any order, which may differ from the order in + which they were sent. + - ORDER_ORDERED: packets are delivered exactly in the order which they were sent + counterparty: + title: counterparty channel end + type: object + properties: + port_id: + type: string + description: >- + port on the counterparty chain which owns the other + end of the channel. + channel_id: + type: string + title: channel end on the counterparty chain + connection_hops: + type: array + items: + type: string + title: >- + list of connection identifiers, in order, along which + packets sent on + + this channel will travel + version: + type: string + title: >- + opaque channel version, which is agreed upon during the + handshake + port_id: + type: string + title: port identifier + channel_id: + type: string + title: channel identifier + upgrade_sequence: + type: string + format: uint64 + title: >- + upgrade sequence indicates the latest upgrade attempt + performed by this channel + + the value of 0 indicates the channel has never been + upgraded + description: >- + IdentifiedChannel defines a channel with additional port and + channel + + identifier fields. + description: list of channels associated with a connection. + pagination: + title: pagination response + type: object + properties: + next_key: + type: string + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: >- + 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; + } + height: + title: query block height + 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: |- + QueryConnectionChannelsResponse is the Response type for the + Query/QueryConnectionChannels 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); + } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } + + 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" + } + parameters: + - name: connection + description: connection unique identifier + in: path + required: true + type: string + - name: pagination.key + description: |- + 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. in: query required: false @@ -13471,49 +14278,311 @@ paths: description: >- 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 + It is less efficient than using key. Only one of offset or key + should + + be set. + in: query + required: false + type: string + format: uint64 + - name: pagination.limit + description: >- + 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. + in: query + required: false + type: string + format: uint64 + - name: pagination.count_total + description: >- + 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. + in: query + required: false + type: 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/params: + get: + summary: ChannelParams queries all parameters of the ibc channel submodule. + operationId: ChannelParams + responses: + '200': + description: A successful response. + schema: + type: object + properties: + params: + description: params defines the parameters of the module. + type: object + properties: + upgrade_timeout: + type: object + properties: + height: + title: >- + block height after which the packet or upgrade times + out + 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 + timestamp: + type: string + format: uint64 + title: >- + block timestamp (in nanoseconds) after which the + packet or upgrade times out + description: >- + Timeout defines an execution deadline structure for + 04-channel handlers. + + This includes packet lifecycle handlers as well as the + upgrade handshake handlers. + + A valid Timeout contains either one or both of a timestamp + and block height (sequence). + description: >- + QueryChannelParamsResponse is the response type for the + Query/ChannelParams 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. - be set. - in: query - required: false - type: string - format: uint64 - - name: pagination.limit - description: >- - 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. - in: query - required: false - type: string - format: uint64 - - name: pagination.count_total - description: >- - count_total is set to true to indicate that the result set should - include + Protobuf library provides support to pack/unpack Any values + in the form - a count of the total number of items available for pagination in - UIs. + of utility functions or additional generated methods of the + Any type. - count_total is only respected when offset is used. It is ignored - when key - is set. - in: query - required: false - type: boolean - - name: pagination.reverse - description: >- - reverse is set to true if results are to be returned in the - descending order. + 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. - Since: cosmos-sdk 0.43 - in: query - required: false - type: boolean + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } + + 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 definitions: @@ -13694,6 +14763,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -13729,7 +14802,6 @@ definitions: name "y.z". - JSON @@ -13870,6 +14942,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -13905,7 +14981,6 @@ definitions: name "y.z". - JSON @@ -15045,6 +16120,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -15080,7 +16159,6 @@ definitions: name "y.z". - JSON @@ -15244,6 +16322,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -15279,7 +16361,6 @@ definitions: name "y.z". - JSON @@ -15452,6 +16533,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -15487,7 +16572,6 @@ definitions: name "y.z". - JSON @@ -15671,6 +16755,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -15709,7 +16797,6 @@ definitions: name "y.z". - JSON @@ -15958,6 +17045,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -15993,7 +17084,6 @@ definitions: name "y.z". - JSON @@ -16208,6 +17298,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -16246,7 +17340,6 @@ definitions: name "y.z". - JSON @@ -16413,6 +17506,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -16448,7 +17545,6 @@ definitions: name "y.z". - JSON @@ -16581,6 +17677,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -16616,7 +17716,6 @@ definitions: name "y.z". - JSON @@ -17027,6 +18126,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -17063,7 +18166,6 @@ definitions: name "y.z". - JSON @@ -17232,6 +18334,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -17267,7 +18373,6 @@ definitions: name "y.z". - JSON @@ -17683,10 +18788,12 @@ definitions: - STATE_TRYOPEN - STATE_OPEN - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE default: STATE_UNINITIALIZED_UNSPECIFIED description: |- State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or UNINITIALIZED. - STATE_UNINITIALIZED_UNSPECIFIED: Default State - STATE_INIT: A channel has just started the opening handshake. @@ -17695,6 +18802,8 @@ definitions: ready to send and receive packets. - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. ordering: title: whether the channel is ordered or unordered type: string @@ -17730,6 +18839,14 @@ definitions: version: type: string title: opaque channel version, which is agreed upon during the handshake + upgrade_sequence: + type: string + format: uint64 + title: >- + upgrade sequence indicates the latest upgrade attempt performed by + this channel + + the value of 0 indicates the channel has never been upgraded description: |- Channel defines pipeline for exactly-once packet delivery between specific modules on separate blockchains, which has at least one end capable of @@ -17746,6 +18863,24 @@ definitions: type: string title: channel end on the counterparty chain title: Counterparty defines a channel end counterparty + ibc.core.channel.v1.ErrorReceipt: + type: object + properties: + sequence: + type: string + format: uint64 + title: the channel upgrade sequence + message: + type: string + title: the error message detailing the cause of failure + description: >- + 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. ibc.core.channel.v1.IdentifiedChannel: type: object properties: @@ -17758,10 +18893,12 @@ definitions: - STATE_TRYOPEN - STATE_OPEN - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE default: STATE_UNINITIALIZED_UNSPECIFIED description: |- State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or UNINITIALIZED. - STATE_UNINITIALIZED_UNSPECIFIED: Default State - STATE_INIT: A channel has just started the opening handshake. @@ -17770,6 +18907,8 @@ definitions: ready to send and receive packets. - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. ordering: title: whether the channel is ordered or unordered type: string @@ -17811,6 +18950,14 @@ definitions: channel_id: type: string title: channel identifier + upgrade_sequence: + type: string + format: uint64 + title: >- + upgrade sequence indicates the latest upgrade attempt performed by + this channel + + the value of 0 indicates the channel has never been upgraded description: |- IdentifiedChannel defines a channel with additional port and channel identifier fields. @@ -17849,6 +18996,57 @@ definitions: packet commitments, acknowledgements, and receipts. Caller is responsible for knowing the context necessary to interpret this state as a commitment, acknowledgement, or a receipt. + ibc.core.channel.v1.Params: + type: object + properties: + upgrade_timeout: + type: object + properties: + height: + title: block height after which the packet or upgrade times out + 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 + timestamp: + type: string + format: uint64 + title: >- + block timestamp (in nanoseconds) after which the packet or upgrade + times out + description: >- + Timeout defines an execution deadline structure for 04-channel + handlers. + + This includes packet lifecycle handlers as well as the upgrade + handshake handlers. + + A valid Timeout contains either one or both of a timestamp and block + height (sequence). + description: Params defines the set of IBC channel parameters. ibc.core.channel.v1.QueryChannelClientStateResponse: type: object properties: @@ -17955,6 +19153,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -17991,7 +19193,6 @@ definitions: name "y.z". - JSON @@ -18160,6 +19361,10 @@ definitions: if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } + // or ... + if (any.isSameTypeAs(Foo.getDefaultInstance())) { + foo = any.unpack(Foo.getDefaultInstance()); + } Example 3: Pack and unpack a message in Python. @@ -18195,7 +19400,6 @@ definitions: name "y.z". - JSON @@ -18268,6 +19472,63 @@ definitions: title: |- QueryChannelClientStateResponse is the Response type for the Query/QueryChannelClientState RPC method + ibc.core.channel.v1.QueryChannelParamsResponse: + type: object + properties: + params: + description: params defines the parameters of the module. + type: object + properties: + upgrade_timeout: + type: object + properties: + height: + title: block height after which the packet or upgrade times out + 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 + timestamp: + type: string + format: uint64 + title: >- + block timestamp (in nanoseconds) after which the packet or + upgrade times out + description: >- + Timeout defines an execution deadline structure for 04-channel + handlers. + + This includes packet lifecycle handlers as well as the upgrade + handshake handlers. + + A valid Timeout contains either one or both of a timestamp and + block height (sequence). + description: >- + QueryChannelParamsResponse is the response type for the + Query/ChannelParams RPC method. ibc.core.channel.v1.QueryChannelResponse: type: object properties: @@ -18284,10 +19545,14 @@ definitions: - STATE_TRYOPEN - STATE_OPEN - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE default: STATE_UNINITIALIZED_UNSPECIFIED - description: |- + description: >- State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or + UNINITIALIZED. - STATE_UNINITIALIZED_UNSPECIFIED: Default State - STATE_INIT: A channel has just started the opening handshake. @@ -18296,6 +19561,8 @@ definitions: ready to send and receive packets. - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. ordering: title: whether the channel is ordered or unordered type: string @@ -18333,6 +19600,14 @@ definitions: version: type: string title: opaque channel version, which is agreed upon during the handshake + upgrade_sequence: + type: string + format: uint64 + title: >- + upgrade sequence indicates the latest upgrade attempt performed by + this channel + + the value of 0 indicates the channel has never been upgraded description: >- Channel defines pipeline for exactly-once packet delivery between specific @@ -18396,10 +19671,14 @@ definitions: - STATE_TRYOPEN - STATE_OPEN - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE default: STATE_UNINITIALIZED_UNSPECIFIED - description: |- + description: >- State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or + UNINITIALIZED. - STATE_UNINITIALIZED_UNSPECIFIED: Default State - STATE_INIT: A channel has just started the opening handshake. @@ -18408,6 +19687,8 @@ definitions: ready to send and receive packets. - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. ordering: title: whether the channel is ordered or unordered type: string @@ -18453,6 +19734,14 @@ definitions: channel_id: type: string title: channel identifier + upgrade_sequence: + type: string + format: uint64 + title: >- + upgrade sequence indicates the latest upgrade attempt performed + by this channel + + the value of 0 indicates the channel has never been upgraded description: |- IdentifiedChannel defines a channel with additional port and channel identifier fields. @@ -18532,10 +19821,14 @@ definitions: - STATE_TRYOPEN - STATE_OPEN - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE default: STATE_UNINITIALIZED_UNSPECIFIED - description: |- + description: >- State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or + UNINITIALIZED. - STATE_UNINITIALIZED_UNSPECIFIED: Default State - STATE_INIT: A channel has just started the opening handshake. @@ -18544,6 +19837,8 @@ definitions: ready to send and receive packets. - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. ordering: title: whether the channel is ordered or unordered type: string @@ -18589,6 +19884,14 @@ definitions: channel_id: type: string title: channel identifier + upgrade_sequence: + type: string + format: uint64 + title: >- + upgrade sequence indicates the latest upgrade attempt performed + by this channel + + the value of 0 indicates the channel has never been upgraded description: |- IdentifiedChannel defines a channel with additional port and channel identifier fields. @@ -18691,7 +19994,7 @@ definitions: gets reset title: |- - QuerySequenceResponse is the request type for the + QuerySequenceResponse is the response type for the Query/QueryNextSequenceReceiveResponse RPC method ibc.core.channel.v1.QueryNextSequenceSendResponse: type: object @@ -19127,6 +20430,191 @@ definitions: title: |- QueryUnreceivedPacketsResponse is the response type for the Query/UnreceivedPacketCommitments RPC method + ibc.core.channel.v1.QueryUpgradeErrorResponse: + type: object + properties: + error_receipt: + type: object + properties: + sequence: + type: string + format: uint64 + title: the channel upgrade sequence + message: + type: string + title: the error message detailing the cause of failure + description: >- + 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. + 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: >- + QueryUpgradeErrorResponse is the response type for the + Query/QueryUpgradeError RPC method + ibc.core.channel.v1.QueryUpgradeResponse: + type: object + properties: + upgrade: + type: object + properties: + fields: + type: object + properties: + ordering: + type: string + enum: + - ORDER_NONE_UNSPECIFIED + - ORDER_UNORDERED + - ORDER_ORDERED + default: ORDER_NONE_UNSPECIFIED + description: |- + - ORDER_NONE_UNSPECIFIED: zero-value for channel ordering + - ORDER_UNORDERED: packets can be delivered in any order, which may differ from the order in + which they were sent. + - ORDER_ORDERED: packets are delivered exactly in the order which they were sent + title: Order defines if a channel is ORDERED or UNORDERED + connection_hops: + type: array + items: + type: string + version: + type: string + description: |- + UpgradeFields are the fields in a channel end which may be changed + during a channel upgrade. + timeout: + type: object + properties: + height: + title: block height after which the packet or upgrade times out + 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 + timestamp: + type: string + format: uint64 + title: >- + block timestamp (in nanoseconds) after which the packet or + upgrade times out + description: >- + Timeout defines an execution deadline structure for 04-channel + handlers. + + This includes packet lifecycle handlers as well as the upgrade + handshake handlers. + + A valid Timeout contains either one or both of a timestamp and + block height (sequence). + next_sequence_send: + type: string + format: uint64 + description: >- + Upgrade is a verifiable type which contains the relevant information + + for an attempted upgrade. It provides the proposed changes to the + channel + + end, the timeout for this upgrade attempt and the next packet sequence + + which allows the counterparty to efficiently know the highest sequence + it has received. + + The next sequence send is used for pruning and upgrading from + unordered to ordered channels. + 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: >- + QueryUpgradeResponse is the response type for the QueryUpgradeResponse RPC + method ibc.core.channel.v1.State: type: string enum: @@ -19135,10 +20623,12 @@ definitions: - STATE_TRYOPEN - STATE_OPEN - STATE_CLOSED + - STATE_FLUSHING + - STATE_FLUSHCOMPLETE default: STATE_UNINITIALIZED_UNSPECIFIED description: |- State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or UNINITIALIZED. - STATE_UNINITIALIZED_UNSPECIFIED: Default State - STATE_INIT: A channel has just started the opening handshake. @@ -19146,4 +20636,166 @@ definitions: - STATE_OPEN: A channel has completed the handshake. Open channels are ready to send and receive packets. - STATE_CLOSED: A channel has been closed and can no longer be used to send or receive - packets. \ No newline at end of file + packets. + - STATE_FLUSHING: A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + - STATE_FLUSHCOMPLETE: A channel has just completed flushing any in-flight packets. + ibc.core.channel.v1.Timeout: + type: object + properties: + height: + title: block height after which the packet or upgrade times out + 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 + timestamp: + type: string + format: uint64 + title: >- + block timestamp (in nanoseconds) after which the packet or upgrade + times out + description: >- + Timeout defines an execution deadline structure for 04-channel handlers. + + This includes packet lifecycle handlers as well as the upgrade handshake + handlers. + + A valid Timeout contains either one or both of a timestamp and block + height (sequence). + ibc.core.channel.v1.Upgrade: + type: object + properties: + fields: + type: object + properties: + ordering: + type: string + enum: + - ORDER_NONE_UNSPECIFIED + - ORDER_UNORDERED + - ORDER_ORDERED + default: ORDER_NONE_UNSPECIFIED + description: |- + - ORDER_NONE_UNSPECIFIED: zero-value for channel ordering + - ORDER_UNORDERED: packets can be delivered in any order, which may differ from the order in + which they were sent. + - ORDER_ORDERED: packets are delivered exactly in the order which they were sent + title: Order defines if a channel is ORDERED or UNORDERED + connection_hops: + type: array + items: + type: string + version: + type: string + description: |- + UpgradeFields are the fields in a channel end which may be changed + during a channel upgrade. + timeout: + type: object + properties: + height: + title: block height after which the packet or upgrade times out + 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 + timestamp: + type: string + format: uint64 + title: >- + block timestamp (in nanoseconds) after which the packet or upgrade + times out + description: >- + Timeout defines an execution deadline structure for 04-channel + handlers. + + This includes packet lifecycle handlers as well as the upgrade + handshake handlers. + + A valid Timeout contains either one or both of a timestamp and block + height (sequence). + next_sequence_send: + type: string + format: uint64 + description: >- + Upgrade is a verifiable type which contains the relevant information + + for an attempted upgrade. It provides the proposed changes to the channel + + end, the timeout for this upgrade attempt and the next packet sequence + + which allows the counterparty to efficiently know the highest sequence it + has received. + + The next sequence send is used for pruning and upgrading from unordered to + ordered channels. + ibc.core.channel.v1.UpgradeFields: + type: object + properties: + ordering: + type: string + enum: + - ORDER_NONE_UNSPECIFIED + - ORDER_UNORDERED + - ORDER_ORDERED + default: ORDER_NONE_UNSPECIFIED + description: |- + - ORDER_NONE_UNSPECIFIED: zero-value for channel ordering + - ORDER_UNORDERED: packets can be delivered in any order, which may differ from the order in + which they were sent. + - ORDER_ORDERED: packets are delivered exactly in the order which they were sent + title: Order defines if a channel is ORDERED or UNORDERED + connection_hops: + type: array + items: + type: string + version: + type: string + description: |- + UpgradeFields are the fields in a channel end which may be changed + during a channel upgrade. diff --git a/docs/docs/01-ibc/06-channel-upgrades.md b/docs/docs/01-ibc/06-channel-upgrades.md new file mode 100644 index 00000000000..6bc445b2bc7 --- /dev/null +++ b/docs/docs/01-ibc/06-channel-upgrades.md @@ -0,0 +1,92 @@ +--- +title: Channel Upgrades +sidebar_label: Channel Upgrades +sidebar_position: 6 +slug: /ibc/channel-upgrades +--- + +# Channel Upgrades + +:::note Synopsis +Learn how to upgrade existing IBC channels. +::: + +Channel upgradability is an IBC-level protocol that allows chains to leverage new application and channel features without having to create new channels or perform a network-wide upgrade. + +Prior to this feature, developers who wanted to update an application module or add a middleware to their application flow would need to create a new channel in order to use the updated application feature/middleware, resulting in a loss of the accumulated state/liquidity, token fungibility (as the channel ID is encoded in the IBC denom), and any other larger network effects of losing usage of the existing channel from relayers monitoring, etc. + +With channel upgradability, applications will be able to implement features such as but not limited to: potentially adding [denom metadata to tokens](https://github.com/cosmos/ibc/discussions/719), or utilizing the [fee middleware](https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment), all while maintaining the channels on which they currently operate. + +This document outlines the channel upgrade feature, and the multiple steps used in the upgrade process. + +## Channel Upgrade Handshake + +Channel upgrades will be achieved using a handshake process that is designed to be similar to the standard connection/channel opening handshake. + +```go +type Channel struct { + // current state of the channel end + State State `protobuf:"varint,1,opt,name=state,proto3,enum=ibc.core.channel.v1.State" json:"state,omitempty"` + // whether the channel is ordered or unordered + Ordering Order `protobuf:"varint,2,opt,name=ordering,proto3,enum=ibc.core.channel.v1.Order" json:"ordering,omitempty"` + // counterparty channel end + Counterparty Counterparty `protobuf:"bytes,3,opt,name=counterparty,proto3" json:"counterparty"` + // list of connection identifiers, in order, along which packets sent on + // this channel will travel + ConnectionHops []string `protobuf:"bytes,4,rep,name=connection_hops,json=connectionHops,proto3" json:"connection_hops,omitempty"` + // opaque channel version, which is agreed upon during the handshake + Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + UpgradeSequence uint64 `protobuf:"varint,6,opt,name=upgrade_sequence,json=upgradeSequence,proto3" json:"upgrade_sequence,omitempty"` +} +``` + +The version, connection hops, and channel ordering are fields in this channel struct which can be changed. For example, the fee middleware can be added to an application module by updating the version string [shown here](https://github.com/cosmos/ibc-go/blob/995b647381b909e9d6065d6c21004f18fab37f55/modules/apps/29-fee/types/metadata.pb.go#L28). However, although connection hops can change in a channel upgrade, both sides must still be each other's counterparty. This is enforced by the upgrade protocol and upgrade attempts which try to alter an expected counterparty will fail. + +On a high level, successful handshake process for channel upgrades works as follows: + +1. The chain initiating the upgrade process will propose an upgrade. +2. If the counterparty agrees with the proposal, it will block sends and begin flushing any in-flight packets on its channel end. This flushing process will be covered in more detail below. +3. Upon successful completion of the previous step, the initiating chain will also block packet sends and begin flushing any in-flight packets on its channel end. +4. Once both channel ends have completed flushing packets within the upgrade timeout window, both channel ends can be opened and upgraded to the new channel fields. + +Each handshake step will be documented below in greater detail. + +## Initializing a Channel Upgrade + +A channel upgrade is initialised by submitting the `ChanUpgradeInit` message, which can be submitted only by the chain itself upon governance authorization. This message should specify an appropriate timeout window for the upgrade. It is possible to upgrade the channel ordering, the channel connection hops, and the channel version. + +As part of the handling of the `ChanUpgradeInit` message, the application's callbacks `OnChanUpgradeInit` will be triggered as well. + +After this message is handled successfully, the channel's upgrade sequence will be incremented. This upgrade sequence will serve as a nonce for the upgrade process to provide replay protection. + +### Governance gating on `ChanUpgradeInit` + +The message signer for `MsgChanUpgradeInit` must be the address which has been designated as the `authority` of the `IBCKeeper`. If this proposal passes, the counterparty's channel will upgrade by default. + +If chains want to initiate the upgrade of many channels, they will need to submit a governance proposal with multiple `MsgChanUpgradeInit` messages, one for each channel they would like to upgrade, again with message signer as the designated `authority` of the `IBCKeeper` + +## Cancelling a Channel Upgrade + +Channel upgrade cancellation is performed by submitting a `MsgChannelUpgradeCancel` message. + +It is possible for the authority to cancel an in-progress channel upgrade if the following are true: + +- The signer is the authority +- The channel state has not reached FLUSHCOMPLETE +- If the channel state has reached FLUSHCOMPLETE, an existence proof of an `ErrorReceipt` on the counterparty chain is provided at our upgrade sequence or greater + +It is possible for a relayer to cancel an in-progress channel upgrade if the following are true: + +- An existence proof of an `ErrorReceipt` on the counterparty chain is provided at our upgrade sequence or greater + +> Note: if the signer is the authority, e.g. the `gov` address, no `ErrorReceipt` or proof is required if the current channel state is not in FLUSHCOMPLETE. +> These can be left empty in the `MsgChannelUpgradeCancel` message in that case. + +Upon cancelling a channel upgrade, an `ErrorReceipt` will be written with the channel's current upgrade sequence, and +the channel will move back to `OPEN` state keeping its original parameters. + +The application's `OnChanUpgradeRestore` callback method will be invoked. + +It will then be possible to re-initiate an upgrade by sending a `MsgChannelOpenInit` message. diff --git a/docs/docs/01-ibc/06-proposals.md b/docs/docs/01-ibc/07-proposals.md similarity index 98% rename from docs/docs/01-ibc/06-proposals.md rename to docs/docs/01-ibc/07-proposals.md index 2d8d8ba1e06..5a4057c1955 100644 --- a/docs/docs/01-ibc/06-proposals.md +++ b/docs/docs/01-ibc/07-proposals.md @@ -1,7 +1,7 @@ --- title: Governance Proposals sidebar_label: Governance Proposals -sidebar_position: 6 +sidebar_position: 7 slug: /ibc/proposals --- @@ -79,7 +79,7 @@ The client is attached to the expected Akash `chain_id`. Note that although the ### Step 2 Anyone can submit the governance proposal to recover the client by executing the following via CLI. -If the chain is on an ibc-go version older than v8, please see the [relevant documentation](https://ibc.cosmos.network/v7.3.x/ibc/proposals.html). +If the chain is on an ibc-go version older than v8, please see the [relevant documentation](https://ibc.cosmos.network/v7/ibc/proposals.html). - From ibc-go v8 onwards diff --git a/docs/docs/01-ibc/07-relayer.md b/docs/docs/01-ibc/08-relayer.md similarity index 99% rename from docs/docs/01-ibc/07-relayer.md rename to docs/docs/01-ibc/08-relayer.md index f40e9e671a3..100d68fc77a 100644 --- a/docs/docs/01-ibc/07-relayer.md +++ b/docs/docs/01-ibc/08-relayer.md @@ -1,7 +1,7 @@ --- title: Relayer sidebar_label: Relayer -sidebar_position: 7 +sidebar_position: 8 slug: /ibc/relayer --- diff --git a/docs/docs/01-ibc/08-proto-docs.md b/docs/docs/01-ibc/09-proto-docs.md similarity index 91% rename from docs/docs/01-ibc/08-proto-docs.md rename to docs/docs/01-ibc/09-proto-docs.md index e1e87fb2845..1666d3b7dd2 100644 --- a/docs/docs/01-ibc/08-proto-docs.md +++ b/docs/docs/01-ibc/09-proto-docs.md @@ -1,7 +1,7 @@ --- title: Protobuf Documentation sidebar_label: Protobuf Documentation -sidebar_position: 8 +sidebar_position: 9 slug: /ibc/proto-docs --- diff --git a/docs/docs/01-ibc/09-roadmap.md b/docs/docs/01-ibc/10-roadmap.md similarity index 99% rename from docs/docs/01-ibc/09-roadmap.md rename to docs/docs/01-ibc/10-roadmap.md index a4e1836d273..1d579a93a9a 100644 --- a/docs/docs/01-ibc/09-roadmap.md +++ b/docs/docs/01-ibc/10-roadmap.md @@ -1,7 +1,7 @@ --- title: Roadmap sidebar_label: Roadmap -sidebar_position: 9 +sidebar_position: 10 slug: /ibc/roadmap --- diff --git a/docs/docs/01-ibc/10-troubleshooting.md b/docs/docs/01-ibc/11-troubleshooting.md similarity index 95% rename from docs/docs/01-ibc/10-troubleshooting.md rename to docs/docs/01-ibc/11-troubleshooting.md index 0504a993b17..ba9dde39256 100644 --- a/docs/docs/01-ibc/10-troubleshooting.md +++ b/docs/docs/01-ibc/11-troubleshooting.md @@ -1,7 +1,7 @@ --- title: Troubleshooting sidebar_label: Troubleshooting -sidebar_position: 10 +sidebar_position: 11 slug: /ibc/troubleshooting --- diff --git a/docs/docs/01-ibc/11-capability-module.md b/docs/docs/01-ibc/12-capability-module.md similarity index 99% rename from docs/docs/01-ibc/11-capability-module.md rename to docs/docs/01-ibc/12-capability-module.md index d8bd27108ce..05db8a887eb 100644 --- a/docs/docs/01-ibc/11-capability-module.md +++ b/docs/docs/01-ibc/12-capability-module.md @@ -1,7 +1,7 @@ --- title: Capability Module sidebar_label: Capability Module -sidebar_position: 11 +sidebar_position: 12 slug: /ibc/capability-module --- diff --git a/docs/docs/05-migrations/02-sdk-to-v1.md b/docs/docs/05-migrations/02-sdk-to-v1.md index e24c0f62bb6..88022435f64 100644 --- a/docs/docs/05-migrations/02-sdk-to-v1.md +++ b/docs/docs/05-migrations/02-sdk-to-v1.md @@ -112,7 +112,7 @@ app.IBCKeeper = ibckeeper.NewKeeper( ### UpdateClientProposal -The `UpdateClient` has been modified to take in two client-identifiers and one initial height. Please see the [documentation](../01-ibc/06-proposals.md) for more information. +The `UpdateClient` has been modified to take in two client-identifiers and one initial height. Please see the [documentation](../01-ibc/07-proposals.md) for more information. ### UpgradeProposal diff --git a/modules/apps/27-interchain-accounts/controller/ibc_middleware.go b/modules/apps/27-interchain-accounts/controller/ibc_middleware.go index b51592a12d8..199c4f2d9da 100644 --- a/modules/apps/27-interchain-accounts/controller/ibc_middleware.go +++ b/modules/apps/27-interchain-accounts/controller/ibc_middleware.go @@ -22,6 +22,7 @@ import ( var ( _ porttypes.Middleware = (*IBCMiddleware)(nil) _ porttypes.PacketDataUnmarshaler = (*IBCMiddleware)(nil) + _ porttypes.UpgradableModule = (*IBCMiddleware)(nil) ) // IBCMiddleware implements the ICS26 callbacks for the fee middleware given the @@ -231,6 +232,100 @@ func (im IBCMiddleware) OnTimeoutPacket( return nil } +// OnChanUpgradeInit implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeInit(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) (string, error) { + if !im.keeper.GetParams(ctx).ControllerEnabled { + return "", types.ErrControllerSubModuleDisabled + } + + version, err := im.keeper.OnChanUpgradeInit(ctx, portID, channelID, order, connectionHops, version) + if 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) { + // Only cast to UpgradableModule if the application is set. + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + return "", errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack") + } + return cbs.OnChanUpgradeInit(ctx, portID, channelID, order, connectionHops, version) + } + + return version, nil +} + +// OnChanUpgradeTry implements the IBCModule interface +func (IBCMiddleware) OnChanUpgradeTry(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, counterpartyVersion string) (string, error) { + return "", errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel upgrade handshake must be initiated by controller chain") +} + +// OnChanUpgradeAck implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, counterpartyVersion string) error { + if !im.keeper.GetParams(ctx).ControllerEnabled { + return types.ErrControllerSubModuleDisabled + } + + if err := im.keeper.OnChanUpgradeAck(ctx, portID, channelID, counterpartyVersion); 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) { + // Only cast to UpgradableModule if the application is set. + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + return errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack") + } + return cbs.OnChanUpgradeAck(ctx, portID, channelID, counterpartyVersion) + } + + return nil +} + +// OnChanUpgradeOpen implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeOpen(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) { + connectionID, err := im.keeper.GetConnectionID(ctx, portID, channelID) + if err != nil { + panic(err) + } + + if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, portID, connectionID) { + // Only cast to UpgradableModule if the application is set. + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + panic(errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack")) + } + cbs.OnChanUpgradeOpen(ctx, portID, channelID, order, connectionHops, version) + } +} + +// OnChanUpgradeRestore implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeRestore(ctx sdk.Context, portID, channelID string) { + connectionID, err := im.keeper.GetConnectionID(ctx, portID, channelID) + if err != nil { + panic(err) + } + + if im.app != nil && im.keeper.IsMiddlewareEnabled(ctx, portID, connectionID) { + // Only cast to UpgradableModule if the application is set. + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + panic(errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack")) + } + cbs.OnChanUpgradeRestore(ctx, portID, channelID) + } +} + // SendPacket implements the ICS4 Wrapper interface func (IBCMiddleware) SendPacket( ctx sdk.Context, 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 3394c1af332..568edb2b031 100644 --- a/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go +++ b/modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go @@ -18,8 +18,11 @@ import ( porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v8/testing" + ibcmock "github.com/cosmos/ibc-go/v8/testing/mock" ) +const invalidVersion = "invalid|version" + var ( // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" @@ -327,7 +330,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenAck() { }, { "ICA OnChanOpenACK fails - invalid version", func() { - path.EndpointB.ChannelConfig.Version = "invalid|version" + path.EndpointB.ChannelConfig.Version = invalidVersion }, false, }, { @@ -762,6 +765,331 @@ func (suite *InterchainAccountsTestSuite) TestOnTimeoutPacket() { } } +func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeInit() { + var ( + path *ibctesting.Path + isNilApp bool + version string + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", func() {}, nil, + }, + { + "success: nil underlying app", + func() { + isNilApp = true + }, + nil, + }, + { + "controller submodule disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.SetParams(suite.chainA.GetContext(), types.NewParams(false)) + }, types.ErrControllerSubModuleDisabled, + }, + { + "ICA OnChanUpgradeInit fails - invalid version", func() { + version = invalidVersion + }, icatypes.ErrUnknownDataType, + }, + { + "ICA auth module callback fails", func() { + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanUpgradeInit = func(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) (string, error) { + return "", ibcmock.MockApplicationCallbackError + } + }, ibcmock.MockApplicationCallbackError, + }, + { + "middleware disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.DeleteMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanUpgradeInit = func(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) (string, error) { + return "", ibcmock.MockApplicationCallbackError + } + }, nil, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false + + path = NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) + + metadata := icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + + tc.malleate() // malleate mutates test data + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) + + app, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + + version, err = cbs.OnChanUpgradeInit( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + channeltypes.ORDERED, + []string{path.EndpointA.ConnectionID}, + version, + ) + + if tc.expError == nil { + suite.Require().NoError(err) + } else { + suite.Require().ErrorIs(err, tc.expError) + suite.Require().Empty(version) + } + }) + } +} + +func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeAck() { + var ( + path *ibctesting.Path + isNilApp bool + counterpartyVersion string + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", func() {}, nil, + }, + { + "success: nil underlying app", + func() { + isNilApp = true + }, + nil, + }, + { + "controller submodule disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.SetParams(suite.chainA.GetContext(), types.NewParams(false)) + }, types.ErrControllerSubModuleDisabled, + }, + { + "ICA OnChanUpgradeAck fails - invalid version", func() { + counterpartyVersion = invalidVersion + }, icatypes.ErrUnknownDataType, + }, + { + "ICA auth module callback fails", func() { + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanUpgradeAck = func(ctx sdk.Context, portID, channelID string, counterpartyVersion string) error { + return ibcmock.MockApplicationCallbackError + } + }, ibcmock.MockApplicationCallbackError, + }, + { + "middleware disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.DeleteMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanUpgradeAck = func(ctx sdk.Context, portID, channelID string, counterpartyVersion string) error { + return ibcmock.MockApplicationCallbackError + } + }, nil, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false + + path = NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + counterpartyVersion = path.EndpointB.GetChannel().Version + + tc.malleate() // malleate mutates test data + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) + + app, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + + err = cbs.OnChanUpgradeAck( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + counterpartyVersion, + ) + + if tc.expError == nil { + suite.Require().NoError(err) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} + +func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeOpen() { + var ( + path *ibctesting.Path + isNilApp bool + counterpartyVersion string + ) + + testCases := []struct { + name string + malleate func() + }{ + { + "success", + func() {}, + }, + { + "success: nil app", + func() { + isNilApp = true + }, + }, + { + "middleware disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.DeleteMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanUpgradeAck = func(ctx sdk.Context, portID, channelID string, counterpartyVersion string) error { + return ibcmock.MockApplicationCallbackError + } + }, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false + + path = NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + counterpartyVersion = path.EndpointB.GetChannel().Version + + tc.malleate() // malleate mutates test data + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) + + app, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + + cbs.OnChanUpgradeOpen( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + channeltypes.ORDERED, + []string{path.EndpointA.ConnectionID}, + counterpartyVersion, + ) + }) + } +} + +func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeRestore() { + var ( + path *ibctesting.Path + isNilApp bool + ) + + testCases := []struct { + name string + malleate func() + }{ + { + "success", func() {}, + }, + { + "success: nil app", + func() { + isNilApp = true + }, + }, + { + "middleware disabled", func() { + suite.chainA.GetSimApp().ICAControllerKeeper.DeleteMiddlewareEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ConnectionID) + suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanUpgradeAck = func(ctx sdk.Context, portID, channelID string, counterpartyVersion string) error { + return ibcmock.MockApplicationCallbackError + } + }, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + isNilApp = false + + path = NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + tc.malleate() // malleate mutates test data + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().NoError(err) + + app, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + if isNilApp { + cbs = controller.NewIBCMiddleware(nil, suite.chainA.GetSimApp().ICAControllerKeeper) + } + + cbs.OnChanUpgradeRestore(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + }) + } +} + func (suite *InterchainAccountsTestSuite) TestSingleHostMultipleControllers() { var ( pathAToB *ibctesting.Path diff --git a/modules/apps/27-interchain-accounts/controller/keeper/export_test.go b/modules/apps/27-interchain-accounts/controller/keeper/export_test.go index 382dde7a805..2cd4338dde2 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/export_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/export_test.go @@ -4,9 +4,19 @@ package keeper This file is to allow for unexported functions and fields to be accessible to the testing package. */ -import porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" +) // GetICS4Wrapper is a getter for the keeper's ICS4Wrapper. func (k *Keeper) GetICS4Wrapper() porttypes.ICS4Wrapper { return k.ics4Wrapper } + +// GetAppMetadata is a wrapper around getAppMetadata to allow the function to be directly called in tests. +func (k Keeper) GetAppMetadata(ctx sdk.Context, portID, channelID string) (icatypes.Metadata, error) { + return k.getAppMetadata(ctx, portID, channelID) +} diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index 0ce3802b48e..eca8a4a18a5 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -10,6 +10,7 @@ import ( capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ) @@ -42,7 +43,10 @@ func (k Keeper) OnChanOpenInit( return "", errorsmod.Wrapf(icatypes.ErrInvalidHostPort, "expected %s, got %s", icatypes.HostPortID, counterparty.PortId) } - var metadata icatypes.Metadata + var ( + err error + metadata icatypes.Metadata + ) if strings.TrimSpace(version) == "" { connection, err := k.channelKeeper.GetConnection(ctx, connectionHops[0]) if err != nil { @@ -51,8 +55,9 @@ func (k Keeper) OnChanOpenInit( metadata = icatypes.NewDefaultMetadata(connectionHops[0], connection.GetCounterparty().GetConnectionID()) } else { - if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(version), &metadata); err != nil { - return "", errorsmod.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") + metadata, err = icatypes.MetadataFromVersion(version) + if err != nil { + return "", err } } @@ -100,11 +105,10 @@ func (k Keeper) OnChanOpenAck( 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 errorsmod.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") + metadata, err := icatypes.MetadataFromVersion(counterpartyVersion) + if err != nil { + return err } - if activeChannelID, found := k.GetOpenActiveChannel(ctx, metadata.ControllerConnectionId, portID); found { return errorsmod.Wrapf(icatypes.ErrActiveChannelAlreadySet, "existing active channel %s for portID %s", activeChannelID, portID) } @@ -136,3 +140,83 @@ func (Keeper) OnChanCloseConfirm( ) error { return nil } + +// OnChanUpgradeInit performs the upgrade init step of the channel upgrade handshake. +func (k Keeper) OnChanUpgradeInit(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) (string, error) { + if strings.TrimSpace(version) == "" { + return "", errorsmod.Wrap(icatypes.ErrInvalidVersion, "version cannot be empty") + } + + // support for unordered ICA channels is not implemented yet + if order != channeltypes.ORDERED { + return "", errorsmod.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s", channeltypes.ORDERED, order) + } + + metadata, err := icatypes.MetadataFromVersion(version) + if err != nil { + return "", err + } + + currentMetadata, err := k.getAppMetadata(ctx, portID, channelID) + if err != nil { + return "", err + } + + if err := icatypes.ValidateControllerMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { + return "", errorsmod.Wrap(err, "invalid metadata") + } + + // the interchain account address on the host chain + // must remain the same after the upgrade. + if currentMetadata.Address != metadata.Address { + return "", errorsmod.Wrap(icatypes.ErrInvalidAccountAddress, "interchain account address cannot be changed") + } + + if currentMetadata.ControllerConnectionId != connectionHops[0] { + return "", errorsmod.Wrap(connectiontypes.ErrInvalidConnectionIdentifier, "proposed connection hop must not change") + } + + return version, nil +} + +// OnChanUpgradeAck implements the ack setup of the channel upgrade handshake. +func (k Keeper) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, counterpartyVersion string) error { + if strings.TrimSpace(counterpartyVersion) == "" { + return errorsmod.Wrap(channeltypes.ErrInvalidChannelVersion, "counterparty version cannot be empty") + } + + metadata, err := icatypes.MetadataFromVersion(counterpartyVersion) + if err != nil { + return err + } + + currentMetadata, err := k.getAppMetadata(ctx, portID, channelID) + if err != nil { + return err + } + + // the interchain account address on the host chain + // must remain the same after the upgrade. + if currentMetadata.Address != metadata.Address { + return errorsmod.Wrap(icatypes.ErrInvalidAccountAddress, "address cannot be changed") + } + + if currentMetadata.ControllerConnectionId != metadata.ControllerConnectionId { + return errorsmod.Wrap(connectiontypes.ErrInvalidConnectionIdentifier, "proposed controller connection ID must not change") + } + + if currentMetadata.HostConnectionId != metadata.HostConnectionId { + return errorsmod.Wrap(connectiontypes.ErrInvalidConnectionIdentifier, "proposed host connection ID must not change") + } + + channel, found := k.channelKeeper.GetChannel(ctx, portID, channelID) + if !found { + 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 { + return err + } + + return nil +} 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 29ebf75dec1..e34d91481a2 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -3,11 +3,16 @@ package keeper_test import ( capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) +const ( + differentConnectionID = "connection-100" +) + func (suite *KeeperTestSuite) TestOnChanOpenInit() { var ( channel *channeltypes.Channel @@ -471,3 +476,258 @@ func (suite *KeeperTestSuite) TestOnChanCloseConfirm() { }) } } + +func (suite *KeeperTestSuite) TestOnChanUpgradeInit() { + var ( + path *ibctesting.Path + metadata icatypes.Metadata + order channeltypes.Order + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + name: "failure: change ICA address", + malleate: func() { + metadata.Address = TestOwnerAddress + }, + expError: icatypes.ErrInvalidAccountAddress, + }, + { + name: "failure: change controller connection id", + malleate: func() { + metadata.ControllerConnectionId = differentConnectionID + }, + expError: connectiontypes.ErrInvalidConnection, + }, + { + name: "failure: change host connection id", + malleate: func() { + metadata.HostConnectionId = differentConnectionID + }, + expError: connectiontypes.ErrInvalidConnection, + }, + { + name: "failure: cannot decode version string", + malleate: func() { + channel := path.EndpointA.GetChannel() + channel.Version = "invalid-metadata-string" + path.EndpointA.SetChannel(channel) + }, + expError: icatypes.ErrUnknownDataType, + }, + { + name: "failure: invalid connection hops", + malleate: func() { + path.EndpointA.ConnectionID = differentConnectionID + }, + expError: connectiontypes.ErrConnectionNotFound, + }, + { + name: "failure: invalid order", + malleate: func() { + order = channeltypes.UNORDERED + }, + expError: channeltypes.ErrInvalidChannelOrdering, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + currentMetadata, err := suite.chainA.GetSimApp().ICAControllerKeeper.GetAppMetadata(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().NoError(err) + + order = channeltypes.ORDERED + metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + // use the same address as the previous metadata. + metadata.Address = currentMetadata.Address + + // this is the actual change to the version. + metadata.Encoding = icatypes.EncodingProto3JSON + + tc.malleate() // malleate mutates test data + + version := string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + + upgradeVersion, err := path.EndpointA.Chain.GetSimApp().ICAControllerKeeper.OnChanUpgradeInit( + path.EndpointA.Chain.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + order, + []string{path.EndpointA.ConnectionID}, + version, + ) + + expPass := tc.expError == nil + + if expPass { + suite.Require().NoError(err) + suite.Require().Equal(upgradeVersion, version) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} + +func (suite *KeeperTestSuite) TestOnChanUpgradeAck() { + const ( + invalidVersion = "invalid-version" + ) + + var ( + path *ibctesting.Path + metadata icatypes.Metadata + counterpartyVersion string + ) + + // updateMetadata is a helper function which modifies the metadata stored in the channel version + // and marshals it into a string to pass to OnChanUpgradeAck as the counterpartyVersion string. + updateMetadata := func(modificationFn func(*icatypes.Metadata)) { + metadata, err := icatypes.MetadataFromVersion(path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version) + suite.Require().NoError(err) + modificationFn(&metadata) + counterpartyVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + } + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + name: "failure: empty counterparty version", + malleate: func() { + counterpartyVersion = "" + }, + expError: channeltypes.ErrInvalidChannelVersion, + }, + { + name: "failure: invalid counterparty version", + malleate: func() { + counterpartyVersion = invalidVersion + }, + expError: icatypes.ErrUnknownDataType, + }, + { + name: "failure: cannot decode self version string", + malleate: func() { + channel := path.EndpointA.GetChannel() + channel.Version = invalidVersion + path.EndpointA.SetChannel(channel) + }, + expError: icatypes.ErrUnknownDataType, + }, + { + name: "failure: invalid tx type", + malleate: func() { + updateMetadata(func(metadata *icatypes.Metadata) { + metadata.TxType = "invalid-tx-type" + }) + }, + expError: icatypes.ErrUnknownDataType, + }, + { + name: "failure: interchain account address has changed", + malleate: func() { + updateMetadata(func(metadata *icatypes.Metadata) { + metadata.Address = "different-address" + }) + }, + expError: icatypes.ErrInvalidAccountAddress, + }, + { + name: "failure: controller connection ID has changed", + malleate: func() { + updateMetadata(func(metadata *icatypes.Metadata) { + metadata.ControllerConnectionId = "different-connection-id" + }) + }, + expError: connectiontypes.ErrInvalidConnectionIdentifier, + }, + { + name: "failure: host connection ID has changed", + malleate: func() { + updateMetadata(func(metadata *icatypes.Metadata) { + metadata.HostConnectionId = "different-host-id" + }) + }, + expError: connectiontypes.ErrInvalidConnectionIdentifier, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + currentMetadata, err := suite.chainA.GetSimApp().ICAControllerKeeper.GetAppMetadata(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().NoError(err) + + metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + // use the same address as the previous metadata. + metadata.Address = currentMetadata.Address + + // this is the actual change to the version. + metadata.Encoding = icatypes.EncodingProto3JSON + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + + err = path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + counterpartyVersion = path.EndpointB.GetChannel().Version + + tc.malleate() // malleate mutates test data + + err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanUpgradeAck( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + counterpartyVersion, + ) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + suite.Require().Equal(path.EndpointA.GetChannel().Version, counterpartyVersion) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} diff --git a/modules/apps/27-interchain-accounts/controller/keeper/keeper.go b/modules/apps/27-interchain-accounts/controller/keeper/keeper.go index 63e606c395e..4e11ea993e7 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/keeper.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/keeper.go @@ -20,6 +20,7 @@ import ( channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" "github.com/cosmos/ibc-go/v8/modules/core/exported" ) @@ -280,6 +281,16 @@ func (k Keeper) GetAuthority() string { return k.authority } +// getAppMetadata retrieves the interchain accounts channel metadata from the store associated with the provided portID and channelID +func (k Keeper) getAppMetadata(ctx sdk.Context, portID, channelID string) (icatypes.Metadata, error) { + appVersion, found := k.GetAppVersion(ctx, portID, channelID) + if !found { + return icatypes.Metadata{}, errorsmod.Wrapf(ibcerrors.ErrNotFound, "app version not found for port %s and channel %s", portID, channelID) + } + + return icatypes.MetadataFromVersion(appVersion) +} + // GetParams returns the current ica/controller submodule parameters. func (k Keeper) GetParams(ctx sdk.Context) types.Params { store := ctx.KVStore(k.storeKey) diff --git a/modules/apps/27-interchain-accounts/host/ibc_module.go b/modules/apps/27-interchain-accounts/host/ibc_module.go index 50efd5c9dd2..bbc68506fc4 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module.go @@ -20,6 +20,7 @@ import ( var ( _ porttypes.IBCModule = (*IBCModule)(nil) _ porttypes.PacketDataUnmarshaler = (*IBCModule)(nil) + _ porttypes.UpgradableModule = (*IBCModule)(nil) ) // IBCModule implements the ICS26 interface for interchain accounts host chains @@ -156,6 +157,32 @@ func (IBCModule) OnTimeoutPacket( 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") } +// OnChanUpgradeInit implements the IBCModule interface +func (IBCModule) OnChanUpgradeInit(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) (string, error) { + return "", errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel upgrade handshake must be initiated by controller chain") +} + +// OnChanUpgradeTry implements the IBCModule interface +func (im IBCModule) OnChanUpgradeTry(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, counterpartyVersion string) (string, error) { + if !im.keeper.GetParams(ctx).HostEnabled { + return "", types.ErrHostSubModuleDisabled + } + + return im.keeper.OnChanUpgradeTry(ctx, portID, channelID, order, connectionHops, counterpartyVersion) +} + +// OnChanUpgradeAck implements the IBCModule interface +func (IBCModule) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, counterpartyVersion string) error { + return errorsmod.Wrap(icatypes.ErrInvalidChannelFlow, "channel upgrade handshake must be initiated by controller chain") +} + +// OnChanUpgradeOpen implements the IBCModule interface +func (IBCModule) OnChanUpgradeOpen(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) { +} + +// OnChanUpgradeRestore implements the IBCModule interface +func (IBCModule) OnChanUpgradeRestore(ctx sdk.Context, portID, channelID string) {} + // UnmarshalPacketData attempts to unmarshal the provided packet data bytes // into an InterchainAccountPacketData. This function implements the optional // PacketDataUnmarshaler interface required for ADR 008 support. 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 a5bb9381e66..f5fdde6c5c1 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module_test.go @@ -20,6 +20,7 @@ import ( feetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/cosmos/ibc-go/v8/modules/core/exported" ibctesting "github.com/cosmos/ibc-go/v8/testing" @@ -603,6 +604,74 @@ func (suite *InterchainAccountsTestSuite) TestOnTimeoutPacket() { } } +func (suite *InterchainAccountsTestSuite) TestOnChanUpgradeTry() { + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", func() {}, nil, + }, + { + "host submodule disabled", func() { + suite.chainB.GetSimApp().ICAHostKeeper.SetParams(suite.chainB.GetContext(), types.NewParams(false, []string{})) + }, types.ErrHostSubModuleDisabled, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path := NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointB.ConnectionID, path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + metadata := icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + metadata.Address = interchainAccountAddr + metadata.Encoding = icatypes.EncodingProto3JSON // this is the actual change to the version + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + + err = path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + tc.malleate() // malleate mutates test data + + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID) + suite.Require().NoError(err) + + app, ok := suite.chainB.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + version, err := cbs.OnChanUpgradeTry( + suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + channeltypes.ORDERED, + []string{path.EndpointB.ConnectionID}, + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version, + ) + + if tc.expError == nil { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + suite.Require().Empty(version) + } + }) + } +} + func (suite *InterchainAccountsTestSuite) fundICAWallet(ctx sdk.Context, portID string, amount sdk.Coins) { interchainAccountAddr, found := suite.chainB.GetSimApp().ICAHostKeeper.GetInterchainAccountAddress(ctx, ibctesting.FirstConnectionID, portID) suite.Require().True(found) diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake.go b/modules/apps/27-interchain-accounts/host/keeper/handshake.go index f3a202a3bae..819abd89426 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake.go @@ -2,6 +2,7 @@ package keeper import ( "fmt" + "strings" errorsmod "cosmossdk.io/errors" @@ -9,7 +10,9 @@ import ( capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ) @@ -35,12 +38,12 @@ func (k Keeper) OnChanOpenTry( 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 "", errorsmod.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") + metadata, err := icatypes.MetadataFromVersion(counterpartyVersion) + if err != nil { + return "", err } - if err := icatypes.ValidateHostMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { + if err = icatypes.ValidateHostMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { return "", err } @@ -67,14 +70,11 @@ func (k Keeper) OnChanOpenTry( // 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 { + if err = k.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { return "", errorsmod.Wrapf(err, "failed to claim capability for channel %s on port %s", channelID, portID) } - var ( - accAddress sdk.AccAddress - err error - ) + var accAddress sdk.AccAddress interchainAccAddr, found := k.GetInterchainAccountAddress(ctx, metadata.HostConnectionId, counterparty.PortId) if found { @@ -130,3 +130,45 @@ func (Keeper) OnChanCloseConfirm( ) error { return nil } + +// OnChanUpgradeTry performs the upgrade try step of the channel upgrade handshake. +func (k Keeper) OnChanUpgradeTry(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, counterpartyVersion string) (string, error) { + if portID != icatypes.HostPortID { + return "", errorsmod.Wrapf(porttypes.ErrInvalidPort, "expected %s, got %s", icatypes.HostPortID, portID) + } + + if strings.TrimSpace(counterpartyVersion) == "" { + return "", errorsmod.Wrap(channeltypes.ErrInvalidChannelVersion, "counterparty version cannot be empty") + } + + // support for unordered ICA channels is not implemented yet + if order != channeltypes.ORDERED { + return "", errorsmod.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s", channeltypes.ORDERED, order) + } + + metadata, err := icatypes.MetadataFromVersion(counterpartyVersion) + if err != nil { + return "", err + } + + currentMetadata, err := k.getAppMetadata(ctx, portID, channelID) + if err != nil { + return "", err + } + + if err := icatypes.ValidateHostMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { + return "", errorsmod.Wrap(err, "invalid metadata") + } + + // the interchain account address on the host chain + // must remain the same after the upgrade. + if currentMetadata.Address != metadata.Address { + return "", errorsmod.Wrap(icatypes.ErrInvalidAccountAddress, "interchain account address cannot be changed") + } + + if currentMetadata.HostConnectionId != connectionHops[0] { + return "", errorsmod.Wrap(connectiontypes.ErrInvalidConnectionIdentifier, "proposed connection hop must not change") + } + + return counterpartyVersion, nil +} 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 3074faf9b8e..c14ac85a576 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -8,7 +8,9 @@ import ( capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" hosttypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types" icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types" + connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -422,3 +424,141 @@ func (suite *KeeperTestSuite) TestOnChanCloseConfirm() { }) } } + +func (suite *KeeperTestSuite) TestOnChanUpgradeTry() { + var ( + path *ibctesting.Path + metadata icatypes.Metadata + order channeltypes.Order + counterpartyVersion string + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + name: "failure: invalid port ID", + malleate: func() { + path.EndpointB.ChannelConfig.PortID = "invalid-port-id" + }, + expError: porttypes.ErrInvalidPort, + }, + { + name: "failure: empty counterparty version", + malleate: func() { + counterpartyVersion = "" + }, + expError: channeltypes.ErrInvalidChannelVersion, + }, + { + name: "failure: cannot parse metadata from counterparty version string", + malleate: func() { + counterpartyVersion = "invalid-version" + }, + expError: icatypes.ErrUnknownDataType, + }, + { + name: "failure: cannot decode version string from channel", + malleate: func() { + channel := path.EndpointB.GetChannel() + channel.Version = "invalid-metadata-string" + path.EndpointB.SetChannel(channel) + }, + expError: icatypes.ErrUnknownDataType, + }, + { + name: "failure: metadata encoding not supported", + malleate: func() { + metadata.Encoding = "invalid-encoding-format" + counterpartyVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + }, + expError: icatypes.ErrInvalidCodec, + }, + { + name: "failure: interchain account address has changed", + malleate: func() { + channel := path.EndpointB.GetChannel() + metadata.Address = "invalid address" + channel.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointB.SetChannel(channel) + }, + expError: icatypes.ErrInvalidAccountAddress, + }, + { + name: "failure: invalid connection identifier", + malleate: func() { + channel := path.EndpointB.GetChannel() + metadata.HostConnectionId = "invalid-connection-id" + channel.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointB.SetChannel(channel) + }, + expError: connectiontypes.ErrInvalidConnectionIdentifier, + }, + { + name: "failure: invalid order", + malleate: func() { + order = channeltypes.UNORDERED + }, + expError: channeltypes.ErrInvalidChannelOrdering, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = NewICAPath(suite.chainA, suite.chainB, icatypes.EncodingProtobuf) + suite.coordinator.SetupConnections(path) + + err := SetupICAPath(path, TestOwnerAddress) + suite.Require().NoError(err) + + currentMetadata, err := suite.chainB.GetSimApp().ICAHostKeeper.GetAppMetadata(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().NoError(err) + + order = channeltypes.ORDERED + metadata = icatypes.NewDefaultMetadata(path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + // use the same address as the previous metadata. + metadata.Address = currentMetadata.Address + + // this is the actual change to the version. + metadata.Encoding = icatypes.EncodingProto3JSON + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = string(icatypes.ModuleCdc.MustMarshalJSON(&metadata)) + + err = path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + counterpartyVersion = path.EndpointA.GetChannel().Version + + tc.malleate() // malleate mutates test data + + version, err := suite.chainB.GetSimApp().ICAHostKeeper.OnChanUpgradeTry( + suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + order, + []string{path.EndpointB.ConnectionID}, + counterpartyVersion, + ) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + suite.Require().Equal(path.EndpointB.GetChannel().Version, version) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} diff --git a/modules/apps/27-interchain-accounts/host/keeper/keeper.go b/modules/apps/27-interchain-accounts/host/keeper/keeper.go index c426c4cc0cb..be0cfc8a0b5 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/keeper.go +++ b/modules/apps/27-interchain-accounts/host/keeper/keeper.go @@ -111,20 +111,14 @@ func (k Keeper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string return k.ics4Wrapper.GetAppVersion(ctx, portID, channelID) } -// GetAppMetadata retrieves the interchain accounts channel metadata from the store associated with the provided portID and channelID +// getAppMetadata retrieves the interchain accounts channel metadata from the store associated with the provided portID and channelID func (k Keeper) getAppMetadata(ctx sdk.Context, portID, channelID string) (icatypes.Metadata, error) { appVersion, found := k.GetAppVersion(ctx, portID, channelID) if !found { return icatypes.Metadata{}, errorsmod.Wrapf(ibcerrors.ErrNotFound, "app version not found for port %s and channel %s", portID, channelID) } - var metadata icatypes.Metadata - if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(appVersion), &metadata); err != nil { - // UnmarshalJSON errors are indeterminate and therefore are not wrapped and included in failed acks - return icatypes.Metadata{}, errorsmod.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") - } - - return metadata, nil + return icatypes.MetadataFromVersion(appVersion) } // GetActiveChannelID retrieves the active channelID from the store keyed by the provided connectionID and portID diff --git a/modules/apps/27-interchain-accounts/types/metadata.go b/modules/apps/27-interchain-accounts/types/metadata.go index 29d1da45d42..61c077a46f0 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.go +++ b/modules/apps/27-interchain-accounts/types/metadata.go @@ -54,11 +54,20 @@ func NewDefaultMetadataString(controllerConnectionID, hostConnectionID string) s return string(ModuleCdc.MustMarshalJSON(&metadata)) } +// MetadataFromVersion parses Metadata from a json encoded version string. +func MetadataFromVersion(versionString string) (Metadata, error) { + var metadata Metadata + if err := ModuleCdc.UnmarshalJSON([]byte(versionString), &metadata); err != nil { + return Metadata{}, errorsmod.Wrapf(ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") + } + return metadata, nil +} + // IsPreviousMetadataEqual compares a metadata to a previous version string set in a channel struct. // It ensures all fields are equal except the Address string func IsPreviousMetadataEqual(previousVersion string, metadata Metadata) bool { - var previousMetadata Metadata - if err := ModuleCdc.UnmarshalJSON([]byte(previousVersion), &previousMetadata); err != nil { + previousMetadata, err := MetadataFromVersion(previousVersion) + if err != nil { return false } diff --git a/modules/apps/29-fee/ibc_middleware.go b/modules/apps/29-fee/ibc_middleware.go index fa97ae7423f..7ba847be359 100644 --- a/modules/apps/29-fee/ibc_middleware.go +++ b/modules/apps/29-fee/ibc_middleware.go @@ -19,6 +19,7 @@ import ( var ( _ porttypes.Middleware = (*IBCMiddleware)(nil) _ porttypes.PacketDataUnmarshaler = (*IBCMiddleware)(nil) + _ porttypes.UpgradableModule = (*IBCMiddleware)(nil) ) // IBCMiddleware implements the ICS26 callbacks for the fee middleware given the @@ -326,6 +327,129 @@ func (im IBCMiddleware) OnTimeoutPacket( return im.app.OnTimeoutPacket(ctx, packet, relayer) } +// OnChanUpgradeInit implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeInit( + ctx sdk.Context, + portID string, + channelID string, + order channeltypes.Order, + connectionHops []string, + upgradeVersion string, +) (string, error) { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + return "", errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack") + } + + versionMetadata, err := types.MetadataFromVersion(upgradeVersion) + if err != nil { + // since it is valid for fee version to not be specified, the upgrade version may be for a middleware + // or application further down in the stack. Thus, passthrough to next middleware or application in callstack. + return cbs.OnChanUpgradeInit(ctx, portID, channelID, order, connectionHops, upgradeVersion) + } + + if versionMetadata.FeeVersion != types.Version { + return "", errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion) + } + + appVersion, err := cbs.OnChanUpgradeInit(ctx, portID, channelID, order, connectionHops, versionMetadata.AppVersion) + if err != nil { + return "", err + } + + versionMetadata.AppVersion = appVersion + versionBz, err := types.ModuleCdc.MarshalJSON(&versionMetadata) + if err != nil { + return "", err + } + + return string(versionBz), nil +} + +// OnChanUpgradeTry implement s the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeTry(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, counterpartyVersion string) (string, error) { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + return "", errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack") + } + + versionMetadata, err := types.MetadataFromVersion(counterpartyVersion) + if err != nil { + // since it is valid for fee version to not be specified, the counterparty upgrade version may be for a middleware + // or application further down in the stack. Thus, passthrough to next middleware or application in callstack. + return cbs.OnChanUpgradeTry(ctx, portID, channelID, order, connectionHops, counterpartyVersion) + } + + if versionMetadata.FeeVersion != types.Version { + return "", errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion) + } + + appVersion, err := cbs.OnChanUpgradeTry(ctx, portID, channelID, order, connectionHops, versionMetadata.AppVersion) + if err != nil { + return "", err + } + + versionMetadata.AppVersion = appVersion + versionBz, err := types.ModuleCdc.MarshalJSON(&versionMetadata) + if err != nil { + return "", err + } + + return string(versionBz), nil +} + +// OnChanUpgradeAck implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, counterpartyVersion string) error { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + return errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack") + } + + versionMetadata, err := types.MetadataFromVersion(counterpartyVersion) + if err != nil { + // since it is valid for fee version to not be specified, the counterparty upgrade version may be for a middleware + // or application further down in the stack. Thus, passthrough to next middleware or application in callstack. + return cbs.OnChanUpgradeAck(ctx, portID, channelID, counterpartyVersion) + } + + if versionMetadata.FeeVersion != types.Version { + return errorsmod.Wrapf(types.ErrInvalidVersion, "expected counterparty fee version: %s, got: %s", types.Version, versionMetadata.FeeVersion) + } + + // call underlying app's OnChanUpgradeAck callback with the counterparty app version. + return cbs.OnChanUpgradeAck(ctx, portID, channelID, versionMetadata.AppVersion) +} + +// OnChanUpgradeOpen implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeOpen(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + panic(errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack")) + } + + versionMetadata, err := types.MetadataFromVersion(version) + if err != nil { + // set fee disabled and passthrough to the next middleware or application in callstack. + im.keeper.DeleteFeeEnabled(ctx, portID, channelID) + cbs.OnChanUpgradeOpen(ctx, portID, channelID, order, connectionHops, version) + return + } + + // set fee enabled and passthrough to the next middleware of application in callstack. + im.keeper.SetFeeEnabled(ctx, portID, channelID) + cbs.OnChanUpgradeOpen(ctx, portID, channelID, order, connectionHops, versionMetadata.AppVersion) +} + +// OnChanUpgradeRestore implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeRestore(ctx sdk.Context, portID, channelID string) { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + panic(errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack")) + } + + cbs.OnChanUpgradeRestore(ctx, portID, channelID) +} + // SendPacket implements the ICS4 Wrapper interface func (im IBCMiddleware) SendPacket( ctx sdk.Context, diff --git a/modules/apps/29-fee/ibc_middleware_test.go b/modules/apps/29-fee/ibc_middleware_test.go index 941bce02dd4..d1a857a0ca7 100644 --- a/modules/apps/29-fee/ibc_middleware_test.go +++ b/modules/apps/29-fee/ibc_middleware_test.go @@ -256,7 +256,7 @@ func (suite *FeeTestSuite) TestOnChanOpenAck() { }, { "invalid version fails to unmarshal metadata", - "invalid-version", + ibctesting.InvalidID, func(suite *FeeTestSuite) {}, false, }, @@ -1009,6 +1009,441 @@ func (suite *FeeTestSuite) TestOnTimeoutPacket() { } } +func (suite *FeeTestSuite) TestOnChanUpgradeInit() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success with downgraded version", + func() { + // create a new path using a fee enabled channel and downgrade it to disable fees + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + mockFeeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: ibcmock.Version})) + path.EndpointA.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointB.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointA.ChannelConfig.Version = mockFeeVersion + path.EndpointB.ChannelConfig.Version = mockFeeVersion + + upgradeVersion := ibcmock.Version + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + + suite.coordinator.Setup(path) + }, + nil, + }, + { + "invalid upgrade version", + func() { + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibctesting.InvalidID + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibctesting.InvalidID + + suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanUpgradeInit = func(_ sdk.Context, _, _ string, _ channeltypes.Order, _ []string, _ string) (string, error) { + // intentionally force the error here so we can assert that a passthrough occurs when fees should not be enabled for this channel + return "", ibcmock.MockApplicationCallbackError + } + }, + ibcmock.MockApplicationCallbackError, + }, + { + "invalid fee version", + func() { + upgradeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: ibctesting.InvalidID, AppVersion: ibcmock.Version})) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + }, + types.ErrInvalidVersion, + }, + { + "underlying app callback returns error", + func() { + suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanUpgradeInit = func(_ sdk.Context, _, _ string, _ channeltypes.Order, _ []string, _ string) (string, error) { + return "", ibcmock.MockApplicationCallbackError + } + }, + ibcmock.MockApplicationCallbackError, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + // configure the initial path to create an unincentivized mock channel + path.EndpointA.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointB.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointA.ChannelConfig.Version = ibcmock.Version + path.EndpointB.ChannelConfig.Version = ibcmock.Version + + suite.coordinator.Setup(path) + + // configure the channel upgrade version to enabled ics29 fee middleware + upgradeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: ibcmock.Version})) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + + tc.malleate() + + err := path.EndpointA.ChanUpgradeInit() + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + suite.Require().Contains(err.Error(), tc.expError.Error()) + } + }) + } +} + +func (suite *FeeTestSuite) TestOnChanUpgradeTry() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success disable fees", + func() { + // create a new path using a fee enabled channel and downgrade it to disable fees + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + mockFeeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: ibcmock.Version})) + path.EndpointA.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointB.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointA.ChannelConfig.Version = mockFeeVersion + path.EndpointB.ChannelConfig.Version = mockFeeVersion + + upgradeVersion := ibcmock.Version + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + + suite.coordinator.Setup(path) + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + }, + nil, + }, + { + "invalid upgrade version", + func() { + counterpartyUpgrade := path.EndpointA.GetChannelUpgrade() + counterpartyUpgrade.Fields.Version = ibctesting.InvalidID + path.EndpointA.SetChannelUpgrade(counterpartyUpgrade) + + suite.coordinator.CommitBlock(suite.chainA) + + // intentionally force the error here so we can assert that a passthrough occurs when fees should not be enabled for this channel + suite.chainB.GetSimApp().FeeMockModule.IBCApp.OnChanUpgradeTry = func(_ sdk.Context, _, _ string, _ channeltypes.Order, _ []string, _ string) (string, error) { + return "", ibcmock.MockApplicationCallbackError + } + }, + ibcmock.MockApplicationCallbackError, + }, + { + "invalid fee version", + func() { + upgradeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: ibctesting.InvalidID, AppVersion: ibcmock.Version})) + + counterpartyUpgrade := path.EndpointA.GetChannelUpgrade() + counterpartyUpgrade.Fields.Version = upgradeVersion + path.EndpointA.SetChannelUpgrade(counterpartyUpgrade) + + suite.coordinator.CommitBlock(suite.chainA) + }, + types.ErrInvalidVersion, + }, + { + "underlying app callback returns error", + func() { + suite.chainB.GetSimApp().FeeMockModule.IBCApp.OnChanUpgradeTry = func(_ sdk.Context, _, _ string, _ channeltypes.Order, _ []string, _ string) (string, error) { + return "", ibcmock.MockApplicationCallbackError + } + }, + ibcmock.MockApplicationCallbackError, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + // configure the initial path to create an unincentivized mock channel + path.EndpointA.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointB.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointA.ChannelConfig.Version = ibcmock.Version + path.EndpointB.ChannelConfig.Version = ibcmock.Version + + suite.coordinator.Setup(path) + + // configure the channel upgrade version to enabled ics29 fee middleware + upgradeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: ibcmock.Version})) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + tc.malleate() + + err = path.EndpointB.ChanUpgradeTry() + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + suite.Require().Contains(err.Error(), tc.expError.Error()) + } + }) + } +} + +func (suite *FeeTestSuite) TestOnChanUpgradeAck() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success with fee middleware disabled", + func() { + suite.chainA.GetSimApp().IBCFeeKeeper.DeleteFeeEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + }, + nil, + }, + { + "invalid upgrade version", + func() { + counterpartyUpgrade := path.EndpointB.GetChannelUpgrade() + counterpartyUpgrade.Fields.Version = ibctesting.InvalidID + path.EndpointB.SetChannelUpgrade(counterpartyUpgrade) + + suite.coordinator.CommitBlock(suite.chainB) + + suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanUpgradeAck = func(_ sdk.Context, _, _, _ string) error { + return types.ErrInvalidVersion + } + }, + types.ErrInvalidVersion, + }, + { + "invalid fee version", + func() { + upgradeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: ibctesting.InvalidID, AppVersion: ibcmock.Version})) + + counterpartyUpgrade := path.EndpointB.GetChannelUpgrade() + counterpartyUpgrade.Fields.Version = upgradeVersion + path.EndpointB.SetChannelUpgrade(counterpartyUpgrade) + + suite.coordinator.CommitBlock(suite.chainB) + }, + types.ErrInvalidVersion, + }, + { + "underlying app callback returns error", + func() { + suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanUpgradeAck = func(_ sdk.Context, _, _, _ string) error { + return ibcmock.MockApplicationCallbackError + } + }, + ibcmock.MockApplicationCallbackError, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + // configure the initial path to create an unincentivized mock channel + path.EndpointA.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointB.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointA.ChannelConfig.Version = ibcmock.Version + path.EndpointB.ChannelConfig.Version = ibcmock.Version + + suite.coordinator.Setup(path) + + // configure the channel upgrade version to enabled ics29 fee middleware + upgradeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: ibcmock.Version})) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + tc.malleate() + + counterpartyUpgrade := path.EndpointB.GetChannelUpgrade() + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.MockFeePort) + suite.Require().NoError(err) + + app, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + err = cbs.OnChanUpgradeAck(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, counterpartyUpgrade.Fields.Version) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} + +func (suite *FeeTestSuite) TestOnChanUpgradeOpen() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expFeeEnabled bool + }{ + { + "success: enable fees", + func() { + // Assert in callback that correct upgrade information is passed + suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanUpgradeOpen = func(_ sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) { + suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, portID) + suite.Require().Equal(path.EndpointA.ChannelID, channelID) + suite.Require().Equal(channeltypes.UNORDERED, order) + suite.Require().Equal([]string{path.EndpointA.ConnectionID}, connectionHops) + suite.Require().Equal(ibcmock.Version, version) + } + }, + true, + }, + { + "success: disable fees", + func() { + // create a new path using a fee enabled channel and downgrade it to disable fees + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + mockFeeVersion := &types.Metadata{FeeVersion: types.Version, AppVersion: ibcmock.Version} + mockFeeVersionBz := string(types.ModuleCdc.MustMarshalJSON(mockFeeVersion)) + path.EndpointA.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointB.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointA.ChannelConfig.Version = mockFeeVersionBz + path.EndpointB.ChannelConfig.Version = mockFeeVersionBz + + upgradeVersion := ibcmock.Version + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + + suite.coordinator.Setup(path) + + // Assert in callback that correct version is passed + suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanUpgradeOpen = func(_ sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) { + suite.Require().Equal(path.EndpointA.ChannelConfig.PortID, portID) + suite.Require().Equal(path.EndpointA.ChannelID, channelID) + suite.Require().Equal(channeltypes.UNORDERED, order) + suite.Require().Equal([]string{path.EndpointA.ConnectionID}, connectionHops) + suite.Require().Equal(mockFeeVersion.AppVersion, version) + } + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + // configure the initial path to create an unincentivized mock channel + path.EndpointA.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointB.ChannelConfig.PortID = ibctesting.MockFeePort + path.EndpointA.ChannelConfig.Version = ibcmock.Version + path.EndpointB.ChannelConfig.Version = ibcmock.Version + + suite.coordinator.Setup(path) + + // configure the channel upgrade version to enabled ics29 fee middleware + upgradeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: ibcmock.Version})) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + + tc.malleate() + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeConfirm() + suite.Require().NoError(err) + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.MockFeePort) + suite.Require().NoError(err) + + app, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + upgrade := path.EndpointA.GetChannelUpgrade() + cbs.OnChanUpgradeOpen(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgrade.Fields.Ordering, upgrade.Fields.ConnectionHops, upgrade.Fields.Version) + + isFeeEnabled := suite.chainA.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + if tc.expFeeEnabled { + suite.Require().True(isFeeEnabled) + } else { + suite.Require().False(isFeeEnabled) + } + }) + } +} + func (suite *FeeTestSuite) TestGetAppVersion() { var ( portID string diff --git a/modules/apps/29-fee/transfer_test.go b/modules/apps/29-fee/transfer_test.go index 287a5cad1b8..d283cdc1713 100644 --- a/modules/apps/29-fee/transfer_test.go +++ b/modules/apps/29-fee/transfer_test.go @@ -68,3 +68,98 @@ func (suite *FeeTestSuite) TestFeeTransfer() { 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[0])) } + +func (suite *FeeTestSuite) TestTransferFeeUpgrade() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + // configure the initial path to create a regular transfer channel + path.EndpointA.ChannelConfig.PortID = transfertypes.PortID + path.EndpointB.ChannelConfig.PortID = transfertypes.PortID + path.EndpointA.ChannelConfig.Version = transfertypes.Version + path.EndpointB.ChannelConfig.Version = transfertypes.Version + + suite.coordinator.Setup(path) + + // configure the channel upgrade to upgrade to an incentivized fee enabled transfer channel + upgradeVersion := string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: transfertypes.Version})) + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = upgradeVersion + + tc.malleate() + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeConfirm() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeOpen() + suite.Require().NoError(err) + + expPass := tc.expError == nil + if expPass { + channelA := path.EndpointA.GetChannel() + suite.Require().Equal(upgradeVersion, channelA.Version) + + channelB := path.EndpointB.GetChannel() + suite.Require().Equal(upgradeVersion, channelB.Version) + + isFeeEnabled := suite.chainA.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(isFeeEnabled) + + isFeeEnabled = suite.chainB.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(isFeeEnabled) + + fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) + 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, ibctesting.TestCoin, 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 + + feeEscrowAddr := suite.chainA.GetSimApp().AccountKeeper.GetModuleAddress(types.ModuleName) + escrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), feeEscrowAddr, sdk.DefaultBondDenom) + suite.Require().Equal(escrowBalance.Amount, fee.Total().AmountOf(sdk.DefaultBondDenom)) + + packet, err := ibctesting.ParsePacketFromEvents(res.Events) + suite.Require().NoError(err) + + err = path.RelayPacket(packet) + suite.Require().NoError(err) // relay committed + + escrowBalance = suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), feeEscrowAddr, sdk.DefaultBondDenom) + suite.Require().True(escrowBalance.IsZero()) + } else { + suite.Require().Error(err) + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} diff --git a/modules/apps/callbacks/ibc_middleware.go b/modules/apps/callbacks/ibc_middleware.go index c7438df23be..5c1b2875656 100644 --- a/modules/apps/callbacks/ibc_middleware.go +++ b/modules/apps/callbacks/ibc_middleware.go @@ -20,6 +20,7 @@ import ( var ( _ porttypes.Middleware = (*IBCMiddleware)(nil) _ porttypes.PacketDataUnmarshaler = (*IBCMiddleware)(nil) + _ porttypes.UpgradableModule = (*IBCMiddleware)(nil) ) // IBCMiddleware implements the ICS26 callbacks for the ibc-callbacks middleware given @@ -363,6 +364,56 @@ func (im IBCMiddleware) OnChanCloseConfirm(ctx sdk.Context, portID, channelID st return im.app.OnChanCloseConfirm(ctx, portID, channelID) } +// OnChanUpgradeInit implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeInit(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) (string, error) { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + return "", errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack") + } + + return cbs.OnChanUpgradeInit(ctx, portID, channelID, order, connectionHops, version) +} + +// OnChanUpgradeTry implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeTry(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, counterpartyVersion string) (string, error) { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + return "", errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack") + } + + return cbs.OnChanUpgradeTry(ctx, portID, channelID, order, connectionHops, counterpartyVersion) +} + +// OnChanUpgradeAck implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, counterpartyVersion string) error { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + return errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack") + } + + return cbs.OnChanUpgradeAck(ctx, portID, channelID, counterpartyVersion) +} + +// OnChanUpgradeOpen implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeOpen(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + panic(errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack")) + } + + cbs.OnChanUpgradeOpen(ctx, portID, channelID, order, connectionHops, version) +} + +// OnChanUpgradeRestore implements the IBCModule interface +func (im IBCMiddleware) OnChanUpgradeRestore(ctx sdk.Context, portID, channelID string) { + cbs, ok := im.app.(porttypes.UpgradableModule) + if !ok { + panic(errorsmod.Wrap(porttypes.ErrInvalidRoute, "upgrade route not found to module in application callstack")) + } + + cbs.OnChanUpgradeRestore(ctx, portID, channelID) +} + // GetAppVersion implements the ICS4Wrapper interface. Callbacks has no version, // so the call is deferred to the underlying application. func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { diff --git a/modules/apps/transfer/ibc_module.go b/modules/apps/transfer/ibc_module.go index db1fc0d5b0a..02ed5fc9d61 100644 --- a/modules/apps/transfer/ibc_module.go +++ b/modules/apps/transfer/ibc_module.go @@ -22,6 +22,7 @@ import ( var ( _ porttypes.IBCModule = (*IBCModule)(nil) _ porttypes.PacketDataUnmarshaler = (*IBCModule)(nil) + _ porttypes.UpgradableModule = (*IBCModule)(nil) ) // IBCModule implements the ICS26 interface for transfer given the transfer keeper. @@ -307,6 +308,48 @@ func (im IBCModule) OnTimeoutPacket( return nil } +// OnChanUpgradeInit implements the IBCModule interface +func (im IBCModule) OnChanUpgradeInit(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, upgradeVersion string) (string, error) { + if err := ValidateTransferChannelParams(ctx, im.keeper, order, portID, channelID); err != nil { + return "", err + } + + if upgradeVersion != types.Version { + return "", errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, upgradeVersion) + } + + return upgradeVersion, nil +} + +// OnChanUpgradeTry implements the IBCModule interface +func (im IBCModule) OnChanUpgradeTry(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, counterpartyVersion string) (string, error) { + if err := ValidateTransferChannelParams(ctx, im.keeper, order, portID, channelID); err != nil { + return "", err + } + + if counterpartyVersion != types.Version { + return "", errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, counterpartyVersion) + } + + return counterpartyVersion, nil +} + +// OnChanUpgradeAck implements the IBCModule interface +func (IBCModule) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, counterpartyVersion string) error { + if counterpartyVersion != types.Version { + return errorsmod.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, counterpartyVersion) + } + + return nil +} + +// OnChanUpgradeOpen implements the IBCModule interface +func (IBCModule) OnChanUpgradeOpen(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) { +} + +// OnChanUpgradeRestore implements the IBCModule interface +func (IBCModule) OnChanUpgradeRestore(ctx sdk.Context, portID, channelID string) {} + // UnmarshalPacketData attempts to unmarshal the provided packet data bytes // into a FungibleTokenPacketData. This function implements the optional // PacketDataUnmarshaler interface required for ADR 008 support. diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go index 81255a32670..6d7df22781a 100644 --- a/modules/apps/transfer/ibc_module_test.go +++ b/modules/apps/transfer/ibc_module_test.go @@ -9,7 +9,9 @@ import ( capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" "github.com/cosmos/ibc-go/v8/modules/apps/transfer" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -242,6 +244,224 @@ func (suite *TransferTestSuite) TestOnChanOpenAck() { } } +func (suite *TransferTestSuite) TestOnChanUpgradeInit() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, // successful happy path for a standalone transfer app is swapping out the underlying connection + nil, + }, + { + "invalid upgrade connection", + func() { + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.ConnectionHops = []string{"connection-100"} + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.ConnectionHops = []string{"connection-100"} + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "invalid upgrade ordering", + func() { + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Ordering = channeltypes.ORDERED + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Ordering = channeltypes.ORDERED + }, + channeltypes.ErrInvalidChannelOrdering, + }, + { + "invalid upgrade version", + func() { + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibctesting.InvalidID + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibctesting.InvalidID + }, + types.ErrInvalidVersion, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = NewTransferPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade to modify the underlying connection + upgradePath := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(upgradePath) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.ConnectionHops = []string{upgradePath.EndpointA.ConnectionID} + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.ConnectionHops = []string{upgradePath.EndpointB.ConnectionID} + + tc.malleate() + + err := path.EndpointA.ChanUpgradeInit() + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + upgrade := path.EndpointA.GetChannelUpgrade() + suite.Require().Equal(upgradePath.EndpointA.ConnectionID, upgrade.Fields.ConnectionHops[0]) + } else { + suite.Require().Error(err) + suite.Require().Contains(err.Error(), tc.expError.Error()) + } + }) + } +} + +func (suite *TransferTestSuite) TestOnChanUpgradeTry() { + var ( + counterpartyUpgrade channeltypes.Upgrade + path *ibctesting.Path + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, // successful happy path for a standalone transfer app is swapping out the underlying connection + nil, + }, + { + "invalid upgrade ordering", + func() { + counterpartyUpgrade.Fields.Ordering = channeltypes.ORDERED + }, + channeltypes.ErrInvalidChannelOrdering, + }, + { + "invalid upgrade version", + func() { + counterpartyUpgrade.Fields.Version = ibctesting.InvalidID + }, + types.ErrInvalidVersion, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = NewTransferPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade to modify the underlying connection + upgradePath := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(upgradePath) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.ConnectionHops = []string{upgradePath.EndpointA.ConnectionID} + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.ConnectionHops = []string{upgradePath.EndpointB.ConnectionID} + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + counterpartyUpgrade = path.EndpointA.GetChannelUpgrade() + + tc.malleate() + + module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), types.PortID) + suite.Require().NoError(err) + + app, ok := suite.chainB.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + version, err := cbs.OnChanUpgradeTry( + suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, + counterpartyUpgrade.Fields.Ordering, counterpartyUpgrade.Fields.ConnectionHops, counterpartyUpgrade.Fields.Version, + ) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + suite.Require().Equal(types.Version, version) + } else { + suite.Require().Error(err) + suite.Require().Contains(err.Error(), tc.expError.Error()) + } + }) + } +} + +func (suite *TransferTestSuite) TestOnChanUpgradeAck() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, // successful happy path for a standalone transfer app is swapping out the underlying connection + nil, + }, + { + "invalid upgrade version", + func() { + path.EndpointB.ChannelConfig.Version = ibctesting.InvalidID + }, + types.ErrInvalidVersion, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = NewTransferPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade to modify the underlying connection + upgradePath := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(upgradePath) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.ConnectionHops = []string{upgradePath.EndpointA.ConnectionID} + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.ConnectionHops = []string{upgradePath.EndpointB.ConnectionID} + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + tc.malleate() + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), types.PortID) + suite.Require().NoError(err) + + app, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module) + suite.Require().True(ok) + + cbs, ok := app.(porttypes.UpgradableModule) + suite.Require().True(ok) + + err = cbs.OnChanUpgradeAck(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.Version) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + suite.Require().Contains(err.Error(), tc.expError.Error()) + } + }) + } +} + func (suite *TransferTestSuite) TestPacketDataUnmarshalerInterface() { var ( sender = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() diff --git a/modules/apps/transfer/transfer_test.go b/modules/apps/transfer/transfer_test.go index 647a1b83665..08f5bc80026 100644 --- a/modules/apps/transfer/transfer_test.go +++ b/modules/apps/transfer/transfer_test.go @@ -32,6 +32,16 @@ func (suite *TransferTestSuite) SetupTest() { suite.chainC = suite.coordinator.GetChain(ibctesting.GetChainID(3)) } +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.EndpointA.ChannelConfig.Version = types.Version + path.EndpointB.ChannelConfig.Version = types.Version + + return path +} + // Constructs the following sends based on the established channels/connections // 1 - from chainA to chainB // 2 - from chainB to chainC diff --git a/modules/core/02-client/keeper/grpc_query_test.go b/modules/core/02-client/keeper/grpc_query_test.go index 231d000a257..40c6dcf3178 100644 --- a/modules/core/02-client/keeper/grpc_query_test.go +++ b/modules/core/02-client/keeper/grpc_query_test.go @@ -164,7 +164,6 @@ func (suite *KeeperTestSuite) TestQueryClientStates() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset - tc.malleate() ctx := suite.chainA.GetContext() diff --git a/modules/core/03-connection/keeper/verify.go b/modules/core/03-connection/keeper/verify.go index bee3d460903..5aadaff3179 100644 --- a/modules/core/03-connection/keeper/verify.go +++ b/modules/core/03-connection/keeper/verify.go @@ -366,6 +366,127 @@ func (k Keeper) VerifyNextSequenceRecv( return nil } +// VerifyChannelUpgradeError verifies a proof of the provided upgrade error receipt. +func (k Keeper) VerifyChannelUpgradeError( + ctx sdk.Context, + connection exported.ConnectionI, + proofHeight exported.Height, + proofErrorReceipt []byte, + portID, + channelID string, + errorReceipt channeltypes.ErrorReceipt, +) error { + clientID := connection.GetClientID() + clientState, clientStore, err := k.getClientStateAndVerificationStore(ctx, clientID) + if err != nil { + return err + } + + if status := k.clientKeeper.GetClientStatus(ctx, clientState, clientID); status != exported.Active { + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + } + + merklePath := commitmenttypes.NewMerklePath(host.ChannelUpgradeErrorPath(portID, channelID)) + merklePath, err = commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + bz, err := k.cdc.Marshal(&errorReceipt) + if err != nil { + return err + } + + if err := clientState.VerifyMembership( + ctx, clientStore, k.cdc, proofHeight, + 0, 0, // skip delay period checks for non-packet processing verification + proofErrorReceipt, merklePath, bz, + ); err != nil { + return errorsmod.Wrapf(err, "failed upgrade error receipt verification for client (%s)", clientID) + } + + return nil +} + +// VerifyChannelUpgradeErrorAbsence verifies a proof of the absence of a +// channel upgrade error. +func (k Keeper) VerifyChannelUpgradeErrorAbsence( + ctx sdk.Context, + connection exported.ConnectionI, + proofHeight exported.Height, + proofErrorReceiptAbsence []byte, + portID, + channelID string, +) error { + clientID := connection.GetClientID() + clientState, clientStore, err := k.getClientStateAndVerificationStore(ctx, clientID) + if err != nil { + return err + } + + if status := k.clientKeeper.GetClientStatus(ctx, clientState, clientID); status != exported.Active { + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + } + + merklePath := commitmenttypes.NewMerklePath(host.ChannelUpgradeErrorPath(portID, channelID)) + merklePath, err = commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + if err := clientState.VerifyNonMembership( + ctx, clientStore, k.cdc, proofHeight, + 0, 0, + proofErrorReceiptAbsence, merklePath, + ); err != nil { + return errorsmod.Wrapf(err, "failed upgrade error receipt absence verification for client (%s)", clientID) + } + + return nil +} + +// VerifyChannelUpgrade verifies the proof that a particular proposed upgrade has been stored in the upgrade path. +func (k Keeper) VerifyChannelUpgrade( + ctx sdk.Context, + connection exported.ConnectionI, + proofHeight exported.Height, + proofUpgrade []byte, + portID, + channelID string, + upgrade channeltypes.Upgrade, +) error { + clientID := connection.GetClientID() + clientState, clientStore, err := k.getClientStateAndVerificationStore(ctx, clientID) + if err != nil { + return err + } + + if status := k.clientKeeper.GetClientStatus(ctx, clientState, clientID); status != exported.Active { + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", clientID, status) + } + + merklePath := commitmenttypes.NewMerklePath(host.ChannelUpgradePath(portID, channelID)) + merklePath, err = commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) + if err != nil { + return err + } + + bz, err := k.cdc.Marshal(&upgrade) + if err != nil { + return err + } + + if err := clientState.VerifyMembership( + ctx, clientStore, k.cdc, proofHeight, + 0, 0, // skip delay period checks for non-packet processing verification + proofUpgrade, merklePath, bz, + ); err != nil { + return errorsmod.Wrapf(err, "failed upgrade verification for client (%s) on channel (%s)", clientID, channelID) + } + + return nil +} + // getBlockDelay calculates the block delay period from the time delay of the connection // and the maximum expected time per block. func (k Keeper) getBlockDelay(ctx sdk.Context, connection exported.ConnectionI) uint64 { diff --git a/modules/core/03-connection/keeper/verify_test.go b/modules/core/03-connection/keeper/verify_test.go index 52977dd08e9..28dd7dd7e4f 100644 --- a/modules/core/03-connection/keeper/verify_test.go +++ b/modules/core/03-connection/keeper/verify_test.go @@ -682,6 +682,239 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { } } +func (suite *KeeperTestSuite) TestVerifyUpgradeErrorReceipt() { + var ( + path *ibctesting.Path + upgradeError *channeltypes.UpgradeError + ) + + cases := []struct { + name string + malleate func() + expPass bool + }{ + { + name: "success", + malleate: func() {}, + expPass: true, + }, + { + name: "fails when client state is frozen", + malleate: func() { + clientState := path.EndpointB.GetClientState().(*ibctm.ClientState) + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) + path.EndpointB.SetClientState(clientState) + }, + expPass: false, + }, + { + name: "fails with bad client id", + malleate: func() { + connection := path.EndpointB.GetConnection() + connection.ClientId = ibctesting.InvalidID + path.EndpointB.SetConnection(connection) + }, + expPass: false, + }, + { + name: "verification fails when the key does not exist", + malleate: func() { + suite.chainA.DeleteKey(host.ChannelUpgradeErrorKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + suite.coordinator.CommitBlock(suite.chainA) + }, + expPass: false, + }, + { + name: "verification fails when message differs", + malleate: func() { + originalSequence := upgradeError.GetErrorReceipt().Sequence + upgradeError = channeltypes.NewUpgradeError(originalSequence, fmt.Errorf("new error")) + }, + expPass: false, + }, + } + + for _, tc := range cases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + upgradeError = channeltypes.NewUpgradeError(1, channeltypes.ErrInvalidChannel) + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgradeError.GetErrorReceipt()) + + suite.chainA.Coordinator.CommitBlock(suite.chainA) + suite.Require().NoError(path.EndpointB.UpdateClient()) + + tc.malleate() + + upgradeErrorReceiptKey := host.ChannelUpgradeErrorKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proof, proofHeight := suite.chainA.QueryProof(upgradeErrorReceiptKey) + + err := suite.chainB.GetSimApp().IBCKeeper.ConnectionKeeper.VerifyChannelUpgradeError(suite.chainB.GetContext(), path.EndpointB.GetConnection(), proofHeight, proof, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, upgradeError.GetErrorReceipt()) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestVerifyUpgradeErrorReceiptAbsence() { + var path *ibctesting.Path + + cases := []struct { + name string + malleate func() + expPass bool + }{ + { + name: "success", + malleate: func() {}, + expPass: true, + }, + { + name: "fails when client state is frozen", + malleate: func() { + clientState := path.EndpointB.GetClientState().(*ibctm.ClientState) + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) + path.EndpointB.SetClientState(clientState) + }, + expPass: false, + }, + { + name: "fails with bad client id", + malleate: func() { + connection := path.EndpointB.GetConnection() + connection.ClientId = ibctesting.InvalidID + path.EndpointB.SetConnection(connection) + }, + expPass: false, + }, + { + name: "verification fails when the key exists", + malleate: func() { + errorReceipt := channeltypes.NewUpgradeError(1, channeltypes.ErrInvalidChannel).GetErrorReceipt() + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, errorReceipt) + suite.chainA.Coordinator.CommitBlock(suite.chainA) + suite.Require().NoError(path.EndpointB.UpdateClient()) + }, + expPass: false, + }, + } + + for _, tc := range cases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + suite.chainA.Coordinator.CommitBlock(suite.chainA) + suite.Require().NoError(path.EndpointB.UpdateClient()) + + tc.malleate() + + upgradeErrorReceiptKey := host.ChannelUpgradeErrorKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proof, proofHeight := suite.chainA.QueryProof(upgradeErrorReceiptKey) + + err := suite.chainB.GetSimApp().IBCKeeper.ConnectionKeeper.VerifyChannelUpgradeErrorAbsence(suite.chainB.GetContext(), path.EndpointB.GetConnection(), proofHeight, proof, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestVerifyUpgrade() { + var ( + path *ibctesting.Path + upgrade channeltypes.Upgrade + ) + + cases := []struct { + name string + malleate func() + expPass bool + }{ + { + name: "success", + malleate: func() {}, + expPass: true, + }, + { + name: "fails when client state is frozen", + malleate: func() { + clientState := path.EndpointB.GetClientState().(*ibctm.ClientState) + clientState.FrozenHeight = clienttypes.NewHeight(0, 1) + path.EndpointB.SetClientState(clientState) + }, + expPass: false, + }, + { + name: "fails with bad client id", + malleate: func() { + connection := path.EndpointB.GetConnection() + connection.ClientId = ibctesting.InvalidID + path.EndpointB.SetConnection(connection) + }, + expPass: false, + }, + { + name: "fails when the upgrade field is different", + malleate: func() { + upgrade.Fields.Ordering = channeltypes.ORDERED + }, + expPass: false, + }, + } + + for _, tc := range cases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + upgrade = channeltypes.NewUpgrade( + channeltypes.NewUpgradeFields(channeltypes.UNORDERED, []string{path.EndpointA.ConnectionID}, "v1.0.0"), + channeltypes.NewTimeout(clienttypes.ZeroHeight(), 100000), + 0, + ) + + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgrade) + + suite.chainA.Coordinator.CommitBlock(suite.chainA) + suite.Require().NoError(path.EndpointB.UpdateClient()) + + tc.malleate() + + channelUpgradeKey := host.ChannelUpgradeKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proof, proofHeight := suite.chainA.QueryProof(channelUpgradeKey) + + err := suite.chainB.GetSimApp().IBCKeeper.ConnectionKeeper.VerifyChannelUpgrade(suite.chainB.GetContext(), path.EndpointB.GetConnection(), proofHeight, proof, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, upgrade) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + func malleateHeight(height exported.Height, diff uint64) exported.Height { return clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+diff) } diff --git a/modules/core/04-channel/client/cli/cli.go b/modules/core/04-channel/client/cli/cli.go index 0a2ed6313a7..450688502e1 100644 --- a/modules/core/04-channel/client/cli/cli.go +++ b/modules/core/04-channel/client/cli/cli.go @@ -31,6 +31,9 @@ func GetQueryCmd() *cobra.Command { GetCmdQueryUnreceivedAcks(), GetCmdQueryNextSequenceReceive(), GetCmdQueryNextSequenceSend(), + GetCmdQueryUpgradeError(), + GetCmdQueryUpgrade(), + GetCmdChannelParams(), ) return queryCmd diff --git a/modules/core/04-channel/client/cli/query.go b/modules/core/04-channel/client/cli/query.go index f255e620ab1..8872b594b49 100644 --- a/modules/core/04-channel/client/cli/query.go +++ b/modules/core/04-channel/client/cli/query.go @@ -491,3 +491,96 @@ func GetCmdQueryNextSequenceSend() *cobra.Command { return cmd } + +// GetCmdQueryUpgradeError defines the command to query for the error receipt associated with an upgrade +func GetCmdQueryUpgradeError() *cobra.Command { + cmd := &cobra.Command{ + Use: "upgrade-error [port-id] [channel-id]", + Short: "Query the upgrade error", + Long: "Query the upgrade error for a given channel", + Example: fmt.Sprintf( + "%s query %s %s upgrade-error [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) + if err != nil { + return err + } + portID := args[0] + channelID := args[1] + prove, _ := cmd.Flags().GetBool(flags.FlagProve) + + errRes, err := utils.QueryUpgradeError(clientCtx, portID, channelID, prove) + if err != nil { + return err + } + + clientCtx = clientCtx.WithHeight(int64(errRes.ProofHeight.RevisionHeight)) + return clientCtx.PrintProto(errRes) + }, + } + cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results") + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdQueryUpgrade defines the command to query for the upgrade associated with a port and channel id +func GetCmdQueryUpgrade() *cobra.Command { + cmd := &cobra.Command{ + Use: "upgrade [port-id] [channel-id]", + Short: "Query the upgrade", + Long: "Query the upgrade for a given channel", + Example: fmt.Sprintf( + "%s query %s %s upgrade [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) + if err != nil { + return err + } + portID := args[0] + channelID := args[1] + prove, _ := cmd.Flags().GetBool(flags.FlagProve) + + upgrade, err := utils.QueryUpgrade(clientCtx, portID, channelID, prove) + if err != nil { + return err + } + + clientCtx = clientCtx.WithHeight(int64(upgrade.ProofHeight.RevisionHeight)) + return clientCtx.PrintProto(upgrade) + }, + } + cmd.Flags().Bool(flags.FlagProve, false, "show proofs for the query results") + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdChannelParams returns the command handler for ibc channel parameter querying. +func GetCmdChannelParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query the current ibc channel parameters", + Long: "Query the current ibc channel 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.ChannelParams(cmd.Context(), &types.QueryChannelParamsRequest{}) + return clientCtx.PrintProto(res.Params) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/modules/core/04-channel/client/utils/utils.go b/modules/core/04-channel/client/utils/utils.go index 6fd5a1b1cfc..c5118aa0011 100644 --- a/modules/core/04-channel/client/utils/utils.go +++ b/modules/core/04-channel/client/utils/utils.go @@ -231,6 +231,92 @@ func queryNextSequenceSendABCI(clientCtx client.Context, portID, channelID strin return types.NewQueryNextSequenceSendResponse(sequence, proofBz, proofHeight), nil } +// QueryUpgradeError returns the upgrade error. +// If prove is true, it performs an ABCI store query in order to retrieve the merkle proof. Otherwise, +// it uses the gRPC query client. +func QueryUpgradeError( + clientCtx client.Context, portID, channelID string, prove bool, +) (*types.QueryUpgradeErrorResponse, error) { + if prove { + return queryUpgradeErrorABCI(clientCtx, portID, channelID) + } + + queryClient := types.NewQueryClient(clientCtx) + req := &types.QueryUpgradeErrorRequest{ + PortId: portID, + ChannelId: channelID, + } + + return queryClient.UpgradeError(context.Background(), req) +} + +// QueryUpgrade returns the upgrade. +// If prove is true, it performs an ABCI store query in order to retrieve the merkle proof. Otherwise, +// it uses the gRPC query client. +func QueryUpgrade( + clientCtx client.Context, portID, channelID string, prove bool, +) (*types.QueryUpgradeResponse, error) { + if prove { + return queryUpgradeABCI(clientCtx, portID, channelID) + } + + queryClient := types.NewQueryClient(clientCtx) + req := &types.QueryUpgradeRequest{ + PortId: portID, + ChannelId: channelID, + } + + return queryClient.Upgrade(context.Background(), req) +} + +// queryUpgradeErrorABCI queries the upgrade error from the store. +func queryUpgradeErrorABCI(clientCtx client.Context, portID, channelID string) (*types.QueryUpgradeErrorResponse, error) { + key := host.ChannelUpgradeErrorKey(portID, channelID) + + value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key) + if err != nil { + return nil, err + } + + // check if upgrade error exists + if len(value) == 0 { + return nil, errorsmod.Wrapf(types.ErrUpgradeErrorNotFound, "portID (%s), channelID (%s)", portID, channelID) + } + + cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) + + var receipt types.ErrorReceipt + if err := cdc.Unmarshal(value, &receipt); err != nil { + return nil, err + } + + return types.NewQueryUpgradeErrorResponse(receipt, proofBz, proofHeight), nil +} + +// queryUpgradeABCI queries the upgrade from the store. +func queryUpgradeABCI(clientCtx client.Context, portID, channelID string) (*types.QueryUpgradeResponse, error) { + key := host.ChannelUpgradeKey(portID, channelID) + + value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key) + if err != nil { + return nil, err + } + + // check if upgrade exists + if len(value) == 0 { + return nil, errorsmod.Wrapf(types.ErrUpgradeErrorNotFound, "portID (%s), channelID (%s)", portID, channelID) + } + + cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry) + + var upgrade types.Upgrade + if err := cdc.Unmarshal(value, &upgrade); err != nil { + return nil, err + } + + return types.NewQueryUpgradeResponse(upgrade, proofBz, proofHeight), nil +} + // QueryPacketCommitment returns a packet commitment. // If prove is true, it performs an ABCI store query in order to retrieve the merkle proof. Otherwise, // it uses the gRPC query client. diff --git a/modules/core/04-channel/genesis.go b/modules/core/04-channel/genesis.go index 48680d962cd..42481e558c1 100644 --- a/modules/core/04-channel/genesis.go +++ b/modules/core/04-channel/genesis.go @@ -1,6 +1,8 @@ package channel import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/ibc-go/v8/modules/core/04-channel/keeper" @@ -10,6 +12,10 @@ import ( // InitGenesis initializes the ibc channel submodule's state from a provided genesis // state. func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { + if err := gs.Params.Validate(); err != nil { + panic(fmt.Sprintf("invalid ibc channel genesis state parameters: %v", err)) + } + k.SetParams(ctx, gs.Params) for _, channel := range gs.Channels { ch := types.NewChannel(channel.State, channel.Ordering, channel.Counterparty, channel.ConnectionHops, channel.Version) k.SetChannel(ctx, channel.PortId, channel.ChannelId, ch) @@ -46,5 +52,6 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState { RecvSequences: k.GetAllPacketRecvSeqs(ctx), AckSequences: k.GetAllPacketAckSeqs(ctx), NextChannelSequence: k.GetNextChannelSequence(ctx), + Params: k.GetParams(ctx), } } diff --git a/modules/core/04-channel/keeper/events.go b/modules/core/04-channel/keeper/events.go index 3d86db32d9f..ff277a463bd 100644 --- a/modules/core/04-channel/keeper/events.go +++ b/modules/core/04-channel/keeper/events.go @@ -270,3 +270,187 @@ func emitChannelClosedEvent(ctx sdk.Context, packet exported.PacketI, channel ty ), }) } + +// EmitChannelUpgradeInitEvent emits a channel upgrade init event +func EmitChannelUpgradeInitEvent(ctx sdk.Context, portID string, channelID string, currentChannel types.Channel, upgrade types.Upgrade) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelUpgradeInit, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyUpgradeConnectionHops, upgrade.Fields.ConnectionHops[0]), + sdk.NewAttribute(types.AttributeKeyUpgradeVersion, upgrade.Fields.Version), + sdk.NewAttribute(types.AttributeKeyUpgradeOrdering, upgrade.Fields.Ordering.String()), + sdk.NewAttribute(types.AttributeKeyUpgradeSequence, fmt.Sprintf("%d", currentChannel.UpgradeSequence)), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} + +// EmitChannelUpgradeTryEvent emits a channel upgrade try event +func EmitChannelUpgradeTryEvent(ctx sdk.Context, portID string, channelID string, currentChannel types.Channel, upgrade types.Upgrade) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelUpgradeTry, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyUpgradeConnectionHops, upgrade.Fields.ConnectionHops[0]), + sdk.NewAttribute(types.AttributeKeyUpgradeVersion, upgrade.Fields.Version), + sdk.NewAttribute(types.AttributeKeyUpgradeOrdering, upgrade.Fields.Ordering.String()), + sdk.NewAttribute(types.AttributeKeyUpgradeSequence, fmt.Sprintf("%d", currentChannel.UpgradeSequence)), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} + +// EmitChannelUpgradeAckEvent emits a channel upgrade ack event +func EmitChannelUpgradeAckEvent(ctx sdk.Context, portID string, channelID string, currentChannel types.Channel, upgrade types.Upgrade) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelUpgradeAck, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyUpgradeConnectionHops, upgrade.Fields.ConnectionHops[0]), + sdk.NewAttribute(types.AttributeKeyUpgradeVersion, upgrade.Fields.Version), + sdk.NewAttribute(types.AttributeKeyUpgradeOrdering, upgrade.Fields.Ordering.String()), + sdk.NewAttribute(types.AttributeKeyUpgradeSequence, fmt.Sprintf("%d", currentChannel.UpgradeSequence)), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} + +// EmitChannelUpgradeConfirmEvent emits a channel upgrade confirm event +func EmitChannelUpgradeConfirmEvent(ctx sdk.Context, portID, channelID string, currentChannel types.Channel) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelUpgradeConfirm, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeKeyChannelState, currentChannel.State.String()), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyUpgradeSequence, fmt.Sprintf("%d", currentChannel.UpgradeSequence)), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} + +// EmitChannelUpgradeOpenEvent emits a channel upgrade open event +func EmitChannelUpgradeOpenEvent(ctx sdk.Context, portID string, channelID string, currentChannel types.Channel) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelUpgradeOpen, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeKeyChannelState, currentChannel.State.String()), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyUpgradeConnectionHops, currentChannel.ConnectionHops[0]), + sdk.NewAttribute(types.AttributeKeyUpgradeVersion, currentChannel.Version), + sdk.NewAttribute(types.AttributeKeyUpgradeOrdering, currentChannel.Ordering.String()), + sdk.NewAttribute(types.AttributeKeyUpgradeSequence, fmt.Sprintf("%d", currentChannel.UpgradeSequence)), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} + +// EmitChannelUpgradeTimeoutEvent emits an upgrade timeout event. +func EmitChannelUpgradeTimeoutEvent(ctx sdk.Context, portID string, channelID string, currentChannel types.Channel, upgrade types.Upgrade) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelUpgradeTimeout, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyUpgradeConnectionHops, upgrade.Fields.ConnectionHops[0]), + sdk.NewAttribute(types.AttributeKeyUpgradeVersion, upgrade.Fields.Version), + sdk.NewAttribute(types.AttributeKeyUpgradeOrdering, upgrade.Fields.Ordering.String()), + sdk.NewAttribute(types.AttributeKeyUpgradeTimeout, upgrade.Timeout.String()), + sdk.NewAttribute(types.AttributeKeyUpgradeSequence, fmt.Sprintf("%d", currentChannel.UpgradeSequence)), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} + +// EmitErrorReceiptEvent emits an error receipt event +func EmitErrorReceiptEvent(ctx sdk.Context, portID string, channelID string, currentChannel types.Channel, err error) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelUpgradeError, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyUpgradeSequence, fmt.Sprintf("%d", currentChannel.UpgradeSequence)), + sdk.NewAttribute(types.AttributeKeyUpgradeErrorReceipt, err.Error()), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} + +// EmitChannelUpgradeCancelEvent emits an upgraded cancelled event. +func EmitChannelUpgradeCancelEvent(ctx sdk.Context, portID string, channelID string, currentChannel types.Channel, upgrade types.Upgrade) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelUpgradeCancel, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyUpgradeConnectionHops, upgrade.Fields.ConnectionHops[0]), + sdk.NewAttribute(types.AttributeKeyUpgradeVersion, upgrade.Fields.Version), + sdk.NewAttribute(types.AttributeKeyUpgradeOrdering, upgrade.Fields.Ordering.String()), + sdk.NewAttribute(types.AttributeKeyUpgradeSequence, fmt.Sprintf("%d", currentChannel.UpgradeSequence)), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} + +// emitChannelFlushCompleteEvents emits an flushing event. +func emitChannelFlushCompleteEvent(ctx sdk.Context, portID string, channelID string, currentChannel types.Channel) { + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelFlushComplete, + sdk.NewAttribute(types.AttributeKeyPortID, portID), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), + sdk.NewAttribute(types.AttributeCounterpartyPortID, currentChannel.Counterparty.PortId), + sdk.NewAttribute(types.AttributeCounterpartyChannelID, currentChannel.Counterparty.ChannelId), + sdk.NewAttribute(types.AttributeKeyChannelState, currentChannel.State.String()), + ), + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + }) +} diff --git a/modules/core/04-channel/keeper/export_test.go b/modules/core/04-channel/keeper/export_test.go new file mode 100644 index 00000000000..21fad92d9dd --- /dev/null +++ b/modules/core/04-channel/keeper/export_test.go @@ -0,0 +1,36 @@ +package keeper + +/* + This file is to allow for unexported functions to be accessible to the testing package. +*/ + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" +) + +// StartFlushing is a wrapper around startFlushing to allow the function to be directly called in tests. +func (k Keeper) StartFlushing(ctx sdk.Context, portID, channelID string, upgrade *types.Upgrade) error { + return k.startFlushing(ctx, portID, channelID, upgrade) +} + +// ValidateSelfUpgradeFields is a wrapper around validateSelfUpgradeFields to allow the function to be directly called in tests. +func (k Keeper) ValidateSelfUpgradeFields(ctx sdk.Context, proposedUpgrade types.UpgradeFields, currentChannel types.Channel) error { + return k.validateSelfUpgradeFields(ctx, proposedUpgrade, currentChannel) +} + +// CheckForUpgradeCompatibility is a wrapper around checkForUpgradeCompatibility to allow the function to be directly called in tests. +func (k Keeper) CheckForUpgradeCompatibility(ctx sdk.Context, upgradeFields, counterpartyUpgradeFields types.UpgradeFields) error { + return k.checkForUpgradeCompatibility(ctx, upgradeFields, counterpartyUpgradeFields) +} + +// SyncUpgradeSequence is a wrapper around syncUpgradeSequence to allow the function to be directly called in tests. +func (k Keeper) SyncUpgradeSequence(ctx sdk.Context, portID, channelID string, channel types.Channel, counterpartyUpgradeSequence uint64) error { + return k.syncUpgradeSequence(ctx, portID, channelID, channel, counterpartyUpgradeSequence) +} + +// WriteErrorReceipt is a wrapper around writeErrorReceipt to allow the function to be directly called in tests. +func (k Keeper) WriteErrorReceipt(ctx sdk.Context, portID, channelID string, upgradeError *types.UpgradeError) { + k.writeErrorReceipt(ctx, portID, channelID, upgradeError) +} diff --git a/modules/core/04-channel/keeper/grpc_query.go b/modules/core/04-channel/keeper/grpc_query.go index 1802b2f4a1e..130edbc9614 100644 --- a/modules/core/04-channel/keeper/grpc_query.go +++ b/modules/core/04-channel/keeper/grpc_query.go @@ -566,6 +566,78 @@ func (k Keeper) NextSequenceSend(c context.Context, req *types.QueryNextSequence return types.NewQueryNextSequenceSendResponse(sequence, nil, selfHeight), nil } +// UpgradeErrorReceipt implements the Query/UpgradeErrorReceipt gRPC method +func (k Keeper) UpgradeErrorReceipt(c context.Context, req *types.QueryUpgradeErrorRequest) (*types.QueryUpgradeErrorResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + if err := validategRPCRequest(req.PortId, req.ChannelId); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(c) + found := k.HasChannel(ctx, req.PortId, req.ChannelId) + if !found { + return nil, status.Error( + codes.NotFound, + errorsmod.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), + ) + } + + receipt, found := k.GetUpgradeErrorReceipt(ctx, req.PortId, req.ChannelId) + if !found { + return nil, status.Error( + codes.NotFound, + errorsmod.Wrapf(types.ErrUpgradeErrorNotFound, "port-id %s, channel-id %s", req.PortId, req.ChannelId).Error(), + ) + } + + selfHeight := clienttypes.GetSelfHeight(ctx) + return types.NewQueryUpgradeErrorResponse(receipt, nil, selfHeight), nil +} + +// Upgrade implements the Query/UpgradeSequence gRPC method +func (k Keeper) Upgrade(c context.Context, req *types.QueryUpgradeRequest) (*types.QueryUpgradeResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + if err := validategRPCRequest(req.PortId, req.ChannelId); err != nil { + return nil, err + } + + ctx := sdk.UnwrapSDKContext(c) + found := k.HasChannel(ctx, req.PortId, req.ChannelId) + if !found { + return nil, status.Error( + codes.NotFound, + errorsmod.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), + ) + } + + upgrade, found := k.GetUpgrade(ctx, req.PortId, req.ChannelId) + if !found { + return nil, status.Error( + codes.NotFound, + errorsmod.Wrapf(types.ErrUpgradeNotFound, "port-id: %s, channel-id %s", req.PortId, req.ChannelId).Error(), + ) + } + + selfHeight := clienttypes.GetSelfHeight(ctx) + return types.NewQueryUpgradeResponse(upgrade, nil, selfHeight), nil +} + +// ChannelParams implements the Query/ChannelParams gRPC method. +func (k Keeper) ChannelParams(c context.Context, req *types.QueryChannelParamsRequest) (*types.QueryChannelParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + params := k.GetParams(ctx) + + return &types.QueryChannelParamsResponse{ + Params: ¶ms, + }, nil +} + func validategRPCRequest(portID, channelID string) error { if err := host.PortIdentifierValidator(portID); err != nil { return status.Error(codes.InvalidArgument, err.Error()) diff --git a/modules/core/04-channel/keeper/grpc_query_test.go b/modules/core/04-channel/keeper/grpc_query_test.go index 6603c972dc2..12ff1fbabbd 100644 --- a/modules/core/04-channel/keeper/grpc_query_test.go +++ b/modules/core/04-channel/keeper/grpc_query_test.go @@ -8,8 +8,10 @@ import ( clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/cosmos/ibc-go/v8/modules/core/exported" ibctesting "github.com/cosmos/ibc-go/v8/testing" + "github.com/cosmos/ibc-go/v8/testing/mock" ) const doesnotexist = "doesnotexist" @@ -1701,3 +1703,195 @@ func (suite *KeeperTestSuite) TestQueryNextSequenceSend() { }) } } + +func (suite *KeeperTestSuite) TestQueryUpgradeError() { + var ( + req *types.QueryUpgradeErrorRequest + upgradeErr *types.UpgradeError + ) + + testCases := []struct { + msg string + malleate func() + expPass bool + }{ + { + "empty request", + func() { + req = nil + }, + false, + }, + { + "invalid port ID", + func() { + req = &types.QueryUpgradeErrorRequest{ + PortId: "", + ChannelId: "test-channel-id", + } + }, + false, + }, + { + "invalid channel ID", + func() { + req = &types.QueryUpgradeErrorRequest{ + PortId: "test-port-id", + ChannelId: "", + } + }, + false, + }, + { + "channel not found", + func() { + req = &types.QueryUpgradeErrorRequest{ + PortId: "test-port-id", + ChannelId: "test-channel-id", + } + }, + false, + }, + { + "success", + func() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + upgradeErr = types.NewUpgradeError(uint64(1), fmt.Errorf("test error")) + suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgradeErr.GetErrorReceipt()) + + req = &types.QueryUpgradeErrorRequest{ + PortId: path.EndpointA.ChannelConfig.PortID, + ChannelId: path.EndpointA.ChannelID, + } + }, + true, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + + ctx := suite.chainA.GetContext() + res, err := suite.chainA.QueryServer.UpgradeError(ctx, req) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(upgradeErr.GetErrorReceipt(), res.ErrorReceipt) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestQueryUpgrade() { + var ( + req *types.QueryUpgradeRequest + expectedUpgrade types.Upgrade + ) + + testCases := []struct { + msg string + malleate func() + expPass bool + }{ + { + "empty request", + func() { + req = nil + }, + false, + }, + { + "invalid port ID", + func() { + req = &types.QueryUpgradeRequest{ + PortId: "", + ChannelId: "test-channel-id", + } + }, + false, + }, + { + "invalid channel ID", + func() { + req = &types.QueryUpgradeRequest{ + PortId: "test-port-id", + ChannelId: "", + } + }, + false, + }, + { + "channel not found", + func() { + req = &types.QueryUpgradeRequest{ + PortId: "test-port-id", + ChannelId: "test-channel-id", + } + }, + false, + }, + { + "upgrade not found", + func() { + storeKey := suite.chainA.GetSimApp().GetKey(exported.StoreKey) + kvStore := suite.chainA.GetContext().KVStore(storeKey) + kvStore.Delete(host.ChannelUpgradeKey(req.PortId, req.ChannelId)) + }, + false, + }, + { + "success", + func() { + }, + true, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + expectedUpgrade = types.NewUpgrade( + types.NewUpgradeFields(types.UNORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + types.NewTimeout(clienttypes.ZeroHeight(), 1000000), + 0, + ) + + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, expectedUpgrade) + + req = &types.QueryUpgradeRequest{ + PortId: path.EndpointA.ChannelConfig.PortID, + ChannelId: path.EndpointA.ChannelID, + } + + tc.malleate() + + ctx := suite.chainA.GetContext() + res, err := suite.chainA.QueryServer.Upgrade(ctx, req) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(expectedUpgrade, res.Upgrade) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestQueryChannelParams() { + ctx := suite.chainA.GetContext() + expParams := types.DefaultParams() + res, _ := suite.chainA.QueryServer.ChannelParams(ctx, &types.QueryChannelParamsRequest{}) + suite.Require().Equal(&expParams, res.Params) +} diff --git a/modules/core/04-channel/keeper/handshake.go b/modules/core/04-channel/keeper/handshake.go index 30420a67270..3aaad5a95d2 100644 --- a/modules/core/04-channel/keeper/handshake.go +++ b/modules/core/04-channel/keeper/handshake.go @@ -431,6 +431,24 @@ func (k Keeper) ChanCloseConfirm( chanCap *capabilitytypes.Capability, proofInit []byte, proofHeight exported.Height, +) error { + return k.ChanCloseConfirmWithCounterpartyUpgradeSequence(ctx, portID, channelID, chanCap, proofInit, proofHeight, 0) +} + +// ChanCloseConfirmWithCounterpartyUpgradeSequence is called by the counterparty module to +// close their end of the channel, since the other end has been closed. The difference with +// ChanCloseConfirm is that it accepts an extra argument counterpartyUpgradeSequence that was +// needed for channel upgradability. +// +// This function will be removed in ibc-go v9.0.0 and the API of ChanCloseConfirm will be updated. +func (k Keeper) ChanCloseConfirmWithCounterpartyUpgradeSequence( + ctx sdk.Context, + portID, + channelID string, + chanCap *capabilitytypes.Capability, + proofInit []byte, + proofHeight exported.Height, + counterpartyUpgradeSequence uint64, ) error { if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) { return errorsmod.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)") @@ -460,10 +478,14 @@ func (k Keeper) ChanCloseConfirm( counterpartyHops := []string{connectionEnd.GetCounterparty().GetConnectionID()} counterparty := types.NewCounterparty(portID, channelID) - expectedChannel := types.NewChannel( - types.CLOSED, channel.Ordering, counterparty, - counterpartyHops, channel.Version, - ) + expectedChannel := types.Channel{ + State: types.CLOSED, + Ordering: channel.Ordering, + Counterparty: counterparty, + ConnectionHops: counterpartyHops, + Version: channel.Version, + UpgradeSequence: counterpartyUpgradeSequence, + } if err := k.connectionKeeper.VerifyChannelState( ctx, connectionEnd, proofHeight, proofInit, diff --git a/modules/core/04-channel/keeper/handshake_test.go b/modules/core/04-channel/keeper/handshake_test.go index c775e7e6297..b38bc2d3ad9 100644 --- a/modules/core/04-channel/keeper/handshake_test.go +++ b/modules/core/04-channel/keeper/handshake_test.go @@ -10,6 +10,7 @@ import ( host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/cosmos/ibc-go/v8/modules/core/exported" ibctesting "github.com/cosmos/ibc-go/v8/testing" + "github.com/cosmos/ibc-go/v8/testing/mock" ) type testCase = struct { @@ -718,9 +719,10 @@ func (suite *KeeperTestSuite) TestChanCloseInit() { // bypassed on chainA by setting the channel state in the ChannelKeeper. func (suite *KeeperTestSuite) TestChanCloseConfirm() { var ( - path *ibctesting.Path - channelCap *capabilitytypes.Capability - heightDiff uint64 + path *ibctesting.Path + channelCap *capabilitytypes.Capability + heightDiff uint64 + counterpartyUpgradeSequence uint64 ) testCases := []testCase{ @@ -794,13 +796,32 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { channelCap = capabilitytypes.NewCapability(3) }, false}, + { + "failure: invalid counterparty upgrade sequence", + func() { + suite.coordinator.Setup(path) + channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + + // trigger upgradeInit on B which will bump the counterparty upgrade sequence. + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + err := path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointA.SetChannelState(types.CLOSED) + suite.Require().NoError(err) + + channelCap = capabilitytypes.NewCapability(3) + }, + false, + }, } for _, tc := range testCases { tc := tc suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { - suite.SetupTest() // reset - heightDiff = 0 // must explicitly be changed + suite.SetupTest() // reset + heightDiff = 0 // must explicitly be changed + counterpartyUpgradeSequence = 0 // must explicitly be changed path = ibctesting.NewPath(suite.chainA, suite.chainB) tc.malleate() @@ -808,9 +829,9 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, ibctesting.FirstChannelID) proof, proofHeight := suite.chainA.QueryProof(channelKey) - err := suite.chainB.App.GetIBCKeeper().ChannelKeeper.ChanCloseConfirm( + err := suite.chainB.App.GetIBCKeeper().ChannelKeeper.ChanCloseConfirmWithCounterpartyUpgradeSequence( suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, ibctesting.FirstChannelID, channelCap, - proof, malleateHeight(proofHeight, heightDiff), + proof, malleateHeight(proofHeight, heightDiff), counterpartyUpgradeSequence, ) if tc.expPass { diff --git a/modules/core/04-channel/keeper/keeper.go b/modules/core/04-channel/keeper/keeper.go index f285839799a..11bfbe33935 100644 --- a/modules/core/04-channel/keeper/keeper.go +++ b/modules/core/04-channel/keeper/keeper.go @@ -194,6 +194,12 @@ func (k Keeper) SetPacketReceipt(ctx sdk.Context, portID, channelID string, sequ store.Set(host.PacketReceiptKey(portID, channelID, sequence), []byte{byte(1)}) } +// deletePacketReceipt deletes a packet receipt from the store +func (k Keeper) deletePacketReceipt(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := ctx.KVStore(k.storeKey) + store.Delete(host.PacketReceiptKey(portID, channelID, sequence)) +} + // GetPacketCommitment gets the packet commitment hash from the store func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte { store := ctx.KVStore(k.storeKey) @@ -240,6 +246,12 @@ func (k Keeper) HasPacketAcknowledgement(ctx sdk.Context, portID, channelID stri return store.Has(host.PacketAcknowledgementKey(portID, channelID, sequence)) } +// deletePacketAcknowledgement deletes the packet ack hash from the store +func (k Keeper) deletePacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := ctx.KVStore(k.storeKey) + store.Delete(host.PacketAcknowledgementKey(portID, channelID, sequence)) +} + // IteratePacketSequence provides an iterator over all send, receive or ack sequences. // For each sequence, cb will be called. If the cb returns true, the iterator // will close and stop. @@ -481,6 +493,107 @@ func (k Keeper) LookupModuleByChannel(ctx sdk.Context, portID, channelID string) return porttypes.GetModuleOwner(modules), capability, nil } +// GetUpgradeErrorReceipt returns the upgrade error receipt for the provided port and channel identifiers. +func (k Keeper) GetUpgradeErrorReceipt(ctx sdk.Context, portID, channelID string) (types.ErrorReceipt, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(host.ChannelUpgradeErrorKey(portID, channelID)) + if bz == nil { + return types.ErrorReceipt{}, false + } + + var errorReceipt types.ErrorReceipt + k.cdc.MustUnmarshal(bz, &errorReceipt) + + return errorReceipt, true +} + +// SetUpgradeErrorReceipt sets the provided error receipt in store using the port and channel identifiers. +func (k Keeper) SetUpgradeErrorReceipt(ctx sdk.Context, portID, channelID string, errorReceipt types.ErrorReceipt) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&errorReceipt) + store.Set(host.ChannelUpgradeErrorKey(portID, channelID), bz) +} + +// GetUpgrade returns the proposed upgrade for the provided port and channel identifiers. +func (k Keeper) GetUpgrade(ctx sdk.Context, portID, channelID string) (types.Upgrade, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(host.ChannelUpgradeKey(portID, channelID)) + if bz == nil { + return types.Upgrade{}, false + } + + var upgrade types.Upgrade + k.cdc.MustUnmarshal(bz, &upgrade) + + return upgrade, true +} + +// SetUpgrade sets the proposed upgrade using the provided port and channel identifiers. +func (k Keeper) SetUpgrade(ctx sdk.Context, portID, channelID string, upgrade types.Upgrade) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&upgrade) + store.Set(host.ChannelUpgradeKey(portID, channelID), bz) +} + +// deleteUpgrade deletes the upgrade for the provided port and channel identifiers. +func (k Keeper) deleteUpgrade(ctx sdk.Context, portID, channelID string) { + store := ctx.KVStore(k.storeKey) + store.Delete(host.ChannelUpgradeKey(portID, channelID)) +} + +// GetCounterpartyUpgrade gets the counterparty upgrade from the store. +func (k Keeper) GetCounterpartyUpgrade(ctx sdk.Context, portID, channelID string) (types.Upgrade, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(host.ChannelCounterpartyUpgradeKey(portID, channelID)) + if bz == nil { + return types.Upgrade{}, false + } + + var upgrade types.Upgrade + k.cdc.MustUnmarshal(bz, &upgrade) + + return upgrade, true +} + +// SetCounterpartyUpgrade sets the counterparty upgrade in the store. +func (k Keeper) SetCounterpartyUpgrade(ctx sdk.Context, portID, channelID string, upgrade types.Upgrade) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&upgrade) + store.Set(host.ChannelCounterpartyUpgradeKey(portID, channelID), bz) +} + +// deleteCounterpartyUpgrade deletes the counterparty upgrade in the store. +func (k Keeper) deleteCounterpartyUpgrade(ctx sdk.Context, portID, channelID string) { + store := ctx.KVStore(k.storeKey) + store.Delete(host.ChannelCounterpartyUpgradeKey(portID, channelID)) +} + +// deleteUpgradeInfo deletes all auxiliary upgrade information. +func (k Keeper) deleteUpgradeInfo(ctx sdk.Context, portID, channelID string) { + k.deleteUpgrade(ctx, portID, channelID) + k.deleteCounterpartyUpgrade(ctx, portID, channelID) +} + +// SetParams sets the channel parameters. +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(¶ms) + store.Set([]byte(types.ParamsKey), bz) +} + +// GetParams returns the total set of the channel parameters. +func (k Keeper) GetParams(ctx sdk.Context) types.Params { + store := ctx.KVStore(k.storeKey) + bz := store.Get([]byte(types.ParamsKey)) + if bz == nil { // only panic on unset params and not on empty params + panic(errors.New("channel params are not set in store")) + } + + var params types.Params + k.cdc.MustUnmarshal(bz, ¶ms) + return params +} + // common functionality for IteratePacketCommitment and IteratePacketAcknowledgement func (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() }) @@ -500,3 +613,94 @@ func (Keeper) iterateHashes(ctx sdk.Context, iterator db.Iterator, cb func(portI } } } + +// HasInflightPackets returns true if there are packet commitments stored at the specified +// port and channel, and false otherwise. +func (k Keeper) HasInflightPackets(ctx sdk.Context, portID, channelID string) bool { + iterator := storetypes.KVStorePrefixIterator(ctx.KVStore(k.storeKey), []byte(host.PacketCommitmentPrefixPath(portID, channelID))) + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) + + return iterator.Valid() +} + +// SetPruningSequenceEnd sets the channel's pruning sequence end to the store. +func (k Keeper) SetPruningSequenceEnd(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set(host.PruningSequenceEndKey(portID, channelID), bz) +} + +// GetPruningSequenceEnd gets a channel's pruning sequence end from the store. +func (k Keeper) GetPruningSequenceEnd(ctx sdk.Context, portID, channelID string) (uint64, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(host.PruningSequenceEndKey(portID, channelID)) + if len(bz) == 0 { + return 0, false + } + + return sdk.BigEndianToUint64(bz), true +} + +// SetPruningSequenceStart sets a channel's pruning sequence start to the store. +func (k Keeper) SetPruningSequenceStart(ctx sdk.Context, portID, channelID string, sequence uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set(host.PruningSequenceStartKey(portID, channelID), bz) +} + +// GetPruningSequenceStart gets a channel's pruning sequence start from the store. +func (k Keeper) GetPruningSequenceStart(ctx sdk.Context, portID, channelID string) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get(host.PruningSequenceStartKey(portID, channelID)) + if len(bz) == 0 { + return 0 + } + + return sdk.BigEndianToUint64(bz) +} + +// HasPruningSequenceStart returns true if the pruning sequence start is set for the specified channel. +func (k Keeper) HasPruningSequenceStart(ctx sdk.Context, portID, channelID string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(host.PruningSequenceStartKey(portID, channelID)) +} + +// PruneAcknowledgements prunes packet acknowledgements and receipts that have a sequence number less than pruning sequence end. +// The number of packet acks/receipts pruned is bounded by the limit. Pruning can only occur after a channel has been upgraded. +// +// Pruning sequence start keeps track of the packet ack/receipt that can be pruned next. When it reaches pruningSequenceEnd, +// pruning is complete. +func (k Keeper) PruneAcknowledgements(ctx sdk.Context, portID, channelID string, limit uint64) (uint64, uint64, error) { + if !k.HasPruningSequenceStart(ctx, portID, channelID) { + return 0, 0, errorsmod.Wrapf(types.ErrPruningSequenceStartNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + pruningSequenceStart := k.GetPruningSequenceStart(ctx, portID, channelID) + pruningSequenceEnd, found := k.GetPruningSequenceEnd(ctx, portID, channelID) + if !found { + return 0, 0, errorsmod.Wrapf(types.ErrPruningSequenceEndNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + start := pruningSequenceStart + end := pruningSequenceStart + limit + for ; start < end; start++ { + // stop pruning if pruningSequenceStart has reached pruningSequenceEnd, pruningSequenceEnd is + // set to be equal to the _next_ sequence to be sent by the counterparty. + if start >= pruningSequenceEnd { + break + } + + k.deletePacketAcknowledgement(ctx, portID, channelID, start) + + // NOTE: packet receipts are only relevant for unordered channels. + k.deletePacketReceipt(ctx, portID, channelID, start) + } + + // set pruning sequence start to the updated value + k.SetPruningSequenceStart(ctx, portID, channelID, start) + + totalPruned := start - pruningSequenceStart + totalRemaining := pruningSequenceEnd - start + + return totalPruned, totalRemaining, nil +} diff --git a/modules/core/04-channel/keeper/keeper_test.go b/modules/core/04-channel/keeper/keeper_test.go index 94917b92d00..93711a93065 100644 --- a/modules/core/04-channel/keeper/keeper_test.go +++ b/modules/core/04-channel/keeper/keeper_test.go @@ -1,13 +1,17 @@ package keeper_test import ( + "fmt" "reflect" "testing" testifysuite "github.com/stretchr/testify/suite" transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + "github.com/cosmos/ibc-go/v8/modules/core/exported" ibctesting "github.com/cosmos/ibc-go/v8/testing" ibcmock "github.com/cosmos/ibc-go/v8/testing/mock" ) @@ -465,3 +469,394 @@ func (suite *KeeperTestSuite) TestSetPacketAcknowledgement() { suite.Require().Equal(ackHash, storedAckHash) suite.Require().True(suite.chainA.App.GetIBCKeeper().ChannelKeeper.HasPacketAcknowledgement(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, seq)) } + +func (suite *KeeperTestSuite) TestSetUpgradeErrorReceipt() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + suite.coordinator.CreateChannels(path) + + errorReceipt, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found) + suite.Require().Empty(errorReceipt) + + expErrorReceipt := types.NewUpgradeError(1, fmt.Errorf("testing")).GetErrorReceipt() + suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, expErrorReceipt) + + errorReceipt, found = suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(expErrorReceipt, errorReceipt) +} + +// TestDefaultSetParams tests the default params set are what is expected +func (suite *KeeperTestSuite) TestDefaultSetParams() { + expParams := types.DefaultParams() + + channelKeeper := suite.chainA.App.GetIBCKeeper().ChannelKeeper + params := channelKeeper.GetParams(suite.chainA.GetContext()) + + suite.Require().Equal(expParams, params) + suite.Require().Equal(expParams.UpgradeTimeout, channelKeeper.GetParams(suite.chainA.GetContext()).UpgradeTimeout) +} + +// TestParams tests that Param setting and retrieval works properly +func (suite *KeeperTestSuite) TestParams() { + testCases := []struct { + name string + input types.Params + expPass bool + }{ + {"success: set default params", types.DefaultParams(), true}, + {"success: zero timeout height", types.NewParams(types.NewTimeout(clienttypes.ZeroHeight(), 10000)), true}, + {"fail: zero timeout timestamp", types.NewParams(types.NewTimeout(clienttypes.NewHeight(1, 1000), 0)), false}, + {"fail: zero timeout", types.NewParams(types.NewTimeout(clienttypes.ZeroHeight(), 0)), false}, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + suite.SetupTest() // reset + ctx := suite.chainA.GetContext() + err := tc.input.Validate() + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetParams(ctx, tc.input) + if tc.expPass { + suite.Require().NoError(err) + expected := tc.input + p := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetParams(ctx) + suite.Require().Equal(expected, p) + } else { + suite.Require().Error(err) + } + }) + } +} + +// TestUnsetParams tests that trying to get params that are not set panics. +func (suite *KeeperTestSuite) TestUnsetParams() { + suite.SetupTest() + ctx := suite.chainA.GetContext() + store := ctx.KVStore(suite.chainA.GetSimApp().GetKey(exported.StoreKey)) + store.Delete([]byte(types.ParamsKey)) + + suite.Require().Panics(func() { + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetParams(ctx) + }) +} + +func (suite *KeeperTestSuite) TestPruneAcknowledgements() { + var ( + path *ibctesting.Path + limit uint64 + upgradeFields types.UpgradeFields + + // postPruneExpState is a helper function to verify the expected state after pruning. Argument expLeft + // denotes the expected amount of packet acks and receipts left after pruning. Argument expSequenceStart + // denotes the expected value of PruneSequenceStart. + postPruneExpState = func(expAcksLen, expReceiptsLen, expPruningSequenceStart uint64) { + acks := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetAllPacketAcks(suite.chainA.GetContext()) + suite.Require().Len(acks, int(expAcksLen)) + + receipts := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetAllPacketReceipts(suite.chainA.GetContext()) + suite.Require().Len(receipts, int(expReceiptsLen)) + + start := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPruningSequenceStart(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(start, expPruningSequenceStart) + } + ) + + testCases := []struct { + name string + pre func() + malleate func() + post func(pruned, left uint64) + expError error + }{ + { + "success: no packets sent, no stale packet state pruned", + func() {}, + func() {}, + func(pruned, left uint64) { + // Assert that PruneSequenceStart and PruneSequenceEnd are both set to 1. + start := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPruningSequenceStart(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + end, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPruningSequenceEnd(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + + suite.Require().Equal(uint64(1), start) + suite.Require().Equal(uint64(1), end) + + // We expect 0 to be pruned and 0 left. + suite.Require().Equal(uint64(0), pruned) + suite.Require().Equal(uint64(0), left) + }, + nil, + }, + { + "success: stale packet state pruned up to limit", + func() { + // Send 10 packets from B -> A, creating 10 packet receipts and 10 packet acks on A. + suite.sendMockPackets(path, 10) + }, + func() {}, + func(pruned, left uint64) { + sequenceEnd, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPruningSequenceEnd(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + + // We expect nothing to be left and sequenceStart == sequenceEnd. + postPruneExpState(0, 0, sequenceEnd) + + // We expect 10 to be pruned and 0 left. + suite.Require().Equal(uint64(10), pruned) + suite.Require().Equal(uint64(0), left) + }, + nil, + }, + { + "success: stale packet state partially pruned", + func() { + // Send 10 packets from B -> A, creating 10 packet receipts and 10 packet acks on A. + suite.sendMockPackets(path, 10) + }, + func() { + // Prune only 6 packet acks. + limit = 6 + }, + func(pruned, left uint64) { + // We expect 4 to be left and sequenceStart == 7. + postPruneExpState(4, 4, 7) + + // We expect 6 to be pruned and 4 left. + suite.Require().Equal(uint64(6), pruned) + suite.Require().Equal(uint64(4), left) + }, + nil, + }, + { + "success: stale packet state pruned, two upgrades", + func() { + // Send 10 packets from B -> A, creating 10 packet receipts and 10 packet acks on A. + // This is _before_ the first upgrade. + suite.sendMockPackets(path, 10) + }, + func() { + // Previous upgrade is complete, send additional packets and do yet another upgrade. + // This is _after_ the first upgrade. + suite.sendMockPackets(path, 5) + + // Do another upgrade. + upgradeFields = types.UpgradeFields{Version: fmt.Sprintf("%s-v3", ibcmock.Version)} + suite.UpgradeChannel(path, upgradeFields) + + // set limit to 15, get them all in one go. + limit = 15 + }, + func(pruned, left uint64) { + sequenceEnd, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPruningSequenceEnd(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + + // We expect nothing to be left and sequenceStart == sequenceEnd. + postPruneExpState(0, 0, sequenceEnd) + + // We expect 15 to be pruned and 0 left. + suite.Require().Equal(uint64(15), pruned) + suite.Require().Equal(uint64(0), left) + }, + nil, + }, + { + "success: stale packet state partially pruned, upgrade, prune again", + func() { + // Send 10 packets from B -> A, creating 10 packet receipts and 10 packet acks on A. + // This is _before_ the first upgrade. + suite.sendMockPackets(path, 10) + }, + func() { + // Prune 5 on A. + pruned, left, err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.PruneAcknowledgements( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + 4, // limit == 4 + ) + suite.Require().NoError(err) + + // We expect 4 to be pruned and 6 left. + suite.Require().Equal(uint64(4), pruned) + suite.Require().Equal(uint64(6), left) + + // Check state post-prune + postPruneExpState(6, 6, 5) + + // Previous upgrade is complete, send additional packets and do yet another upgrade. + // This is _after_ the first upgrade. + suite.sendMockPackets(path, 10) + + // Do another upgrade. + upgradeFields = types.UpgradeFields{Version: fmt.Sprintf("%s-v3", ibcmock.Version)} + suite.UpgradeChannel(path, upgradeFields) + + // A total of 16 stale acks/receipts exist on A. Prune 10 of them (default in test). + }, + func(pruned, left uint64) { + // Expected state should be 6 acks/receipts left, sequenceStart == 15. + postPruneExpState(6, 6, 15) + + // We expect 10 to be pruned and 6 left. + suite.Require().Equal(uint64(10), pruned) + suite.Require().Equal(uint64(6), left) + }, + nil, + }, + { + "success: unordered -> ordered -> unordered, acksLen != receiptsLen after packet sends", + func() { + // Send 5 packets from B -> A, creating 5 packet receipts and 5 packet acks on A. + // This is _before_ the first upgrade. + suite.sendMockPackets(path, 5) + + // Set Order for upgrade to Ordered. + upgradeFields = types.UpgradeFields{Version: fmt.Sprintf("%s-v2", ibcmock.Version), Ordering: types.ORDERED} + }, + func() { + // Previous upgrade is complete, send additional packets now on ordered channel (only acks!) + suite.sendMockPackets(path, 10) + + // Do another upgrade (go back to Unordered) + upgradeFields = types.UpgradeFields{Version: fmt.Sprintf("%s-v3", ibcmock.Version), Ordering: types.UNORDERED} + suite.UpgradeChannel(path, upgradeFields) + }, + func(pruned, left uint64) { + // After pruning 10 sequences we should be left with 5 acks and zero receipts. + postPruneExpState(5, 0, 11) + + // We expect 10 to be pruned and 5 left. + suite.Require().Equal(uint64(10), pruned) + suite.Require().Equal(uint64(5), left) + }, + nil, + }, + { + "success: packets sent before upgrade are pruned, after upgrade are not", + func() { + // Send 5 packets from B -> A, creating 5 packet receipts and 5 packet acks on A. + suite.sendMockPackets(path, 5) + }, + func() {}, + func(pruned, left uint64) { + // We expect 5 to be pruned and 0 left. + suite.Require().Equal(uint64(5), pruned) + suite.Require().Equal(uint64(0), left) + + // channel upgraded, send additional packets and try and prune. + suite.sendMockPackets(path, 12) + + // attempt to prune 5. + pruned, left, err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.PruneAcknowledgements( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + 5, + ) + suite.Require().NoError(err) + // We expect 0 to be pruned and 0 left. + suite.Require().Equal(uint64(0), pruned) + suite.Require().Equal(uint64(0), left) + + // we _do not_ expect error, simply a fast return + postPruneExpState(12, 12, 6) + }, + nil, + }, + { + "failure: packet sequence start not set", + func() {}, + func() { + path.EndpointA.ChannelConfig.PortID = "portidone" + }, + func(_, _ uint64) {}, + types.ErrPruningSequenceStartNotFound, + }, + { + "failure: packet sequence end not set", + func() {}, + func() { + store := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetKey(exported.StoreKey)) + store.Delete(host.PruningSequenceEndKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + func(_, _ uint64) {}, + types.ErrPruningSequenceEndNotFound, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // Defaults will be filled in for rest. + upgradeFields = types.UpgradeFields{Version: ibcmock.UpgradeVersion} + limit = 10 + + // perform pre upgrade ops. + tc.pre() + + suite.UpgradeChannel(path, upgradeFields) + + tc.malleate() + + pruned, left, err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.PruneAcknowledgements( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + limit, + ) + + suite.Require().ErrorIs(err, tc.expError) + + // check on post state. + tc.post(pruned, left) + }) + } +} + +// UpgradeChannel performs a channel upgrade given a specific set of upgrade fields. +// Question(jim): setup.coordinator.UpgradeChannel() wen? +func (suite *KeeperTestSuite) UpgradeChannel(path *ibctesting.Path, upgradeFields types.UpgradeFields) { + // configure the channel upgrade version on testing endpoints + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields = upgradeFields + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields = upgradeFields + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeConfirm() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeOpen() + suite.Require().NoError(err) + + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) +} + +// sendMockPacket sends a packet from source to dest and acknowledges it on the source (completing the packet lifecycle). +// Question(jim): find a nicer home for this? +func (suite *KeeperTestSuite) sendMockPackets(path *ibctesting.Path, numPackets int) { + for i := 0; i < numPackets; i++ { + + sequence, err := path.EndpointB.SendPacket(clienttypes.NewHeight(1, 1000), disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + + packet := types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, clienttypes.NewHeight(1, 1000), disabledTimeoutTimestamp) + err = path.RelayPacket(packet) + suite.Require().NoError(err) + } +} diff --git a/modules/core/04-channel/keeper/packet.go b/modules/core/04-channel/keeper/packet.go index 28fdbe7a13e..78b7c464b3a 100644 --- a/modules/core/04-channel/keeper/packet.go +++ b/modules/core/04-channel/keeper/packet.go @@ -2,6 +2,7 @@ package keeper import ( "bytes" + "slices" "strconv" "time" @@ -34,11 +35,8 @@ func (k Keeper) SendPacket( return 0, errorsmod.Wrap(types.ErrChannelNotFound, sourceChannel) } - if !channel.IsOpen() { - return 0, errorsmod.Wrapf( - types.ErrInvalidChannelState, - "channel state is not OPEN (got %s)", channel.State.String(), - ) + if channel.State != types.OPEN { + return 0, errorsmod.Wrapf(types.ErrInvalidChannelState, "channel is not OPEN (got %s)", channel.State) } if !k.scopedKeeper.AuthenticateCapability(ctx, channelCap, host.ChannelCapabilityPath(sourcePort, sourceChannel)) { @@ -130,11 +128,26 @@ func (k Keeper) RecvPacket( return errorsmod.Wrap(types.ErrChannelNotFound, packet.GetDestChannel()) } - if !channel.IsOpen() { - return errorsmod.Wrapf( - types.ErrInvalidChannelState, - "channel state is not OPEN (got %s)", channel.State.String(), - ) + if !slices.Contains([]types.State{types.OPEN, types.FLUSHING}, channel.State) { + return errorsmod.Wrapf(types.ErrInvalidChannelState, "expected channel state to be one of [%s, %s], but got %s", types.OPEN, types.FLUSHING, channel.State) + } + + // If counterpartyUpgrade is stored we need to ensure that the + // packet sequence is < counterparty next sequence send. This is a defensive + // check and if the counterparty is implemented correctly, this should never abort. + counterpartyUpgrade, found := k.GetCounterpartyUpgrade(ctx, packet.GetDestPort(), packet.GetDestChannel()) + if found { + // only error if the counterparty next sequence send is set (> 0) + // this error should never be reached, as under normal circumstances the counterparty + // should not send any packets after the upgrade has been started. + counterpartyNextSequenceSend := counterpartyUpgrade.NextSequenceSend + if packet.GetSequence() >= counterpartyNextSequenceSend { + return errorsmod.Wrapf( + types.ErrInvalidPacket, + "failed to receive packet, cannot flush packet at sequence greater than or equal to counterparty next sequence send (%d) ≥ (%d). UNEXPECTED BEHAVIOUR ON COUNTERPARTY, PLEASE REPORT ISSUE TO RELEVANT CHAIN DEVELOPERS", + packet.GetSequence(), counterpartyNextSequenceSend, + ) + } } // Authenticate capability to ensure caller has authority to receive packet on this channel @@ -255,7 +268,6 @@ func (k Keeper) RecvPacket( // incrementing nextSequenceRecv and storing under this chain's channelEnd identifiers // Since this is the receiving chain, our channelEnd is packet's destination port and channel k.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), nextSequenceRecv) - } // log that a packet has been received & executed @@ -371,11 +383,8 @@ func (k Keeper) AcknowledgePacket( ) } - if !channel.IsOpen() { - return errorsmod.Wrapf( - types.ErrInvalidChannelState, - "channel state is not OPEN (got %s)", channel.State.String(), - ) + if !slices.Contains([]types.State{types.OPEN, types.FLUSHING}, channel.State) { + return errorsmod.Wrapf(types.ErrInvalidChannelState, "packets cannot be acknowledged on channel with state (%s)", channel.State) } // Authenticate capability to ensure caller has authority to receive packet on this channel @@ -481,5 +490,29 @@ func (k Keeper) AcknowledgePacket( // emit an event marking that we have processed the acknowledgement emitAcknowledgePacketEvent(ctx, packet, channel) + // if an upgrade is in progress, handling packet flushing and update channel state appropriately + if channel.State == types.FLUSHING { + // counterparty upgrade is written in the OnChanUpgradeAck step. + counterpartyUpgrade, found := k.GetCounterpartyUpgrade(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + if found { + timeout := counterpartyUpgrade.Timeout + selfHeight, selfTimestamp := clienttypes.GetSelfHeight(ctx), uint64(ctx.BlockTime().UnixNano()) + + if timeout.Elapsed(selfHeight, selfTimestamp) { + // packet flushing timeout has expired, abort the upgrade and return nil, + // committing an error receipt to state, restoring the channel and successfully acknowledging the packet. + k.MustAbortUpgrade(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), timeout.ErrTimeoutElapsed(selfHeight, selfTimestamp)) + return nil + } + + // set the channel state to flush complete if all packets have been acknowledged/flushed. + if !k.HasInflightPackets(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) { + channel.State = types.FLUSHCOMPLETE + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + emitChannelFlushCompleteEvent(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } + } + } + return nil } diff --git a/modules/core/04-channel/keeper/packet_test.go b/modules/core/04-channel/keeper/packet_test.go index bd361cb2466..27f43dc9b72 100644 --- a/modules/core/04-channel/keeper/packet_test.go +++ b/modules/core/04-channel/keeper/packet_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" @@ -215,6 +217,34 @@ func (suite *KeeperTestSuite) TestSendPacket() { channelCap = capabilitytypes.NewCapability(5) }, false}, + { + "channel is in FLUSH_COMPLETE state", + func() { + suite.coordinator.Setup(path) + sourceChannel = path.EndpointA.ChannelID + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHCOMPLETE + path.EndpointA.SetChannel(channel) + }, + false, + }, + { + "channel is in FLUSHING state", + func() { + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + + err := path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeTry() + suite.Require().NoError(err) + }, + false, + }, } for i, tc := range testCases { @@ -307,6 +337,77 @@ func (suite *KeeperTestSuite) TestRecvPacket() { }, nil, }, + { + "success with counterpartyNextSequenceSend higher than packet sequence", + func() { + suite.coordinator.Setup(path) + 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) + + channel := path.EndpointB.GetChannel() + channel.State = types.FLUSHING + path.EndpointB.SetChannel(channel) + + // set upgrade next sequence send to sequence + 1 + counterpartyUpgrade := types.Upgrade{NextSequenceSend: sequence + 1} + path.EndpointB.SetChannelCounterpartyUpgrade(counterpartyUpgrade) + }, + nil, + }, + { + "success with counterparty upgrade not found", + func() { + suite.coordinator.Setup(path) + 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) + + channel := path.EndpointB.GetChannel() + channel.State = types.FLUSHING + path.EndpointB.SetChannel(channel) + }, + nil, + }, + { + "failure while upgrading channel, packet sequence ≥ counterparty next send sequence", + func() { + suite.coordinator.Setup(path) + // send 2 packets so that when NextSequenceSend is set to sequence - 1, it is not 0. + _, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + 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) + + channel := path.EndpointB.GetChannel() + channel.State = types.FLUSHING + path.EndpointB.SetChannel(channel) + + // set upgrade next sequence send to sequence - 1 + counterpartyUpgrade := types.Upgrade{NextSequenceSend: sequence - 1} + path.EndpointB.SetChannelCounterpartyUpgrade(counterpartyUpgrade) + }, + types.ErrInvalidPacket, + }, + { + "failure while upgrading channel, channel in flush complete state", + func() { + suite.coordinator.Setup(path) + 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) + + channel := path.EndpointB.GetChannel() + channel.State = types.FLUSHCOMPLETE + path.EndpointB.SetChannel(channel) + }, + types.ErrInvalidChannelState, + }, { "packet already relayed ORDERED channel (no-op)", func() { @@ -675,6 +776,7 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { name string malleate func() expResult func(commitment []byte, err error) + expEvents func(path *ibctesting.Path) map[string]map[string]string }{ { name: "success on ordered channel", @@ -728,6 +830,144 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { suite.Require().Equal(uint64(1), nextSequenceAck, "sequence incremented for UNORDERED channel") }, }, + { + name: "success on channel in flushing state", + malleate: func() { + // setup uses an UNORDERED channel + suite.coordinator.Setup(path) + + // create packet commitment + 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) + + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + path.EndpointA.SetChannel(channel) + }, + expResult: func(commitment []byte, err error) { + suite.Require().NoError(err) + suite.Require().Nil(commitment) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.FLUSHING, channel.State) + + nextSequenceAck, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetNextSequenceAck(suite.chainA.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel()) + suite.Require().True(found) + suite.Require().Equal(uint64(1), nextSequenceAck, "sequence incremented for UNORDERED channel") + }, + }, + { + name: "success on channel in flushing state with valid timeout", + malleate: func() { + // setup uses an UNORDERED channel + suite.coordinator.Setup(path) + + // create packet commitment + 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) + + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + + path.EndpointA.SetChannel(channel) + + counterpartyUpgrade := types.Upgrade{ + Timeout: types.NewTimeout(suite.chainB.GetTimeoutHeight(), 0), + } + + path.EndpointA.SetChannelCounterpartyUpgrade(counterpartyUpgrade) + }, + expResult: func(commitment []byte, err error) { + suite.Require().NoError(err) + suite.Require().Nil(commitment) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.FLUSHCOMPLETE, channel.State) + + nextSequenceAck, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetNextSequenceAck(suite.chainA.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel()) + suite.Require().True(found) + suite.Require().Equal(uint64(1), nextSequenceAck, "sequence incremented for UNORDERED channel") + }, + expEvents: func(path *ibctesting.Path) map[string]map[string]string { + return ibctesting.EventsMap{ + types.EventTypeChannelFlushComplete: { + types.AttributeKeyPortID: path.EndpointA.ChannelConfig.PortID, + types.AttributeKeyChannelID: path.EndpointA.ChannelID, + types.AttributeCounterpartyPortID: path.EndpointB.ChannelConfig.PortID, + types.AttributeCounterpartyChannelID: path.EndpointB.ChannelID, + types.AttributeKeyChannelState: path.EndpointA.GetChannel().State.String(), + }, + sdk.EventTypeMessage: { + sdk.AttributeKeyModule: types.AttributeValueCategory, + }, + } + }, + }, + { + name: "success on channel in flushing state with timeout passed", + malleate: func() { + // setup uses an UNORDERED channel + suite.coordinator.Setup(path) + + // create packet commitment + 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) + + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + + path.EndpointA.SetChannel(channel) + + upgrade := types.Upgrade{ + Fields: types.NewUpgradeFields(types.UNORDERED, []string{ibctesting.FirstConnectionID}, ibcmock.UpgradeVersion), + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), 1), + } + + counterpartyUpgrade := types.Upgrade{ + Fields: types.NewUpgradeFields(types.UNORDERED, []string{ibctesting.FirstConnectionID}, ibcmock.UpgradeVersion), + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), 1), + } + + path.EndpointA.SetChannelUpgrade(upgrade) + path.EndpointA.SetChannelCounterpartyUpgrade(counterpartyUpgrade) + }, + expResult: func(commitment []byte, err error) { + suite.Require().NoError(err) + suite.Require().Nil(commitment) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.OPEN, channel.State) + + nextSequenceAck, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetNextSequenceAck(suite.chainA.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel()) + suite.Require().True(found) + suite.Require().Equal(uint64(1), nextSequenceAck, "sequence incremented for UNORDERED channel") + + errorReceipt, found := path.EndpointA.Chain.App.GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().NotEmpty(errorReceipt) + }, + }, { name: "packet already acknowledged ordered channel (no-op)", malleate: func() { @@ -819,6 +1059,24 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { suite.Require().NotNil(commitment) }, }, + { + name: "channel in flush complete state", + malleate: 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, defaultTimeoutHeight, disabledTimeoutTimestamp) + channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHCOMPLETE + + path.EndpointA.SetChannel(channel) + }, + expResult: func(commitment []byte, err error) { + suite.Require().Error(err) + suite.Require().ErrorIs(err, types.ErrInvalidChannelState) + suite.Require().Nil(commitment) + }, + }, { name: "capability authentication failed ORDERED", malleate: func() { @@ -1057,16 +1315,24 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { suite.SetupTest() // reset path = ibctesting.NewPath(suite.chainA, suite.chainB) + ctx := suite.chainA.GetContext() tc.malleate() packetKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) proof, proofHeight := path.EndpointB.QueryProof(packetKey) - err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.AcknowledgePacket(suite.chainA.GetContext(), channelCap, packet, ack.Acknowledgement(), proof, proofHeight) + err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.AcknowledgePacket(ctx, channelCap, packet, ack.Acknowledgement(), proof, proofHeight) - commitment := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPacketCommitment(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, packet.GetSequence()) + commitment := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPacketCommitment(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, packet.GetSequence()) tc.expResult(commitment, err) + if tc.expEvents != nil { + events := ctx.EventManager().ABCIEvents() + + expEvents := tc.expEvents(path) + + ibctesting.AssertEventsLegacy(&suite.Suite, expEvents, events) + } }) } } diff --git a/modules/core/04-channel/keeper/timeout.go b/modules/core/04-channel/keeper/timeout.go index a3334d2fcdd..c99419cb77f 100644 --- a/modules/core/04-channel/keeper/timeout.go +++ b/modules/core/04-channel/keeper/timeout.go @@ -9,6 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" @@ -84,13 +85,6 @@ func (k Keeper) TimeoutPacket( return types.ErrNoOpMsg } - if !channel.IsOpen() { - return errorsmod.Wrapf( - types.ErrInvalidChannelState, - "channel state is not OPEN (got %s)", channel.State.String(), - ) - } - packetCommitment := types.CommitPacket(k.cdc, packet) // verify we sent the packet and haven't cleared it out yet @@ -132,6 +126,9 @@ func (k Keeper) TimeoutPacket( // TimeoutExecuted deletes the commitment send from this chain after it verifies timeout. // If the timed-out packet came from an ORDERED channel then this channel will be closed. +// If the channel is in the FLUSHING state and there is a counterparty upgrade, then the +// upgrade will be aborted if the upgrade has timed out. Otherwise, if there are no more inflight packets, +// then the channel will be set to the FLUSHCOMPLETE state. // // CONTRACT: this function must be called in the IBC handler func (k Keeper) TimeoutExecuted( @@ -154,9 +151,39 @@ func (k Keeper) TimeoutExecuted( k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + // if an upgrade is in progress, handling packet flushing and update channel state appropriately + if channel.State == types.FLUSHING && channel.Ordering == types.UNORDERED { + counterpartyUpgrade, found := k.GetCounterpartyUpgrade(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) + // once we have received the counterparty timeout in the channel UpgradeAck or UpgradeConfirm handshake steps + // then we can move to flushing complete if the timeout has not passed and there are no in-flight packets + if found { + timeout := counterpartyUpgrade.Timeout + selfHeight, selfTimestamp := clienttypes.GetSelfHeight(ctx), uint64(ctx.BlockTime().UnixNano()) + + if timeout.Elapsed(selfHeight, selfTimestamp) { + // packet flushing timeout has expired, abort the upgrade and return nil, + // committing an error receipt to state, restoring the channel and successfully timing out the packet. + k.MustAbortUpgrade(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), timeout.ErrTimeoutElapsed(selfHeight, selfTimestamp)) + } else if !k.HasInflightPackets(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) { + // set the channel state to flush complete if all packets have been flushed. + channel.State = types.FLUSHCOMPLETE + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + emitChannelFlushCompleteEvent(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } + } + } + if channel.Ordering == types.ORDERED { + // NOTE: if the channel is ORDERED and a packet is timed out in FLUSHING state then + // the upgrade is aborted and the channel is set to CLOSED. + if channel.State == types.FLUSHING { + // an error receipt is written to state and the channel is restored to OPEN + k.MustAbortUpgrade(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), types.ErrPacketTimeout) + } + channel.State = types.CLOSED k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + emitChannelClosedEvent(ctx, packet, channel) } k.Logger(ctx).Info( @@ -171,10 +198,6 @@ func (k Keeper) TimeoutExecuted( // emit an event marking that we have processed the timeout emitTimeoutPacketEvent(ctx, packet, channel) - if channel.Ordering == types.ORDERED && channel.IsClosed() { - emitChannelClosedEvent(ctx, packet, channel) - } - return nil } @@ -189,6 +212,27 @@ func (k Keeper) TimeoutOnClose( proofClosed []byte, proofHeight exported.Height, nextSequenceRecv uint64, +) error { + return k.TimeoutOnCloseWithCounterpartyUpgradeSequence(ctx, chanCap, packet, proof, proofClosed, proofHeight, nextSequenceRecv, 0) +} + +// TimeoutOnCloseWithCounterpartyUpgradeSequence is called by a module in order +// to prove that the channel to which an unreceived packet was addressed has +// been closed, so the packet will never be received (even if the timeoutHeight +// has not yet been reached). The difference with TimeoutOnClose is that it +// accepts an extra argument counterpartyUpgradeSequence that was needed for +// channel upgradability. +// +// This function will be removed in ibc-go v9.0.0 and the API of TimeoutOnClose will be updated. +func (k Keeper) TimeoutOnCloseWithCounterpartyUpgradeSequence( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + packet exported.PacketI, + proof, + proofClosed []byte, + proofHeight exported.Height, + nextSequenceRecv uint64, + counterpartyUpgradeSequence uint64, ) error { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { @@ -243,9 +287,14 @@ func (k Keeper) TimeoutOnClose( counterpartyHops := []string{connectionEnd.GetCounterparty().GetConnectionID()} counterparty := types.NewCounterparty(packet.GetSourcePort(), packet.GetSourceChannel()) - expectedChannel := types.NewChannel( - types.CLOSED, channel.Ordering, counterparty, counterpartyHops, channel.Version, - ) + expectedChannel := types.Channel{ + State: types.CLOSED, + Ordering: channel.Ordering, + Counterparty: counterparty, + ConnectionHops: counterpartyHops, + Version: channel.Version, + UpgradeSequence: counterpartyUpgradeSequence, + } // check that the opposing channel end has closed if err := k.connectionKeeper.VerifyChannelState( diff --git a/modules/core/04-channel/keeper/timeout_test.go b/modules/core/04-channel/keeper/timeout_test.go index adaf237cf42..2656469157d 100644 --- a/modules/core/04-channel/keeper/timeout_test.go +++ b/modules/core/04-channel/keeper/timeout_test.go @@ -6,6 +6,8 @@ import ( errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" @@ -13,6 +15,7 @@ import ( host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/cosmos/ibc-go/v8/modules/core/exported" ibctesting "github.com/cosmos/ibc-go/v8/testing" + "github.com/cosmos/ibc-go/v8/testing/mock" ) // TestTimeoutPacket test the TimeoutPacket call on chainA by ensuring the timeout has passed @@ -98,22 +101,6 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { suite.coordinator.Setup(path) 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) - - 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 - err = path.EndpointA.UpdateClient() - suite.Require().NoError(err) - - 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) @@ -246,8 +233,9 @@ func (suite *KeeperTestSuite) TestTimeoutPacket() { } } -// TestTimeoutExectued verifies that packet commitments are deleted on chainA after the -// channel capabilities are verified. +// TestTimeoutExecuted verifies that packet commitments are deleted on chainA after the +// channel capabilities are verified. In addition, the test verifies that the channel state +// after a timeout is updated accordingly. func (suite *KeeperTestSuite) TestTimeoutExecuted() { var ( path *ibctesting.Path @@ -255,38 +243,276 @@ func (suite *KeeperTestSuite) TestTimeoutExecuted() { chanCap *capabilitytypes.Capability ) - testCases := []testCase{ - {"success ORDERED", func() { - path.SetChannelOrdered() - suite.coordinator.Setup(path) + testCases := []struct { + msg string + malleate func() + expResult func(packetCommitment []byte, err error) + expEvents func(path *ibctesting.Path) map[string]map[string]string + }{ + { + "success ORDERED", + func() { + path.SetChannelOrdered() + suite.coordinator.Setup(path) + + 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) - timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) - timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + 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) + }, + func(packetCommitment []byte, err error) { + suite.Require().NoError(err) + suite.Require().Nil(packetCommitment) + + // Check channel has been closed + channel := path.EndpointA.GetChannel() + suite.Require().Equal(channel.State, types.CLOSED) + }, + nil, + }, + { + "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, defaultTimeoutHeight, disabledTimeoutTimestamp) + }, + func(packetCommitment []byte, err error) { + suite.Require().Error(err) + suite.Require().ErrorIs(err, types.ErrChannelNotFound) + + // packet never sent. + suite.Require().Nil(packetCommitment) + }, + nil, + }, + { + "incorrect capability ORDERED", + func() { + path.SetChannelOrdered() + suite.coordinator.Setup(path) + + 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) - 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) + }, + func(packetCommitment []byte, err error) { + suite.Require().Error(err) + suite.Require().ErrorIs(err, types.ErrChannelCapabilityNotFound) + + // packet sent, never deleted. + suite.Require().NotNil(packetCommitment) + }, + nil, + }, + { + "set to flush complete with no inflight packets", + func() { + suite.coordinator.Setup(path) + + chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + path.EndpointA.SetChannel(channel) + path.EndpointA.SetChannelCounterpartyUpgrade(types.Upgrade{ + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), uint64(suite.chainA.GetContext().BlockTime().UnixNano())+types.DefaultTimeout.Timestamp), + }) + }, + func(packetCommitment []byte, err error) { + 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, defaultTimeoutHeight, disabledTimeoutTimestamp) - }, false}, - {"incorrect capability ORDERED", func() { - path.SetChannelOrdered() - suite.coordinator.Setup(path) + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.FLUSHCOMPLETE, channel.State, "channel state should still be set to FLUSHCOMPLETE") + }, + func(path *ibctesting.Path) map[string]map[string]string { + return ibctesting.EventsMap{ + types.EventTypeChannelFlushComplete: { + types.AttributeKeyPortID: path.EndpointA.ChannelConfig.PortID, + types.AttributeKeyChannelID: path.EndpointA.ChannelID, + types.AttributeCounterpartyPortID: path.EndpointB.ChannelConfig.PortID, + types.AttributeCounterpartyChannelID: path.EndpointB.ChannelID, + types.AttributeKeyChannelState: path.EndpointA.GetChannel().State.String(), + }, + sdk.EventTypeMessage: { + sdk.AttributeKeyModule: types.AttributeValueCategory, + }, + } + }, + }, + { + "conterparty upgrade timeout is invalid", + func() { + suite.coordinator.Setup(path) - timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) - timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + 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) + 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}, + 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) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + path.EndpointA.SetChannel(channel) + }, + func(packetCommitment []byte, err error) { + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.FLUSHING, channel.State, "channel state should still be FLUSHING") + }, + nil, + }, + { + "conterparty upgrade timed out (abort)", + func() { + suite.coordinator.Setup(path) + + 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) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + path.EndpointA.SetChannel(channel) + path.EndpointA.SetChannelUpgrade(types.Upgrade{ + Fields: path.EndpointA.GetProposedUpgrade().Fields, + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), 1), + }) + path.EndpointA.SetChannelCounterpartyUpgrade(types.Upgrade{ + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), 1), + }) + }, + func(packetCommitment []byte, err error) { + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.OPEN, channel.State, "channel state should still be OPEN") + + upgrade, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found, "upgrade should not be present") + suite.Require().Equal(types.Upgrade{}, upgrade, "upgrade should be zero value") + + upgrade, found = suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetCounterpartyUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found, "counterparty upgrade should not be present") + suite.Require().Equal(types.Upgrade{}, upgrade, "counterparty upgrade should be zero value") + + errorReceipt, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found, "error receipt should be present") + suite.Require().Equal(channel.UpgradeSequence, errorReceipt.Sequence, "error receipt sequence should be equal to channel upgrade sequence") + }, + nil, + }, + { + "conterparty upgrade has not timed out with in-flight packets", + func() { + suite.coordinator.Setup(path) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + timeoutTimestamp := uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + + // we are sending two packets here as one will be removed in TimeoutExecuted. This is to ensure that + // there is still an in-flight packet so that the channel remains in the flushing state. + _, err := path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + + 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) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + path.EndpointA.SetChannel(channel) + path.EndpointA.SetChannelUpgrade(types.Upgrade{ + Fields: path.EndpointA.GetProposedUpgrade().Fields, + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), uint64(suite.chainA.GetContext().BlockTime().UnixNano())+types.DefaultTimeout.Timestamp), + }) + path.EndpointA.SetChannelCounterpartyUpgrade(types.Upgrade{ + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), uint64(suite.chainB.GetContext().BlockTime().UnixNano())+types.DefaultTimeout.Timestamp), + }) + }, + func(packetCommitment []byte, err error) { + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.FLUSHING, channel.State, "channel state should still be FLUSHING") + + _, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found, "upgrade should not be deleted") + + _, found = suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetCounterpartyUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found, "counterparty upgrade should not be deleted") + + _, found = suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found, "error receipt should not be written") + }, + nil, + }, + { + "ordered channel is closed and upgrade is aborted when timeout is executed", + func() { + path.SetChannelOrdered() + suite.coordinator.Setup(path) + + 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) + + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + path.EndpointA.SetChannel(channel) + path.EndpointA.SetChannelUpgrade(types.Upgrade{ + Fields: path.EndpointA.GetProposedUpgrade().Fields, + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), 1), + }) + path.EndpointA.SetChannelCounterpartyUpgrade(types.Upgrade{ + Timeout: types.NewTimeout(clienttypes.ZeroHeight(), 1), + }) + }, + func(packetCommitment []byte, err error) { + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.CLOSED, channel.State, "channel state should be CLOSED") + + upgrade, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found, "upgrade should not be present") + suite.Require().Equal(types.Upgrade{}, upgrade, "upgrade should be zero value") + + upgrade, found = suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetCounterpartyUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found, "counterparty upgrade should not be present") + suite.Require().Equal(types.Upgrade{}, upgrade, "counterparty upgrade should be zero value") + + errorReceipt, found := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found, "error receipt should be present") + suite.Require().Equal(channel.UpgradeSequence, errorReceipt.Sequence, "error receipt sequence should be equal to channel upgrade sequence") + }, + nil, + }, } for i, tc := range testCases { @@ -294,17 +520,20 @@ func (suite *KeeperTestSuite) TestTimeoutExecuted() { suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { suite.SetupTest() // reset path = ibctesting.NewPath(suite.chainA, suite.chainB) + ctx := suite.chainA.GetContext() tc.malleate() - err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.TimeoutExecuted(suite.chainA.GetContext(), chanCap, packet) - pc := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPacketCommitment(suite.chainA.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.TimeoutExecuted(ctx, chanCap, packet) + pc := suite.chainA.App.GetIBCKeeper().ChannelKeeper.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) - if tc.expPass { - suite.NoError(err) - suite.Nil(pc) - } else { - suite.Error(err) + tc.expResult(pc, err) + if tc.expEvents != nil { + events := ctx.EventManager().ABCIEvents() + + expEvents := tc.expEvents(path) + + ibctesting.AssertEventsLegacy(&suite.Suite, expEvents, events) } }) } @@ -314,11 +543,12 @@ func (suite *KeeperTestSuite) TestTimeoutExecuted() { // channel on chainB after the packet commitment has been created. func (suite *KeeperTestSuite) TestTimeoutOnClose() { var ( - path *ibctesting.Path - packet types.Packet - chanCap *capabilitytypes.Capability - nextSeqRecv uint64 - ordered bool + path *ibctesting.Path + packet types.Packet + chanCap *capabilitytypes.Capability + nextSeqRecv uint64 + counterpartyUpgradeSequence uint64 + ordered bool ) testCases := []testCase{ @@ -483,6 +713,34 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { 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}, + { + "failure: invalid counterparty upgrade sequence", + func() { + ordered = false + suite.coordinator.Setup(path) + + timeoutHeight := clienttypes.GetSelfHeight(suite.chainB.GetContext()) + + sequence, err := path.EndpointA.SendPacket(timeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + + // trigger upgradeInit on B which will bump the counterparty upgrade sequence. + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + err = path.EndpointB.ChanUpgradeInit() + 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 + 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, + }, } for i, tc := range testCases { @@ -490,8 +748,9 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { var proof []byte - suite.SetupTest() // reset - nextSeqRecv = 1 // must be explicitly changed + suite.SetupTest() // reset + nextSeqRecv = 1 // must be explicitly changed + counterpartyUpgradeSequence = 0 // must be explicitly changed path = ibctesting.NewPath(suite.chainA, suite.chainB) tc.malleate() @@ -508,7 +767,16 @@ func (suite *KeeperTestSuite) TestTimeoutOnClose() { proof, _ = suite.chainB.QueryProof(unorderedPacketKey) } - err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.TimeoutOnClose(suite.chainA.GetContext(), chanCap, packet, proof, proofClosed, proofHeight, nextSeqRecv) + err := suite.chainA.App.GetIBCKeeper().ChannelKeeper.TimeoutOnCloseWithCounterpartyUpgradeSequence( + suite.chainA.GetContext(), + chanCap, + packet, + proof, + proofClosed, + proofHeight, + nextSeqRecv, + counterpartyUpgradeSequence, + ) if tc.expPass { suite.Require().NoError(err) diff --git a/modules/core/04-channel/keeper/upgrade.go b/modules/core/04-channel/keeper/upgrade.go new file mode 100644 index 00000000000..5f451955606 --- /dev/null +++ b/modules/core/04-channel/keeper/upgrade.go @@ -0,0 +1,1015 @@ +package keeper + +import ( + "fmt" + "reflect" + "slices" + + errorsmod "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v8/modules/core/exported" +) + +// ChanUpgradeInit is called by a module to initiate a channel upgrade handshake with +// a module on another chain. +func (k Keeper) ChanUpgradeInit( + ctx sdk.Context, + portID string, + channelID string, + upgradeFields types.UpgradeFields, +) (types.Upgrade, error) { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.Upgrade{}, errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + if channel.State != types.OPEN { + return types.Upgrade{}, errorsmod.Wrapf(types.ErrInvalidChannelState, "expected %s, got %s", types.OPEN, channel.State) + } + + if err := k.validateSelfUpgradeFields(ctx, upgradeFields, channel); err != nil { + return types.Upgrade{}, err + } + + // NOTE: the Upgrade returned here is intentionally not fully populated. The Timeout remains unset + // until the counterparty calls ChanUpgradeTry. + return types.Upgrade{Fields: upgradeFields}, nil +} + +// WriteUpgradeInitChannel writes a channel which has successfully passed the UpgradeInit handshake step. +// An event is emitted for the handshake step. +func (k Keeper) WriteUpgradeInitChannel(ctx sdk.Context, portID, channelID string, upgrade types.Upgrade, upgradeVersion string) (types.Channel, types.Upgrade) { + defer telemetry.IncrCounter(1, "ibc", "channel", "upgrade-init") + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing channel when updating channel state in successful ChanUpgradeInit step, channelID: %s, portID: %s", channelID, portID)) + } + + channel.UpgradeSequence++ + + upgrade.Fields.Version = upgradeVersion + + k.SetChannel(ctx, portID, channelID, channel) + k.SetUpgrade(ctx, portID, channelID, upgrade) + + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "state", channel.State, "upgrade-sequence", fmt.Sprintf("%d", channel.UpgradeSequence)) + + return channel, upgrade +} + +// ChanUpgradeTry is called by a module to accept the first step of a channel upgrade handshake initiated by +// a module on another chain. If this function is successful, the proposed upgrade will be returned. If the upgrade fails, the upgrade sequence will still be incremented but an error will be returned. +func (k Keeper) ChanUpgradeTry( + ctx sdk.Context, + portID, + channelID string, + proposedConnectionHops []string, + counterpartyUpgradeFields types.UpgradeFields, + counterpartyUpgradeSequence uint64, + proofCounterpartyChannel, + proofCounterpartyUpgrade []byte, + proofHeight clienttypes.Height, +) (types.Channel, types.Upgrade, error) { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return types.Channel{}, types.Upgrade{}, errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + if !channel.IsOpen() { + return types.Channel{}, types.Upgrade{}, errorsmod.Wrapf(types.ErrInvalidChannelState, "expected %s, got %s", types.OPEN, channel.State) + } + + connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return types.Channel{}, types.Upgrade{}, errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + return types.Channel{}, types.Upgrade{}, errorsmod.Wrapf( + connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connection.GetState()).String(), + ) + } + + // construct expected counterparty channel from information in state + // only the counterpartyUpgradeSequence is provided by the relayer + counterpartyConnectionHops := []string{connection.GetCounterparty().GetConnectionID()} + counterpartyChannel := types.Channel{ + State: types.OPEN, + Ordering: channel.Ordering, + Counterparty: types.NewCounterparty(portID, channelID), + ConnectionHops: counterpartyConnectionHops, + Version: channel.Version, + UpgradeSequence: counterpartyUpgradeSequence, // provided by the relayer + } + + // verify the counterparty channel state containing the upgrade sequence + if err := k.connectionKeeper.VerifyChannelState( + ctx, + connection, + proofHeight, proofCounterpartyChannel, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + counterpartyChannel, + ); err != nil { + return types.Channel{}, types.Upgrade{}, errorsmod.Wrap(err, "failed to verify counterparty channel state") + } + + var ( + err error + upgrade types.Upgrade + isCrossingHello bool + ) + + upgrade, isCrossingHello = k.GetUpgrade(ctx, portID, channelID) + if counterpartyUpgradeSequence < channel.UpgradeSequence { + // In this case, the counterparty upgrade is outdated. We want to force the counterparty + // to abort their upgrade and come back to sync with our own upgrade sequence. + var upgradeSequence uint64 + if isCrossingHello { + // In the crossing hello case, we already have an upgrade but it is at a higher sequence than the counterparty. + // Thus, our upgrade should take priority. We force the counterparty to abort their upgrade by invalidating all counterparty + // upgrade attempts below our own sequence by setting errorReceipt to upgradeSequence - 1. + // The upgrade handshake may then proceed on the counterparty with our sequence + upgradeSequence = channel.UpgradeSequence - 1 + } else { + // In the case, that we are in a non-crossing hello (i.e. upgrade does not exist on our side), + // the sequence on both sides should move to a fresh sequence on the next upgrade attempt. + // Thus, we write an error receipt with our own upgrade sequence which will cause the counterparty + // to cancel their upgrade and move to the same sequence. When a new upgrade attempt is started from either + // side, it will be a fresh sequence for both sides (i.e. channel.upgradeSequence + 1) + upgradeSequence = channel.UpgradeSequence + } + + // NOTE: Two possible outcomes may occur in this scenario. + // The ChanUpgradeCancel datagram may reach the counterparty first, which will cause the counterparty to cancel. The counterparty + // may then receive a TRY with our channel upgrade sequence and correctly increment their sequence to become synced with our upgrade attempt. + // The ChanUpgradeTry message may arrive first, in this case, **IF** the upgrade fields are mutually compatible; the counterparty will simply + // fast forward their sequence to our own and continue the upgrade. The following ChanUpgradeCancel message will be rejected as it is below the current sequence. + + return channel, upgrade, types.NewUpgradeError(upgradeSequence, errorsmod.Wrapf( + types.ErrInvalidUpgradeSequence, "counterparty upgrade sequence < current upgrade sequence (%d < %d)", counterpartyUpgradeSequence, channel.UpgradeSequence, + )) + } + + // verifies the proof that a particular proposed upgrade has been stored in the upgrade path of the counterparty + if err := k.connectionKeeper.VerifyChannelUpgrade( + ctx, + connection, + proofHeight, proofCounterpartyUpgrade, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + types.NewUpgrade(counterpartyUpgradeFields, types.Timeout{}, 0), + ); err != nil { + return types.Channel{}, types.Upgrade{}, errorsmod.Wrap(err, "failed to verify counterparty upgrade") + } + + // construct counterpartyChannel from existing information and provided counterpartyUpgradeSequence + // create upgrade fields from counterparty proposed upgrade and own verified connection hops + proposedUpgradeFields := types.UpgradeFields{ + Ordering: counterpartyUpgradeFields.Ordering, + ConnectionHops: proposedConnectionHops, + Version: counterpartyUpgradeFields.Version, + } + + // NOTE: if an upgrade exists (crossing hellos) then use existing upgrade fields + // otherwise, run the upgrade init sub-protocol + if isCrossingHello { + proposedUpgradeFields = upgrade.Fields + } else { + // NOTE: OnChanUpgradeInit will not be executed by the application + upgrade, err = k.ChanUpgradeInit(ctx, portID, channelID, proposedUpgradeFields) + if err != nil { + return types.Channel{}, types.Upgrade{}, errorsmod.Wrap(err, "failed to initialize upgrade") + } + + channel, upgrade = k.WriteUpgradeInitChannel(ctx, portID, channelID, upgrade, upgrade.Fields.Version) + } + + if err := k.checkForUpgradeCompatibility(ctx, proposedUpgradeFields, counterpartyUpgradeFields); err != nil { + return types.Channel{}, types.Upgrade{}, errorsmod.Wrap(err, "failed upgrade compatibility check") + } + + // if the counterparty sequence is greater than the current sequence, we fast-forward to the counterparty sequence. + if counterpartyUpgradeSequence > channel.UpgradeSequence { + channel.UpgradeSequence = counterpartyUpgradeSequence + k.SetChannel(ctx, portID, channelID, channel) + } + + if err := k.startFlushing(ctx, portID, channelID, &upgrade); err != nil { + return types.Channel{}, types.Upgrade{}, err + } + + return channel, upgrade, nil +} + +// WriteUpgradeTryChannel writes the channel end and upgrade to state after successfully passing the UpgradeTry handshake step. +// An event is emitted for the handshake step. +func (k Keeper) WriteUpgradeTryChannel(ctx sdk.Context, portID, channelID string, upgrade types.Upgrade, upgradeVersion string) (types.Channel, types.Upgrade) { + defer telemetry.IncrCounter(1, "ibc", "channel", "upgrade-try") + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing channel when updating channel state in successful ChanUpgradeTry step, channelID: %s, portID: %s", channelID, portID)) + } + + upgrade.Fields.Version = upgradeVersion + k.SetUpgrade(ctx, portID, channelID, upgrade) + + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "previous-state", types.OPEN, "new-state", channel.State) + + return channel, upgrade +} + +// ChanUpgradeAck is called by a module to accept the ACKUPGRADE handshake step of the channel upgrade protocol. +// This method should only be called by the IBC core msg server. +// This method will verify that the counterparty has called the ChanUpgradeTry handler. +// and that its own upgrade is compatible with the selected counterparty version. +// NOTE: the channel may be in either the OPEN or FLUSHING state. +// The channel may be in OPEN if we are in the happy path. +// +// A -> Init (OPEN), B -> Try (FLUSHING), A -> Ack (begins in OPEN) +// +// The channel may be in FLUSHING if we are in a crossing hellos situation. +// +// A -> Init (OPEN), B -> Init (OPEN) -> A -> Try (FLUSHING), B -> Try (FLUSHING), A -> Ack (begins in FLUSHING) +func (k Keeper) ChanUpgradeAck( + ctx sdk.Context, + portID, + channelID string, + counterpartyUpgrade types.Upgrade, + proofChannel, + proofUpgrade []byte, + proofHeight clienttypes.Height, +) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + if !slices.Contains([]types.State{types.OPEN, types.FLUSHING}, channel.State) { + return errorsmod.Wrapf(types.ErrInvalidChannelState, "expected one of [%s, %s], got %s", types.OPEN, types.FLUSHING, channel.State) + } + + connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + return errorsmod.Wrapf(connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connection.GetState()).String()) + } + + counterpartyHops := []string{connection.GetCounterparty().GetConnectionID()} + counterpartyChannel := types.Channel{ + State: types.FLUSHING, + Ordering: channel.Ordering, + ConnectionHops: counterpartyHops, + Counterparty: types.NewCounterparty(portID, channelID), + Version: channel.Version, + UpgradeSequence: channel.UpgradeSequence, + } + + // verify the counterparty channel state containing the upgrade sequence + if err := k.connectionKeeper.VerifyChannelState( + ctx, + connection, + proofHeight, proofChannel, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + counterpartyChannel, + ); err != nil { + return errorsmod.Wrap(err, "failed to verify counterparty channel state") + } + + // verifies the proof that a particular proposed upgrade has been stored in the upgrade path of the counterparty + if err := k.connectionKeeper.VerifyChannelUpgrade( + ctx, + connection, + proofHeight, proofUpgrade, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + counterpartyUpgrade, + ); err != nil { + return errorsmod.Wrap(err, "failed to verify counterparty upgrade") + } + + upgrade, found := k.GetUpgrade(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrUpgradeNotFound, "failed to retrieve channel upgrade: port ID (%s) channel ID (%s)", portID, channelID) + } + + // optimistically accept version that TRY chain proposes and pass this to callback for confirmation + // in the crossing hello case, we do not modify version that our TRY call returned and instead enforce + // that both TRY calls returned the same version. It is possible that this will fail in the OnChanUpgradeAck + // callback if the version is invalid. + if channel.IsOpen() { + upgrade.Fields.Version = counterpartyUpgrade.Fields.Version + } + + // if upgrades are not compatible by ACK step, then we restore the channel + if err := k.checkForUpgradeCompatibility(ctx, upgrade.Fields, counterpartyUpgrade.Fields); err != nil { + return types.NewUpgradeError(channel.UpgradeSequence, err) + } + + if channel.IsOpen() { + if err := k.startFlushing(ctx, portID, channelID, &upgrade); err != nil { + return err + } + } + + timeout := counterpartyUpgrade.Timeout + selfHeight, selfTimestamp := clienttypes.GetSelfHeight(ctx), uint64(ctx.BlockTime().UnixNano()) + + if timeout.Elapsed(selfHeight, selfTimestamp) { + return types.NewUpgradeError(channel.UpgradeSequence, errorsmod.Wrap(timeout.ErrTimeoutElapsed(selfHeight, selfTimestamp), "counterparty upgrade timeout elapsed")) + } + + return nil +} + +// WriteUpgradeAckChannel writes a channel which has successfully passed the UpgradeAck handshake step as well as +// setting the upgrade for that channel. +// An event is emitted for the handshake step. +func (k Keeper) WriteUpgradeAckChannel(ctx sdk.Context, portID, channelID string, counterpartyUpgrade types.Upgrade) (types.Channel, types.Upgrade) { + defer telemetry.IncrCounter(1, "ibc", "channel", "upgrade-ack") + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing channel when updating channel state in successful ChanUpgradeAck step, channelID: %s, portID: %s", channelID, portID)) + } + + if !k.HasInflightPackets(ctx, portID, channelID) { + channel.State = types.FLUSHCOMPLETE + k.SetChannel(ctx, portID, channelID, channel) + } + + upgrade, found := k.GetUpgrade(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing upgrade when updating channel state in successful ChanUpgradeAck step, channelID: %s, portID: %s", channelID, portID)) + } + + upgrade.Fields.Version = counterpartyUpgrade.Fields.Version + + k.SetUpgrade(ctx, portID, channelID, upgrade) + k.SetCounterpartyUpgrade(ctx, portID, channelID, counterpartyUpgrade) + + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "state", channel.State.String()) + return channel, upgrade +} + +// ChanUpgradeConfirm is called on the chain which is on FLUSHING after chanUpgradeAck is called on the counterparty. +// This will inform the TRY chain of the timeout set on ACK by the counterparty. If the timeout has already exceeded, we will write an error receipt and restore. +func (k Keeper) ChanUpgradeConfirm( + ctx sdk.Context, + portID, + channelID string, + counterpartyChannelState types.State, + counterpartyUpgrade types.Upgrade, + proofChannel, + proofUpgrade []byte, + proofHeight clienttypes.Height, +) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + if channel.State != types.FLUSHING { + return errorsmod.Wrapf(types.ErrInvalidChannelState, "expected %s, got %s", types.FLUSHING, channel.State) + } + + if !slices.Contains([]types.State{types.FLUSHING, types.FLUSHCOMPLETE}, counterpartyChannelState) { + return errorsmod.Wrapf(types.ErrInvalidCounterparty, "expected one of [%s, %s], got %s", types.FLUSHING, types.FLUSHCOMPLETE, counterpartyChannelState) + } + + connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + return errorsmod.Wrapf(connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connection.GetState()).String()) + } + + counterpartyHops := []string{connection.GetCounterparty().GetConnectionID()} + counterpartyChannel := types.Channel{ + State: counterpartyChannelState, + Ordering: channel.Ordering, + ConnectionHops: counterpartyHops, + Counterparty: types.NewCounterparty(portID, channelID), + Version: channel.Version, + UpgradeSequence: channel.UpgradeSequence, + } + + if err := k.connectionKeeper.VerifyChannelState( + ctx, + connection, + proofHeight, proofChannel, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + counterpartyChannel, + ); err != nil { + return errorsmod.Wrap(err, "failed to verify counterparty channel state") + } + + if err := k.connectionKeeper.VerifyChannelUpgrade( + ctx, + connection, + proofHeight, proofUpgrade, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + counterpartyUpgrade, + ); err != nil { + return errorsmod.Wrap(err, "failed to verify counterparty upgrade") + } + + timeout := counterpartyUpgrade.Timeout + selfHeight, selfTimestamp := clienttypes.GetSelfHeight(ctx), uint64(ctx.BlockTime().UnixNano()) + + if timeout.Elapsed(selfHeight, selfTimestamp) { + return types.NewUpgradeError(channel.UpgradeSequence, errorsmod.Wrap(timeout.ErrTimeoutElapsed(selfHeight, selfTimestamp), "counterparty upgrade timeout elapsed")) + } + + return nil +} + +// WriteUpgradeConfirmChannel writes a channel which has successfully passed the ChanUpgradeConfirm handshake step. +// If the channel has no in-flight packets, its state is updated to indicate that flushing has completed. Otherwise, the counterparty upgrade is set +// and the channel state is left unchanged. +// An event is emitted for the handshake step. +func (k Keeper) WriteUpgradeConfirmChannel(ctx sdk.Context, portID, channelID string, counterpartyUpgrade types.Upgrade) types.Channel { + defer telemetry.IncrCounter(1, "ibc", "channel", "upgrade-confirm") + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing channel when updating channel state in successful ChanUpgradeConfirm step, channelID: %s, portID: %s", channelID, portID)) + } + + if !k.HasInflightPackets(ctx, portID, channelID) { + previousState := channel.State + channel.State = types.FLUSHCOMPLETE + k.SetChannel(ctx, portID, channelID, channel) + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "previous-state", previousState, "new-state", channel.State) + } + + k.SetCounterpartyUpgrade(ctx, portID, channelID, counterpartyUpgrade) + return channel +} + +// ChanUpgradeOpen is called by a module to complete the channel upgrade handshake and move the channel back to an OPEN state. +// This method should only be called after both channels have flushed any in-flight packets. +// This method should only be called directly by the core IBC message server. +func (k Keeper) ChanUpgradeOpen( + ctx sdk.Context, + portID, + channelID string, + counterpartyChannelState types.State, + proofCounterpartyChannel []byte, + proofHeight clienttypes.Height, +) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + if channel.State != types.FLUSHCOMPLETE { + return errorsmod.Wrapf(types.ErrInvalidChannelState, "expected %s, got %s", types.FLUSHCOMPLETE, channel.State) + } + + connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + return errorsmod.Wrapf(connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connection.GetState()).String()) + } + + var counterpartyChannel types.Channel + switch counterpartyChannelState { + case types.OPEN: + upgrade, found := k.GetUpgrade(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrUpgradeNotFound, "failed to retrieve channel upgrade: port ID (%s) channel ID (%s)", portID, channelID) + } + // If counterparty has reached OPEN, we must use the upgraded connection to verify the counterparty channel + upgradeConnection, found := k.connectionKeeper.GetConnection(ctx, upgrade.Fields.ConnectionHops[0]) + if !found { + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, upgrade.Fields.ConnectionHops[0]) + } + + if upgradeConnection.GetState() != int32(connectiontypes.OPEN) { + return errorsmod.Wrapf(connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(upgradeConnection.GetState()).String()) + } + + counterpartyChannel = types.Channel{ + State: types.OPEN, + Ordering: upgrade.Fields.Ordering, + ConnectionHops: []string{upgradeConnection.GetCounterparty().GetConnectionID()}, + Counterparty: types.NewCounterparty(portID, channelID), + Version: upgrade.Fields.Version, + UpgradeSequence: channel.UpgradeSequence, + } + + case types.FLUSHCOMPLETE: + counterpartyChannel = types.Channel{ + State: types.FLUSHCOMPLETE, + Ordering: channel.Ordering, + ConnectionHops: []string{connection.GetCounterparty().GetConnectionID()}, + Counterparty: types.NewCounterparty(portID, channelID), + Version: channel.Version, + UpgradeSequence: channel.UpgradeSequence, + } + + default: + return errorsmod.Wrapf(types.ErrInvalidCounterparty, "counterparty channel state must be one of [%s, %s], got %s", types.OPEN, types.FLUSHCOMPLETE, counterpartyChannelState) + } + + if err := k.connectionKeeper.VerifyChannelState( + ctx, + connection, + proofHeight, proofCounterpartyChannel, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + counterpartyChannel, + ); err != nil { + return errorsmod.Wrap(err, "failed to verify counterparty channel") + } + + return nil +} + +// WriteUpgradeOpenChannel writes the agreed upon upgrade fields to the channel, and sets the channel state back to OPEN. This can be called in one of two cases: +// - In the UpgradeConfirm step of the handshake if both sides have already flushed all in-flight packets. +// - In the UpgradeOpen step of the handshake. +func (k Keeper) WriteUpgradeOpenChannel(ctx sdk.Context, portID, channelID string) types.Channel { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing channel when updating channel state, channelID: %s, portID: %s", channelID, portID)) + } + + upgrade, found := k.GetUpgrade(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find upgrade when updating channel state, channelID: %s, portID: %s", channelID, portID)) + } + + counterpartyUpgrade, found := k.GetCounterpartyUpgrade(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find counterparty upgrade when updating channel state, channelID: %s, portID: %s", channelID, portID)) + } + + // next seq recv and ack is used for ordered channels to verify the packet has been received/acked in the correct order + // this is no longer necessary if the channel is UNORDERED and should be reset to 1 + if channel.Ordering == types.ORDERED && upgrade.Fields.Ordering == types.UNORDERED { + k.SetNextSequenceRecv(ctx, portID, channelID, 1) + k.SetNextSequenceAck(ctx, portID, channelID, 1) + } + + // next seq recv and ack should updated when moving from UNORDERED to ORDERED using the counterparty NextSequenceSend as set just after blocking new packet sends. + // we can be sure that the next packet we are set to receive will be the first packet the counterparty sends after reopening. + // we can be sure that our next acknowledgement will be our first packet sent after upgrade, as the counterparty processed all sent packets after flushing completes. + if channel.Ordering == types.UNORDERED && upgrade.Fields.Ordering == types.ORDERED { + k.SetNextSequenceRecv(ctx, portID, channelID, counterpartyUpgrade.NextSequenceSend) + k.SetNextSequenceAck(ctx, portID, channelID, upgrade.NextSequenceSend) + } + + // set the counterparty next sequence send as pruning sequence end in order to have upper bound to prune to + k.SetPruningSequenceEnd(ctx, portID, channelID, counterpartyUpgrade.NextSequenceSend) + + // First upgrade for this channel will set the pruning sequence to 1, the starting sequence for pruning. + // Subsequent upgrades will not modify the pruning sequence thereby allowing pruning to continue from the last + // pruned sequence. + if !k.HasPruningSequenceStart(ctx, portID, channelID) { + k.SetPruningSequenceStart(ctx, portID, channelID, 1) + } + + // Switch channel fields to upgrade fields and set channel state to OPEN + previousState := channel.State + channel.Ordering = upgrade.Fields.Ordering + channel.Version = upgrade.Fields.Version + channel.ConnectionHops = upgrade.Fields.ConnectionHops + channel.State = types.OPEN + + k.SetChannel(ctx, portID, channelID, channel) + + // delete state associated with upgrade which is no longer required. + k.deleteUpgradeInfo(ctx, portID, channelID) + + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "previous-state", previousState.String(), "new-state", types.OPEN.String()) + return channel +} + +// ChanUpgradeCancel is called by the msg server to prove that an error receipt was written on the counterparty +// which constitutes a valid situation where the upgrade should be cancelled. An error is returned if sufficient evidence +// for cancelling the upgrade has not been provided. +func (k Keeper) ChanUpgradeCancel(ctx sdk.Context, portID, channelID string, errorReceipt types.ErrorReceipt, errorReceiptProof []byte, proofHeight clienttypes.Height) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + _, found = k.GetUpgrade(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrUpgradeNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + // an error receipt proof must be provided. + if len(errorReceiptProof) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty error receipt proof unless the sender is authorized to cancel upgrades AND channel is not in FLUSHCOMPLETE") + } + + // the error receipt should also have a sequence greater than or equal to the current upgrade sequence. + if errorReceipt.Sequence < channel.UpgradeSequence { + return errorsmod.Wrapf(types.ErrInvalidUpgradeSequence, "error receipt sequence (%d) must be greater than or equal to current upgrade sequence (%d)", errorReceipt.Sequence, channel.UpgradeSequence) + } + + // get underlying connection for proof verification + connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + return errorsmod.Wrapf( + connectiontypes.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectiontypes.State(connection.GetState()).String(), + ) + } + + if err := k.connectionKeeper.VerifyChannelUpgradeError( + ctx, + connection, + proofHeight, + errorReceiptProof, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + errorReceipt, + ); err != nil { + return errorsmod.Wrap(err, "failed to verify counterparty error receipt") + } + + return nil +} + +// WriteUpgradeCancelChannel writes a channel which has canceled the upgrade process.Auxiliary upgrade state is +// also deleted. +func (k Keeper) WriteUpgradeCancelChannel(ctx sdk.Context, portID, channelID string, sequence uint64) { + defer telemetry.IncrCounter(1, "ibc", "channel", "upgrade-cancel") + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing channel when updating channel state, channelID: %s, portID: %s", channelID, portID)) + } + + upgrade, found := k.GetUpgrade(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find upgrade when updating channel state, channelID: %s, portID: %s", channelID, portID)) + } + + previousState := channel.State + + channel = k.restoreChannel(ctx, portID, channelID, sequence, channel, types.NewUpgradeError(sequence, types.ErrInvalidUpgrade)) + + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "previous-state", previousState, "new-state", types.OPEN.String()) + EmitChannelUpgradeCancelEvent(ctx, portID, channelID, channel, upgrade) +} + +// ChanUpgradeTimeout times out an outstanding upgrade. +// This should be used by the initialising chain when the counterparty chain has not responded to an upgrade proposal within the specified timeout period. +func (k Keeper) ChanUpgradeTimeout( + ctx sdk.Context, + portID, channelID string, + counterpartyChannel types.Channel, + proofCounterpartyChannel []byte, + proofHeight exported.Height, +) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + if !slices.Contains([]types.State{types.FLUSHING, types.FLUSHCOMPLETE}, channel.State) { + return errorsmod.Wrapf(types.ErrInvalidChannelState, "expected one of [%s, %s], got %s", types.FLUSHING, types.FLUSHCOMPLETE, channel.State) + } + + upgrade, found := k.GetUpgrade(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrUpgradeNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return errorsmod.Wrap( + connectiontypes.ErrConnectionNotFound, + channel.ConnectionHops[0], + ) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + return errorsmod.Wrapf( + connectiontypes.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectiontypes.State(connection.GetState()).String(), + ) + } + + proofTimestamp, err := k.connectionKeeper.GetTimestampAtHeight(ctx, connection, proofHeight) + if err != nil { + return err + } + + // proof must be from a height after timeout has elapsed. Either timeoutHeight or timeoutTimestamp must be defined. + // if timeoutHeight is defined and proof is from before timeout height, abort transaction + timeoutHeight := upgrade.Timeout.Height + timeoutTimeStamp := upgrade.Timeout.Timestamp + if (timeoutHeight.IsZero() || proofHeight.LT(timeoutHeight)) && + (timeoutTimeStamp == 0 || proofTimestamp < timeoutTimeStamp) { + return errorsmod.Wrap(types.ErrInvalidUpgradeTimeout, "upgrade timeout has not been reached for height or timestamp") + } + + // counterparty channel must be proved to still be in OPEN state or FLUSHING state. + if !slices.Contains([]types.State{types.OPEN, types.FLUSHING}, counterpartyChannel.State) { + return errorsmod.Wrapf(types.ErrInvalidCounterparty, "expected one of [%s, %s], got %s", types.OPEN, types.FLUSHING, counterpartyChannel.State) + } + + if counterpartyChannel.State == types.OPEN { + upgradeConnection, found := k.connectionKeeper.GetConnection(ctx, upgrade.Fields.ConnectionHops[0]) + if !found { + return errorsmod.Wrap( + connectiontypes.ErrConnectionNotFound, + upgrade.Fields.ConnectionHops[0], + ) + } + counterpartyHops := []string{upgradeConnection.GetCounterparty().GetConnectionID()} + + upgradeAlreadyComplete := upgrade.Fields.Version == counterpartyChannel.Version && upgrade.Fields.Ordering == counterpartyChannel.Ordering && upgrade.Fields.ConnectionHops[0] == counterpartyHops[0] + if upgradeAlreadyComplete { + // counterparty has already successfully upgraded so we cannot timeout + return errorsmod.Wrap(types.ErrUpgradeTimeoutFailed, "counterparty channel is already upgraded") + } + } + + if counterpartyChannel.UpgradeSequence < channel.UpgradeSequence { + return errorsmod.Wrapf(types.ErrInvalidUpgradeSequence, "counterparty channel upgrade sequence (%d) must be greater than or equal to current upgrade sequence (%d)", counterpartyChannel.UpgradeSequence, channel.UpgradeSequence) + } + + // verify the counterparty channel state + if err := k.connectionKeeper.VerifyChannelState( + ctx, + connection, + proofHeight, proofCounterpartyChannel, + channel.Counterparty.PortId, + channel.Counterparty.ChannelId, + counterpartyChannel, + ); err != nil { + return errorsmod.Wrap(err, "failed to verify counterparty channel state") + } + + return nil +} + +// WriteUpgradeTimeoutChannel restores the channel state of an initialising chain in the event that the counterparty chain has passed the timeout set in ChanUpgradeInit to the state before the upgrade was proposed. +// Auxiliary upgrade state is also deleted. +// An event is emitted for the handshake step. +func (k Keeper) WriteUpgradeTimeoutChannel( + ctx sdk.Context, + portID, channelID string, +) (types.Channel, types.Upgrade) { + defer telemetry.IncrCounter(1, "ibc", "channel", "upgrade-timeout") + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing channel when updating channel state in successful ChanUpgradeTimeout step, channelID: %s, portID: %s", channelID, portID)) + } + + upgrade, found := k.GetUpgrade(ctx, portID, channelID) + if !found { + panic(fmt.Errorf("could not find existing upgrade when cancelling channel upgrade, channelID: %s, portID: %s", channelID, portID)) + } + + channel = k.restoreChannel(ctx, portID, channelID, channel.UpgradeSequence, channel, types.NewUpgradeError(channel.UpgradeSequence, types.ErrUpgradeTimeout)) + + k.Logger(ctx).Info("channel state restored", "port-id", portID, "channel-id", channelID) + + return channel, upgrade +} + +// startFlushing will set the upgrade last packet send and continue blocking the upgrade from continuing until all +// in-flight packets have been flushed. +func (k Keeper) startFlushing(ctx sdk.Context, portID, channelID string, upgrade *types.Upgrade) error { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + return errorsmod.Wrapf(connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connection.GetState()).String()) + } + + channel.State = types.FLUSHING + k.SetChannel(ctx, portID, channelID, channel) + + nextSequenceSend, found := k.GetNextSequenceSend(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrSequenceSendNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + upgrade.NextSequenceSend = nextSequenceSend + upgrade.Timeout = k.getAbsoluteUpgradeTimeout(ctx) + k.SetUpgrade(ctx, portID, channelID, *upgrade) + + return nil +} + +// getAbsoluteUpgradeTimeout returns the absolute timeout for the given upgrade. +func (k Keeper) getAbsoluteUpgradeTimeout(ctx sdk.Context) types.Timeout { + upgradeTimeout := k.GetParams(ctx).UpgradeTimeout + return types.NewTimeout(clienttypes.ZeroHeight(), uint64(ctx.BlockTime().UnixNano())+upgradeTimeout.Timestamp) +} + +// syncUpgradeSequence ensures current upgrade handshake only continues if both channels are using the same upgrade sequence, +// otherwise an upgrade error is returned so that an error receipt will be written so that the upgrade handshake may be attempted again with synchronized sequences. +func (k Keeper) syncUpgradeSequence(ctx sdk.Context, portID, channelID string, channel types.Channel, counterpartyUpgradeSequence uint64) error { + // save the previous upgrade sequence for the error message + prevUpgradeSequence := channel.UpgradeSequence + + if counterpartyUpgradeSequence != channel.UpgradeSequence { + // error on the higher sequence so that both chains synchronize on a fresh sequence + channel.UpgradeSequence = sdkmath.Max(counterpartyUpgradeSequence, channel.UpgradeSequence) + k.SetChannel(ctx, portID, channelID, channel) + + return types.NewUpgradeError(channel.UpgradeSequence, errorsmod.Wrapf( + types.ErrInvalidUpgradeSequence, "expected upgrade sequence (%d) to match counterparty upgrade sequence (%d)", prevUpgradeSequence, counterpartyUpgradeSequence), + ) + } + + return nil +} + +// checkForUpgradeCompatibility checks performs stateful validation of self upgrade fields relative to counterparty upgrade. +func (k Keeper) checkForUpgradeCompatibility(ctx sdk.Context, upgradeFields, counterpartyUpgradeFields types.UpgradeFields) error { + // assert that both sides propose the same channel ordering + if upgradeFields.Ordering != counterpartyUpgradeFields.Ordering { + return errorsmod.Wrapf(types.ErrIncompatibleCounterpartyUpgrade, "expected upgrade ordering (%s) to match counterparty upgrade ordering (%s)", upgradeFields.Ordering, counterpartyUpgradeFields.Ordering) + } + + if upgradeFields.Version != counterpartyUpgradeFields.Version { + return errorsmod.Wrapf(types.ErrIncompatibleCounterpartyUpgrade, "expected upgrade version (%s) to match counterparty upgrade version (%s)", upgradeFields.Version, counterpartyUpgradeFields.Version) + } + + connection, found := k.connectionKeeper.GetConnection(ctx, upgradeFields.ConnectionHops[0]) + if !found { + // NOTE: this error is expected to be unreachable as the proposed upgrade connectionID should have been + // validated in the upgrade INIT and TRY handlers + return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, upgradeFields.ConnectionHops[0]) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + // NOTE: this error is expected to be unreachable as the proposed upgrade connectionID should have been + // validated in the upgrade INIT and TRY handlers + return errorsmod.Wrapf(connectiontypes.ErrInvalidConnectionState, "expected proposed connection to be OPEN (got %s)", connectiontypes.State(connection.GetState()).String()) + } + + // connectionHops can change in a channelUpgrade, however both sides must still be each other's counterparty. + if counterpartyUpgradeFields.ConnectionHops[0] != connection.GetCounterparty().GetConnectionID() { + return errorsmod.Wrapf( + types.ErrIncompatibleCounterpartyUpgrade, "counterparty upgrade connection end is not a counterparty of self proposed connection end (%s != %s)", counterpartyUpgradeFields.ConnectionHops[0], connection.GetCounterparty().GetConnectionID()) + } + + return nil +} + +// validateSelfUpgradeFields validates the proposed upgrade fields against the existing channel. +// It returns an error if the following constraints are not met: +// - there exists at least one valid proposed change to the existing channel fields +// - the proposed connection hops do not exist +// - the proposed version is non-empty (checked in UpgradeFields.ValidateBasic()) +// - the proposed connection hops are not open +func (k Keeper) validateSelfUpgradeFields(ctx sdk.Context, proposedUpgrade types.UpgradeFields, currentChannel types.Channel) error { + currentFields := extractUpgradeFields(currentChannel) + + if reflect.DeepEqual(proposedUpgrade, currentFields) { + return errorsmod.Wrapf(types.ErrInvalidUpgrade, "existing channel end is identical to proposed upgrade channel end: got %s", proposedUpgrade) + } + + connectionID := proposedUpgrade.ConnectionHops[0] + connection, found := k.connectionKeeper.GetConnection(ctx, connectionID) + if !found { + return errorsmod.Wrapf(connectiontypes.ErrConnectionNotFound, "failed to retrieve connection: %s", connectionID) + } + + if connection.GetState() != int32(connectiontypes.OPEN) { + return errorsmod.Wrapf( + connectiontypes.ErrInvalidConnectionState, + "connection state is not OPEN (got %s)", connectiontypes.State(connection.GetState()).String(), + ) + } + + getVersions := connection.GetVersions() + if len(getVersions) != 1 { + return errorsmod.Wrapf( + connectiontypes.ErrInvalidVersion, + "single version must be negotiated on connection before opening channel, got: %v", + getVersions, + ) + } + + if !connectiontypes.VerifySupportedFeature(getVersions[0], proposedUpgrade.Ordering.String()) { + return errorsmod.Wrapf( + connectiontypes.ErrInvalidVersion, + "connection version %s does not support channel ordering: %s", + getVersions[0], proposedUpgrade.Ordering.String(), + ) + } + + return nil +} + +// extractUpgradeFields returns the upgrade fields from the provided channel. +func extractUpgradeFields(channel types.Channel) types.UpgradeFields { + return types.UpgradeFields{ + Ordering: channel.Ordering, + ConnectionHops: channel.ConnectionHops, + Version: channel.Version, + } +} + +// MustAbortUpgrade will restore the channel state to its pre-upgrade state so that upgrade is aborted. +// Any unnecessary state is deleted and an error receipt is written. +// This function is expected to always succeed, a panic will occur if an error occurs. +func (k Keeper) MustAbortUpgrade(ctx sdk.Context, portID, channelID string, err error) { + if err := k.abortUpgrade(ctx, portID, channelID, err); err != nil { + panic(err) + } +} + +// abortUpgrade will restore the channel state to its pre-upgrade state so that upgrade is aborted. +// Any unnecessary state is delete and an error receipt is written. +func (k Keeper) abortUpgrade(ctx sdk.Context, portID, channelID string, err error) error { + if err == nil { + return errorsmod.Wrap(types.ErrInvalidUpgradeError, "cannot abort upgrade handshake with nil error") + } + + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + return errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID) + } + + // in the case of application callbacks, the error may not be an upgrade error. + // in this case we need to construct one in order to write the error receipt. + upgradeError, ok := err.(*types.UpgradeError) + if !ok { + upgradeError = types.NewUpgradeError(channel.UpgradeSequence, err) + } + + // the channel upgrade sequence has already been updated in ChannelUpgradeTry, so we can pass + // its updated value. + k.restoreChannel(ctx, portID, channelID, channel.UpgradeSequence, channel, upgradeError) + return nil +} + +// restoreChannel will restore the channel state to its pre-upgrade state so that upgrade is aborted. +func (k Keeper) restoreChannel(ctx sdk.Context, portID, channelID string, upgradeSequence uint64, channel types.Channel, err *types.UpgradeError) types.Channel { + channel.State = types.OPEN + channel.UpgradeSequence = upgradeSequence + + k.SetChannel(ctx, portID, channelID, channel) + + // delete state associated with upgrade which is no longer required. + k.deleteUpgradeInfo(ctx, portID, channelID) + + k.SetUpgradeErrorReceipt(ctx, portID, channelID, err.GetErrorReceipt()) + + return channel +} + +// writeErrorReceipt will write an error receipt from the provided UpgradeError. +func (k Keeper) writeErrorReceipt(ctx sdk.Context, portID, channelID string, upgradeError *types.UpgradeError) { + channel, found := k.GetChannel(ctx, portID, channelID) + if !found { + panic(errorsmod.Wrapf(types.ErrChannelNotFound, "port ID (%s) channel ID (%s)", portID, channelID)) + } + + errorReceiptToWrite := upgradeError.GetErrorReceipt() + + existingErrorReceipt, found := k.GetUpgradeErrorReceipt(ctx, portID, channelID) + if found && existingErrorReceipt.Sequence >= errorReceiptToWrite.Sequence { + panic(errorsmod.Wrapf(types.ErrInvalidUpgradeSequence, "error receipt sequence (%d) must be greater than existing error receipt sequence (%d)", errorReceiptToWrite.Sequence, existingErrorReceipt.Sequence)) + } + + k.SetUpgradeErrorReceipt(ctx, portID, channelID, errorReceiptToWrite) + EmitErrorReceiptEvent(ctx, portID, channelID, channel, upgradeError) +} diff --git a/modules/core/04-channel/keeper/upgrade_test.go b/modules/core/04-channel/keeper/upgrade_test.go new file mode 100644 index 00000000000..475fb3b438b --- /dev/null +++ b/modules/core/04-channel/keeper/upgrade_test.go @@ -0,0 +1,2892 @@ +package keeper_test + +import ( + "fmt" + "math" + "testing" + + errorsmod "cosmossdk.io/errors" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + "github.com/cosmos/ibc-go/v8/testing/mock" +) + +func (suite *KeeperTestSuite) TestChanUpgradeInit() { + var ( + path *ibctesting.Path + expSequence uint64 + upgradeFields types.UpgradeFields + ) + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "success with later upgrade sequence", + func() { + channel := path.EndpointA.GetChannel() + channel.UpgradeSequence = 4 + path.EndpointA.SetChannel(channel) + expSequence = 5 + }, + true, + }, + { + "upgrade fields are identical to channel end", + func() { + channel := path.EndpointA.GetChannel() + upgradeFields = types.NewUpgradeFields(channel.Ordering, channel.ConnectionHops, channel.Version) + }, + false, + }, + { + "channel not found", + func() { + path.EndpointA.ChannelID = "invalid-channel" + path.EndpointA.ChannelConfig.PortID = "invalid-port" + }, + false, + }, + { + "channel state is not in OPEN state", + func() { + suite.Require().NoError(path.EndpointA.SetChannelState(types.CLOSED)) + }, + false, + }, + { + "proposed channel connection not found", + func() { + upgradeFields.ConnectionHops = []string{"connection-100"} + }, + false, + }, + { + "invalid proposed channel connection state", + func() { + connectionEnd := path.EndpointA.GetConnection() + connectionEnd.State = connectiontypes.UNINITIALIZED + + suite.chainA.GetSimApp().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainA.GetContext(), "connection-100", connectionEnd) + upgradeFields.ConnectionHops = []string{"connection-100"} + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + expSequence = 1 + + upgradeFields = types.NewUpgradeFields(types.UNORDERED, []string{path.EndpointA.ConnectionID}, mock.UpgradeVersion) + + tc.malleate() + + upgrade, err := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ChanUpgradeInit( + suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgradeFields, + ) + + if tc.expPass { + ctx := suite.chainA.GetContext() + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeInitChannel(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgrade, upgrade.Fields.Version) + channel := path.EndpointA.GetChannel() + + // events := ctx.EventManager().Events().ToABCIEvents() + // expEvents := ibctesting.EventsMap{ + // types.EventTypeChannelUpgradeInit: { + // types.AttributeKeyPortID: path.EndpointA.ChannelConfig.PortID, + // types.AttributeKeyChannelID: path.EndpointA.ChannelID, + // types.AttributeCounterpartyPortID: path.EndpointB.ChannelConfig.PortID, + // types.AttributeCounterpartyChannelID: path.EndpointB.ChannelID, + // types.AttributeKeyUpgradeConnectionHops: upgradeFields.ConnectionHops[0], + // types.AttributeKeyUpgradeVersion: upgradeFields.Version, + // types.AttributeKeyUpgradeOrdering: upgradeFields.Ordering.String(), + // types.AttributeKeyUpgradeSequence: fmt.Sprintf("%d", channel.UpgradeSequence), + // }, + // sdk.EventTypeMessage: { + // sdk.AttributeKeyModule: types.AttributeValueCategory, + // }, + // } + + suite.Require().NoError(err) + suite.Require().Equal(expSequence, channel.UpgradeSequence) + suite.Require().Equal(mock.Version, channel.Version) + suite.Require().Equal(types.OPEN, channel.State) + + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestChanUpgradeTry() { + var ( + path *ibctesting.Path + proposedUpgrade types.Upgrade + counterpartyUpgrade types.Upgrade + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success: crossing hellos", + func() { + err := path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + }, + nil, + }, + { + "success: upgrade sequence is fast forwarded to counterparty upgrade sequence", + func() { + channel := path.EndpointA.GetChannel() + channel.UpgradeSequence = 5 + path.EndpointA.SetChannel(channel) + + suite.coordinator.CommitBlock(suite.chainA) + }, + nil, + }, + { + "channel not found", + func() { + path.EndpointB.ChannelID = ibctesting.InvalidID + }, + types.ErrChannelNotFound, + }, + { + "channel state is not in OPEN state", + func() { + suite.Require().NoError(path.EndpointB.SetChannelState(types.CLOSED)) + }, + types.ErrInvalidChannelState, + }, + { + "connection not found", + func() { + channel := path.EndpointB.GetChannel() + channel.ConnectionHops = []string{"connection-100"} + path.EndpointB.SetChannel(channel) + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "invalid connection state", + func() { + connectionEnd := path.EndpointB.GetConnection() + connectionEnd.State = connectiontypes.UNINITIALIZED + suite.chainB.GetSimApp().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), path.EndpointB.ConnectionID, connectionEnd) + }, + connectiontypes.ErrInvalidConnectionState, + }, + { + "initializing handshake fails, proposed connection hops do not exist", + func() { + proposedUpgrade.Fields.ConnectionHops = []string{ibctesting.InvalidID} + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "fails due to proof verification failure, counterparty channel ordering does not match expected ordering", + func() { + channel := path.EndpointB.GetChannel() + channel.Ordering = types.ORDERED + path.EndpointB.SetChannel(channel) + }, + commitmenttypes.ErrInvalidProof, + }, + { + "fails due to proof verification failure, counterparty upgrade connection hops are tampered with", + func() { + counterpartyUpgrade.Fields.ConnectionHops = []string{ibctesting.InvalidID} + }, + commitmenttypes.ErrInvalidProof, + }, + { + "fails due to incompatible upgrades, chainB proposes a new connection hop that does not match counterparty", + func() { + // reuse existing connection to create a new connection in a non OPEN state + connection := path.EndpointB.GetConnection() + // ensure counterparty connectionID does not match connectionID set in counterparty proposed upgrade + connection.Counterparty.ConnectionId = "connection-50" + + // set proposed connection in state + proposedConnectionID := "connection-100" //nolint:goconst + suite.chainB.GetSimApp().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), proposedConnectionID, connection) + proposedUpgrade.Fields.ConnectionHops[0] = proposedConnectionID + }, + types.ErrIncompatibleCounterpartyUpgrade, + }, + { + "fails due to mismatch in upgrade sequences", + func() { + channel := path.EndpointB.GetChannel() + channel.UpgradeSequence = 5 + path.EndpointB.SetChannel(channel) + }, + // channel sequence will be returned so that counterparty inits on completely fresh sequence for both sides + types.NewUpgradeError(5, types.ErrInvalidUpgradeSequence), + }, + { + // ChainA(Sequence: 0, mock-version-v2), ChainB(Sequence: 0, mock-version-v3) + // ChainA.INIT(Sequence: 1) + // ChainB.INIT(Sequence: 1) + // ChainA.TRY => error (incompatible versions) + // ChainB.TRY => error (incompatible versions) + "crossing hellos: fails due to incompatible version", + func() { + // use incompatible version + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = fmt.Sprintf("%s-v3", mock.Version) + proposedUpgrade = path.EndpointB.GetProposedUpgrade() + + err := path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeTry() + suite.Require().Error(err) + suite.Require().ErrorContains(err, "incompatible counterparty upgrade") + suite.Require().Equal(uint64(1), path.EndpointA.GetChannel().UpgradeSequence) + }, + types.ErrIncompatibleCounterpartyUpgrade, + }, + { + // ChainA(Sequence: 0, mock-version-v2), ChainB(Sequence: 4, mock-version-v3) + // ChainA.INIT(Sequence: 1) + // ChainB.INIT(Sequence: 5) + // ChainA.TRY => error (incompatible versions) + // ChainB.TRY(ErrorReceipt: 4) + "crossing hellos: upgrade starts with mismatching upgrade sequences and try fails on counterparty due to incompatible version", + func() { + channel := path.EndpointB.GetChannel() + channel.UpgradeSequence = 4 + path.EndpointB.SetChannel(channel) + + // use incompatible version + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = fmt.Sprintf("%s-v3", mock.Version) + proposedUpgrade = path.EndpointB.GetProposedUpgrade() + + err := path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeTry() + suite.Require().Error(err) + suite.Require().ErrorContains(err, "incompatible counterparty upgrade") + suite.Require().Equal(uint64(1), path.EndpointA.GetChannel().UpgradeSequence) + }, + types.NewUpgradeError(4, types.ErrInvalidUpgradeSequence), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + expPass := tc.expError == nil + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + proposedUpgrade = path.EndpointB.GetProposedUpgrade() + + var found bool + counterpartyUpgrade, found = path.EndpointA.Chain.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgrade(path.EndpointA.Chain.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + + tc.malleate() + + // ensure clients are up to date to receive valid proofs + suite.Require().NoError(path.EndpointB.UpdateClient()) + + proofChannel, proofUpgrade, proofHeight := path.EndpointA.QueryChannelUpgradeProof() + + _, upgrade, err := suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.ChanUpgradeTry( + suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + proposedUpgrade.Fields.ConnectionHops, + counterpartyUpgrade.Fields, + path.EndpointA.GetChannel().UpgradeSequence, + proofChannel, + proofUpgrade, + proofHeight, + ) + + if expPass { + suite.Require().NoError(err) + suite.Require().NotEmpty(upgrade) + suite.Require().Equal(proposedUpgrade.Fields, upgrade.Fields) + + nextSequenceSend, found := path.EndpointB.Chain.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceSend(path.EndpointB.Chain.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(found) + suite.Require().Equal(nextSequenceSend, upgrade.NextSequenceSend) + } else { + suite.assertUpgradeError(err, tc.expError) + } + }) + } +} + +// TestChanUpgrade_CrossingHellos_UpgradeSucceeds_AfterCancel verifies that under crossing hellos if upgrade +// sequences become out of sync, the upgrade can still be performed successfully after the upgrade is cancelled. +// ChainA(Sequence: 0), ChainB(Sequence 4) +// ChainA.INIT(Sequence: 1) +// ChainB.INIT(Sequence: 5) +// ChainB.TRY(ErrorReceipt: 4) +// ChainA.Cancel(Sequence: 4) +// ChainA.TRY(Sequence: 5) // fastforward +// ChainB.ACK => Success +// ChainA.Confirm => Success +// ChainB.Open => Success +func (suite *KeeperTestSuite) TestChanUpgrade_CrossingHellos_UpgradeSucceeds_AfterCancel() { + var path *ibctesting.Path + + suite.Run("setup path", func() { + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + }) + + suite.Run("chainA upgrade init", func() { + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + }) + + suite.Run("set chainB upgrade sequence ahead of counterparty", func() { + channel := path.EndpointB.GetChannel() + channel.UpgradeSequence = 4 + path.EndpointB.SetChannel(channel) + }) + + suite.Run("chainB upgrade init (crossing hello)", func() { + err := path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + }) + + suite.Run("chainB upgrade try fails with invalid sequence", func() { + err := path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + errorReceipt, found := path.EndpointB.Chain.GetSimApp().GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(4), errorReceipt.Sequence) + }) + + suite.Run("cancel upgrade on chainA and fast forward upgrade sequence", func() { + err := path.EndpointA.ChanUpgradeCancel() + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.OPEN, channel.State) + suite.Require().Equal(uint64(4), channel.UpgradeSequence) + }) + + suite.Run("try chainA upgrade now succeeds with synchronized upgrade sequences", func() { + err := path.EndpointA.ChanUpgradeTry() + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.FLUSHING, channel.State) + suite.Require().Equal(uint64(5), channel.UpgradeSequence) + }) + + suite.Run("upgrade handshake completes successfully", func() { + err := path.EndpointB.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeConfirm() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeOpen() + suite.Require().NoError(err) + }) + + suite.Run("assert successful upgrade expected channel state", func() { + channelA := path.EndpointA.GetChannel() + suite.Require().Equal(types.OPEN, channelA.State, "channel should be in OPEN state") + suite.Require().Equal(mock.UpgradeVersion, channelA.Version, "version should be correctly upgraded") + suite.Require().Equal(mock.UpgradeVersion, path.EndpointB.GetChannel().Version, "version should be correctly upgraded") + suite.Require().Equal(uint64(5), channelA.UpgradeSequence, "upgrade sequence should be incremented") + + channelB := path.EndpointB.GetChannel() + suite.Require().Equal(types.OPEN, channelB.State, "channel should be in OPEN state") + suite.Require().Equal(mock.UpgradeVersion, channelB.Version, "version should be correctly upgraded") + suite.Require().Equal(mock.UpgradeVersion, channelB.Version, "version should be correctly upgraded") + suite.Require().Equal(uint64(5), channelB.UpgradeSequence, "upgrade sequence should be incremented") + }) +} + +// TestChanUpgrade_CrossingHellos_UpgradeSucceeds_AfterCancelErrors verifies that under crossing hellos if upgrade +// sequences become out of sync, the upgrade can still be performed successfully after the cancel fails. +// ChainA(Sequence: 0), ChainB(Sequence 4) +// ChainA.INIT(Sequence: 1) +// ChainB.INIT(Sequence: 5) +// ChainA.TRY(Sequence: 5) // fastforward +// ChainB.TRY(ErrorReceipt: 4) +// ChainA.Cancel => Error (errorReceipt.Sequence < channel.UpgradeSequence) +// ChainB.ACK => Success +// ChainA.Confirm => Success +// ChainB.Open => Success +func (suite *KeeperTestSuite) TestChanUpgrade_CrossingHellos_UpgradeSucceeds_AfterCancelErrors() { + var ( + historicalChannelProof []byte + historicalUpgradeProof []byte + proofHeight clienttypes.Height + path *ibctesting.Path + ) + + suite.Run("setup path", func() { + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + }) + + suite.Run("chainA upgrade init", func() { + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }) + + suite.Run("set chainB upgrade sequence ahead of counterparty", func() { + channel := path.EndpointB.GetChannel() + channel.UpgradeSequence = 4 + path.EndpointB.SetChannel(channel) + }) + + suite.Run("chainB upgrade init (crossing hello)", func() { + err := path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + + channel := path.EndpointB.GetChannel() + suite.Require().Equal(uint64(5), channel.UpgradeSequence) + }) + + suite.Run("query proofs at chainA upgrade sequence 1", func() { + // commit block and update client on chainB + suite.coordinator.CommitBlock(suite.chainA, suite.chainB) + suite.Require().NoError(path.EndpointB.UpdateClient()) + // use proofs when chain A has not executed TRY yet and use them when executing TRY on chain B + historicalChannelProof, historicalUpgradeProof, proofHeight = path.EndpointA.QueryChannelUpgradeProof() + }) + + suite.Run("chainA upgrade try (fast-forwards sequence)", func() { + err := path.EndpointA.ChanUpgradeTry() + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(uint64(5), channel.UpgradeSequence) + }) + + suite.Run("chainB upgrade try fails with written error receipt (4)", func() { + // NOTE: ante handlers are bypassed here and the handler is invoked directly. + // Thus, we set the upgrade error receipt explicitly below + _, _, err := suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.ChanUpgradeTry( + suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + path.EndpointB.GetChannelUpgrade().Fields.ConnectionHops, + path.EndpointA.GetChannelUpgrade().Fields, + 1, // proofs queried at chainA upgrade sequence 1 + historicalChannelProof, + historicalUpgradeProof, + proofHeight, + ) + suite.Require().Error(err) + suite.assertUpgradeError(err, types.NewUpgradeError(4, types.ErrInvalidUpgradeSequence)) + + errorReceipt := err.(*types.UpgradeError).GetErrorReceipt() + suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, errorReceipt) + suite.coordinator.CommitBlock(suite.chainB) + }) + + suite.Run("chainA upgrade cancellation fails for invalid sequence", func() { + err := path.EndpointA.ChanUpgradeCancel() + suite.Require().Error(err) + suite.Require().ErrorContains(err, "invalid upgrade sequence") + + // assert channel remains in flushing state at upgrade sequence 5 + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.FLUSHING, channel.State) + suite.Require().Equal(uint64(5), channel.UpgradeSequence) + }) + + suite.Run("upgrade handshake completes successfully", func() { + err := path.EndpointB.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeConfirm() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeOpen() + suite.Require().NoError(err) + }) + + suite.Run("assert successful upgrade expected channel state", func() { + channelA := path.EndpointA.GetChannel() + suite.Require().Equal(types.OPEN, channelA.State, "channel should be in OPEN state") + suite.Require().Equal(mock.UpgradeVersion, channelA.Version, "version should be correctly upgraded") + suite.Require().Equal(mock.UpgradeVersion, path.EndpointB.GetChannel().Version, "version should be correctly upgraded") + suite.Require().Equal(uint64(5), channelA.UpgradeSequence, "upgrade sequence should be incremented") + + channelB := path.EndpointB.GetChannel() + suite.Require().Equal(types.OPEN, channelB.State, "channel should be in OPEN state") + suite.Require().Equal(mock.UpgradeVersion, channelB.Version, "version should be correctly upgraded") + suite.Require().Equal(mock.UpgradeVersion, channelB.Version, "version should be correctly upgraded") + suite.Require().Equal(uint64(5), channelB.UpgradeSequence, "upgrade sequence should be incremented") + }) +} + +func (suite *KeeperTestSuite) TestWriteUpgradeTry() { + var ( + path *ibctesting.Path + proposedUpgrade types.Upgrade + ) + + testCases := []struct { + name string + malleate func() + }{ + { + "success with no packet commitments", + func() {}, + }, + { + "success with packet commitments", + func() { + // manually set packet commitment + sequence, err := path.EndpointB.SendPacket(suite.chainB.GetTimeoutHeight(), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + suite.Require().Equal(uint64(1), sequence) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + proposedUpgrade = path.EndpointB.GetProposedUpgrade() + + tc.malleate() + + ctx := suite.chainB.GetContext() + upgradedChannelEnd, upgradeWithAppCallbackVersion := suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeTryChannel( + ctx, + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + proposedUpgrade, + proposedUpgrade.Fields.Version, + ) + + channel := path.EndpointB.GetChannel() + suite.Require().Equal(upgradedChannelEnd, channel) + + upgrade, found := suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgrade(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(found) + suite.Require().Equal(upgradeWithAppCallbackVersion, upgrade) + + // events := ctx.EventManager().Events().ToABCIEvents() + // expEvents := ibctesting.EventsMap{ + // types.EventTypeChannelUpgradeTry: { + // types.AttributeKeyPortID: path.EndpointB.ChannelConfig.PortID, + // types.AttributeKeyChannelID: path.EndpointB.ChannelID, + // types.AttributeCounterpartyPortID: path.EndpointA.ChannelConfig.PortID, + // types.AttributeCounterpartyChannelID: path.EndpointA.ChannelID, + // types.AttributeKeyUpgradeConnectionHops: upgrade.Fields.ConnectionHops[0], + // types.AttributeKeyUpgradeVersion: upgrade.Fields.Version, + // types.AttributeKeyUpgradeOrdering: upgrade.Fields.Ordering.String(), + // types.AttributeKeyUpgradeSequence: fmt.Sprintf("%d", channel.UpgradeSequence), + // }, + // sdk.EventTypeMessage: { + // sdk.AttributeKeyModule: types.AttributeValueCategory, + // }, + // } + }) + } +} + +func (suite *KeeperTestSuite) TestChanUpgradeAck() { + var ( + path *ibctesting.Path + counterpartyUpgrade types.Upgrade + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success with later upgrade sequence", + func() { + channel := path.EndpointA.GetChannel() + channel.UpgradeSequence = 10 + path.EndpointA.SetChannel(channel) + + channel = path.EndpointB.GetChannel() + channel.UpgradeSequence = 10 + path.EndpointB.SetChannel(channel) + + suite.coordinator.CommitBlock(suite.chainA, suite.chainB) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + }, + nil, + }, + { + "channel not found", + func() { + path.EndpointA.ChannelID = ibctesting.InvalidID + path.EndpointA.ChannelConfig.PortID = ibctesting.InvalidID + }, + types.ErrChannelNotFound, + }, + { + "channel state is not in FLUSHING state", + func() { + suite.Require().NoError(path.EndpointA.SetChannelState(types.CLOSED)) + }, + types.ErrInvalidChannelState, + }, + { + "connection not found", + func() { + channel := path.EndpointA.GetChannel() + channel.ConnectionHops = []string{"connection-100"} + path.EndpointA.SetChannel(channel) + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "invalid connection state", + func() { + connectionEnd := path.EndpointA.GetConnection() + connectionEnd.State = connectiontypes.UNINITIALIZED + path.EndpointA.SetConnection(connectionEnd) + }, + connectiontypes.ErrInvalidConnectionState, + }, + { + "upgrade not found", + func() { + store := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetKey(exported.ModuleName)) + store.Delete(host.ChannelUpgradeKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + types.ErrUpgradeNotFound, + }, + { + "fails due to upgrade incompatibility", + func() { + // Need to set counterparty upgrade in state and update clients to ensure + // proofs submitted reflect the altered upgrade. + counterpartyUpgrade.Fields.ConnectionHops = []string{ibctesting.InvalidID} + path.EndpointB.SetChannelUpgrade(counterpartyUpgrade) + + suite.coordinator.CommitBlock(suite.chainB) + + err := path.EndpointA.UpdateClient() + suite.Require().NoError(err) + }, + types.NewUpgradeError(1, types.ErrIncompatibleCounterpartyUpgrade), + }, + { + "fails due to proof verification failure, counterparty channel ordering does not match expected ordering", + func() { + channel := path.EndpointA.GetChannel() + channel.Ordering = types.ORDERED + path.EndpointA.SetChannel(channel) + }, + commitmenttypes.ErrInvalidProof, + }, + { + "fails due to proof verification failure, counterparty update has unexpected sequence", + func() { + // Decrementing NextSequenceSend is sufficient to cause the proof to fail. + counterpartyUpgrade.NextSequenceSend-- + }, + commitmenttypes.ErrInvalidProof, + }, + { + "fails due to mismatch in upgrade ordering", + func() { + upgrade := path.EndpointA.GetChannelUpgrade() + upgrade.Fields.Ordering = types.NONE + + path.EndpointA.SetChannelUpgrade(upgrade) + }, + types.NewUpgradeError(1, types.ErrIncompatibleCounterpartyUpgrade), + }, + { + "counterparty timeout has elapsed", + func() { + // Need to set counterparty upgrade in state and update clients to ensure + // proofs submitted reflect the altered upgrade. + counterpartyUpgrade.Timeout = types.NewTimeout(clienttypes.NewHeight(0, 1), 0) + path.EndpointB.SetChannelUpgrade(counterpartyUpgrade) + + err := path.EndpointB.UpdateClient() + suite.Require().NoError(err) + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + }, + types.NewUpgradeError(1, types.ErrTimeoutElapsed), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + // manually set packet commitment so that the chainB channel state is FLUSHING + sequence, err := path.EndpointB.SendPacket(suite.chainB.GetTimeoutHeight(), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + suite.Require().Equal(uint64(1), sequence) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + // ensure client is up to date to receive valid proofs + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + counterpartyUpgrade = path.EndpointB.GetChannelUpgrade() + + tc.malleate() + + proofChannel, proofUpgrade, proofHeight := path.EndpointB.QueryChannelUpgradeProof() + + err = suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ChanUpgradeAck( + suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, counterpartyUpgrade, + proofChannel, proofUpgrade, proofHeight, + ) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + + channel := path.EndpointA.GetChannel() + // ChanUpgradeAck will set the channel state to FLUSHING + // It will be set to FLUSHING_COMPLETE in the write function. + suite.Require().Equal(types.FLUSHING, channel.State) + } else { + suite.assertUpgradeError(err, tc.expError) + } + }) + } +} + +func (suite *KeeperTestSuite) TestWriteChannelUpgradeAck() { + var ( + path *ibctesting.Path + proposedUpgrade types.Upgrade + ) + + testCases := []struct { + name string + malleate func() + hasPacketCommitments bool + }{ + { + "success with no packet commitments", + func() {}, + false, + }, + { + "success with packet commitments", + func() { + // manually set packet commitment + sequence, err := path.EndpointA.SendPacket(suite.chainB.GetTimeoutHeight(), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + suite.Require().Equal(uint64(1), sequence) + }, + true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + tc.malleate() + + // perform the upgrade handshake. + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + + ctx := suite.chainA.GetContext() + proposedUpgrade = path.EndpointB.GetChannelUpgrade() + + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeAckChannel(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, proposedUpgrade) + + channel := path.EndpointA.GetChannel() + upgrade := path.EndpointA.GetChannelUpgrade() + suite.Require().Equal(mock.UpgradeVersion, upgrade.Fields.Version) + + // events := ctx.EventManager().Events().ToABCIEvents() + // expEvents := ibctesting.EventsMap{ + // types.EventTypeChannelUpgradeAck: { + // types.AttributeKeyPortID: path.EndpointA.ChannelConfig.PortID, + // types.AttributeKeyChannelID: path.EndpointA.ChannelID, + // types.AttributeCounterpartyPortID: path.EndpointB.ChannelConfig.PortID, + // types.AttributeCounterpartyChannelID: path.EndpointB.ChannelID, + // types.AttributeKeyUpgradeConnectionHops: upgrade.Fields.ConnectionHops[0], + // types.AttributeKeyUpgradeVersion: upgrade.Fields.Version, + // types.AttributeKeyUpgradeOrdering: upgrade.Fields.Ordering.String(), + // types.AttributeKeyUpgradeSequence: fmt.Sprintf("%d", channel.UpgradeSequence), + // }, + // sdk.EventTypeMessage: { + // sdk.AttributeKeyModule: types.AttributeValueCategory, + // }, + // } + + if !tc.hasPacketCommitments { + suite.Require().Equal(types.FLUSHCOMPLETE, channel.State) + } + counterpartyUpgrade, ok := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetCounterpartyUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(ok) + suite.Require().Equal(proposedUpgrade, counterpartyUpgrade) + }) + } +} + +func (suite *KeeperTestSuite) TestChanUpgradeConfirm() { + var ( + path *ibctesting.Path + counterpartyChannelState types.State + counterpartyUpgrade types.Upgrade + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success with later upgrade sequence", + func() { + channel := path.EndpointA.GetChannel() + channel.UpgradeSequence = 10 + path.EndpointA.SetChannel(channel) + + channel = path.EndpointB.GetChannel() + channel.UpgradeSequence = 10 + path.EndpointB.SetChannel(channel) + + suite.coordinator.CommitBlock(suite.chainA, suite.chainB) + + err := path.EndpointB.UpdateClient() + suite.Require().NoError(err) + }, + nil, + }, + { + "success with in-flight packets on init chain", + func() { + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + seq, err := path.EndpointA.SendPacket(defaultTimeoutHeight, 0, ibctesting.MockPacketData) + suite.Require().Equal(uint64(1), seq) + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + counterpartyChannelState = path.EndpointA.GetChannel().State + counterpartyUpgrade = path.EndpointA.GetChannelUpgrade() + }, + nil, + }, + { + "success with in-flight packets on try chain", + func() { + portID, channelID := path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID + suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), portID, channelID, 1, []byte("hash")) + }, + nil, + }, + { + "channel not found", + func() { + path.EndpointB.ChannelID = ibctesting.InvalidID + path.EndpointB.ChannelConfig.PortID = ibctesting.InvalidID + }, + types.ErrChannelNotFound, + }, + { + "channel is not in FLUSHING state", + func() { + err := path.EndpointB.SetChannelState(types.CLOSED) + suite.Require().NoError(err) + }, + types.ErrInvalidChannelState, + }, + { + "invalid counterparty channel state", + func() { + counterpartyChannelState = types.CLOSED + }, + types.ErrInvalidCounterparty, + }, + { + "connection not found", + func() { + channel := path.EndpointB.GetChannel() + channel.ConnectionHops = []string{"connection-100"} + path.EndpointB.SetChannel(channel) + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "invalid connection state", + func() { + connectionEnd := path.EndpointB.GetConnection() + connectionEnd.State = connectiontypes.UNINITIALIZED + path.EndpointB.SetConnection(connectionEnd) + }, + connectiontypes.ErrInvalidConnectionState, + }, + { + "fails due to proof verification failure, counterparty channel ordering does not match expected ordering", + func() { + channel := path.EndpointA.GetChannel() + channel.Ordering = types.ORDERED + path.EndpointA.SetChannel(channel) + + suite.coordinator.CommitBlock(suite.chainA) + + err := path.EndpointB.UpdateClient() + suite.Require().NoError(err) + }, + commitmenttypes.ErrInvalidProof, + }, + { + "fails due to mismatch in upgrade ordering", + func() { + upgrade := path.EndpointA.GetChannelUpgrade() + upgrade.Fields.Ordering = types.NONE + + path.EndpointA.SetChannelUpgrade(upgrade) + + suite.coordinator.CommitBlock(suite.chainA) + + err := path.EndpointB.UpdateClient() + suite.Require().NoError(err) + }, + commitmenttypes.ErrInvalidProof, + }, + { + "counterparty timeout has elapsed", + func() { + // Need to set counterparty upgrade in state and update clients to ensure + // proofs submitted reflect the altered upgrade. + counterpartyUpgrade.Timeout = types.NewTimeout(clienttypes.NewHeight(0, 1), 0) + path.EndpointA.SetChannelUpgrade(counterpartyUpgrade) + + suite.coordinator.CommitBlock(suite.chainA) + + err := path.EndpointB.UpdateClient() + suite.Require().NoError(err) + }, + types.NewUpgradeError(1, types.ErrTimeoutElapsed), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + counterpartyChannelState = path.EndpointA.GetChannel().State + counterpartyUpgrade = path.EndpointA.GetChannelUpgrade() + + tc.malleate() + + proofChannel, proofUpgrade, proofHeight := path.EndpointA.QueryChannelUpgradeProof() + + err = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.ChanUpgradeConfirm( + suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, counterpartyChannelState, counterpartyUpgrade, + proofChannel, proofUpgrade, proofHeight, + ) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + } else { + suite.assertUpgradeError(err, tc.expError) + } + }) + } +} + +func (suite *KeeperTestSuite) TestWriteUpgradeConfirm() { + var ( + path *ibctesting.Path + proposedUpgrade types.Upgrade + ) + + testCases := []struct { + name string + malleate func() + hasPacketCommitments bool + }{ + { + "success with no packet commitments", + func() {}, + false, + }, + { + "success with packet commitments", + func() { + // manually set packet commitment + sequence, err := path.EndpointA.SendPacket(suite.chainB.GetTimeoutHeight(), 0, ibctesting.MockPacketData) + suite.Require().NoError(err) + suite.Require().Equal(uint64(1), sequence) + }, + true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + tc.malleate() + + // perform the upgrade handshake. + suite.Require().NoError(path.EndpointB.ChanUpgradeInit()) + + suite.Require().NoError(path.EndpointA.ChanUpgradeTry()) + + suite.Require().NoError(path.EndpointB.ChanUpgradeAck()) + + ctx := suite.chainA.GetContext() + proposedUpgrade = path.EndpointB.GetChannelUpgrade() + + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeConfirmChannel(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, proposedUpgrade) + + channel := path.EndpointA.GetChannel() + upgrade := path.EndpointA.GetChannelUpgrade() + suite.Require().Equal(mock.UpgradeVersion, upgrade.Fields.Version) + + // events := ctx.EventManager().Events().ToABCIEvents() + // expEvents := ibctesting.EventsMap{ + // types.EventTypeChannelUpgradeConfirm: { + // types.AttributeKeyPortID: path.EndpointA.ChannelConfig.PortID, + // types.AttributeKeyChannelID: path.EndpointA.ChannelID, + // types.AttributeKeyChannelState: channel.State.String(), + // types.AttributeCounterpartyPortID: path.EndpointB.ChannelConfig.PortID, + // types.AttributeCounterpartyChannelID: path.EndpointB.ChannelID, + // types.AttributeKeyUpgradeSequence: fmt.Sprintf("%d", channel.UpgradeSequence), + // }, + // sdk.EventTypeMessage: { + // sdk.AttributeKeyModule: types.AttributeValueCategory, + // }, + // } + + if !tc.hasPacketCommitments { + suite.Require().Equal(types.FLUSHCOMPLETE, channel.State) + } else { + suite.Require().Equal(types.FLUSHING, channel.State) + } + counterpartyUpgrade, ok := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetCounterpartyUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(ok, "counterparty upgrade should be present") + suite.Require().Equal(proposedUpgrade, counterpartyUpgrade) + }) + } +} + +func (suite *KeeperTestSuite) TestChanUpgradeOpen() { + var path *ibctesting.Path + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success: counterparty in flushcomplete", + func() { + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + // Need to create a packet commitment on A so as to keep it from going to FLUSHCOMPLETE if no inflight packets exist. + 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.EndpointB.RecvPacket(packet) + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeConfirm() + suite.Require().NoError(err) + + err = path.EndpointA.AcknowledgePacket(packet, ibctesting.MockAcknowledgement) + suite.Require().NoError(err) + + // cause the packet commitment on chain A to be deleted and the channel state to be updated to FLUSHCOMPLETE. + suite.coordinator.CommitBlock(suite.chainA, suite.chainB) + suite.Require().NoError(path.EndpointA.UpdateClient()) + }, + nil, + }, + { + "channel not found", + func() { + path.EndpointA.ChannelConfig.PortID = ibctesting.InvalidID + }, + types.ErrChannelNotFound, + }, + { + "channel state is not FLUSHCOMPLETE", + func() { + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + path.EndpointA.SetChannel(channel) + }, + types.ErrInvalidChannelState, + }, + { + "connection not found", + func() { + channel := path.EndpointA.GetChannel() + channel.ConnectionHops = []string{"connection-100"} + path.EndpointA.SetChannel(channel) + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "invalid connection state", + func() { + connectionEnd := path.EndpointA.GetConnection() + connectionEnd.State = connectiontypes.UNINITIALIZED + path.EndpointA.SetConnection(connectionEnd) + }, + connectiontypes.ErrInvalidConnectionState, + }, + { + "invalid counterparty channel state", + func() { + channel := path.EndpointB.GetChannel() + channel.State = types.CLOSED + path.EndpointB.SetChannel(channel) + }, + types.ErrInvalidCounterparty, + }, + } + + // Create an initial path used only to invoke a ChanOpenInit handshake. + // This bumps the channel identifier generated for chain A on the + // next path used to run the upgrade handshake. + // See issue 4062. + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + suite.Require().NoError(path.EndpointA.ChanOpenInit()) + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeConfirm() + suite.Require().NoError(err) + + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + tc.malleate() + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight := path.EndpointB.QueryProof(channelKey) + + err = suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ChanUpgradeOpen( + suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, + path.EndpointB.GetChannel().State, proofChannel, proofHeight, + ) + + if tc.expError == nil { + suite.Require().NoError(err) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} + +func (suite *KeeperTestSuite) TestWriteUpgradeOpenChannel() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expPanic bool + }{ + { + name: "success", + malleate: func() {}, + expPanic: false, + }, + { + name: "channel not found", + malleate: func() { + path.EndpointA.Chain.DeleteKey(host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + expPanic: true, + }, + { + name: "upgrade not found", + malleate: func() { + path.EndpointA.Chain.DeleteKey(host.ChannelUpgradeKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + expPanic: true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // Need to create a packet commitment on A so as to keep it from going to OPEN if no inflight packets exist. + 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.EndpointB.RecvPacket(packet) + suite.Require().NoError(err) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + suite.Require().NoError(path.EndpointA.ChanUpgradeAck()) + suite.Require().NoError(path.EndpointB.ChanUpgradeConfirm()) + + // Ack packet to delete packet commitment before calling WriteUpgradeOpenChannel + err = path.EndpointA.AcknowledgePacket(packet, ibctesting.MockAcknowledgement) + suite.Require().NoError(err) + + ctx := suite.chainA.GetContext() + + tc.malleate() + + if tc.expPanic { + suite.Require().Panics(func() { + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeOpenChannel(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + }) + } else { + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeOpenChannel(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + channel := path.EndpointA.GetChannel() + + // Assert that channel state has been updated + suite.Require().Equal(types.OPEN, channel.State) + suite.Require().Equal(mock.UpgradeVersion, channel.Version) + + // Assert that state stored for upgrade has been deleted + upgrade, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(types.Upgrade{}, upgrade) + suite.Require().False(found) + + counterpartyUpgrade, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetCounterpartyUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(types.Upgrade{}, counterpartyUpgrade) + suite.Require().False(found) + + // events := ctx.EventManager().Events().ToABCIEvents() + // expEvents := ibctesting.EventsMap{ + // types.EventTypeChannelUpgradeOpen: { + // types.AttributeKeyPortID: path.EndpointA.ChannelConfig.PortID, + // types.AttributeKeyChannelID: path.EndpointA.ChannelID, + // types.AttributeCounterpartyPortID: path.EndpointB.ChannelConfig.PortID, + // types.AttributeCounterpartyChannelID: path.EndpointB.ChannelID, + // types.AttributeKeyChannelState: types.OPEN.String(), + // types.AttributeKeyUpgradeConnectionHops: channel.ConnectionHops[0], + // types.AttributeKeyUpgradeVersion: channel.Version, + // types.AttributeKeyUpgradeOrdering: channel.Ordering.String(), + // types.AttributeKeyUpgradeSequence: fmt.Sprintf("%d", channel.UpgradeSequence), + // }, + // sdk.EventTypeMessage: { + // sdk.AttributeKeyModule: types.AttributeValueCategory, + // }, + // } + // ibctesting.AssertEventsLegacy(&suite.Suite, expEvents, events) + } + }) + } +} + +func (suite *KeeperTestSuite) TestWriteUpgradeOpenChannel_Ordering() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + preUpgrade func() + postUpgrade func() + }{ + { + name: "success: ORDERED -> UNORDERED", + malleate: func() { + path.EndpointA.ChannelConfig.Order = types.ORDERED + path.EndpointB.ChannelConfig.Order = types.ORDERED + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Ordering = types.UNORDERED + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Ordering = types.UNORDERED + }, + preUpgrade: func() { + ctx := suite.chainA.GetContext() + + // assert that NextSeqAck is incremented to 2 because channel is still ordered + seq, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceAck(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(2), seq) + + // assert that NextSeqRecv is incremented to 2 because channel is still ordered + seq, found = suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceRecv(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(2), seq) + + // Assert that pruning sequence start has not been initialized. + suite.Require().False(suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.HasPruningSequenceStart(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + + // Assert that pruning sequence end has not been set + counterpartyNextSequenceSend, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetPruningSequenceEnd(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found) + suite.Require().Equal(uint64(0), counterpartyNextSequenceSend) + }, + postUpgrade: func() { + channel := path.EndpointA.GetChannel() + ctx := suite.chainA.GetContext() + + // Assert that channel state has been updated + suite.Require().Equal(types.OPEN, channel.State) + suite.Require().Equal(types.UNORDERED, channel.Ordering) + + // assert that NextSeqRecv is now 1, because channel is now UNORDERED + seq, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceRecv(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(1), seq) + + // assert that NextSeqAck is now 1, because channel is now UNORDERED + seq, found = suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceAck(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(1), seq) + + // Assert that pruning sequence start has been initialized (set to 1) + suite.Require().True(suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.HasPruningSequenceStart(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + pruningSeq := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetPruningSequenceStart(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(uint64(1), pruningSeq) + + // Assert that pruning sequence end has been set correctly + counterpartySequenceSend, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetPruningSequenceEnd(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(2), counterpartySequenceSend) + }, + }, + { + name: "success: UNORDERED -> ORDERED", + malleate: func() { + path.EndpointA.ChannelConfig.Order = types.UNORDERED + path.EndpointB.ChannelConfig.Order = types.UNORDERED + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Ordering = types.ORDERED + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Ordering = types.ORDERED + }, + preUpgrade: func() { + ctx := suite.chainA.GetContext() + + // assert that NextSeqRecv is 1 because channel is UNORDERED + seq, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceRecv(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(1), seq) + + // assert that NextSeqAck is 1 because channel is UNORDERED + seq, found = suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceAck(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(1), seq) + + // Assert that pruning sequence start has not been initialized. + suite.Require().False(suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.HasPruningSequenceStart(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + + // Assert that pruning sequence end has not been set + counterpartyNextSequenceSend, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetPruningSequenceEnd(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found) + suite.Require().Equal(uint64(0), counterpartyNextSequenceSend) + }, + postUpgrade: func() { + channel := path.EndpointA.GetChannel() + ctx := suite.chainA.GetContext() + + // Assert that channel state has been updated + suite.Require().Equal(types.OPEN, channel.State) + suite.Require().Equal(types.ORDERED, channel.Ordering) + + // assert that NextSeqRecv is incremented to 2, because channel is now ORDERED + // NextSeqRecv updated in WriteUpgradeOpenChannel to latest sequence (one packet sent) + 1 + seq, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceRecv(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(2), seq) + + // assert that NextSeqAck is incremented to 2 because channel is now ORDERED + seq, found = suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceAck(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(2), seq) + + // Assert that pruning sequence start has been initialized (set to 1) + suite.Require().True(suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.HasPruningSequenceStart(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + pruningSeq := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetPruningSequenceStart(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(uint64(1), pruningSeq) + + // Assert that pruning sequence end has been set correctly + counterpartySequenceSend, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetPruningSequenceEnd(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(2), counterpartySequenceSend) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + + tc.malleate() + + suite.coordinator.Setup(path) + + // Need to create a packet commitment on A so as to keep it from going to OPEN if no inflight packets exist. + sequenceA, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packetA := types.NewPacket(ibctesting.MockPacketData, sequenceA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) + err = path.EndpointB.RecvPacket(packetA) + suite.Require().NoError(err) + + // send second packet from B to A + sequenceB, err := path.EndpointB.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData) + suite.Require().NoError(err) + packetB := types.NewPacket(ibctesting.MockPacketData, sequenceB, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp) + err = path.EndpointA.RecvPacket(packetB) + suite.Require().NoError(err) + + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + suite.Require().NoError(path.EndpointA.ChanUpgradeAck()) + suite.Require().NoError(path.EndpointB.ChanUpgradeConfirm()) + + // Ack packets to delete packet commitments before calling WriteUpgradeOpenChannel + err = path.EndpointA.AcknowledgePacket(packetA, ibctesting.MockAcknowledgement) + suite.Require().NoError(err) + + err = path.EndpointB.AcknowledgePacket(packetB, ibctesting.MockAcknowledgement) + suite.Require().NoError(err) + + // pre upgrade assertions + tc.preUpgrade() + + tc.malleate() + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeOpenChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + + // post upgrade assertions + tc.postUpgrade() + + // Assert that state stored for upgrade has been deleted + upgrade, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(types.Upgrade{}, upgrade) + suite.Require().False(found) + + counterpartyUpgrade, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetCounterpartyUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(types.Upgrade{}, counterpartyUpgrade) + suite.Require().False(found) + + // events := ctx.EventManager().Events().ToABCIEvents() + // expEvents := ibctesting.EventsMap{ + // types.EventTypeChannelUpgradeOpen: { + // types.AttributeKeyPortID: path.EndpointA.ChannelConfig.PortID, + // types.AttributeKeyChannelID: path.EndpointA.ChannelID, + // types.AttributeCounterpartyPortID: path.EndpointB.ChannelConfig.PortID, + // types.AttributeCounterpartyChannelID: path.EndpointB.ChannelID, + // types.AttributeKeyChannelState: types.OPEN.String(), + // types.AttributeKeyUpgradeConnectionHops: channel.ConnectionHops[0], + // types.AttributeKeyUpgradeVersion: channel.Version, + // types.AttributeKeyUpgradeOrdering: channel.Ordering.String(), + // types.AttributeKeyUpgradeSequence: fmt.Sprintf("%d", channel.UpgradeSequence), + // }, + // sdk.EventTypeMessage: { + // sdk.AttributeKeyModule: types.AttributeValueCategory, + // }, + // } + // ibctesting.AssertEventsLegacy(&suite.Suite, expEvents, events) + }) + } +} + +func (suite *KeeperTestSuite) TestChanUpgradeCancel() { + var ( + path *ibctesting.Path + errorReceipt types.ErrorReceipt + errorReceiptProof []byte + proofHeight clienttypes.Height + ) + + tests := []struct { + name string + malleate func() + expError error + }{ + { + name: "success with flush complete state", + malleate: func() {}, + expError: nil, + }, + { + name: "success with flushing state", + malleate: func() { + channel := path.EndpointA.GetChannel() + channel.State = types.FLUSHING + path.EndpointA.SetChannel(channel) + }, + expError: nil, + }, + { + name: "upgrade cannot be cancelled in FLUSHCOMPLETE with invalid error receipt", + malleate: func() { + errorReceiptProof = nil + }, + expError: commitmenttypes.ErrInvalidProof, + }, + { + name: "upgrade cannot be cancelled in FLUSHCOMPLETE with error receipt sequence less than channel upgrade sequence", + malleate: func() { + var ok bool + errorReceipt, ok = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + + errorReceipt.Sequence = path.EndpointA.GetChannel().UpgradeSequence - 1 + + suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, errorReceipt) + + suite.coordinator.CommitBlock(suite.chainB) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + upgradeErrorReceiptKey := host.ChannelUpgradeErrorKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + errorReceiptProof, proofHeight = suite.chainB.QueryProof(upgradeErrorReceiptKey) + }, + expError: types.ErrInvalidUpgradeSequence, + }, + { + name: "channel not found", + malleate: func() { + path.EndpointA.Chain.DeleteKey(host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + expError: types.ErrChannelNotFound, + }, + { + name: "upgrade not found", + malleate: func() { + path.EndpointA.Chain.DeleteKey(host.ChannelUpgradeKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + expError: types.ErrUpgradeNotFound, + }, + { + name: "error receipt sequence less than channel upgrade sequence", + malleate: func() { + var ok bool + errorReceipt, ok = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + + errorReceipt.Sequence = path.EndpointA.GetChannel().UpgradeSequence - 1 + + suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, errorReceipt) + + suite.coordinator.CommitBlock(suite.chainB) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + upgradeErrorReceiptKey := host.ChannelUpgradeErrorKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + errorReceiptProof, proofHeight = suite.chainB.QueryProof(upgradeErrorReceiptKey) + }, + expError: types.ErrInvalidUpgradeSequence, + }, + { + name: "connection not found", + malleate: func() { + channel := path.EndpointA.GetChannel() + channel.ConnectionHops = []string{"connection-100"} + path.EndpointA.SetChannel(channel) + }, + expError: connectiontypes.ErrConnectionNotFound, + }, + { + name: "channel is in flush complete, error verification failed", + malleate: func() { + var ok bool + errorReceipt, ok = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + + errorReceipt.Message = ibctesting.InvalidID + + suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, errorReceipt) + suite.coordinator.CommitBlock(suite.chainB) + }, + expError: commitmenttypes.ErrInvalidProof, + }, + { + name: "error verification failed", + malleate: func() { + var ok bool + errorReceipt, ok = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + + errorReceipt.Message = ibctesting.InvalidID + suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, errorReceipt) + suite.coordinator.CommitBlock(suite.chainB) + }, + expError: commitmenttypes.ErrInvalidProof, + }, + { + name: "error verification failed with empty proof", + malleate: func() { + errorReceiptProof = nil + }, + expError: commitmenttypes.ErrInvalidProof, + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + + // cause the upgrade to fail on chain b so an error receipt is written. + // if the counterparty (chain A) upgrade sequence is less than the current sequence, (chain B) + // an upgrade error will be returned by chain B during ChanUpgradeTry. + channel := path.EndpointA.GetChannel() + channel.UpgradeSequence = 1 + path.EndpointA.SetChannel(channel) + + channel = path.EndpointB.GetChannel() + channel.UpgradeSequence = 2 + path.EndpointB.SetChannel(channel) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + suite.Require().NoError(path.EndpointB.UpdateClient()) + + // error receipt is written to chain B here. + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + upgradeErrorReceiptKey := host.ChannelUpgradeErrorKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + errorReceiptProof, proofHeight = suite.chainB.QueryProof(upgradeErrorReceiptKey) + + var ok bool + errorReceipt, ok = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + + channel = path.EndpointA.GetChannel() + channel.State = types.FLUSHCOMPLETE + path.EndpointA.SetChannel(channel) + + tc.malleate() + + err := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ChanUpgradeCancel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, errorReceipt, errorReceiptProof, proofHeight) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} + +// TestChanUpgrade_UpgradeSucceeds_AfterCancel verifies that if upgrade sequences +// become out of sync, the upgrade can still be performed successfully after the upgrade is cancelled. +func (suite *KeeperTestSuite) TestChanUpgrade_UpgradeSucceeds_AfterCancel() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + + // cause the upgrade to fail on chain b so an error receipt is written. + // if the counterparty (chain A) upgrade sequence is less than the current sequence, (chain B) + // an upgrade error will be returned by chain B during ChanUpgradeTry. + channel := path.EndpointA.GetChannel() + channel.UpgradeSequence = 1 + path.EndpointA.SetChannel(channel) + + channel = path.EndpointB.GetChannel() + channel.UpgradeSequence = 5 + path.EndpointB.SetChannel(channel) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + suite.Require().NoError(path.EndpointB.UpdateClient()) + + // error receipt is written to chain B here. + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + var errorReceipt types.ErrorReceipt + suite.T().Run("error receipt written", func(t *testing.T) { + var ok bool + errorReceipt, ok = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + }) + + suite.T().Run("upgrade cancelled successfully", func(t *testing.T) { + upgradeErrorReceiptKey := host.ChannelUpgradeErrorKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + errorReceiptProof, proofHeight := suite.chainB.QueryProof(upgradeErrorReceiptKey) + + err := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ChanUpgradeCancel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, errorReceipt, errorReceiptProof, proofHeight) + suite.Require().NoError(err) + + // need to explicitly call WriteUpgradeOpenChannel as this usually would happen in the msg server layer. + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeCancelChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, errorReceipt.Sequence) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.OPEN, channel.State) + + suite.T().Run("verify upgrade sequence fastforwards to channelB sequence", func(t *testing.T) { + suite.Require().Equal(uint64(5), channel.UpgradeSequence) + }) + }) + + suite.T().Run("successfully completes upgrade", func(t *testing.T) { + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + suite.Require().NoError(path.EndpointA.ChanUpgradeAck()) + suite.Require().NoError(path.EndpointB.ChanUpgradeConfirm()) + suite.Require().NoError(path.EndpointA.ChanUpgradeOpen()) + }) + + suite.T().Run("channel in expected state", func(t *testing.T) { + channel := path.EndpointA.GetChannel() + suite.Require().Equal(types.OPEN, channel.State, "channel should be in OPEN state") + suite.Require().Equal(mock.UpgradeVersion, channel.Version, "version should be correctly upgraded") + suite.Require().Equal(mock.UpgradeVersion, path.EndpointB.GetChannel().Version, "version should be correctly upgraded") + suite.Require().Equal(uint64(6), channel.UpgradeSequence, "upgrade sequence should be incremented") + suite.Require().Equal(uint64(6), path.EndpointB.GetChannel().UpgradeSequence, "upgrade sequence should be incremented on counterparty") + }) +} + +func (suite *KeeperTestSuite) TestWriteUpgradeCancelChannel() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expPanic bool + }{ + { + name: "success", + malleate: func() {}, + expPanic: false, + }, + { + name: "channel not found", + malleate: func() { + path.EndpointA.Chain.DeleteKey(host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + expPanic: true, + }, + { + name: "upgrade not found", + malleate: func() { + path.EndpointA.Chain.DeleteKey(host.ChannelUpgradeKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + expPanic: true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + + // cause the upgrade to fail on chain b so an error receipt is written. + // if the counterparty (chain A) upgrade sequence is less than the current sequence, (chain B) + // an upgrade error will be returned by chain B during ChanUpgradeTry. + channel := path.EndpointA.GetChannel() + channel.UpgradeSequence = 1 + path.EndpointA.SetChannel(channel) + + channel = path.EndpointB.GetChannel() + channel.UpgradeSequence = 2 + path.EndpointB.SetChannel(channel) + + err := path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + errorReceipt, ok := suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + + ctx := suite.chainA.GetContext() + tc.malleate() + + if tc.expPanic { + suite.Require().Panics(func() { + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeCancelChannel(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, errorReceipt.Sequence) + }) + } else { + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.WriteUpgradeCancelChannel(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, errorReceipt.Sequence) + + channel = path.EndpointA.GetChannel() + + // Verify that channel has been restored to previous state + suite.Require().Equal(types.OPEN, channel.State) + suite.Require().Equal(mock.Version, channel.Version) + suite.Require().Equal(errorReceipt.Sequence, channel.UpgradeSequence) + + // Assert that state stored for upgrade has been deleted + upgrade, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(types.Upgrade{}, upgrade) + suite.Require().False(found) + + counterpartyUpgrade, found := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.GetCounterpartyUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Equal(types.Upgrade{}, counterpartyUpgrade) + suite.Require().False(found) + + // we need to find the event values from the proposed upgrade as the actual upgrade has been deleted. + // proposedUpgrade := path.EndpointA.GetProposedUpgrade() + // events := ctx.EventManager().Events().ToABCIEvents() + // expEvents := ibctesting.EventsMap{ + // types.EventTypeChannelUpgradeCancel: { + // types.AttributeKeyPortID: path.EndpointA.ChannelConfig.PortID, + // types.AttributeKeyChannelID: path.EndpointA.ChannelID, + // types.AttributeCounterpartyPortID: path.EndpointB.ChannelConfig.PortID, + // types.AttributeCounterpartyChannelID: path.EndpointB.ChannelID, + // types.AttributeKeyUpgradeConnectionHops: proposedUpgrade.Fields.ConnectionHops[0], + // types.AttributeKeyUpgradeVersion: proposedUpgrade.Fields.Version, + // types.AttributeKeyUpgradeOrdering: proposedUpgrade.Fields.Ordering.String(), + // types.AttributeKeyUpgradeSequence: fmt.Sprintf("%d", channel.UpgradeSequence), + // }, + // sdk.EventTypeMessage: { + // sdk.AttributeKeyModule: types.AttributeValueCategory, + // }, + // } + + } + }) + } +} + +func (suite *KeeperTestSuite) TestChanUpgradeTimeout() { + var ( + path *ibctesting.Path + proofChannel []byte + proofHeight exported.Height + ) + + timeoutUpgrade := func() { + upgrade := path.EndpointA.GetProposedUpgrade() + upgrade.Timeout = types.NewTimeout(clienttypes.ZeroHeight(), 1) + path.EndpointA.SetChannelUpgrade(upgrade) + suite.Require().NoError(path.EndpointB.UpdateClient()) + } + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success: proof timestamp has passed", + func() { + timeoutUpgrade() + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight = path.EndpointB.QueryProof(channelKey) + }, + nil, + }, + { + "channel not found", + func() { + path.EndpointA.ChannelID = ibctesting.InvalidID + }, + types.ErrChannelNotFound, + }, + { + "channel state is not in FLUSHING or FLUSHINGCOMPLETE state", + func() { + suite.Require().NoError(path.EndpointA.SetChannelState(types.OPEN)) + }, + types.ErrInvalidChannelState, + }, + { + "current upgrade not found", + func() { + suite.chainA.DeleteKey(host.ChannelUpgradeKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + types.ErrUpgradeNotFound, + }, + { + "connection not found", + func() { + channel := path.EndpointA.GetChannel() + channel.ConnectionHops[0] = ibctesting.InvalidID + path.EndpointA.SetChannel(channel) + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "connection not open", + func() { + connectionEnd := path.EndpointA.GetConnection() + connectionEnd.State = connectiontypes.UNINITIALIZED + path.EndpointA.SetConnection(connectionEnd) + }, + connectiontypes.ErrInvalidConnectionState, + }, + { + "unable to retrieve timestamp at proof height", + func() { + // TODO: revert this when the upgrade timeout is not hard coded to 1000 + proofHeight = clienttypes.NewHeight(clienttypes.ParseChainID(suite.chainA.ChainID), uint64(suite.chainA.GetContext().BlockHeight())+1000) + }, + clienttypes.ErrConsensusStateNotFound, + }, + { + "invalid channel state proof", + func() { + channel := path.EndpointB.GetChannel() + channel.State = types.OPEN + path.EndpointB.SetChannel(channel) + + timeoutUpgrade() + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight = path.EndpointB.QueryProof(channelKey) + + // modify state so the proof becomes invalid. + channel.State = types.FLUSHING + path.EndpointB.SetChannel(channel) + suite.coordinator.CommitNBlocks(suite.chainB, 1) + }, + commitmenttypes.ErrInvalidProof, + }, + { + "invalid counterparty upgrade sequence", + func() { + channel := path.EndpointB.GetChannel() + channel.UpgradeSequence = path.EndpointA.GetChannel().UpgradeSequence - 1 + path.EndpointB.SetChannel(channel) + + timeoutUpgrade() + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight = path.EndpointB.QueryProof(channelKey) + }, + types.ErrInvalidUpgradeSequence, + }, + { + "timeout timestamp has not passed", + func() { + upgrade := path.EndpointA.GetProposedUpgrade() + upgrade.Timeout.Timestamp = math.MaxUint64 + path.EndpointA.SetChannelUpgrade(upgrade) + + suite.Require().NoError(path.EndpointB.UpdateClient()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight = path.EndpointB.QueryProof(channelKey) + }, + types.ErrInvalidUpgradeTimeout, + }, + { + "counterparty channel state is not OPEN or FLUSHING (crossing hellos)", + func() { + channel := path.EndpointB.GetChannel() + channel.State = types.FLUSHCOMPLETE + path.EndpointB.SetChannel(channel) + + timeoutUpgrade() + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight = path.EndpointB.QueryProof(channelKey) + }, + types.ErrInvalidCounterparty, + }, + { + "counterparty proposed connection invalid", + func() { + channel := path.EndpointB.GetChannel() + channel.State = types.OPEN + path.EndpointB.SetChannel(channel) + + timeoutUpgrade() + + upgrade := path.EndpointA.GetChannelUpgrade() + upgrade.Fields.ConnectionHops = []string{"connection-100"} + path.EndpointA.SetChannelUpgrade(upgrade) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + suite.Require().NoError(path.EndpointB.UpdateClient()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight = path.EndpointB.QueryProof(channelKey) + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "counterparty channel already upgraded", + func() { + // put chainA channel into OPEN state since both sides are in FLUSHCOMPLETE + suite.Require().NoError(path.EndpointB.ChanUpgradeConfirm()) + + timeoutUpgrade() + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight = path.EndpointB.QueryProof(channelKey) + }, + types.ErrUpgradeTimeoutFailed, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + expPass := tc.expError == nil + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + suite.Require().NoError(path.EndpointA.ChanUpgradeAck()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight = path.EndpointB.QueryProof(channelKey) + + tc.malleate() + + err := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ChanUpgradeTimeout( + suite.chainA.GetContext(), + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + path.EndpointB.GetChannel(), + proofChannel, + proofHeight, + ) + + if expPass { + suite.Require().NoError(err) + } else { + suite.assertUpgradeError(err, tc.expError) + } + }) + } +} + +func (suite *KeeperTestSuite) TestStartFlush() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "channel not found", + func() { + path.EndpointB.ChannelID = "invalid-channel" + path.EndpointB.ChannelConfig.PortID = "invalid-port" + }, + types.ErrChannelNotFound, + }, + { + "connection not found", + func() { + channel := path.EndpointB.GetChannel() + channel.ConnectionHops[0] = ibctesting.InvalidID + path.EndpointB.SetChannel(channel) + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "connection state is not in OPEN state", + func() { + conn := path.EndpointB.GetConnection() + conn.State = connectiontypes.INIT + path.EndpointB.SetConnection(conn) + }, + connectiontypes.ErrInvalidConnectionState, + }, + { + "next sequence send not found", + func() { + // Delete next sequence send key from store + store := suite.chainB.GetContext().KVStore(suite.chainB.GetSimApp().GetKey(exported.StoreKey)) + store.Delete(host.NextSequenceSendKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) + }, + types.ErrSequenceSendNotFound, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + // crossing hellos so that the upgrade is created on chain B. + // the ChanUpgradeInit sub protocol is also called when it is not a crossing hello situation. + err = path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + + upgrade := path.EndpointB.GetChannelUpgrade() + + tc.malleate() + + err = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.StartFlushing( + suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, &upgrade, + ) + + if tc.expError != nil { + suite.assertUpgradeError(err, tc.expError) + } else { + channel := path.EndpointB.GetChannel() + + nextSequenceSend, ok := suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetNextSequenceSend(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + + suite.Require().Equal(types.FLUSHING, channel.State) + suite.Require().Equal(nextSequenceSend, upgrade.NextSequenceSend) + + expectedTimeoutTimestamp := types.DefaultTimeout.Timestamp + uint64(suite.chainB.GetContext().BlockTime().UnixNano()) + suite.Require().Equal(expectedTimeoutTimestamp, upgrade.Timeout.Timestamp) + suite.Require().Equal(clienttypes.ZeroHeight(), upgrade.Timeout.Height, "only timestamp should be set") + suite.Require().NoError(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestValidateUpgradeFields() { + var ( + proposedUpgrade *types.UpgradeFields + path *ibctesting.Path + ) + tests := []struct { + name string + malleate func() + expPass bool + }{ + { + name: "change channel version", + malleate: func() { + proposedUpgrade.Version = mock.UpgradeVersion + }, + expPass: true, + }, + { + name: "change connection hops", + malleate: func() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + proposedUpgrade.ConnectionHops = []string{path.EndpointA.ConnectionID} + }, + expPass: true, + }, + { + name: "fails with unmodified fields", + malleate: func() {}, + expPass: false, + }, + { + name: "fails when connection is not set", + malleate: func() { + storeKey := suite.chainA.GetSimApp().GetKey(exported.StoreKey) + kvStore := suite.chainA.GetContext().KVStore(storeKey) + kvStore.Delete(host.ConnectionKey(ibctesting.FirstConnectionID)) + }, + expPass: false, + }, + { + name: "fails when connection is not open", + malleate: func() { + connection := path.EndpointA.GetConnection() + connection.State = connectiontypes.UNINITIALIZED + path.EndpointA.SetConnection(connection) + }, + expPass: false, + }, + { + name: "fails when connection versions do not exist", + malleate: func() { + // update channel version first so that existing channel end is not identical to proposed upgrade + proposedUpgrade.Version = mock.UpgradeVersion + + connection := path.EndpointA.GetConnection() + connection.Versions = []*connectiontypes.Version{} + path.EndpointA.SetConnection(connection) + }, + expPass: false, + }, + { + name: "fails when connection version does not support the new ordering", + malleate: func() { + // update channel version first so that existing channel end is not identical to proposed upgrade + proposedUpgrade.Version = mock.UpgradeVersion + + connection := path.EndpointA.GetConnection() + connection.Versions = []*connectiontypes.Version{ + connectiontypes.NewVersion("1", []string{"ORDER_ORDERED"}), + } + path.EndpointA.SetConnection(connection) + }, + expPass: false, + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + existingChannel := path.EndpointA.GetChannel() + proposedUpgrade = &types.UpgradeFields{ + Ordering: existingChannel.Ordering, + ConnectionHops: existingChannel.ConnectionHops, + Version: existingChannel.Version, + } + + tc.malleate() + + err := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.ValidateSelfUpgradeFields(suite.chainA.GetContext(), *proposedUpgrade, existingChannel) + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *KeeperTestSuite) assertUpgradeError(actualError, expError error) { + suite.Require().Error(actualError) + + if expUpgradeError, ok := expError.(*types.UpgradeError); ok { + upgradeError, ok := actualError.(*types.UpgradeError) + suite.Require().True(ok) + suite.Require().Equal(expUpgradeError.GetErrorReceipt(), upgradeError.GetErrorReceipt()) + } + + suite.Require().True(errorsmod.IsOf(actualError, expError), fmt.Sprintf("expected error: %s, actual error: %s", expError, actualError)) +} + +// TestAbortUpgrade tests that when the channel handshake is aborted, the channel state +// is restored the previous state and that an error receipt is written, and upgrade state which +// is no longer required is deleted. +func (suite *KeeperTestSuite) TestAbortUpgrade() { + var ( + path *ibctesting.Path + upgradeError error + ) + + tests := []struct { + name string + malleate func() + expPass bool + }{ + { + name: "success", + malleate: func() {}, + expPass: true, + }, + { + name: "regular error", + malleate: func() { + // in app callbacks error receipts should still be written if a regular error is returned. + // i.e. not an instance of `types.UpgradeError` + upgradeError = types.ErrInvalidUpgrade + }, + expPass: true, + }, + { + name: "channel does not exist", + malleate: func() { + suite.chainA.DeleteKey(host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + expPass: false, + }, + { + name: "fails with nil upgrade error", + malleate: func() { + upgradeError = nil + }, + expPass: false, + }, + } + + for _, tc := range tests { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + channelKeeper := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper + + path.EndpointA.ChannelConfig.Version = mock.UpgradeVersion + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + + // fetch the upgrade before abort for assertions later on. + actualUpgrade, ok := channelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(ok, "upgrade should be found") + + upgradeError = types.NewUpgradeError(1, types.ErrInvalidChannel) + + tc.malleate() + + if tc.expPass { + + ctx := suite.chainA.GetContext() + + suite.Require().NotPanics(func() { + channelKeeper.MustAbortUpgrade(ctx, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgradeError) + }) + + // events := ctx.EventManager().Events().ToABCIEvents() + // expEvents := ibctesting.EventsMap{ + // "channel_upgrade_error": { + // "port_id": path.EndpointA.ChannelConfig.PortID, + // "channel_id": path.EndpointA.ChannelID, + // "counterparty_port_id": path.EndpointB.ChannelConfig.PortID, + // "counterparty_channel_id": path.EndpointB.ChannelID, + // "upgrade_sequence": fmt.Sprintf("%d", path.EndpointA.GetChannel().UpgradeSequence), + // "upgrade_error_receipt": upgradeError.Error(), + // }, + // } + + channel, found := channelKeeper.GetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found, "channel should be found") + + suite.Require().Equal(types.OPEN, channel.State, "channel state should be %s", types.OPEN.String()) + + _, found = channelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found, "upgrade info should be deleted") + + errorReceipt, found := channelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found, "error receipt should be found") + + if ue, ok := upgradeError.(*types.UpgradeError); ok { + suite.Require().Equal(ue.GetErrorReceipt(), errorReceipt, "error receipt does not match expected error receipt") + } + } else { + + suite.Require().Panics(func() { + channelKeeper.MustAbortUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgradeError) + }) + + channel, found := channelKeeper.GetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + if found { // test cases uses a channel that exists + suite.Require().Equal(types.OPEN, channel.State, "channel state should not be restored to %s", types.OPEN.String()) + } + + _, found = channelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found, "error receipt should not be found") + + upgrade, found := channelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + if found { // this should be all test cases except for when the upgrade is explicitly deleted. + suite.Require().Equal(actualUpgrade, upgrade, "upgrade info should not be deleted") + } + } + }) + } +} + +func (suite *KeeperTestSuite) TestCheckForUpgradeCompatibility() { + var ( + path *ibctesting.Path + upgradeFields types.UpgradeFields + counterpartyUpgradeFields types.UpgradeFields + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "upgrade ordering is not the same on both sides", + func() { + upgradeFields.Ordering = types.ORDERED + }, + types.ErrIncompatibleCounterpartyUpgrade, + }, + { + "proposed connection is not found", + func() { + upgradeFields.ConnectionHops[0] = ibctesting.InvalidID + }, + connectiontypes.ErrConnectionNotFound, + }, + { + "proposed connection is not in OPEN state", + func() { + // reuse existing connection to create a new connection in a non OPEN state + connectionEnd := path.EndpointB.GetConnection() + connectionEnd.State = connectiontypes.UNINITIALIZED + connectionEnd.Counterparty.ConnectionId = counterpartyUpgradeFields.ConnectionHops[0] // both sides must be each other's counterparty + + // set proposed connection in state + proposedConnectionID := "connection-100" + suite.chainB.GetSimApp().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), proposedConnectionID, connectionEnd) + upgradeFields.ConnectionHops[0] = proposedConnectionID + }, + connectiontypes.ErrInvalidConnectionState, + }, + { + "proposed connection ends are not each other's counterparty", + func() { + // reuse existing connection to create a new connection in a non OPEN state + connectionEnd := path.EndpointB.GetConnection() + // ensure counterparty connectionID does not match connectionID set in counterparty proposed upgrade + connectionEnd.Counterparty.ConnectionId = "connection-50" + + // set proposed connection in state + proposedConnectionID := "connection-100" + suite.chainB.GetSimApp().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), proposedConnectionID, connectionEnd) + upgradeFields.ConnectionHops[0] = proposedConnectionID + }, + types.ErrIncompatibleCounterpartyUpgrade, + }, + { + "proposed upgrade version is not the same on both sides", + func() { + upgradeFields.Version = mock.Version + }, + types.ErrIncompatibleCounterpartyUpgrade, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + upgradeFields = path.EndpointA.GetProposedUpgrade().Fields + counterpartyUpgradeFields = path.EndpointB.GetProposedUpgrade().Fields + + tc.malleate() + + err = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.CheckForUpgradeCompatibility(suite.chainB.GetContext(), upgradeFields, counterpartyUpgradeFields) + if tc.expError != nil { + suite.Require().ErrorIs(err, tc.expError) + } else { + suite.Require().NoError(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestSyncUpgradeSequence() { + var ( + path *ibctesting.Path + counterpartyUpgradeSequence uint64 + ) + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "upgrade sequence mismatch, endpointB channel upgrade sequence is ahead", + func() { + channel := path.EndpointB.GetChannel() + channel.UpgradeSequence = 10 + path.EndpointB.SetChannel(channel) + }, + types.NewUpgradeError(10, types.ErrInvalidUpgradeSequence), // max sequence will be returned + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + + counterpartyUpgradeSequence = 1 + + tc.malleate() + + err = suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SyncUpgradeSequence(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointB.GetChannel(), counterpartyUpgradeSequence) + if tc.expError != nil { + suite.Require().ErrorIs(err, tc.expError) + } else { + suite.Require().NoError(err) + } + }) + } +} + +func (suite *KeeperTestSuite) TestChanUpgradeCrossingHelloWithHistoricalProofs() { + var path *ibctesting.Path + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "counterparty (chain B) has already progressed to ACK step", + func() { + err := path.EndpointB.ChanUpgradeAck() + suite.Require().NoError(err) + }, + types.ErrInvalidChannelState, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = mock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeInit() + suite.Require().NoError(err) + + suite.coordinator.CommitBlock(suite.chainA, suite.chainB) + + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + historicalChannelProof, historicalUpgradeProof, proofHeight := path.EndpointA.QueryChannelUpgradeProof() + + err = path.EndpointA.ChanUpgradeTry() + suite.Require().NoError(err) + + tc.malleate() + + _, upgrade, err := suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.ChanUpgradeTry( + suite.chainB.GetContext(), + path.EndpointB.ChannelConfig.PortID, + path.EndpointB.ChannelID, + path.EndpointB.GetChannelUpgrade().Fields.ConnectionHops, + path.EndpointA.GetChannelUpgrade().Fields, + 1, + historicalChannelProof, + historicalUpgradeProof, + proofHeight, + ) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + suite.Require().NotEmpty(upgrade) + } else { + suite.Require().ErrorIs(err, tc.expError) + } + }) + } +} + +func (suite *KeeperTestSuite) TestWriteErrorReceipt() { + var path *ibctesting.Path + var upgradeError *types.UpgradeError + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "success: existing error receipt found at a lower sequence", + func() { + // write an error sequence with a lower sequence number + previousUpgradeError := types.NewUpgradeError(upgradeError.GetErrorReceipt().Sequence-1, types.ErrInvalidUpgrade) + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, previousUpgradeError.GetErrorReceipt()) + }, + nil, + }, + { + "failure: existing error receipt found at a higher sequence", + func() { + // write an error sequence with a higher sequence number + previousUpgradeError := types.NewUpgradeError(upgradeError.GetErrorReceipt().Sequence+1, types.ErrInvalidUpgrade) + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, previousUpgradeError.GetErrorReceipt()) + }, + errorsmod.Wrap(types.ErrInvalidUpgradeSequence, "error receipt sequence (10) must be greater than existing error receipt sequence (11)"), + }, + { + "failure: channel not found", + func() { + suite.chainA.DeleteKey(host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) + }, + errorsmod.Wrap(types.ErrChannelNotFound, "port ID (mock) channel ID (channel-0)"), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + channelKeeper := suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper + + upgradeError = types.NewUpgradeError(10, types.ErrInvalidUpgrade) + + tc.malleate() + + expPass := tc.expError == nil + if expPass { + suite.NotPanics(func() { + channelKeeper.WriteErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgradeError) + }) + } else { + suite.PanicsWithError(tc.expError.Error(), func() { + channelKeeper.WriteErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, upgradeError) + }) + } + }) + } +} diff --git a/modules/core/04-channel/types/channel.go b/modules/core/04-channel/types/channel.go index d288a2a8842..21b7bf3b658 100644 --- a/modules/core/04-channel/types/channel.go +++ b/modules/core/04-channel/types/channel.go @@ -23,6 +23,8 @@ func NewChannel( Counterparty: counterparty, ConnectionHops: hops, Version: version, + // UpgradeSequence is intentionally left empty as a new channel has not performed an upgrade. + UpgradeSequence: 0, } } @@ -115,13 +117,14 @@ func (c Counterparty) ValidateBasic() error { // NewIdentifiedChannel creates a new IdentifiedChannel instance func NewIdentifiedChannel(portID, channelID string, ch Channel) IdentifiedChannel { return IdentifiedChannel{ - State: ch.State, - Ordering: ch.Ordering, - Counterparty: ch.Counterparty, - ConnectionHops: ch.ConnectionHops, - Version: ch.Version, - PortId: portID, - ChannelId: channelID, + State: ch.State, + Ordering: ch.Ordering, + Counterparty: ch.Counterparty, + ConnectionHops: ch.ConnectionHops, + Version: ch.Version, + UpgradeSequence: ch.UpgradeSequence, + PortId: portID, + ChannelId: channelID, } } diff --git a/modules/core/04-channel/types/channel.pb.go b/modules/core/04-channel/types/channel.pb.go index 4e6c985b8db..39a11872ca0 100644 --- a/modules/core/04-channel/types/channel.pb.go +++ b/modules/core/04-channel/types/channel.pb.go @@ -25,7 +25,7 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // State defines if a channel is in one of the following states: -// CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. +// CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or UNINITIALIZED. type State int32 const ( @@ -41,6 +41,10 @@ const ( // A channel has been closed and can no longer be used to send or receive // packets. CLOSED State = 4 + // A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + FLUSHING State = 5 + // A channel has just completed flushing any in-flight packets. + FLUSHCOMPLETE State = 6 ) var State_name = map[int32]string{ @@ -49,6 +53,8 @@ var State_name = map[int32]string{ 2: "STATE_TRYOPEN", 3: "STATE_OPEN", 4: "STATE_CLOSED", + 5: "STATE_FLUSHING", + 6: "STATE_FLUSHCOMPLETE", } var State_value = map[string]int32{ @@ -57,6 +63,8 @@ var State_value = map[string]int32{ "STATE_TRYOPEN": 2, "STATE_OPEN": 3, "STATE_CLOSED": 4, + "STATE_FLUSHING": 5, + "STATE_FLUSHCOMPLETE": 6, } func (x State) String() string { @@ -115,6 +123,9 @@ type Channel struct { ConnectionHops []string `protobuf:"bytes,4,rep,name=connection_hops,json=connectionHops,proto3" json:"connection_hops,omitempty"` // opaque channel version, which is agreed upon during the handshake Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + UpgradeSequence uint64 `protobuf:"varint,6,opt,name=upgrade_sequence,json=upgradeSequence,proto3" json:"upgrade_sequence,omitempty"` } func (m *Channel) Reset() { *m = Channel{} } @@ -168,6 +179,9 @@ type IdentifiedChannel struct { PortId string `protobuf:"bytes,6,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` // channel identifier ChannelId string `protobuf:"bytes,7,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + UpgradeSequence uint64 `protobuf:"varint,8,opt,name=upgrade_sequence,json=upgradeSequence,proto3" json:"upgrade_sequence,omitempty"` } func (m *IdentifiedChannel) Reset() { *m = IdentifiedChannel{} } @@ -543,6 +557,52 @@ func (m *Timeout) GetTimestamp() uint64 { return 0 } +// Params defines the set of IBC channel parameters. +type Params struct { + // the relative timeout after which channel upgrades will time out. + UpgradeTimeout Timeout `protobuf:"bytes,1,opt,name=upgrade_timeout,json=upgradeTimeout,proto3" json:"upgrade_timeout"` +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_c3a07336710636a0, []int{8} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetUpgradeTimeout() Timeout { + if m != nil { + return m.UpgradeTimeout + } + return Timeout{} +} + func init() { proto.RegisterEnum("ibc.core.channel.v1.State", State_name, State_value) proto.RegisterEnum("ibc.core.channel.v1.Order", Order_name, Order_value) @@ -554,65 +614,72 @@ func init() { proto.RegisterType((*PacketId)(nil), "ibc.core.channel.v1.PacketId") proto.RegisterType((*Acknowledgement)(nil), "ibc.core.channel.v1.Acknowledgement") proto.RegisterType((*Timeout)(nil), "ibc.core.channel.v1.Timeout") + proto.RegisterType((*Params)(nil), "ibc.core.channel.v1.Params") } func init() { proto.RegisterFile("ibc/core/channel/v1/channel.proto", fileDescriptor_c3a07336710636a0) } var fileDescriptor_c3a07336710636a0 = []byte{ - // 842 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x55, 0xcd, 0x8e, 0xdb, 0x54, - 0x14, 0xb6, 0x33, 0xce, 0xdf, 0xc9, 0x64, 0x26, 0x73, 0x0b, 0x83, 0x65, 0x15, 0xc7, 0x1d, 0x81, - 0x08, 0x45, 0x8d, 0x3b, 0x05, 0xa1, 0xc2, 0x6e, 0x26, 0x31, 0xc4, 0x62, 0x94, 0x44, 0x4e, 0x66, - 0x41, 0x37, 0x91, 0x63, 0x5f, 0x12, 0xab, 0x89, 0xaf, 0xb1, 0x6f, 0x52, 0x55, 0xbc, 0x40, 0xc9, - 0x8a, 0x17, 0x88, 0x84, 0xc4, 0x43, 0xf0, 0x0a, 0x95, 0xd8, 0x74, 0xd9, 0x15, 0x42, 0x33, 0x2f, - 0x82, 0x7c, 0xef, 0xf5, 0x24, 0xa9, 0x46, 0x23, 0x84, 0xc4, 0x8a, 0x55, 0xee, 0xf9, 0xce, 0x77, - 0xbe, 0x73, 0xfc, 0x1d, 0xc7, 0x17, 0x1e, 0x04, 0x63, 0xcf, 0xf4, 0x48, 0x8c, 0x4d, 0x6f, 0xea, - 0x86, 0x21, 0x9e, 0x99, 0xcb, 0xd3, 0xec, 0xd8, 0x8c, 0x62, 0x42, 0x09, 0xba, 0x17, 0x8c, 0xbd, - 0x66, 0x4a, 0x69, 0x66, 0xf8, 0xf2, 0x54, 0x7b, 0x6f, 0x42, 0x26, 0x84, 0xe5, 0xcd, 0xf4, 0xc4, - 0xa9, 0x5a, 0x7d, 0xa3, 0x36, 0x0b, 0x70, 0x48, 0x99, 0x18, 0x3b, 0x71, 0xc2, 0xc9, 0xcf, 0x39, - 0x28, 0xb6, 0xb8, 0x0a, 0x7a, 0x0c, 0xf9, 0x84, 0xba, 0x14, 0xab, 0xb2, 0x21, 0x37, 0x0e, 0x9e, - 0x68, 0xcd, 0x5b, 0xfa, 0x34, 0x07, 0x29, 0xc3, 0xe1, 0x44, 0xf4, 0x25, 0x94, 0x48, 0xec, 0xe3, - 0x38, 0x08, 0x27, 0x6a, 0xee, 0x8e, 0xa2, 0x5e, 0x4a, 0x72, 0x6e, 0xb8, 0xe8, 0x3b, 0xd8, 0xf7, - 0xc8, 0x22, 0xa4, 0x38, 0x8e, 0xdc, 0x98, 0xbe, 0x54, 0xf7, 0x0c, 0xb9, 0x51, 0x79, 0xf2, 0xe0, - 0xd6, 0xda, 0xd6, 0x16, 0xf1, 0x5c, 0x79, 0xfd, 0x67, 0x5d, 0x72, 0x76, 0x8a, 0xd1, 0x27, 0x70, - 0xe8, 0x91, 0x30, 0xc4, 0x1e, 0x0d, 0x48, 0x38, 0x9a, 0x92, 0x28, 0x51, 0x15, 0x63, 0xaf, 0x51, - 0x76, 0x0e, 0x36, 0x70, 0x87, 0x44, 0x09, 0x52, 0xa1, 0xb8, 0xc4, 0x71, 0x12, 0x90, 0x50, 0xcd, - 0x1b, 0x72, 0xa3, 0xec, 0x64, 0xe1, 0xd7, 0xca, 0xab, 0x5f, 0xeb, 0xd2, 0xc9, 0x1f, 0x39, 0x38, - 0xb2, 0x7d, 0x1c, 0xd2, 0xe0, 0x87, 0x00, 0xfb, 0xff, 0x7b, 0x57, 0xd0, 0x07, 0x50, 0x8c, 0x48, - 0x4c, 0x47, 0x81, 0xaf, 0x16, 0x58, 0xa6, 0x90, 0x86, 0xb6, 0x8f, 0x3e, 0x04, 0x10, 0xa3, 0xa4, - 0xb9, 0x22, 0xcb, 0x95, 0x05, 0x62, 0xfb, 0xc2, 0xcd, 0x0b, 0xd8, 0xdf, 0x1e, 0x72, 0x5b, 0x4d, - 0xbe, 0x43, 0x2d, 0x77, 0xbb, 0xda, 0xdb, 0x1c, 0x14, 0xfa, 0xae, 0xf7, 0x1c, 0x53, 0xa4, 0x41, - 0x29, 0xc1, 0x3f, 0x2e, 0x70, 0xe8, 0xf1, 0x9d, 0x28, 0xce, 0x4d, 0x8c, 0xea, 0x50, 0x49, 0xc8, - 0x22, 0xf6, 0xf0, 0x28, 0x15, 0x17, 0x62, 0xc0, 0xa1, 0x3e, 0x89, 0x29, 0xfa, 0x18, 0x0e, 0x04, - 0x41, 0x74, 0x60, 0x2e, 0x97, 0x9d, 0x2a, 0x47, 0xb3, 0xa5, 0x7f, 0x0a, 0x35, 0x1f, 0x27, 0x34, - 0x08, 0x5d, 0x66, 0x1f, 0x13, 0x53, 0x18, 0xf1, 0x70, 0x0b, 0x67, 0x8a, 0x26, 0xdc, 0xdb, 0xa6, - 0x66, 0xb2, 0xdc, 0x4b, 0xb4, 0x95, 0xca, 0xb4, 0x11, 0x28, 0xbe, 0x4b, 0x5d, 0xe6, 0xe9, 0xbe, - 0xc3, 0xce, 0xe8, 0x5b, 0x38, 0xa0, 0xc1, 0x1c, 0x93, 0x05, 0x1d, 0x4d, 0x71, 0x30, 0x99, 0x52, - 0xe6, 0x6a, 0x65, 0xe7, 0xc5, 0xe1, 0x7f, 0xdb, 0xe5, 0x69, 0xb3, 0xc3, 0x18, 0x62, 0xeb, 0x55, - 0x51, 0xc7, 0x41, 0xf4, 0x19, 0x1c, 0x65, 0x42, 0xe9, 0x6f, 0x42, 0xdd, 0x79, 0xa4, 0x96, 0x98, - 0x4b, 0x35, 0x91, 0x18, 0x66, 0xb8, 0xb0, 0xf6, 0x27, 0xa8, 0x70, 0x67, 0xd9, 0x4b, 0xfc, 0x6f, - 0xf7, 0xb4, 0xb3, 0x96, 0xbd, 0x77, 0xd6, 0x92, 0x3d, 0xb2, 0xb2, 0x79, 0x64, 0xd1, 0xdc, 0x87, - 0x12, 0x6f, 0x6e, 0xfb, 0xff, 0x45, 0x67, 0xd1, 0xa5, 0x07, 0x87, 0x67, 0xde, 0xf3, 0x90, 0xbc, - 0x98, 0x61, 0x7f, 0x82, 0xe7, 0x38, 0xa4, 0x48, 0x85, 0x42, 0x8c, 0x93, 0xc5, 0x8c, 0xaa, 0xef, - 0xa7, 0x43, 0x75, 0x24, 0x47, 0xc4, 0xe8, 0x18, 0xf2, 0x38, 0x8e, 0x49, 0xac, 0x1e, 0xa7, 0x8d, - 0x3a, 0x92, 0xc3, 0xc3, 0x73, 0x80, 0x52, 0x8c, 0x93, 0x88, 0x84, 0x09, 0x3e, 0x71, 0xa1, 0x38, - 0xe4, 0x6e, 0xa2, 0xa7, 0x50, 0x10, 0x2b, 0x93, 0xff, 0xe1, 0xca, 0x04, 0x1f, 0xdd, 0x87, 0xf2, - 0x66, 0x47, 0x39, 0x36, 0xf8, 0x06, 0x78, 0xf8, 0xbb, 0x0c, 0xf9, 0x81, 0xf8, 0x9e, 0xd4, 0x07, - 0xc3, 0xb3, 0xa1, 0x35, 0xba, 0xec, 0xda, 0x5d, 0x7b, 0x68, 0x9f, 0x5d, 0xd8, 0xcf, 0xac, 0xf6, - 0xe8, 0xb2, 0x3b, 0xe8, 0x5b, 0x2d, 0xfb, 0x1b, 0xdb, 0x6a, 0xd7, 0x24, 0xed, 0x68, 0xb5, 0x36, - 0xaa, 0x3b, 0x04, 0xa4, 0x02, 0xf0, 0xba, 0x14, 0xac, 0xc9, 0x5a, 0x69, 0xb5, 0x36, 0x94, 0xf4, - 0x8c, 0x74, 0xa8, 0xf2, 0xcc, 0xd0, 0xf9, 0xbe, 0xd7, 0xb7, 0xba, 0xb5, 0x9c, 0x56, 0x59, 0xad, - 0x8d, 0xa2, 0x08, 0x37, 0x95, 0x2c, 0xb9, 0xc7, 0x2b, 0x59, 0xe6, 0x3e, 0xec, 0xf3, 0x4c, 0xeb, - 0xa2, 0x37, 0xb0, 0xda, 0x35, 0x45, 0x83, 0xd5, 0xda, 0x28, 0xf0, 0x48, 0x53, 0x5e, 0xfd, 0xa6, - 0x4b, 0x0f, 0x5f, 0x40, 0x9e, 0x7d, 0xda, 0xd0, 0x47, 0x70, 0xdc, 0x73, 0xda, 0x96, 0x33, 0xea, - 0xf6, 0xba, 0xd6, 0x3b, 0xf3, 0x32, 0xc9, 0x14, 0x47, 0x27, 0x70, 0xc8, 0x59, 0x97, 0x5d, 0xf6, - 0x6b, 0xb5, 0x6b, 0xb2, 0x56, 0x5d, 0xad, 0x8d, 0xf2, 0x0d, 0x90, 0x0e, 0xcc, 0x39, 0x19, 0x43, - 0x0c, 0x2c, 0x42, 0xde, 0xf8, 0x7c, 0xf0, 0xfa, 0x4a, 0x97, 0xdf, 0x5c, 0xe9, 0xf2, 0x5f, 0x57, - 0xba, 0xfc, 0xcb, 0xb5, 0x2e, 0xbd, 0xb9, 0xd6, 0xa5, 0xb7, 0xd7, 0xba, 0xf4, 0xec, 0xab, 0x49, - 0x40, 0xa7, 0x8b, 0x71, 0xd3, 0x23, 0x73, 0xd3, 0x23, 0xc9, 0x9c, 0x24, 0x66, 0x30, 0xf6, 0x1e, - 0x4d, 0x88, 0xb9, 0x7c, 0x6a, 0xce, 0x89, 0xbf, 0x98, 0xe1, 0x84, 0xdf, 0x93, 0x8f, 0xbf, 0x78, - 0x94, 0x5d, 0xbc, 0xf4, 0x65, 0x84, 0x93, 0x71, 0x81, 0x5d, 0x94, 0x9f, 0xff, 0x1d, 0x00, 0x00, - 0xff, 0xff, 0x15, 0x20, 0x09, 0x7f, 0x99, 0x07, 0x00, 0x00, + // 937 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x56, 0x4f, 0x6f, 0xe2, 0xc6, + 0x1b, 0xc6, 0xc4, 0xfc, 0x7b, 0x93, 0x80, 0x33, 0xf9, 0xfd, 0x52, 0xcb, 0x4a, 0xc1, 0x8b, 0x5a, + 0x95, 0x4d, 0xb5, 0xb0, 0xd9, 0x56, 0xd5, 0xb6, 0xb7, 0x04, 0xbc, 0x8b, 0xb5, 0x14, 0x90, 0x81, + 0x43, 0xf7, 0x82, 0x8c, 0x3d, 0x05, 0x6b, 0xc1, 0x43, 0xed, 0x81, 0xd5, 0xaa, 0xe7, 0x4a, 0x2b, + 0x4e, 0xfd, 0x02, 0x48, 0x95, 0xfa, 0x15, 0xfa, 0x21, 0xf6, 0xb8, 0xc7, 0x3d, 0x55, 0x55, 0xf2, + 0x1d, 0x7a, 0xae, 0x3c, 0x33, 0x0e, 0x10, 0x45, 0x51, 0x55, 0xa9, 0xb7, 0x9e, 0x98, 0xf7, 0x79, + 0x9f, 0xf7, 0x7d, 0xde, 0x3f, 0xc3, 0xc8, 0xf0, 0xc0, 0x1b, 0x39, 0x35, 0x87, 0x04, 0xb8, 0xe6, + 0x4c, 0x6c, 0xdf, 0xc7, 0xd3, 0xda, 0xf2, 0x3c, 0x3e, 0x56, 0xe7, 0x01, 0xa1, 0x04, 0x1d, 0x7b, + 0x23, 0xa7, 0x1a, 0x51, 0xaa, 0x31, 0xbe, 0x3c, 0xd7, 0xfe, 0x37, 0x26, 0x63, 0xc2, 0xfc, 0xb5, + 0xe8, 0xc4, 0xa9, 0x5a, 0x69, 0x93, 0x6d, 0xea, 0x61, 0x9f, 0xb2, 0x64, 0xec, 0xc4, 0x09, 0xe5, + 0xdf, 0x92, 0x90, 0xa9, 0xf3, 0x2c, 0xe8, 0x31, 0xa4, 0x42, 0x6a, 0x53, 0xac, 0x4a, 0xba, 0x54, + 0xc9, 0x3f, 0xd1, 0xaa, 0x77, 0xe8, 0x54, 0x7b, 0x11, 0xc3, 0xe2, 0x44, 0xf4, 0x15, 0x64, 0x49, + 0xe0, 0xe2, 0xc0, 0xf3, 0xc7, 0x6a, 0xf2, 0x9e, 0xa0, 0x4e, 0x44, 0xb2, 0x6e, 0xb8, 0xe8, 0x05, + 0x1c, 0x38, 0x64, 0xe1, 0x53, 0x1c, 0xcc, 0xed, 0x80, 0xbe, 0x51, 0xf7, 0x74, 0xa9, 0xb2, 0xff, + 0xe4, 0xc1, 0x9d, 0xb1, 0xf5, 0x2d, 0xe2, 0xa5, 0xfc, 0xee, 0xf7, 0x52, 0xc2, 0xda, 0x09, 0x46, + 0x9f, 0x41, 0xc1, 0x21, 0xbe, 0x8f, 0x1d, 0xea, 0x11, 0x7f, 0x38, 0x21, 0xf3, 0x50, 0x95, 0xf5, + 0xbd, 0x4a, 0xce, 0xca, 0x6f, 0xe0, 0x26, 0x99, 0x87, 0x48, 0x85, 0xcc, 0x12, 0x07, 0xa1, 0x47, + 0x7c, 0x35, 0xa5, 0x4b, 0x95, 0x9c, 0x15, 0x9b, 0xe8, 0x21, 0x28, 0x8b, 0xf9, 0x38, 0xb0, 0x5d, + 0x3c, 0x0c, 0xf1, 0x0f, 0x0b, 0xec, 0x3b, 0x58, 0x4d, 0xeb, 0x52, 0x45, 0xb6, 0x0a, 0x02, 0xef, + 0x09, 0xf8, 0x1b, 0xf9, 0xed, 0x2f, 0xa5, 0x44, 0xf9, 0xcf, 0x24, 0x1c, 0x99, 0x2e, 0xf6, 0xa9, + 0xf7, 0xbd, 0x87, 0xdd, 0xff, 0x06, 0xf8, 0x11, 0x64, 0xe6, 0x24, 0xa0, 0x43, 0xcf, 0x65, 0x73, + 0xcb, 0x59, 0xe9, 0xc8, 0x34, 0x5d, 0xf4, 0x31, 0x80, 0x28, 0x25, 0xf2, 0x65, 0x98, 0x2f, 0x27, + 0x10, 0xd3, 0xbd, 0x73, 0xf0, 0xd9, 0xfb, 0x06, 0xdf, 0x82, 0x83, 0xed, 0x7e, 0xb6, 0x85, 0xa5, + 0x7b, 0x84, 0x93, 0xb7, 0x84, 0x45, 0xb6, 0x0f, 0x49, 0x48, 0x77, 0x6d, 0xe7, 0x15, 0xa6, 0x48, + 0x83, 0xec, 0x4d, 0x05, 0x12, 0xab, 0xe0, 0xc6, 0x46, 0x25, 0xd8, 0x0f, 0xc9, 0x22, 0x70, 0xf0, + 0x30, 0x4a, 0x2e, 0x92, 0x01, 0x87, 0xba, 0x24, 0xa0, 0xe8, 0x53, 0xc8, 0x0b, 0x82, 0x50, 0x60, + 0x0b, 0xc9, 0x59, 0x87, 0x1c, 0x8d, 0xef, 0xc7, 0x43, 0x50, 0x5c, 0x1c, 0x52, 0xcf, 0xb7, 0xd9, + 0xa4, 0x59, 0x32, 0x99, 0x11, 0x0b, 0x5b, 0x38, 0xcb, 0x58, 0x83, 0xe3, 0x6d, 0x6a, 0x9c, 0x96, + 0x8f, 0x1d, 0x6d, 0xb9, 0xe2, 0xdc, 0x08, 0x64, 0xd7, 0xa6, 0x36, 0x1b, 0xff, 0x81, 0xc5, 0xce, + 0xe8, 0x39, 0xe4, 0xa9, 0x37, 0xc3, 0x64, 0x41, 0x87, 0x13, 0xec, 0x8d, 0x27, 0x94, 0x2d, 0x60, + 0x7f, 0xe7, 0x8e, 0xf1, 0xc7, 0x60, 0x79, 0x5e, 0x6d, 0x32, 0x86, 0xb8, 0x20, 0x87, 0x22, 0x8e, + 0x83, 0xe8, 0x73, 0x38, 0x8a, 0x13, 0x45, 0xbf, 0x21, 0xb5, 0x67, 0x73, 0xb1, 0x27, 0x45, 0x38, + 0xfa, 0x31, 0x2e, 0x46, 0xfb, 0x23, 0xec, 0xf3, 0xc9, 0xb2, 0xfb, 0xfe, 0x4f, 0xf7, 0xb4, 0xb3, + 0x96, 0xbd, 0x5b, 0x6b, 0x89, 0x5b, 0x96, 0x37, 0x2d, 0x0b, 0x71, 0x17, 0xb2, 0x5c, 0xdc, 0x74, + 0xff, 0x0d, 0x65, 0xa1, 0xd2, 0x81, 0xc2, 0x85, 0xf3, 0xca, 0x27, 0xaf, 0xa7, 0xd8, 0x1d, 0xe3, + 0x19, 0xf6, 0x29, 0x52, 0x21, 0x1d, 0xe0, 0x70, 0x31, 0xa5, 0xea, 0xff, 0xa3, 0xa2, 0x9a, 0x09, + 0x4b, 0xd8, 0xe8, 0x04, 0x52, 0x38, 0x08, 0x48, 0xa0, 0x9e, 0x44, 0x42, 0xcd, 0x84, 0xc5, 0xcd, + 0x4b, 0x80, 0x6c, 0x80, 0xc3, 0x39, 0xf1, 0x43, 0x5c, 0xb6, 0x21, 0xd3, 0xe7, 0xd3, 0x44, 0x4f, + 0x21, 0x2d, 0x56, 0x26, 0xfd, 0xcd, 0x95, 0x09, 0x3e, 0x3a, 0x85, 0xdc, 0x66, 0x47, 0x49, 0x56, + 0xf8, 0x06, 0x28, 0x0f, 0xa2, 0x0b, 0x1f, 0xd8, 0xb3, 0x10, 0xbd, 0x80, 0xf8, 0x2f, 0x36, 0x14, + 0x2b, 0x14, 0x52, 0xa7, 0x77, 0xbe, 0x22, 0xa2, 0x30, 0x21, 0x96, 0x17, 0xa1, 0x02, 0x3d, 0xfb, + 0x29, 0x09, 0xa9, 0x9e, 0x78, 0xd1, 0x4a, 0xbd, 0xfe, 0x45, 0xdf, 0x18, 0x0e, 0xda, 0x66, 0xdb, + 0xec, 0x9b, 0x17, 0x2d, 0xf3, 0xa5, 0xd1, 0x18, 0x0e, 0xda, 0xbd, 0xae, 0x51, 0x37, 0x9f, 0x99, + 0x46, 0x43, 0x49, 0x68, 0x47, 0xab, 0xb5, 0x7e, 0xb8, 0x43, 0x40, 0x2a, 0x00, 0x8f, 0x8b, 0x40, + 0x45, 0xd2, 0xb2, 0xab, 0xb5, 0x2e, 0x47, 0x67, 0x54, 0x84, 0x43, 0xee, 0xe9, 0x5b, 0xdf, 0x75, + 0xba, 0x46, 0x5b, 0x49, 0x6a, 0xfb, 0xab, 0xb5, 0x9e, 0x11, 0xe6, 0x26, 0x92, 0x39, 0xf7, 0x78, + 0x24, 0xf3, 0x9c, 0xc2, 0x01, 0xf7, 0xd4, 0x5b, 0x9d, 0x9e, 0xd1, 0x50, 0x64, 0x0d, 0x56, 0x6b, + 0x3d, 0xcd, 0x2d, 0xa4, 0x43, 0x9e, 0x7b, 0x9f, 0xb5, 0x06, 0xbd, 0xa6, 0xd9, 0x7e, 0xae, 0xa4, + 0xb4, 0x83, 0xd5, 0x5a, 0xcf, 0xc6, 0x36, 0x3a, 0x83, 0xe3, 0x2d, 0x46, 0xbd, 0xf3, 0x6d, 0xb7, + 0x65, 0xf4, 0x0d, 0x25, 0xcd, 0xeb, 0xdf, 0x01, 0x35, 0xf9, 0xed, 0xaf, 0xc5, 0xc4, 0xd9, 0x6b, + 0x48, 0xb1, 0xa7, 0x1a, 0x7d, 0x02, 0x27, 0x1d, 0xab, 0x61, 0x58, 0xc3, 0x76, 0xa7, 0x6d, 0xdc, + 0xea, 0x9e, 0x15, 0x18, 0xe1, 0xa8, 0x0c, 0x05, 0xce, 0x1a, 0xb4, 0xd9, 0xaf, 0xd1, 0x50, 0x24, + 0xed, 0x70, 0xb5, 0xd6, 0x73, 0x37, 0x40, 0xd4, 0x3e, 0xe7, 0xc4, 0x0c, 0xd1, 0xbe, 0x30, 0xb9, + 0xf0, 0x65, 0xef, 0xdd, 0x55, 0x51, 0x7a, 0x7f, 0x55, 0x94, 0xfe, 0xb8, 0x2a, 0x4a, 0x3f, 0x5f, + 0x17, 0x13, 0xef, 0xaf, 0x8b, 0x89, 0x0f, 0xd7, 0xc5, 0xc4, 0xcb, 0xaf, 0xc7, 0x1e, 0x9d, 0x2c, + 0x46, 0x55, 0x87, 0xcc, 0x6a, 0x0e, 0x09, 0x67, 0x24, 0xac, 0x79, 0x23, 0xe7, 0xd1, 0x98, 0xd4, + 0x96, 0x4f, 0x6b, 0x33, 0xe2, 0x2e, 0xa6, 0x38, 0xe4, 0x9f, 0x08, 0x8f, 0xbf, 0x7c, 0x14, 0x7f, + 0x73, 0xd0, 0x37, 0x73, 0x1c, 0x8e, 0xd2, 0xec, 0x1b, 0xe1, 0x8b, 0xbf, 0x02, 0x00, 0x00, 0xff, + 0xff, 0x90, 0xd1, 0xb4, 0xca, 0x94, 0x08, 0x00, 0x00, } func (m *Channel) Marshal() (dAtA []byte, err error) { @@ -635,6 +702,11 @@ func (m *Channel) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.UpgradeSequence != 0 { + i = encodeVarintChannel(dAtA, i, uint64(m.UpgradeSequence)) + i-- + dAtA[i] = 0x30 + } if len(m.Version) > 0 { i -= len(m.Version) copy(dAtA[i:], m.Version) @@ -694,6 +766,11 @@ func (m *IdentifiedChannel) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.UpgradeSequence != 0 { + i = encodeVarintChannel(dAtA, i, uint64(m.UpgradeSequence)) + i-- + dAtA[i] = 0x40 + } if len(m.ChannelId) > 0 { i -= len(m.ChannelId) copy(dAtA[i:], m.ChannelId) @@ -1057,6 +1134,39 @@ func (m *Timeout) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.UpgradeTimeout.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintChannel(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func encodeVarintChannel(dAtA []byte, offset int, v uint64) int { offset -= sovChannel(v) base := offset @@ -1092,6 +1202,9 @@ func (m *Channel) Size() (n int) { if l > 0 { n += 1 + l + sovChannel(uint64(l)) } + if m.UpgradeSequence != 0 { + n += 1 + sovChannel(uint64(m.UpgradeSequence)) + } return n } @@ -1127,6 +1240,9 @@ func (m *IdentifiedChannel) Size() (n int) { if l > 0 { n += 1 + l + sovChannel(uint64(l)) } + if m.UpgradeSequence != 0 { + n += 1 + sovChannel(uint64(m.UpgradeSequence)) + } return n } @@ -1276,6 +1392,17 @@ func (m *Timeout) Size() (n int) { return n } +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.UpgradeTimeout.Size() + n += 1 + l + sovChannel(uint64(l)) + return n +} + func sovChannel(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1446,6 +1573,25 @@ func (m *Channel) Unmarshal(dAtA []byte) error { } m.Version = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradeSequence", wireType) + } + m.UpgradeSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChannel + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UpgradeSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipChannel(dAtA[iNdEx:]) @@ -1695,6 +1841,25 @@ func (m *IdentifiedChannel) Unmarshal(dAtA []byte) error { } m.ChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradeSequence", wireType) + } + m.UpgradeSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChannel + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UpgradeSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipChannel(dAtA[iNdEx:]) @@ -2630,6 +2795,89 @@ func (m *Timeout) Unmarshal(dAtA []byte) error { } return nil } +func (m *Params) 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 ErrIntOverflowChannel + } + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradeTimeout", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChannel + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChannel + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthChannel + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UpgradeTimeout.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipChannel(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthChannel + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipChannel(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/modules/core/04-channel/types/channel_test.go b/modules/core/04-channel/types/channel_test.go index d35ec13a519..211be035fe8 100644 --- a/modules/core/04-channel/types/channel_test.go +++ b/modules/core/04-channel/types/channel_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" ) func TestChannelValidateBasic(t *testing.T) { @@ -57,3 +58,37 @@ func TestCounterpartyValidateBasic(t *testing.T) { } } } + +// TestIdentifiedChannelValidateBasic tests ValidateBasic for IdentifiedChannel. +func TestIdentifiedChannelValidateBasic(t *testing.T) { + channel := types.NewChannel(types.TRYOPEN, types.ORDERED, types.Counterparty{"portidone", "channelidone"}, connHops, version) + + testCases := []struct { + name string + identifiedChannel types.IdentifiedChannel + expErr error + }{ + { + "valid identified channel", + types.NewIdentifiedChannel("portidone", "channelidone", channel), + nil, + }, + { + "invalid portID", + types.NewIdentifiedChannel("(InvalidPort)", "channelidone", channel), + host.ErrInvalidID, + }, + { + "invalid channelID", + types.NewIdentifiedChannel("portidone", "(InvalidChannel)", channel), + host.ErrInvalidID, + }, + } + + for _, tc := range testCases { + tc := tc + + err := tc.identifiedChannel.ValidateBasic() + require.ErrorIs(t, err, tc.expErr) + } +} diff --git a/modules/core/04-channel/types/codec.go b/modules/core/04-channel/types/codec.go index 86f2f495d19..d55fffece0c 100644 --- a/modules/core/04-channel/types/codec.go +++ b/modules/core/04-channel/types/codec.go @@ -39,6 +39,15 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { &MsgAcknowledgement{}, &MsgTimeout{}, &MsgTimeoutOnClose{}, + &MsgChannelUpgradeInit{}, + &MsgChannelUpgradeTry{}, + &MsgChannelUpgradeAck{}, + &MsgChannelUpgradeConfirm{}, + &MsgChannelUpgradeOpen{}, + &MsgChannelUpgradeTimeout{}, + &MsgChannelUpgradeCancel{}, + &MsgPruneAcknowledgements{}, + &MsgUpdateParams{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/modules/core/04-channel/types/codec_test.go b/modules/core/04-channel/types/codec_test.go index 9122a95df0a..fab8d9e5bd0 100644 --- a/modules/core/04-channel/types/codec_test.go +++ b/modules/core/04-channel/types/codec_test.go @@ -83,6 +83,51 @@ func TestCodecTypeRegistration(t *testing.T) { sdk.MsgTypeURL(&types.MsgTimeoutOnClose{}), true, }, + { + "success: MsgChannelUpgradeInit", + sdk.MsgTypeURL(&types.MsgChannelUpgradeInit{}), + true, + }, + { + "success: MsgChannelUpgradeTry", + sdk.MsgTypeURL(&types.MsgChannelUpgradeTry{}), + true, + }, + { + "success: MsgChannelUpgradeAck", + sdk.MsgTypeURL(&types.MsgChannelUpgradeAck{}), + true, + }, + { + "success: MsgChannelUpgradeConfirm", + sdk.MsgTypeURL(&types.MsgChannelUpgradeConfirm{}), + true, + }, + { + "success: MsgChannelUpgradeOpen", + sdk.MsgTypeURL(&types.MsgChannelUpgradeOpen{}), + true, + }, + { + "success: MsgChannelUpgradeTimeout", + sdk.MsgTypeURL(&types.MsgChannelUpgradeTimeout{}), + true, + }, + { + "success: MsgChannelUpgradeCancel", + sdk.MsgTypeURL(&types.MsgChannelUpgradeCancel{}), + true, + }, + { + "success: MsgPruneAcknowledgements", + sdk.MsgTypeURL(&types.MsgPruneAcknowledgements{}), + true, + }, + { + "success: MsgUpdateParams", + sdk.MsgTypeURL(&types.MsgUpdateParams{}), + true, + }, { "type not registered on codec", "ibc.invalid.MsgTypeURL", diff --git a/modules/core/04-channel/types/errors.go b/modules/core/04-channel/types/errors.go index dfbbf30a1cb..703832a9330 100644 --- a/modules/core/04-channel/types/errors.go +++ b/modules/core/04-channel/types/errors.go @@ -37,7 +37,23 @@ var ( // Perform a no-op on the current Msg ErrNoOpMsg = errorsmod.Register(SubModuleName, 23, "message is redundant, no-op will be performed") - 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") + 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") + ErrUpgradeErrorNotFound = errorsmod.Register(SubModuleName, 27, "upgrade error receipt not found") + ErrInvalidUpgrade = errorsmod.Register(SubModuleName, 28, "invalid upgrade") + ErrInvalidUpgradeSequence = errorsmod.Register(SubModuleName, 29, "invalid upgrade sequence") + ErrUpgradeNotFound = errorsmod.Register(SubModuleName, 30, "upgrade not found") + ErrIncompatibleCounterpartyUpgrade = errorsmod.Register(SubModuleName, 31, "incompatible counterparty upgrade") + ErrInvalidUpgradeError = errorsmod.Register(SubModuleName, 32, "invalid upgrade error") + ErrUpgradeRestoreFailed = errorsmod.Register(SubModuleName, 33, "restore failed") + ErrUpgradeTimeout = errorsmod.Register(SubModuleName, 34, "upgrade timed-out") + ErrInvalidUpgradeTimeout = errorsmod.Register(SubModuleName, 35, "upgrade timeout is invalid") + ErrPendingInflightPackets = errorsmod.Register(SubModuleName, 36, "pending inflight packets exist") + ErrUpgradeTimeoutFailed = errorsmod.Register(SubModuleName, 37, "upgrade timeout failed") + ErrInvalidPruningLimit = errorsmod.Register(SubModuleName, 38, "invalid pruning limit") + ErrTimeoutNotReached = errorsmod.Register(SubModuleName, 39, "timeout not reached") + ErrTimeoutElapsed = errorsmod.Register(SubModuleName, 40, "timeout elapsed") + ErrPruningSequenceStartNotFound = errorsmod.Register(SubModuleName, 41, "pruning sequence start not found") + ErrPruningSequenceEndNotFound = errorsmod.Register(SubModuleName, 42, "pruning sequence end not found") ) diff --git a/modules/core/04-channel/types/events.go b/modules/core/04-channel/types/events.go index 3d4738626e2..414a02208e5 100644 --- a/modules/core/04-channel/types/events.go +++ b/modules/core/04-channel/types/events.go @@ -11,6 +11,7 @@ const ( AttributeKeyConnectionID = "connection_id" AttributeKeyPortID = "port_id" AttributeKeyChannelID = "channel_id" + AttributeKeyChannelState = "channel_state" AttributeVersion = "version" AttributeCounterpartyPortID = "counterparty_port_id" AttributeCounterpartyChannelID = "counterparty_channel_id" @@ -37,17 +38,34 @@ const ( AttributeKeyDstChannel = "packet_dst_channel" AttributeKeyChannelOrdering = "packet_channel_ordering" AttributeKeyConnection = "packet_connection" + + // upgrade specific keys + AttributeKeyUpgradeSequence = "upgrade_sequence" + AttributeKeyUpgradeVersion = "upgrade_version" + AttributeKeyUpgradeConnectionHops = "upgrade_connection_hops" + AttributeKeyUpgradeOrdering = "upgrade_ordering" + AttributeKeyUpgradeErrorReceipt = "upgrade_error_receipt" + AttributeKeyUpgradeTimeout = "upgrade_timeout" ) // IBC channel events vars var ( - EventTypeChannelOpenInit = "channel_open_init" - EventTypeChannelOpenTry = "channel_open_try" - EventTypeChannelOpenAck = "channel_open_ack" - EventTypeChannelOpenConfirm = "channel_open_confirm" - EventTypeChannelCloseInit = "channel_close_init" - EventTypeChannelCloseConfirm = "channel_close_confirm" - EventTypeChannelClosed = "channel_close" + EventTypeChannelOpenInit = "channel_open_init" + EventTypeChannelOpenTry = "channel_open_try" + EventTypeChannelOpenAck = "channel_open_ack" + EventTypeChannelOpenConfirm = "channel_open_confirm" + EventTypeChannelCloseInit = "channel_close_init" + EventTypeChannelCloseConfirm = "channel_close_confirm" + EventTypeChannelClosed = "channel_close" + EventTypeChannelUpgradeInit = "channel_upgrade_init" + EventTypeChannelUpgradeTry = "channel_upgrade_try" + EventTypeChannelUpgradeAck = "channel_upgrade_ack" + EventTypeChannelUpgradeConfirm = "channel_upgrade_confirm" + EventTypeChannelUpgradeOpen = "channel_upgrade_open" + EventTypeChannelUpgradeTimeout = "channel_upgrade_timeout" + EventTypeChannelUpgradeCancel = "channel_upgrade_cancelled" + EventTypeChannelUpgradeError = "channel_upgrade_error" + EventTypeChannelFlushComplete = "channel_flush_complete" 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 b1e3aae98d3..9b3b4b2e2de 100644 --- a/modules/core/04-channel/types/expected_keepers.go +++ b/modules/core/04-channel/types/expected_keepers.go @@ -73,6 +73,32 @@ type ConnectionKeeper interface { channelID string, nextSequenceRecv uint64, ) error + VerifyChannelUpgrade( + ctx sdk.Context, + connection exported.ConnectionI, + height exported.Height, + proof []byte, + portID, + channelID string, + upgrade Upgrade, + ) error + VerifyChannelUpgradeError( + ctx sdk.Context, + connection exported.ConnectionI, + proofHeight exported.Height, + proofErrorReceipt []byte, + portID, + channelID string, + errorReceipt ErrorReceipt, + ) error + VerifyChannelUpgradeErrorAbsence( + ctx sdk.Context, + connection exported.ConnectionI, + proofHeight exported.Height, + proofErrorReceiptAbsence []byte, + portID, + channelID string, + ) error } // PortKeeper expected account IBC port keeper diff --git a/modules/core/04-channel/types/genesis.go b/modules/core/04-channel/types/genesis.go index fd85574d554..d95f24c35e6 100644 --- a/modules/core/04-channel/types/genesis.go +++ b/modules/core/04-channel/types/genesis.go @@ -41,7 +41,9 @@ func (ps PacketSequence) Validate() error { return validateGenFields(ps.PortId, ps.ChannelId, ps.Sequence) } -// NewGenesisState creates a GenesisState instance. +// NewGenesisState creates a GenesisState instance. It uses the default params. +// Breakage in v9.0.0 will allow the params to be provided. Please use +// NewGenesisStateWithParams in this version if you want to provide custom params. func NewGenesisState( channels []IdentifiedChannel, acks, receipts, commitments []PacketState, sendSeqs, recvSeqs, ackSeqs []PacketSequence, nextChannelSequence uint64, @@ -54,6 +56,25 @@ func NewGenesisState( RecvSequences: recvSeqs, AckSequences: ackSeqs, NextChannelSequence: nextChannelSequence, + Params: DefaultParams(), + } +} + +// NewGenesisStateWithParams creates a GenesisState instance. +func NewGenesisStateWithParams( + channels []IdentifiedChannel, acks, receipts, commitments []PacketState, + sendSeqs, recvSeqs, ackSeqs []PacketSequence, nextChannelSequence uint64, + params Params, +) GenesisState { + return GenesisState{ + Channels: channels, + Acknowledgements: acks, + Commitments: commitments, + SendSequences: sendSeqs, + RecvSequences: recvSeqs, + AckSequences: ackSeqs, + NextChannelSequence: nextChannelSequence, + Params: params, } } @@ -68,6 +89,7 @@ func DefaultGenesisState() GenesisState { RecvSequences: []PacketSequence{}, AckSequences: []PacketSequence{}, NextChannelSequence: 0, + Params: DefaultParams(), } } diff --git a/modules/core/04-channel/types/genesis.pb.go b/modules/core/04-channel/types/genesis.pb.go index 0ed3da2e528..bd8723eb637 100644 --- a/modules/core/04-channel/types/genesis.pb.go +++ b/modules/core/04-channel/types/genesis.pb.go @@ -34,6 +34,7 @@ type GenesisState struct { AckSequences []PacketSequence `protobuf:"bytes,7,rep,name=ack_sequences,json=ackSequences,proto3" json:"ack_sequences"` // the sequence for the next generated channel identifier NextChannelSequence uint64 `protobuf:"varint,8,opt,name=next_channel_sequence,json=nextChannelSequence,proto3" json:"next_channel_sequence,omitempty"` + Params Params `protobuf:"bytes,9,opt,name=params,proto3" json:"params"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -125,6 +126,13 @@ func (m *GenesisState) GetNextChannelSequence() uint64 { return 0 } +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + // PacketSequence defines the genesis type necessary to retrieve and store // next send and receive sequences. type PacketSequence struct { @@ -195,35 +203,37 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/genesis.proto", fileDescriptor_cb06ec201f452595) } var fileDescriptor_cb06ec201f452595 = []byte{ - // 446 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0xd3, 0x4d, 0x6f, 0xd3, 0x30, - 0x18, 0x07, 0xf0, 0x66, 0x2d, 0x5d, 0xe7, 0xbd, 0x08, 0x3c, 0x10, 0xa1, 0x12, 0x59, 0x19, 0x12, - 0xea, 0x65, 0x31, 0x1b, 0x1c, 0xe0, 0x1a, 0x0e, 0xd0, 0x0b, 0x9a, 0xb2, 0x1b, 0x12, 0xaa, 0x12, - 0xfb, 0x21, 0xb3, 0xd2, 0xd8, 0x21, 0x76, 0x03, 0x7c, 0x0b, 0x3e, 0xd6, 0x8e, 0x3b, 0x72, 0x9a, - 0x50, 0xfb, 0x21, 0x90, 0x38, 0xa1, 0x38, 0x2f, 0x2b, 0x6a, 0x35, 0x29, 0xb7, 0xda, 0xcf, 0xf3, - 0xff, 0xfd, 0x7b, 0x88, 0xd1, 0x33, 0x1e, 0x52, 0x42, 0x65, 0x06, 0x84, 0x5e, 0x06, 0x42, 0xc0, - 0x8c, 0xe4, 0xa7, 0x24, 0x02, 0x01, 0x8a, 0x2b, 0x37, 0xcd, 0xa4, 0x96, 0xf8, 0x90, 0x87, 0xd4, - 0x2d, 0x56, 0xdc, 0x6a, 0xc5, 0xcd, 0x4f, 0x87, 0x0f, 0x23, 0x19, 0x49, 0x33, 0x27, 0xc5, 0xaf, - 0x72, 0x75, 0xb8, 0x51, 0xab, 0x53, 0x66, 0xe5, 0xf8, 0x4f, 0x0f, 0xed, 0xbd, 0x2f, 0xfd, 0x0b, - 0x1d, 0x68, 0xc0, 0x9f, 0xd1, 0xa0, 0xda, 0x50, 0xb6, 0x35, 0xea, 0x8e, 0x77, 0xcf, 0x5e, 0xb8, - 0x1b, 0x1a, 0xdd, 0x09, 0x03, 0xa1, 0xf9, 0x17, 0x0e, 0xec, 0x5d, 0x79, 0xe9, 0x3d, 0xb9, 0xba, - 0x39, 0xea, 0xfc, 0xbd, 0x39, 0x7a, 0xb0, 0x36, 0xf2, 0x1b, 0x12, 0xfb, 0xe8, 0x7e, 0x40, 0x63, - 0x21, 0xbf, 0xcd, 0x80, 0x45, 0x90, 0x80, 0xd0, 0xca, 0xde, 0x32, 0x35, 0xa3, 0x8d, 0x35, 0xe7, - 0x01, 0x8d, 0x41, 0x9b, 0xbf, 0xe6, 0xf5, 0x8a, 0x02, 0x7f, 0x2d, 0x8f, 0x3f, 0xa0, 0x5d, 0x2a, - 0x93, 0x84, 0xeb, 0x92, 0xeb, 0xb6, 0xe2, 0x56, 0xa3, 0xd8, 0x43, 0x83, 0x0c, 0x28, 0xf0, 0x54, - 0x2b, 0xbb, 0xd7, 0x8a, 0x69, 0x72, 0xf8, 0x1c, 0x1d, 0x28, 0x10, 0x6c, 0xaa, 0xe0, 0xeb, 0x1c, - 0x04, 0x05, 0x65, 0xdf, 0x33, 0xd2, 0xf3, 0xbb, 0xa4, 0x6a, 0xb7, 0xc2, 0xf6, 0x0b, 0xa0, 0xbe, - 0x33, 0x62, 0x06, 0x34, 0x5f, 0x11, 0xfb, 0xad, 0xc5, 0x02, 0xb8, 0x15, 0x3f, 0xa2, 0xfd, 0x80, - 0xc6, 0x2b, 0xe0, 0x76, 0x5b, 0x70, 0x2f, 0xa0, 0xf1, 0xad, 0x77, 0x86, 0x1e, 0x09, 0xf8, 0xae, - 0xa7, 0x55, 0xaa, 0x81, 0xed, 0xc1, 0xc8, 0x1a, 0xf7, 0xfc, 0xc3, 0x62, 0x58, 0x7d, 0x0b, 0x75, - 0xe8, 0x98, 0xa1, 0x83, 0xff, 0x65, 0xfc, 0x18, 0x6d, 0xa7, 0x32, 0xd3, 0x53, 0xce, 0x6c, 0x6b, - 0x64, 0x8d, 0x77, 0xfc, 0x7e, 0x71, 0x9c, 0x30, 0xfc, 0x14, 0xa1, 0x5a, 0xe6, 0xcc, 0xde, 0x32, - 0xb3, 0x9d, 0xea, 0x66, 0xc2, 0xf0, 0x10, 0x0d, 0x9a, 0xc2, 0xae, 0x29, 0x6c, 0xce, 0xde, 0xc5, - 0xd5, 0xc2, 0xb1, 0xae, 0x17, 0x8e, 0xf5, 0x7b, 0xe1, 0x58, 0x3f, 0x97, 0x4e, 0xe7, 0x7a, 0xe9, - 0x74, 0x7e, 0x2d, 0x9d, 0xce, 0xa7, 0xb7, 0x11, 0xd7, 0x97, 0xf3, 0xd0, 0xa5, 0x32, 0x21, 0x54, - 0xaa, 0x44, 0x2a, 0xc2, 0x43, 0x7a, 0x12, 0x49, 0x92, 0xbf, 0x21, 0x89, 0x64, 0xf3, 0x19, 0xa8, - 0xf2, 0xf1, 0xbc, 0x7c, 0x7d, 0x52, 0xbf, 0x1f, 0xfd, 0x23, 0x05, 0x15, 0xf6, 0xcd, 0xdb, 0x79, - 0xf5, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xce, 0x58, 0xd9, 0xe7, 0xae, 0x03, 0x00, 0x00, + // 471 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x41, 0x6f, 0xd3, 0x30, + 0x18, 0x86, 0x9b, 0xb5, 0xeb, 0x5a, 0x77, 0x9b, 0xc0, 0x03, 0x11, 0x8a, 0xc8, 0xca, 0x90, 0x50, + 0x2f, 0x8b, 0x59, 0xe1, 0xc0, 0xae, 0xe5, 0x00, 0xbd, 0xa0, 0x29, 0xbb, 0x21, 0xa1, 0x2a, 0xb1, + 0x3f, 0x32, 0xab, 0x8d, 0x1d, 0x62, 0xb7, 0xc0, 0xbf, 0xe0, 0xb7, 0xf0, 0x2b, 0x76, 0xdc, 0x91, + 0xd3, 0x84, 0xda, 0x7f, 0xc1, 0x09, 0xc5, 0x71, 0xb2, 0xa2, 0x95, 0x49, 0xbd, 0xc5, 0xdf, 0xf7, + 0xbe, 0xcf, 0xfb, 0x1e, 0xf2, 0xa1, 0x67, 0x3c, 0xa2, 0x84, 0xca, 0x0c, 0x08, 0xbd, 0x08, 0x85, + 0x80, 0x29, 0x99, 0x9f, 0x90, 0x18, 0x04, 0x28, 0xae, 0xfc, 0x34, 0x93, 0x5a, 0xe2, 0x03, 0x1e, + 0x51, 0x3f, 0x97, 0xf8, 0x56, 0xe2, 0xcf, 0x4f, 0xba, 0x0f, 0x62, 0x19, 0x4b, 0xb3, 0x27, 0xf9, + 0x57, 0x21, 0xed, 0xae, 0xa5, 0x95, 0x2e, 0x23, 0x39, 0xfa, 0xb9, 0x8d, 0x76, 0xdf, 0x15, 0xfc, + 0x73, 0x1d, 0x6a, 0xc0, 0x9f, 0x50, 0xcb, 0x2a, 0x94, 0xeb, 0xf4, 0xea, 0xfd, 0xce, 0xe0, 0x85, + 0xbf, 0x26, 0xd1, 0x1f, 0x31, 0x10, 0x9a, 0x7f, 0xe6, 0xc0, 0xde, 0x16, 0xc3, 0xe1, 0xe3, 0xcb, + 0xeb, 0xc3, 0xda, 0x9f, 0xeb, 0xc3, 0xfb, 0xb7, 0x56, 0x41, 0x85, 0xc4, 0x01, 0xba, 0x17, 0xd2, + 0x89, 0x90, 0x5f, 0xa7, 0xc0, 0x62, 0x48, 0x40, 0x68, 0xe5, 0x6e, 0x99, 0x98, 0xde, 0xda, 0x98, + 0xb3, 0x90, 0x4e, 0x40, 0x9b, 0x6a, 0xc3, 0x46, 0x1e, 0x10, 0xdc, 0xf2, 0xe3, 0xf7, 0xa8, 0x43, + 0x65, 0x92, 0x70, 0x5d, 0xe0, 0xea, 0x1b, 0xe1, 0x56, 0xad, 0x78, 0x88, 0x5a, 0x19, 0x50, 0xe0, + 0xa9, 0x56, 0x6e, 0x63, 0x23, 0x4c, 0xe5, 0xc3, 0x67, 0x68, 0x5f, 0x81, 0x60, 0x63, 0x05, 0x5f, + 0x66, 0x20, 0x28, 0x28, 0x77, 0xdb, 0x90, 0x9e, 0xdf, 0x45, 0xb2, 0x5a, 0x0b, 0xdb, 0xcb, 0x01, + 0xe5, 0xcc, 0x10, 0x33, 0xa0, 0xf3, 0x15, 0x62, 0x73, 0x63, 0x62, 0x0e, 0xb8, 0x21, 0x7e, 0x40, + 0x7b, 0x21, 0x9d, 0xac, 0x00, 0x77, 0x36, 0x05, 0xee, 0x86, 0x74, 0x72, 0xc3, 0x1b, 0xa0, 0x87, + 0x02, 0xbe, 0xe9, 0xb1, 0x75, 0x55, 0x60, 0xb7, 0xd5, 0x73, 0xfa, 0x8d, 0xe0, 0x20, 0x5f, 0xda, + 0x7f, 0xa1, 0x34, 0xe1, 0x53, 0xd4, 0x4c, 0xc3, 0x2c, 0x4c, 0x94, 0xdb, 0xee, 0x39, 0xfd, 0xce, + 0xe0, 0xc9, 0x7f, 0xc2, 0x73, 0x89, 0x0d, 0xb5, 0x86, 0x23, 0x86, 0xf6, 0xff, 0x2d, 0x85, 0x1f, + 0xa1, 0x9d, 0x54, 0x66, 0x7a, 0xcc, 0x99, 0xeb, 0xf4, 0x9c, 0x7e, 0x3b, 0x68, 0xe6, 0xcf, 0x11, + 0xc3, 0x4f, 0x11, 0x2a, 0x4b, 0x71, 0xe6, 0x6e, 0x99, 0x5d, 0xdb, 0x4e, 0x46, 0x0c, 0x77, 0x51, + 0xab, 0xea, 0x5a, 0x37, 0x5d, 0xab, 0xf7, 0xf0, 0xfc, 0x72, 0xe1, 0x39, 0x57, 0x0b, 0xcf, 0xf9, + 0xbd, 0xf0, 0x9c, 0x1f, 0x4b, 0xaf, 0x76, 0xb5, 0xf4, 0x6a, 0xbf, 0x96, 0x5e, 0xed, 0xe3, 0x69, + 0xcc, 0xf5, 0xc5, 0x2c, 0xf2, 0xa9, 0x4c, 0x08, 0x95, 0x2a, 0x91, 0x8a, 0xf0, 0x88, 0x1e, 0xc7, + 0x92, 0xcc, 0xdf, 0x90, 0x44, 0xb2, 0xd9, 0x14, 0x54, 0x71, 0x77, 0x2f, 0x5f, 0x1f, 0x97, 0xa7, + 0xa7, 0xbf, 0xa7, 0xa0, 0xa2, 0xa6, 0x39, 0xbb, 0x57, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xaf, + 0xa9, 0x60, 0xe8, 0xe9, 0x03, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -246,6 +256,16 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a if m.NextChannelSequence != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.NextChannelSequence)) i-- @@ -456,6 +476,8 @@ func (m *GenesisState) Size() (n int) { if m.NextChannelSequence != 0 { n += 1 + sovGenesis(uint64(m.NextChannelSequence)) } + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) return n } @@ -771,6 +793,39 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { break } } + case 9: + 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 ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/modules/core/04-channel/types/keys.go b/modules/core/04-channel/types/keys.go index bc9e88afdea..a99e14d5b21 100644 --- a/modules/core/04-channel/types/keys.go +++ b/modules/core/04-channel/types/keys.go @@ -28,6 +28,9 @@ const ( // ChannelPrefix is the prefix used when creating a channel identifier ChannelPrefix = "channel-" + + // ParamsKey defines the key to store the params in the keeper. + ParamsKey = "channelParams" ) // FormatChannelIdentifier returns the channel identifier with the sequence appended. diff --git a/modules/core/04-channel/types/msgs.go b/modules/core/04-channel/types/msgs.go index 812829307c0..cbbfec4dc66 100644 --- a/modules/core/04-channel/types/msgs.go +++ b/modules/core/04-channel/types/msgs.go @@ -2,6 +2,7 @@ package types import ( "encoding/base64" + "slices" errorsmod "cosmossdk.io/errors" @@ -24,6 +25,7 @@ var ( _ sdk.Msg = (*MsgAcknowledgement)(nil) _ sdk.Msg = (*MsgTimeout)(nil) _ sdk.Msg = (*MsgTimeoutOnClose)(nil) + _ sdk.Msg = (*MsgPruneAcknowledgements)(nil) _ sdk.HasValidateBasic = (*MsgChannelOpenInit)(nil) _ sdk.HasValidateBasic = (*MsgChannelOpenTry)(nil) @@ -35,6 +37,11 @@ var ( _ sdk.HasValidateBasic = (*MsgAcknowledgement)(nil) _ sdk.HasValidateBasic = (*MsgTimeout)(nil) _ sdk.HasValidateBasic = (*MsgTimeoutOnClose)(nil) + _ sdk.HasValidateBasic = (*MsgChannelUpgradeInit)(nil) + _ sdk.HasValidateBasic = (*MsgChannelUpgradeTry)(nil) + _ sdk.HasValidateBasic = (*MsgChannelUpgradeAck)(nil) + _ sdk.HasValidateBasic = (*MsgChannelUpgradeConfirm)(nil) + _ sdk.HasValidateBasic = (*MsgPruneAcknowledgements)(nil) ) // NewMsgChannelOpenInit creates a new MsgChannelOpenInit. It sets the counterparty channel @@ -263,16 +270,36 @@ func (msg MsgChannelCloseInit) GetSigners() []sdk.AccAddress { } // NewMsgChannelCloseConfirm creates a new MsgChannelCloseConfirm instance +// Breakage in v9.0.0 will allow for the counterparty upgrade sequence to be provided. +// Please use NewMsgChannelCloseConfirmWithCounterpartyUpgradeSequence to provide the +// counterparty upgrade sequence in this version. func NewMsgChannelCloseConfirm( portID, channelID string, proofInit []byte, proofHeight clienttypes.Height, signer string, ) *MsgChannelCloseConfirm { return &MsgChannelCloseConfirm{ - PortId: portID, - ChannelId: channelID, - ProofInit: proofInit, - ProofHeight: proofHeight, - Signer: signer, + PortId: portID, + ChannelId: channelID, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer, + CounterpartyUpgradeSequence: 0, + } +} + +// NewMsgChannelCloseConfirmWithCounterpartyUpgradeSequence creates a new MsgChannelCloseConfirm instance +// with a non-zero counterparty upgrade sequence. +func NewMsgChannelCloseConfirmWithCounterpartyUpgradeSequence( + portID, channelID string, proofInit []byte, proofHeight clienttypes.Height, + signer string, counterpartyUpgradeSequence uint64, +) *MsgChannelCloseConfirm { + return &MsgChannelCloseConfirm{ + PortId: portID, + ChannelId: channelID, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer, + CounterpartyUpgradeSequence: counterpartyUpgradeSequence, } } @@ -382,19 +409,43 @@ func (msg MsgTimeout) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{signer} } -// NewMsgTimeoutOnClose constructs new MsgTimeoutOnClose +// NewMsgTimeoutOnClose constructs a new MsgTimeoutOnClose. +// The counterparty upgrade sequence is set to 0. Breakage in +// v9.0.0 will allow the counterparty upgrade sequence to be provided. +// Please use NewMsgTimeoutOnCloseWithCounterpartyUpgradeSequence in this version +// to provide the counterparty upgrade sequence. func NewMsgTimeoutOnClose( packet Packet, nextSequenceRecv uint64, proofUnreceived, proofClose []byte, proofHeight clienttypes.Height, signer string, ) *MsgTimeoutOnClose { return &MsgTimeoutOnClose{ - Packet: packet, - NextSequenceRecv: nextSequenceRecv, - ProofUnreceived: proofUnreceived, - ProofClose: proofClose, - ProofHeight: proofHeight, - Signer: signer, + Packet: packet, + NextSequenceRecv: nextSequenceRecv, + ProofUnreceived: proofUnreceived, + ProofClose: proofClose, + ProofHeight: proofHeight, + Signer: signer, + CounterpartyUpgradeSequence: 0, + } +} + +// NewMsgTimeoutOnCloseWithCounterpartyUpgradeSequence constructs a new MsgTimeoutOnClose +// with the provided counterparty upgrade sequence. +func NewMsgTimeoutOnCloseWithCounterpartyUpgradeSequence( + packet Packet, nextSequenceRecv uint64, + proofUnreceived, proofClose []byte, + proofHeight clienttypes.Height, signer string, + counterpartyUpgradeSequence uint64, +) *MsgTimeoutOnClose { + return &MsgTimeoutOnClose{ + Packet: packet, + NextSequenceRecv: nextSequenceRecv, + ProofUnreceived: proofUnreceived, + ProofClose: proofClose, + ProofHeight: proofHeight, + Signer: signer, + CounterpartyUpgradeSequence: counterpartyUpgradeSequence, } } @@ -464,3 +515,377 @@ func (msg MsgAcknowledgement) GetSigners() []sdk.AccAddress { } return []sdk.AccAddress{signer} } + +var _ sdk.Msg = &MsgChannelUpgradeInit{} + +// NewMsgChannelUpgradeInit constructs a new MsgChannelUpgradeInit +// nolint:interfacer +func NewMsgChannelUpgradeInit( + portID, channelID string, + upgradeFields UpgradeFields, + signer string, +) *MsgChannelUpgradeInit { + return &MsgChannelUpgradeInit{ + PortId: portID, + ChannelId: channelID, + Fields: upgradeFields, + Signer: signer, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelUpgradeInit) ValidateBasic() error { + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return errorsmod.Wrap(err, "invalid port ID") + } + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + return msg.Fields.ValidateBasic() +} + +var _ sdk.Msg = &MsgChannelUpgradeTry{} + +// NewMsgChannelUpgradeTry constructs a new MsgChannelUpgradeTry +// nolint:interfacer +func NewMsgChannelUpgradeTry( + portID, + channelID string, + proposedConnectionHops []string, + counterpartyUpgradeFields UpgradeFields, + counterpartyUpgradeSequence uint64, + proofChannel []byte, + proofUpgrade []byte, + proofHeight clienttypes.Height, + signer string, +) *MsgChannelUpgradeTry { + return &MsgChannelUpgradeTry{ + PortId: portID, + ChannelId: channelID, + ProposedUpgradeConnectionHops: proposedConnectionHops, + CounterpartyUpgradeFields: counterpartyUpgradeFields, + CounterpartyUpgradeSequence: counterpartyUpgradeSequence, + ProofChannel: proofChannel, + ProofUpgrade: proofUpgrade, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelUpgradeTry) ValidateBasic() error { + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return errorsmod.Wrap(err, "invalid port ID") + } + + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + + if len(msg.ProposedUpgradeConnectionHops) == 0 { + return errorsmod.Wrap(ErrInvalidUpgrade, "proposed connection hops cannot be empty") + } + + if err := msg.CounterpartyUpgradeFields.ValidateBasic(); err != nil { + return errorsmod.Wrap(err, "error validating counterparty upgrade fields") + } + + if msg.CounterpartyUpgradeSequence == 0 { + return errorsmod.Wrap(ErrInvalidUpgradeSequence, "counterparty sequence cannot be 0") + } + + if len(msg.ProofChannel) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") + } + + if len(msg.ProofUpgrade) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade proof") + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + return nil +} + +var _ sdk.Msg = &MsgChannelUpgradeAck{} + +// NewMsgChannelUpgradeAck constructs a new MsgChannelUpgradeAck +// nolint:interfacer +func NewMsgChannelUpgradeAck(portID, channelID string, counterpartyUpgrade Upgrade, proofChannel, proofUpgrade []byte, proofHeight clienttypes.Height, signer string) *MsgChannelUpgradeAck { + return &MsgChannelUpgradeAck{ + PortId: portID, + ChannelId: channelID, + CounterpartyUpgrade: counterpartyUpgrade, + ProofChannel: proofChannel, + ProofUpgrade: proofUpgrade, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelUpgradeAck) ValidateBasic() error { + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return errorsmod.Wrap(err, "invalid port ID") + } + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + if len(msg.ProofChannel) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") + } + if len(msg.ProofUpgrade) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade sequence proof") + } + if _, err := sdk.AccAddressFromBech32(msg.Signer); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + return msg.CounterpartyUpgrade.ValidateBasic() +} + +var _ sdk.Msg = &MsgChannelUpgradeConfirm{} + +// NewMsgChannelUpgradeConfirm constructs a new MsgChannelUpgradeConfirm +func NewMsgChannelUpgradeConfirm( + portID, + channelID string, + counterpartyChannelState State, + counterpartyUpgrade Upgrade, + proofChannel, + proofUpgrade []byte, + proofHeight clienttypes.Height, + signer string, +) *MsgChannelUpgradeConfirm { + return &MsgChannelUpgradeConfirm{ + PortId: portID, + ChannelId: channelID, + CounterpartyChannelState: counterpartyChannelState, + CounterpartyUpgrade: counterpartyUpgrade, + ProofChannel: proofChannel, + ProofUpgrade: proofUpgrade, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelUpgradeConfirm) ValidateBasic() error { + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return errorsmod.Wrap(err, "invalid port ID") + } + + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + + if !slices.Contains([]State{FLUSHING, FLUSHCOMPLETE}, msg.CounterpartyChannelState) { + return errorsmod.Wrapf(ErrInvalidChannelState, "expected channel state to be one of: %s or %s, got: %s", FLUSHING, FLUSHCOMPLETE, msg.CounterpartyChannelState) + } + + if len(msg.ProofChannel) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") + } + + if len(msg.ProofUpgrade) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty upgrade proof") + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + return msg.CounterpartyUpgrade.ValidateBasic() +} + +var _ sdk.Msg = &MsgChannelUpgradeOpen{} + +// NewMsgChannelUpgradeOpen constructs a new MsgChannelUpgradeOpen +// nolint:interfacer +func NewMsgChannelUpgradeOpen( + portID, + channelID string, + counterpartyChannelState State, + proofChannel []byte, + proofHeight clienttypes.Height, + signer string, +) *MsgChannelUpgradeOpen { + return &MsgChannelUpgradeOpen{ + PortId: portID, + ChannelId: channelID, + CounterpartyChannelState: counterpartyChannelState, + ProofChannel: proofChannel, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelUpgradeOpen) ValidateBasic() error { + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return errorsmod.Wrap(err, "invalid port ID") + } + + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + + if len(msg.ProofChannel) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty channel proof") + } + + if !slices.Contains([]State{FLUSHCOMPLETE, OPEN}, msg.CounterpartyChannelState) { + return errorsmod.Wrapf(ErrInvalidChannelState, "expected channel state to be one of: [%s, %s], got: %s", FLUSHCOMPLETE, OPEN, msg.CounterpartyChannelState) + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + return nil +} + +var _ sdk.Msg = &MsgChannelUpgradeTimeout{} + +// NewMsgChannelUpgradeTimeout constructs a new MsgChannelUpgradeTimeout +// nolint:interfacer +func NewMsgChannelUpgradeTimeout( + portID, channelID string, + counterpartyChannel Channel, + proofChannel []byte, + proofHeight clienttypes.Height, + signer string, +) *MsgChannelUpgradeTimeout { + return &MsgChannelUpgradeTimeout{ + PortId: portID, + ChannelId: channelID, + CounterpartyChannel: counterpartyChannel, + ProofChannel: proofChannel, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelUpgradeTimeout) ValidateBasic() error { + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return errorsmod.Wrap(err, "invalid port ID") + } + + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + + if len(msg.ProofChannel) == 0 { + return errorsmod.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof") + } + + if !slices.Contains([]State{FLUSHING, OPEN}, msg.CounterpartyChannel.State) { + return errorsmod.Wrapf(ErrInvalidChannelState, "expected counterparty channel state to be one of: [%s, %s], got: %s", FLUSHING, OPEN, msg.CounterpartyChannel.State) + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + return nil +} + +var _ sdk.Msg = &MsgChannelUpgradeCancel{} + +// NewMsgChannelUpgradeCancel constructs a new MsgChannelUpgradeCancel +// nolint:interfacer +func NewMsgChannelUpgradeCancel( + portID, channelID string, + errorReceipt ErrorReceipt, + proofErrReceipt []byte, + proofHeight clienttypes.Height, + signer string, +) *MsgChannelUpgradeCancel { + return &MsgChannelUpgradeCancel{ + PortId: portID, + ChannelId: channelID, + ErrorReceipt: errorReceipt, + ProofErrorReceipt: proofErrReceipt, + ProofHeight: proofHeight, + Signer: signer, + } +} + +// ValidateBasic implements sdk.Msg +func (msg MsgChannelUpgradeCancel) ValidateBasic() error { + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return errorsmod.Wrap(err, "invalid port ID") + } + + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + return nil +} + +// NewMsgUpdateChannelParams creates a new instance of MsgUpdateParams. +func NewMsgUpdateChannelParams(authority string, params Params) *MsgUpdateParams { + return &MsgUpdateParams{ + Authority: authority, + Params: params, + } +} + +// ValidateBasic performs basic checks on a MsgUpdateParams. +func (msg *MsgUpdateParams) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + return msg.Params.Validate() +} + +// NewMsgPruneAcknowledgements creates a new instance of MsgPruneAcknowledgements. +func NewMsgPruneAcknowledgements(portID, channelID string, limit uint64, signer string) *MsgPruneAcknowledgements { + return &MsgPruneAcknowledgements{ + PortId: portID, + ChannelId: channelID, + Limit: limit, + Signer: signer, + } +} + +// ValidateBasic performs basic checks on a MsgPruneAcknowledgements. +func (msg *MsgPruneAcknowledgements) ValidateBasic() error { + if err := host.PortIdentifierValidator(msg.PortId); err != nil { + return errorsmod.Wrap(err, "invalid port ID") + } + + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + if msg.Limit == 0 { + return errorsmod.Wrap(ErrInvalidPruningLimit, "number of acknowledgements to prune must be greater than 0") + } + + return nil +} diff --git a/modules/core/04-channel/types/msgs_test.go b/modules/core/04-channel/types/msgs_test.go index 8570ad59065..f0dc4e46d99 100644 --- a/modules/core/04-channel/types/msgs_test.go +++ b/modules/core/04-channel/types/msgs_test.go @@ -14,19 +14,26 @@ import ( storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + ibc "github.com/cosmos/ibc-go/v8/modules/core" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + "github.com/cosmos/ibc-go/v8/testing/mock" "github.com/cosmos/ibc-go/v8/testing/simapp" ) const ( - // valid constatns used for testing - portid = "testportid" - chanid = "channel-0" - cpportid = "testcpport" - cpchanid = "testcpchannel" + // valid constants used for testing + portid = "testportid" + chanid = "channel-0" + cpportid = "testcpport" + cpchanid = "testcpchannel" + counterpartyUpgradeSequence = 0 version = "1.0" @@ -144,6 +151,18 @@ func (suite *TypesTestSuite) TestMsgChannelOpenInitValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgChannelOpenInitGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgChannelOpenInit(portid, version, types.ORDERED, connHops, cpportid, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + func (suite *TypesTestSuite) TestMsgChannelOpenTryValidateBasic() { counterparty := types.NewCounterparty(cpportid, cpchanid) initChannel := types.NewChannel(types.INIT, types.ORDERED, counterparty, connHops, version) @@ -186,6 +205,18 @@ func (suite *TypesTestSuite) TestMsgChannelOpenTryValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgChannelOpenTryGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgChannelOpenTry(portid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + func (suite *TypesTestSuite) TestMsgChannelOpenAckValidateBasic() { testCases := []struct { name string @@ -219,6 +250,18 @@ func (suite *TypesTestSuite) TestMsgChannelOpenAckValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgChannelOpenAckGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgChannelOpenAck(portid, chanid, chanid, version, suite.proof, height, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + func (suite *TypesTestSuite) TestMsgChannelOpenConfirmValidateBasic() { testCases := []struct { name string @@ -250,6 +293,18 @@ func (suite *TypesTestSuite) TestMsgChannelOpenConfirmValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgChannelOpenConfirmGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgChannelOpenConfirm(portid, chanid, suite.proof, height, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + func (suite *TypesTestSuite) TestMsgChannelCloseInitValidateBasic() { testCases := []struct { name string @@ -280,13 +335,26 @@ func (suite *TypesTestSuite) TestMsgChannelCloseInitValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgChannelCloseInitGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgChannelCloseInit(portid, chanid, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + func (suite *TypesTestSuite) TestMsgChannelCloseConfirmValidateBasic() { testCases := []struct { name string msg *types.MsgChannelCloseConfirm expPass bool }{ - {"", types.NewMsgChannelCloseConfirm(portid, chanid, suite.proof, height, addr), true}, + {"success", types.NewMsgChannelCloseConfirm(portid, chanid, suite.proof, height, addr), true}, + {"success, positive counterparty upgrade sequence", types.NewMsgChannelCloseConfirmWithCounterpartyUpgradeSequence(portid, chanid, suite.proof, height, addr, 1), true}, {"too short port id", types.NewMsgChannelCloseConfirm(invalidShortPort, chanid, suite.proof, height, addr), false}, {"too long port id", types.NewMsgChannelCloseConfirm(invalidLongPort, chanid, suite.proof, height, addr), false}, {"port id contains non-alpha", types.NewMsgChannelCloseConfirm(invalidPort, chanid, suite.proof, height, addr), false}, @@ -311,6 +379,18 @@ func (suite *TypesTestSuite) TestMsgChannelCloseConfirmValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgChannelCloseConfirmGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgChannelCloseConfirm(portid, chanid, suite.proof, height, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + func (suite *TypesTestSuite) TestMsgRecvPacketValidateBasic() { testCases := []struct { name string @@ -339,11 +419,15 @@ func (suite *TypesTestSuite) TestMsgRecvPacketValidateBasic() { } func (suite *TypesTestSuite) TestMsgRecvPacketGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) msg := types.NewMsgRecvPacket(packet, suite.proof, height, addr) - res := msg.GetSigners() - expected := "[7465737461646472313131313131313131313131]" - suite.Equal(expected, fmt.Sprintf("%v", res)) + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) } func (suite *TypesTestSuite) TestMsgTimeoutValidateBasic() { @@ -374,6 +458,18 @@ func (suite *TypesTestSuite) TestMsgTimeoutValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgTimeoutGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgTimeout(packet, 1, suite.proof, height, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + func (suite *TypesTestSuite) TestMsgTimeoutOnCloseValidateBasic() { testCases := []struct { name string @@ -381,6 +477,7 @@ func (suite *TypesTestSuite) TestMsgTimeoutOnCloseValidateBasic() { expPass bool }{ {"success", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, height, addr), true}, + {"success, positive counterparty upgrade sequence", types.NewMsgTimeoutOnCloseWithCounterpartyUpgradeSequence(packet, 1, suite.proof, suite.proof, height, addr, 1), true}, {"seq 0", types.NewMsgTimeoutOnClose(packet, 0, suite.proof, suite.proof, height, addr), false}, {"signer address is empty", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, height, emptyAddr), false}, {"empty proof", types.NewMsgTimeoutOnClose(packet, 1, emptyProof, suite.proof, height, addr), false}, @@ -403,6 +500,18 @@ func (suite *TypesTestSuite) TestMsgTimeoutOnCloseValidateBasic() { } } +func (suite *TypesTestSuite) TestMsgTimeoutOnCloseGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, height, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + func (suite *TypesTestSuite) TestMsgAcknowledgementValidateBasic() { testCases := []struct { name string @@ -430,3 +539,730 @@ func (suite *TypesTestSuite) TestMsgAcknowledgementValidateBasic() { }) } } + +func (suite *TypesTestSuite) TestMsgAcknowledgementGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgAcknowledgement(packet, packet.GetData(), suite.proof, height, addr) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeInitValidateBasic() { + var msg *types.MsgChannelUpgradeInit + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + false, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + false, + }, + { + "empty proposed upgrade channel version", + func() { + msg.Fields.Version = " " + }, + false, + }, + { + "missing signer address", + func() { + msg.Signer = emptyAddr + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + msg = types.NewMsgChannelUpgradeInit( + ibctesting.MockPort, ibctesting.FirstChannelID, + types.NewUpgradeFields(types.UNORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + addr, + ) + + tc.malleate() + err := msg.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeInitGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgChannelUpgradeInit( + ibctesting.MockPort, ibctesting.FirstChannelID, + types.NewUpgradeFields(types.UNORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + addr, + ) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeTryValidateBasic() { + var msg *types.MsgChannelUpgradeTry + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + false, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + false, + }, + { + "counterparty sequence cannot be zero", + func() { + msg.CounterpartyUpgradeSequence = 0 + }, + false, + }, + { + "invalid connection hops", + func() { + msg.ProposedUpgradeConnectionHops = []string{} + }, + false, + }, + { + "invalid counterparty upgrade fields ordering", + func() { + msg.CounterpartyUpgradeFields.Ordering = types.NONE + }, + false, + }, + { + "cannot submit an empty channel proof", + func() { + msg.ProofChannel = emptyProof + }, + false, + }, + { + "cannot submit an empty upgrade proof", + func() { + msg.ProofUpgrade = emptyProof + }, + false, + }, + { + "missing signer address", + func() { + msg.Signer = emptyAddr + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + msg = types.NewMsgChannelUpgradeTry( + ibctesting.MockPort, + ibctesting.FirstChannelID, + []string{ibctesting.FirstConnectionID}, + types.NewUpgradeFields(types.UNORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + 1, + suite.proof, + suite.proof, + height, + addr, + ) + + tc.malleate() + err := msg.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeTryGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgChannelUpgradeTry( + ibctesting.MockPort, + ibctesting.FirstChannelID, + []string{ibctesting.FirstConnectionID}, + types.NewUpgradeFields(types.UNORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + 1, + suite.proof, + suite.proof, + height, + addr, + ) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeAckValidateBasic() { + var msg *types.MsgChannelUpgradeAck + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + false, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + false, + }, + { + "cannot submit an empty channel proof", + func() { + msg.ProofChannel = emptyProof + }, + false, + }, + { + "cannot submit an empty upgrade proof", + func() { + msg.ProofUpgrade = emptyProof + }, + false, + }, + { + "missing signer address", + func() { + msg.Signer = emptyAddr + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + upgrade := types.NewUpgrade( + types.NewUpgradeFields(types.ORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + types.NewTimeout(clienttypes.NewHeight(1, 100), 0), + 0, + ) + + msg = types.NewMsgChannelUpgradeAck( + ibctesting.MockPort, ibctesting.FirstChannelID, + upgrade, suite.proof, suite.proof, + height, addr, + ) + + tc.malleate() + err := msg.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeAckGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + upgrade := types.NewUpgrade( + types.NewUpgradeFields(types.ORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + types.NewTimeout(clienttypes.NewHeight(1, 100), 0), + 0, + ) + + msg := types.NewMsgChannelUpgradeAck( + ibctesting.MockPort, ibctesting.FirstChannelID, + upgrade, suite.proof, suite.proof, + height, addr, + ) + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeConfirmValidateBasic() { + var msg *types.MsgChannelUpgradeConfirm + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "success: counterparty state set to FLUSHCOMPLETE", + func() { + msg.CounterpartyChannelState = types.FLUSHCOMPLETE + }, + true, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + false, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + false, + }, + { + "invalid counterparty channel state", + func() { + msg.CounterpartyChannelState = types.CLOSED + }, + false, + }, + { + "cannot submit an empty channel proof", + func() { + msg.ProofChannel = emptyProof + }, + false, + }, + { + "cannot submit an empty upgrade proof", + func() { + msg.ProofUpgrade = emptyProof + }, + false, + }, + { + "missing signer address", + func() { + msg.Signer = emptyAddr + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + counterpartyUpgrade := types.NewUpgrade( + types.NewUpgradeFields(types.UNORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + types.NewTimeout(clienttypes.NewHeight(0, 10000), timeoutTimestamp), + 0, + ) + + msg = types.NewMsgChannelUpgradeConfirm( + ibctesting.MockPort, ibctesting.FirstChannelID, + types.FLUSHING, counterpartyUpgrade, suite.proof, suite.proof, + height, addr, + ) + + tc.malleate() + err := msg.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeConfirmGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + + msg := &types.MsgChannelUpgradeConfirm{Signer: addr} + + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeOpenValidateBasic() { + var msg *types.MsgChannelUpgradeOpen + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success: flushcomplete state", + func() {}, + true, + }, + { + "success: open state", + func() { + msg.CounterpartyChannelState = types.OPEN + }, + true, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + false, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + false, + }, + { + "invalid counterparty channel state", + func() { + msg.CounterpartyChannelState = types.CLOSED + }, + false, + }, + { + "cannot submit an empty channel proof", + func() { + msg.ProofChannel = emptyProof + }, + false, + }, + { + "missing signer address", + func() { + msg.Signer = emptyAddr + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + msg = types.NewMsgChannelUpgradeOpen( + ibctesting.MockPort, ibctesting.FirstChannelID, + types.FLUSHCOMPLETE, suite.proof, + height, addr, + ) + + tc.malleate() + err := msg.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeTimeoutValidateBasic() { + var msg *types.MsgChannelUpgradeTimeout + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + false, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + false, + }, + { + "cannot submit an empty proof", + func() { + msg.ProofChannel = emptyProof + }, + false, + }, + { + "invalid counterparty channel state", + func() { + msg.CounterpartyChannel.State = types.CLOSED + }, + false, + }, + { + "missing signer address", + func() { + msg.Signer = emptyAddr + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + msg = types.NewMsgChannelUpgradeTimeout( + ibctesting.MockPort, ibctesting.FirstChannelID, + types.Channel{State: types.OPEN}, + suite.proof, + height, addr, + ) + + tc.malleate() + err := msg.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeTimeoutGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + + msg := types.NewMsgChannelUpgradeTimeout( + ibctesting.MockPort, ibctesting.FirstChannelID, + types.Channel{}, + suite.proof, + height, addr, + ) + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeCancelValidateBasic() { + var msg *types.MsgChannelUpgradeCancel + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + false, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + false, + }, + { + "can submit an empty proof", + func() { + msg.ProofErrorReceipt = emptyProof + }, + true, + }, + { + "missing signer address", + func() { + msg.Signer = emptyAddr + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + msg = types.NewMsgChannelUpgradeCancel(ibctesting.MockPort, ibctesting.FirstChannelID, types.ErrorReceipt{Sequence: 1}, suite.proof, height, addr) + + tc.malleate() + err := msg.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TypesTestSuite) TestMsgChannelUpgradeCancelGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + + msg := types.NewMsgChannelUpgradeCancel(ibctesting.MockPort, ibctesting.FirstChannelID, types.ErrorReceipt{Sequence: 1}, suite.proof, height, addr) + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} + +func (suite *TypesTestSuite) TestMsgPruneAcknowledgementsValidateBasic() { + var msg *types.MsgPruneAcknowledgements + + testCases := []struct { + name string + malleate func() + expErr error + }{ + { + "success", + func() {}, + nil, + }, + { + "failure: zero pruning limit", + func() { + msg.Limit = 0 + }, + types.ErrInvalidPruningLimit, + }, + { + "invalid port identifier", + func() { + msg.PortId = invalidPort + }, + host.ErrInvalidID, + }, + { + "invalid channel identifier", + func() { + msg.ChannelId = invalidChannel + }, + types.ErrInvalidChannelIdentifier, + }, + { + "empty signer address", + func() { + msg.Signer = emptyAddr + }, + ibcerrors.ErrInvalidAddress, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + msg = types.NewMsgPruneAcknowledgements(ibctesting.MockPort, ibctesting.FirstChannelID, 1, addr) + + tc.malleate() + err := msg.ValidateBasic() + + expPass := tc.expErr == nil + if expPass { + suite.Require().NoError(err) + } else { + suite.Require().ErrorIs(err, tc.expErr) + } + }) + } +} + +func (suite *TypesTestSuite) TestMsgPruneAcknowledgementsGetSigners() { + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + + msg := types.NewMsgPruneAcknowledgements(ibctesting.MockPort, ibctesting.FirstChannelID, 0, addr) + encodingCfg := moduletestutil.MakeTestEncodingConfig(ibc.AppModuleBasic{}) + signers, _, err := encodingCfg.Codec.GetMsgV1Signers(msg) + + suite.Require().NoError(err) + suite.Require().Equal(expSigner.Bytes(), signers[0]) +} diff --git a/modules/core/04-channel/types/params.go b/modules/core/04-channel/types/params.go new file mode 100644 index 00000000000..cf44ae307c0 --- /dev/null +++ b/modules/core/04-channel/types/params.go @@ -0,0 +1,36 @@ +package types + +import ( + "fmt" + "time" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" +) + +// DefaultTimeout defines a default parameter for the channel upgrade protocol. +// It allows relayers a window in which they can flush all in-flight packets on a channel before completing the upgrade handshake. +// This parameter can be overridden by a valid authority using the UpdateChannelParams rpc. +var DefaultTimeout = NewTimeout(clienttypes.ZeroHeight(), uint64(10*time.Minute.Nanoseconds())) + +// NewParams creates a new parameter configuration for the channel submodule +func NewParams(upgradeTimeout Timeout) Params { + return Params{ + UpgradeTimeout: upgradeTimeout, + } +} + +// DefaultParams is the default parameter configuration for the channel submodule +func DefaultParams() Params { + return NewParams(DefaultTimeout) +} + +// Validate the params. +func (p Params) Validate() error { + if !p.UpgradeTimeout.Height.IsZero() { + return fmt.Errorf("upgrade timeout height must be zero. got : %v", p.UpgradeTimeout.Height) + } + if p.UpgradeTimeout.Timestamp == 0 { + return fmt.Errorf("upgrade timeout timestamp invalid: %v", p.UpgradeTimeout.Timestamp) + } + return nil +} diff --git a/modules/core/04-channel/types/query.go b/modules/core/04-channel/types/query.go index 81b0cb58307..baa307d827f 100644 --- a/modules/core/04-channel/types/query.go +++ b/modules/core/04-channel/types/query.go @@ -104,3 +104,21 @@ func NewQueryNextSequenceSendResponse( ProofHeight: height, } } + +// NewQueryUpgradeErrorResponse creates a new QueryUpgradeErrorResponse instance +func NewQueryUpgradeErrorResponse(errorReceipt ErrorReceipt, proof []byte, height clienttypes.Height) *QueryUpgradeErrorResponse { + return &QueryUpgradeErrorResponse{ + ErrorReceipt: errorReceipt, + Proof: proof, + ProofHeight: height, + } +} + +// NewQueryUpgradeResponse creates a new QueryUpgradeResponse instance +func NewQueryUpgradeResponse(upgrade Upgrade, proof []byte, height clienttypes.Height) *QueryUpgradeResponse { + return &QueryUpgradeResponse{ + Upgrade: upgrade, + Proof: proof, + ProofHeight: height, + } +} diff --git a/modules/core/04-channel/types/query.pb.go b/modules/core/04-channel/types/query.pb.go index 8ca3338c254..9d3c481b71b 100644 --- a/modules/core/04-channel/types/query.pb.go +++ b/modules/core/04-channel/types/query.pb.go @@ -1611,7 +1611,7 @@ func (m *QueryNextSequenceReceiveRequest) GetChannelId() string { return "" } -// QuerySequenceResponse is the request type for the +// QuerySequenceResponse is the response type for the // Query/QueryNextSequenceReceiveResponse RPC method type QueryNextSequenceReceiveResponse struct { // next sequence receive number @@ -1797,6 +1797,321 @@ func (m *QueryNextSequenceSendResponse) GetProofHeight() types.Height { return types.Height{} } +// QueryUpgradeErrorRequest is the request type for the Query/QueryUpgradeError RPC method +type QueryUpgradeErrorRequest struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` +} + +func (m *QueryUpgradeErrorRequest) Reset() { *m = QueryUpgradeErrorRequest{} } +func (m *QueryUpgradeErrorRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradeErrorRequest) ProtoMessage() {} +func (*QueryUpgradeErrorRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_1034a1e9abc4cca1, []int{28} +} +func (m *QueryUpgradeErrorRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradeErrorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradeErrorRequest.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 *QueryUpgradeErrorRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradeErrorRequest.Merge(m, src) +} +func (m *QueryUpgradeErrorRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradeErrorRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradeErrorRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradeErrorRequest proto.InternalMessageInfo + +func (m *QueryUpgradeErrorRequest) GetPortId() string { + if m != nil { + return m.PortId + } + return "" +} + +func (m *QueryUpgradeErrorRequest) GetChannelId() string { + if m != nil { + return m.ChannelId + } + return "" +} + +// QueryUpgradeErrorResponse is the response type for the Query/QueryUpgradeError RPC method +type QueryUpgradeErrorResponse struct { + ErrorReceipt ErrorReceipt `protobuf:"bytes,1,opt,name=error_receipt,json=errorReceipt,proto3" json:"error_receipt"` + // merkle proof of existence + Proof []byte `protobuf:"bytes,2,opt,name=proof,proto3" json:"proof,omitempty"` + // height at which the proof was retrieved + ProofHeight types.Height `protobuf:"bytes,3,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` +} + +func (m *QueryUpgradeErrorResponse) Reset() { *m = QueryUpgradeErrorResponse{} } +func (m *QueryUpgradeErrorResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradeErrorResponse) ProtoMessage() {} +func (*QueryUpgradeErrorResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1034a1e9abc4cca1, []int{29} +} +func (m *QueryUpgradeErrorResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradeErrorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradeErrorResponse.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 *QueryUpgradeErrorResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradeErrorResponse.Merge(m, src) +} +func (m *QueryUpgradeErrorResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradeErrorResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradeErrorResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradeErrorResponse proto.InternalMessageInfo + +func (m *QueryUpgradeErrorResponse) GetErrorReceipt() ErrorReceipt { + if m != nil { + return m.ErrorReceipt + } + return ErrorReceipt{} +} + +func (m *QueryUpgradeErrorResponse) GetProof() []byte { + if m != nil { + return m.Proof + } + return nil +} + +func (m *QueryUpgradeErrorResponse) GetProofHeight() types.Height { + if m != nil { + return m.ProofHeight + } + return types.Height{} +} + +// QueryUpgradeRequest is the request type for the QueryUpgradeRequest RPC method +type QueryUpgradeRequest struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` +} + +func (m *QueryUpgradeRequest) Reset() { *m = QueryUpgradeRequest{} } +func (m *QueryUpgradeRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradeRequest) ProtoMessage() {} +func (*QueryUpgradeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_1034a1e9abc4cca1, []int{30} +} +func (m *QueryUpgradeRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradeRequest.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 *QueryUpgradeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradeRequest.Merge(m, src) +} +func (m *QueryUpgradeRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradeRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradeRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradeRequest proto.InternalMessageInfo + +func (m *QueryUpgradeRequest) GetPortId() string { + if m != nil { + return m.PortId + } + return "" +} + +func (m *QueryUpgradeRequest) GetChannelId() string { + if m != nil { + return m.ChannelId + } + return "" +} + +// QueryUpgradeResponse is the response type for the QueryUpgradeResponse RPC method +type QueryUpgradeResponse struct { + Upgrade Upgrade `protobuf:"bytes,1,opt,name=upgrade,proto3" json:"upgrade"` + // merkle proof of existence + Proof []byte `protobuf:"bytes,2,opt,name=proof,proto3" json:"proof,omitempty"` + // height at which the proof was retrieved + ProofHeight types.Height `protobuf:"bytes,3,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` +} + +func (m *QueryUpgradeResponse) Reset() { *m = QueryUpgradeResponse{} } +func (m *QueryUpgradeResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradeResponse) ProtoMessage() {} +func (*QueryUpgradeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1034a1e9abc4cca1, []int{31} +} +func (m *QueryUpgradeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradeResponse.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 *QueryUpgradeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradeResponse.Merge(m, src) +} +func (m *QueryUpgradeResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradeResponse proto.InternalMessageInfo + +func (m *QueryUpgradeResponse) GetUpgrade() Upgrade { + if m != nil { + return m.Upgrade + } + return Upgrade{} +} + +func (m *QueryUpgradeResponse) GetProof() []byte { + if m != nil { + return m.Proof + } + return nil +} + +func (m *QueryUpgradeResponse) GetProofHeight() types.Height { + if m != nil { + return m.ProofHeight + } + return types.Height{} +} + +// QueryChannelParamsRequest is the request type for the Query/ChannelParams RPC method. +type QueryChannelParamsRequest struct { +} + +func (m *QueryChannelParamsRequest) Reset() { *m = QueryChannelParamsRequest{} } +func (m *QueryChannelParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryChannelParamsRequest) ProtoMessage() {} +func (*QueryChannelParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_1034a1e9abc4cca1, []int{32} +} +func (m *QueryChannelParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryChannelParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryChannelParamsRequest.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 *QueryChannelParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryChannelParamsRequest.Merge(m, src) +} +func (m *QueryChannelParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryChannelParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryChannelParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryChannelParamsRequest proto.InternalMessageInfo + +// QueryChannelParamsResponse is the response type for the Query/ChannelParams RPC method. +type QueryChannelParamsResponse struct { + // params defines the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (m *QueryChannelParamsResponse) Reset() { *m = QueryChannelParamsResponse{} } +func (m *QueryChannelParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryChannelParamsResponse) ProtoMessage() {} +func (*QueryChannelParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1034a1e9abc4cca1, []int{33} +} +func (m *QueryChannelParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryChannelParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryChannelParamsResponse.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 *QueryChannelParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryChannelParamsResponse.Merge(m, src) +} +func (m *QueryChannelParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryChannelParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryChannelParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryChannelParamsResponse proto.InternalMessageInfo + +func (m *QueryChannelParamsResponse) GetParams() *Params { + if m != nil { + return m.Params + } + return nil +} + func init() { proto.RegisterType((*QueryChannelRequest)(nil), "ibc.core.channel.v1.QueryChannelRequest") proto.RegisterType((*QueryChannelResponse)(nil), "ibc.core.channel.v1.QueryChannelResponse") @@ -1826,109 +2141,128 @@ func init() { proto.RegisterType((*QueryNextSequenceReceiveResponse)(nil), "ibc.core.channel.v1.QueryNextSequenceReceiveResponse") proto.RegisterType((*QueryNextSequenceSendRequest)(nil), "ibc.core.channel.v1.QueryNextSequenceSendRequest") proto.RegisterType((*QueryNextSequenceSendResponse)(nil), "ibc.core.channel.v1.QueryNextSequenceSendResponse") + proto.RegisterType((*QueryUpgradeErrorRequest)(nil), "ibc.core.channel.v1.QueryUpgradeErrorRequest") + proto.RegisterType((*QueryUpgradeErrorResponse)(nil), "ibc.core.channel.v1.QueryUpgradeErrorResponse") + proto.RegisterType((*QueryUpgradeRequest)(nil), "ibc.core.channel.v1.QueryUpgradeRequest") + proto.RegisterType((*QueryUpgradeResponse)(nil), "ibc.core.channel.v1.QueryUpgradeResponse") + proto.RegisterType((*QueryChannelParamsRequest)(nil), "ibc.core.channel.v1.QueryChannelParamsRequest") + proto.RegisterType((*QueryChannelParamsResponse)(nil), "ibc.core.channel.v1.QueryChannelParamsResponse") } func init() { proto.RegisterFile("ibc/core/channel/v1/query.proto", fileDescriptor_1034a1e9abc4cca1) } var fileDescriptor_1034a1e9abc4cca1 = []byte{ - // 1547 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xcf, 0x6f, 0x13, 0x47, - 0x14, 0xce, 0x38, 0x06, 0x92, 0x07, 0x85, 0x30, 0x49, 0x4a, 0x58, 0x82, 0x13, 0x5c, 0xb5, 0x04, - 0x54, 0x76, 0x48, 0xa0, 0x34, 0xad, 0x5a, 0x24, 0x12, 0xa9, 0x90, 0xaa, 0xfc, 0xda, 0x94, 0x16, - 0x90, 0x5a, 0x77, 0xbd, 0x1e, 0x9c, 0x55, 0xe2, 0x5d, 0xe3, 0x5d, 0x1b, 0x50, 0xea, 0xaa, 0xea, - 0x81, 0x72, 0xac, 0xca, 0xa1, 0x52, 0x2f, 0x95, 0x7a, 0x2a, 0x87, 0x1e, 0xfa, 0x17, 0xf4, 0xca, - 0xad, 0x48, 0xf4, 0x50, 0x09, 0x89, 0x56, 0x04, 0x89, 0x5e, 0x7b, 0xe9, 0xb9, 0xda, 0xf9, 0xb1, - 0xde, 0xb5, 0x77, 0x37, 0x76, 0x1c, 0x4b, 0x51, 0x6f, 0xde, 0x99, 0x79, 0x6f, 0xbe, 0xef, 0x7b, - 0xf3, 0xde, 0xce, 0x5b, 0xc3, 0x84, 0x99, 0x37, 0x88, 0x61, 0x57, 0x28, 0x31, 0x96, 0x74, 0xcb, - 0xa2, 0x2b, 0xa4, 0x36, 0x4d, 0x6e, 0x56, 0x69, 0xe5, 0x8e, 0x5a, 0xae, 0xd8, 0xae, 0x8d, 0x87, - 0xcd, 0xbc, 0xa1, 0x7a, 0x0b, 0x54, 0xb1, 0x40, 0xad, 0x4d, 0x2b, 0x01, 0xab, 0x15, 0x93, 0x5a, - 0xae, 0x67, 0xc4, 0x7f, 0x71, 0x2b, 0xe5, 0xa8, 0x61, 0x3b, 0x25, 0xdb, 0x21, 0x79, 0xdd, 0xa1, - 0xdc, 0x1d, 0xa9, 0x4d, 0xe7, 0xa9, 0xab, 0x4f, 0x93, 0xb2, 0x5e, 0x34, 0x2d, 0xdd, 0x35, 0x6d, - 0x4b, 0xac, 0x3d, 0x14, 0x05, 0x41, 0x6e, 0xc6, 0x97, 0x8c, 0x17, 0x6d, 0xbb, 0xb8, 0x42, 0x89, - 0x5e, 0x36, 0x89, 0x6e, 0x59, 0xb6, 0xcb, 0xec, 0x1d, 0x31, 0xbb, 0x5f, 0xcc, 0xb2, 0xa7, 0x7c, - 0xf5, 0x06, 0xd1, 0x2d, 0x81, 0x5e, 0x19, 0x29, 0xda, 0x45, 0x9b, 0xfd, 0x24, 0xde, 0x2f, 0x3e, - 0x9a, 0x3d, 0x0f, 0xc3, 0x97, 0x3d, 0x4c, 0xf3, 0x7c, 0x13, 0x8d, 0xde, 0xac, 0x52, 0xc7, 0xc5, - 0xfb, 0x60, 0x47, 0xd9, 0xae, 0xb8, 0x39, 0xb3, 0x30, 0x86, 0x26, 0xd1, 0xd4, 0xa0, 0xb6, 0xdd, - 0x7b, 0x5c, 0x28, 0xe0, 0x83, 0x00, 0x02, 0x8f, 0x37, 0x97, 0x62, 0x73, 0x83, 0x62, 0x64, 0xa1, - 0x90, 0x7d, 0x80, 0x60, 0x24, 0xec, 0xcf, 0x29, 0xdb, 0x96, 0x43, 0xf1, 0x29, 0xd8, 0x21, 0x56, - 0x31, 0x87, 0x3b, 0x67, 0xc6, 0xd5, 0x08, 0x35, 0x55, 0x69, 0x26, 0x17, 0xe3, 0x11, 0xd8, 0x56, - 0xae, 0xd8, 0xf6, 0x0d, 0xb6, 0xd5, 0x2e, 0x8d, 0x3f, 0xe0, 0x79, 0xd8, 0xc5, 0x7e, 0xe4, 0x96, - 0xa8, 0x59, 0x5c, 0x72, 0xc7, 0xfa, 0x99, 0x4b, 0x25, 0xe0, 0x92, 0x47, 0xa0, 0x36, 0xad, 0x9e, - 0x63, 0x2b, 0xe6, 0xd2, 0x0f, 0x9f, 0x4e, 0xf4, 0x69, 0x3b, 0x99, 0x15, 0x1f, 0xca, 0x7e, 0x1a, - 0x86, 0xea, 0x48, 0xee, 0xef, 0x01, 0x34, 0x02, 0x23, 0xd0, 0xbe, 0xa6, 0xf2, 0x28, 0xaa, 0x5e, - 0x14, 0x55, 0x7e, 0x28, 0x44, 0x14, 0xd5, 0x4b, 0x7a, 0x91, 0x0a, 0x5b, 0x2d, 0x60, 0x99, 0x7d, - 0x8a, 0x60, 0xb4, 0x69, 0x03, 0x21, 0xc6, 0x1c, 0x0c, 0x08, 0x7e, 0xce, 0x18, 0x9a, 0xec, 0x67, - 0xfe, 0xa3, 0xd4, 0x58, 0x28, 0x50, 0xcb, 0x35, 0x6f, 0x98, 0xb4, 0x20, 0x75, 0xf1, 0xed, 0xf0, - 0xd9, 0x10, 0xca, 0x14, 0x43, 0x79, 0x78, 0x5d, 0x94, 0x1c, 0x40, 0x10, 0x26, 0x9e, 0x85, 0xed, - 0x1d, 0xaa, 0x28, 0xd6, 0x67, 0xef, 0x21, 0xc8, 0x70, 0x82, 0xb6, 0x65, 0x51, 0xc3, 0xf3, 0xd6, - 0xac, 0x65, 0x06, 0xc0, 0xf0, 0x27, 0xc5, 0x51, 0x0a, 0x8c, 0x34, 0x69, 0x9d, 0xda, 0xb0, 0xd6, - 0x7f, 0x23, 0x98, 0x88, 0x85, 0xf2, 0xff, 0x52, 0xfd, 0xaa, 0x14, 0x9d, 0x63, 0x9a, 0x67, 0xab, - 0x17, 0x5d, 0xdd, 0xa5, 0xdd, 0x26, 0xef, 0x9f, 0xbe, 0x88, 0x11, 0xae, 0x85, 0x88, 0x3a, 0xec, - 0x33, 0x7d, 0x7d, 0x72, 0x1c, 0x6a, 0xce, 0xf1, 0x96, 0x88, 0x4c, 0x39, 0x12, 0x45, 0x24, 0x20, - 0x69, 0xc0, 0xe7, 0xa8, 0x19, 0x35, 0xdc, 0xcb, 0x94, 0xff, 0x19, 0xc1, 0xa1, 0x10, 0x43, 0x8f, - 0x93, 0xe5, 0x54, 0x9d, 0xcd, 0xd0, 0x0f, 0x1f, 0x86, 0x3d, 0x15, 0x5a, 0x33, 0x1d, 0xd3, 0xb6, - 0x72, 0x56, 0xb5, 0x94, 0xa7, 0x15, 0x86, 0x32, 0xad, 0xed, 0x96, 0xc3, 0x17, 0xd8, 0x68, 0x68, - 0xa1, 0xa0, 0x93, 0x0e, 0x2f, 0x14, 0x78, 0x9f, 0x20, 0xc8, 0x26, 0xe1, 0x15, 0x41, 0x79, 0x17, - 0xf6, 0x18, 0x72, 0x26, 0x14, 0x8c, 0x11, 0x95, 0xbf, 0x0f, 0x54, 0xf9, 0x3e, 0x50, 0xcf, 0x58, - 0x77, 0xb4, 0xdd, 0x46, 0xc8, 0x0d, 0x3e, 0x00, 0x83, 0x22, 0x90, 0x3e, 0xab, 0x01, 0x3e, 0xb0, - 0x50, 0x68, 0x44, 0xa3, 0x3f, 0x29, 0x1a, 0xe9, 0x8d, 0x44, 0xa3, 0x02, 0xe3, 0x8c, 0xdc, 0x25, - 0xdd, 0x58, 0xa6, 0xee, 0xbc, 0x5d, 0x2a, 0x99, 0x6e, 0x89, 0x5a, 0x6e, 0xb7, 0x71, 0x50, 0x60, - 0xc0, 0xf1, 0x5c, 0x58, 0x06, 0x15, 0x01, 0xf0, 0x9f, 0xb3, 0xdf, 0x23, 0x38, 0x18, 0xb3, 0xa9, - 0x10, 0x93, 0x95, 0x2c, 0x39, 0xca, 0x36, 0xde, 0xa5, 0x05, 0x46, 0x7a, 0x79, 0x3c, 0x7f, 0x88, - 0x03, 0xe7, 0x74, 0x2b, 0x49, 0xb8, 0xce, 0xf6, 0x6f, 0xb8, 0xce, 0xbe, 0x90, 0x25, 0x3f, 0x02, - 0xa1, 0x5f, 0x66, 0x77, 0x36, 0xd4, 0x92, 0x95, 0x76, 0x32, 0xb2, 0xd2, 0x72, 0x27, 0xfc, 0x2c, - 0x07, 0x8d, 0xb6, 0x42, 0x99, 0xb5, 0x61, 0x7f, 0x80, 0xa8, 0x46, 0x0d, 0x6a, 0x96, 0x7b, 0x7a, - 0x32, 0xef, 0x23, 0x50, 0xa2, 0x76, 0x14, 0xb2, 0x2a, 0x30, 0x50, 0xf1, 0x86, 0x6a, 0x94, 0xfb, - 0x1d, 0xd0, 0xfc, 0xe7, 0x5e, 0xe6, 0xe8, 0x2d, 0x51, 0x30, 0x39, 0xa8, 0x33, 0xc6, 0xb2, 0x65, - 0xdf, 0x5a, 0xa1, 0x85, 0x22, 0xed, 0x75, 0xa2, 0x3e, 0x90, 0xa5, 0x2f, 0x66, 0x67, 0x21, 0xcb, - 0x14, 0xec, 0xd1, 0xc3, 0x53, 0x22, 0x65, 0x9b, 0x87, 0x7b, 0x99, 0xb7, 0xcf, 0x13, 0xb1, 0x6e, - 0x95, 0xe4, 0xc5, 0xa7, 0xe1, 0x40, 0x99, 0x01, 0xcc, 0x35, 0x72, 0x2d, 0x27, 0x05, 0x77, 0xc6, - 0xd2, 0x93, 0xfd, 0x53, 0x69, 0x6d, 0x7f, 0xb9, 0x29, 0xb3, 0x17, 0xe5, 0x82, 0xec, 0xbf, 0x08, - 0x5e, 0x49, 0xa4, 0x29, 0x62, 0xf2, 0x01, 0x0c, 0x35, 0x89, 0xdf, 0x7e, 0x19, 0x68, 0xb1, 0xdc, - 0x0a, 0xb5, 0xe0, 0x3b, 0x59, 0x97, 0xaf, 0x58, 0x32, 0xe7, 0x38, 0xe6, 0xae, 0x43, 0xbb, 0x4e, - 0x48, 0xfa, 0xd7, 0x0b, 0xc9, 0x6d, 0x51, 0x8e, 0x23, 0x80, 0x89, 0x60, 0x8c, 0xc3, 0x60, 0xc3, - 0x1f, 0x62, 0xfe, 0x1a, 0x03, 0x01, 0x4d, 0x52, 0x1d, 0x6a, 0x72, 0x57, 0x96, 0xab, 0xc6, 0xd6, - 0x67, 0x8c, 0xe5, 0xae, 0x05, 0x39, 0x0e, 0x23, 0x42, 0x10, 0xdd, 0x58, 0x6e, 0x51, 0x02, 0x97, - 0xe5, 0xc9, 0x6b, 0x48, 0x50, 0x85, 0x03, 0x91, 0x38, 0x7a, 0xcc, 0xff, 0x9a, 0xb8, 0x2b, 0x5f, - 0xa0, 0xb7, 0xfd, 0x78, 0x68, 0x1c, 0x40, 0xb7, 0xf7, 0xf0, 0x5f, 0x10, 0x4c, 0xc6, 0xfb, 0x16, - 0xbc, 0x66, 0x60, 0xd4, 0xa2, 0xb7, 0x1b, 0x87, 0x25, 0x27, 0xd8, 0xb3, 0xad, 0xd2, 0xda, 0xb0, - 0xd5, 0x6a, 0xdb, 0xcb, 0x12, 0xf8, 0x91, 0xb8, 0xcb, 0x05, 0x21, 0x2f, 0x52, 0xab, 0xd0, 0xad, - 0x16, 0x3f, 0xc9, 0xd4, 0x6b, 0x75, 0x2c, 0x84, 0x78, 0x1d, 0x70, 0x58, 0x08, 0x87, 0x5a, 0x05, - 0xa1, 0xc2, 0x90, 0xd5, 0x64, 0xd5, 0x43, 0x09, 0x66, 0x9e, 0xee, 0x83, 0x6d, 0x0c, 0x2a, 0xfe, - 0x11, 0xc1, 0x0e, 0x71, 0x63, 0xc7, 0x53, 0x91, 0x25, 0x2f, 0xe2, 0x9b, 0x8b, 0x72, 0xa4, 0x8d, - 0x95, 0x9c, 0x73, 0x76, 0xee, 0xab, 0xc7, 0xcf, 0xef, 0xa7, 0xde, 0xc1, 0x6f, 0x93, 0x84, 0x0f, - 0x46, 0x0e, 0x59, 0x6d, 0x28, 0x5b, 0x27, 0x9e, 0xde, 0x0e, 0x59, 0x15, 0x51, 0xa8, 0xe3, 0x7b, - 0x08, 0x06, 0x64, 0x8f, 0x8c, 0xd7, 0xdf, 0x5b, 0x66, 0xb6, 0x72, 0xb4, 0x9d, 0xa5, 0x02, 0xe7, - 0xab, 0x0c, 0xe7, 0x04, 0x3e, 0x98, 0x88, 0x13, 0xff, 0x8a, 0x00, 0xb7, 0x36, 0xee, 0xf8, 0x44, - 0xc2, 0x4e, 0x71, 0x5f, 0x1c, 0x94, 0x93, 0x9d, 0x19, 0x09, 0xa0, 0xa7, 0x19, 0xd0, 0x59, 0x7c, - 0x2a, 0x1a, 0xa8, 0x6f, 0xe8, 0x69, 0xea, 0x3f, 0xd4, 0x1b, 0x0c, 0x1e, 0x79, 0x0c, 0x5a, 0xba, - 0xe6, 0x44, 0x06, 0x71, 0xed, 0x7b, 0x22, 0x83, 0xd8, 0xc6, 0x3c, 0x7b, 0x91, 0x31, 0x58, 0xc0, - 0x67, 0x37, 0x7e, 0x24, 0x48, 0xb0, 0x9d, 0xc7, 0xdf, 0xa6, 0x60, 0x34, 0xb2, 0xed, 0xc4, 0xa7, - 0xd6, 0x07, 0x18, 0xd5, 0x57, 0x2b, 0x6f, 0x76, 0x6c, 0x27, 0xb8, 0x7d, 0x8d, 0x18, 0xb9, 0x2f, - 0x11, 0xfe, 0xa2, 0x1b, 0x76, 0xe1, 0x16, 0x99, 0xc8, 0x5e, 0x9b, 0xac, 0x36, 0x75, 0xed, 0x75, - 0xc2, 0xcb, 0x40, 0x60, 0x82, 0x0f, 0xd4, 0xf1, 0x13, 0x04, 0x43, 0xcd, 0xad, 0x0f, 0x9e, 0x8e, - 0xe7, 0x15, 0xd3, 0xda, 0x2a, 0x33, 0x9d, 0x98, 0x08, 0x15, 0x3e, 0x63, 0x22, 0x5c, 0xc7, 0x57, - 0xbb, 0xd0, 0xa0, 0xe5, 0xb2, 0xe1, 0x90, 0x55, 0x59, 0x38, 0xeb, 0xf8, 0x31, 0x82, 0xbd, 0x2d, - 0x8d, 0x1d, 0xee, 0x00, 0xab, 0x9f, 0x85, 0x27, 0x3a, 0xb2, 0x11, 0x04, 0xaf, 0x30, 0x82, 0x17, - 0xf1, 0xf9, 0x4d, 0x25, 0x88, 0x7f, 0x43, 0xf0, 0x52, 0xa8, 0xa7, 0xc2, 0xea, 0x7a, 0xe8, 0xc2, - 0xed, 0x9e, 0x42, 0xda, 0x5e, 0x2f, 0x98, 0x7c, 0xc2, 0x98, 0x7c, 0x8c, 0xaf, 0x74, 0xcf, 0xa4, - 0xc2, 0x5d, 0x87, 0xe2, 0xb4, 0x86, 0x60, 0x34, 0xf2, 0x0e, 0x9e, 0x94, 0x9a, 0x49, 0x1d, 0x5c, - 0x52, 0x6a, 0x26, 0xf6, 0x5f, 0xd9, 0x6b, 0x8c, 0xe9, 0x22, 0xbe, 0xdc, 0x3d, 0x53, 0xdd, 0x58, - 0x0e, 0xb1, 0x7c, 0x81, 0xe0, 0xe5, 0xe8, 0x4e, 0x03, 0x77, 0x0a, 0xd7, 0x3f, 0x97, 0xb3, 0x9d, - 0x1b, 0x0a, 0xa2, 0xd7, 0x19, 0xd1, 0x0f, 0xb1, 0xb6, 0x29, 0x44, 0xc3, 0x74, 0xee, 0xa6, 0x60, - 0x6f, 0xcb, 0x0d, 0x3e, 0x29, 0xef, 0xe2, 0xfa, 0x90, 0xa4, 0xbc, 0x8b, 0x6d, 0x11, 0x36, 0xa9, - 0xbc, 0x46, 0x95, 0x96, 0x84, 0xde, 0xa6, 0x4e, 0xaa, 0x3e, 0xa0, 0x5c, 0x59, 0x50, 0xfe, 0x07, - 0xc1, 0xee, 0xf0, 0x3d, 0x1e, 0x93, 0x76, 0x18, 0x05, 0x3a, 0x0f, 0xe5, 0x78, 0xfb, 0x06, 0x82, - 0xff, 0xe7, 0x8c, 0x7e, 0x0d, 0xbb, 0xbd, 0x61, 0x1f, 0x6a, 0x64, 0x42, 0xb4, 0xbd, 0x13, 0x8f, - 0x7f, 0x47, 0x30, 0x1c, 0x71, 0xd1, 0xc7, 0x09, 0xd7, 0x80, 0xf8, 0x9e, 0x43, 0x79, 0xa3, 0x43, - 0x2b, 0x21, 0xc1, 0x25, 0x26, 0xc1, 0xfb, 0xf8, 0x5c, 0x17, 0x12, 0x84, 0x6e, 0xe1, 0xde, 0x8d, - 0x68, 0xa8, 0xf9, 0xce, 0x9e, 0xf4, 0xa6, 0x8c, 0x69, 0x1c, 0x92, 0xde, 0x94, 0x71, 0x2d, 0xc1, - 0xa6, 0xbc, 0x48, 0x5a, 0x7b, 0x8a, 0xb9, 0xc5, 0x87, 0xcf, 0x32, 0xe8, 0xd1, 0xb3, 0x0c, 0xfa, - 0xeb, 0x59, 0x06, 0x7d, 0xb3, 0x96, 0xe9, 0x7b, 0xb4, 0x96, 0xe9, 0xfb, 0x63, 0x2d, 0xd3, 0x77, - 0xfd, 0xad, 0xa2, 0xe9, 0x2e, 0x55, 0xf3, 0xaa, 0x61, 0x97, 0x88, 0xf8, 0xbb, 0xd7, 0xcc, 0x1b, - 0xc7, 0x8a, 0x36, 0xa9, 0xcd, 0x92, 0x92, 0x5d, 0xa8, 0xae, 0x50, 0x87, 0xe3, 0x38, 0x7e, 0xf2, - 0x98, 0x84, 0xe2, 0xde, 0x29, 0x53, 0x27, 0xbf, 0x9d, 0x7d, 0x9a, 0x3f, 0xf1, 0x5f, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xfa, 0x61, 0xcc, 0x20, 0x7e, 0x1e, 0x00, 0x00, + // 1757 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5a, 0xcf, 0x6f, 0x14, 0x47, + 0x16, 0x76, 0xd9, 0xc6, 0x3f, 0x0a, 0x03, 0xa6, 0x6c, 0x2f, 0xa6, 0x6d, 0x8f, 0xcd, 0xa0, 0x5d, + 0x0c, 0x5a, 0xba, 0xb1, 0xcd, 0xb2, 0xde, 0x15, 0x8b, 0x84, 0xbd, 0xbb, 0x60, 0xb4, 0x80, 0x69, + 0x2f, 0x09, 0x20, 0x25, 0x93, 0x9e, 0x9e, 0x62, 0xdc, 0xb2, 0xa7, 0xbb, 0x99, 0xee, 0x19, 0x40, + 0x8e, 0xa3, 0x28, 0x07, 0xc2, 0x31, 0x0a, 0x8a, 0x22, 0xe5, 0x12, 0x29, 0xa7, 0x10, 0x29, 0x8a, + 0xf2, 0x17, 0xe4, 0x92, 0x03, 0xb7, 0x20, 0x91, 0x43, 0x24, 0x24, 0x12, 0x61, 0x22, 0x72, 0xcd, + 0x25, 0xe7, 0xa8, 0xab, 0x5e, 0xf5, 0x74, 0xcf, 0x74, 0xb7, 0x3d, 0x6e, 0x8f, 0x84, 0x72, 0x9b, + 0xae, 0xae, 0xf7, 0xea, 0xfb, 0xbe, 0x57, 0xf5, 0xba, 0xde, 0xb3, 0xf1, 0xb8, 0x91, 0xd7, 0x15, + 0xdd, 0x2a, 0x53, 0x45, 0x5f, 0xd6, 0x4c, 0x93, 0xae, 0x2a, 0xd5, 0x29, 0xe5, 0x56, 0x85, 0x96, + 0xef, 0xca, 0x76, 0xd9, 0x72, 0x2d, 0x32, 0x60, 0xe4, 0x75, 0xd9, 0x9b, 0x20, 0xc3, 0x04, 0xb9, + 0x3a, 0x25, 0x05, 0xac, 0x56, 0x0d, 0x6a, 0xba, 0x9e, 0x11, 0xff, 0xc5, 0xad, 0xa4, 0x63, 0xba, + 0xe5, 0x94, 0x2c, 0x47, 0xc9, 0x6b, 0x0e, 0xe5, 0xee, 0x94, 0xea, 0x54, 0x9e, 0xba, 0xda, 0x94, + 0x62, 0x6b, 0x45, 0xc3, 0xd4, 0x5c, 0xc3, 0x32, 0x61, 0xee, 0xa1, 0x28, 0x08, 0x62, 0x31, 0x3e, + 0x65, 0xb4, 0x68, 0x59, 0xc5, 0x55, 0xaa, 0x68, 0xb6, 0xa1, 0x68, 0xa6, 0x69, 0xb9, 0xcc, 0xde, + 0x81, 0xb7, 0x07, 0xe1, 0x2d, 0x7b, 0xca, 0x57, 0x6e, 0x2a, 0x9a, 0x09, 0xe8, 0xa5, 0xc1, 0xa2, + 0x55, 0xb4, 0xd8, 0x4f, 0xc5, 0xfb, 0x95, 0xb4, 0x62, 0xc5, 0x2e, 0x96, 0xb5, 0x02, 0xe5, 0x53, + 0xb2, 0x17, 0xf1, 0xc0, 0x15, 0x0f, 0xf6, 0x3c, 0x9f, 0xa0, 0xd2, 0x5b, 0x15, 0xea, 0xb8, 0xe4, + 0x00, 0xee, 0xb6, 0xad, 0xb2, 0x9b, 0x33, 0x0a, 0xc3, 0x68, 0x02, 0x4d, 0xf6, 0xaa, 0x5d, 0xde, + 0xe3, 0x42, 0x81, 0x8c, 0x61, 0x0c, 0xbe, 0xbc, 0x77, 0xed, 0xec, 0x5d, 0x2f, 0x8c, 0x2c, 0x14, + 0xb2, 0x0f, 0x11, 0x1e, 0x0c, 0xfb, 0x73, 0x6c, 0xcb, 0x74, 0x28, 0x39, 0x85, 0xbb, 0x61, 0x16, + 0x73, 0xb8, 0x7b, 0x7a, 0x54, 0x8e, 0x10, 0x5c, 0x16, 0x66, 0x62, 0x32, 0x19, 0xc4, 0xbb, 0xec, + 0xb2, 0x65, 0xdd, 0x64, 0x4b, 0xf5, 0xa9, 0xfc, 0x81, 0xcc, 0xe3, 0x3e, 0xf6, 0x23, 0xb7, 0x4c, + 0x8d, 0xe2, 0xb2, 0x3b, 0xdc, 0xc1, 0x5c, 0x4a, 0x01, 0x97, 0x3c, 0x48, 0xd5, 0x29, 0xf9, 0x3c, + 0x9b, 0x31, 0xd7, 0xf9, 0xe8, 0xd9, 0x78, 0x9b, 0xba, 0x9b, 0x59, 0xf1, 0xa1, 0xec, 0x9b, 0x61, + 0xa8, 0x8e, 0xe0, 0xfe, 0x5f, 0x8c, 0x6b, 0xb1, 0x03, 0xb4, 0x7f, 0x91, 0x79, 0xa0, 0x65, 0x2f, + 0xd0, 0x32, 0xdf, 0x37, 0x10, 0x68, 0x79, 0x51, 0x2b, 0x52, 0xb0, 0x55, 0x03, 0x96, 0xd9, 0x67, + 0x08, 0x0f, 0xd5, 0x2d, 0x00, 0x62, 0xcc, 0xe1, 0x1e, 0xe0, 0xe7, 0x0c, 0xa3, 0x89, 0x0e, 0xe6, + 0x3f, 0x4a, 0x8d, 0x85, 0x02, 0x35, 0x5d, 0xe3, 0xa6, 0x41, 0x0b, 0x42, 0x17, 0xdf, 0x8e, 0x9c, + 0x0b, 0xa1, 0x6c, 0x67, 0x28, 0x8f, 0x6c, 0x8a, 0x92, 0x03, 0x08, 0xc2, 0x24, 0xb3, 0xb8, 0xab, + 0x49, 0x15, 0x61, 0x7e, 0xf6, 0x3e, 0xc2, 0x19, 0x4e, 0xd0, 0x32, 0x4d, 0xaa, 0x7b, 0xde, 0xea, + 0xb5, 0xcc, 0x60, 0xac, 0xfb, 0x2f, 0x61, 0x2b, 0x05, 0x46, 0xea, 0xb4, 0x6e, 0xdf, 0xb6, 0xd6, + 0xbf, 0x20, 0x3c, 0x1e, 0x0b, 0xe5, 0x8f, 0xa5, 0xfa, 0x35, 0x21, 0x3a, 0xc7, 0x34, 0xcf, 0x66, + 0x2f, 0xb9, 0x9a, 0x4b, 0xd3, 0x1e, 0xde, 0x1f, 0x7d, 0x11, 0x23, 0x5c, 0x83, 0x88, 0x1a, 0x3e, + 0x60, 0xf8, 0xfa, 0xe4, 0x38, 0xd4, 0x9c, 0xe3, 0x4d, 0x81, 0x93, 0x72, 0x34, 0x8a, 0x48, 0x40, + 0xd2, 0x80, 0xcf, 0x21, 0x23, 0x6a, 0xb8, 0x95, 0x47, 0xfe, 0x4b, 0x84, 0x0f, 0x85, 0x18, 0x7a, + 0x9c, 0x4c, 0xa7, 0xe2, 0xec, 0x84, 0x7e, 0xe4, 0x08, 0xde, 0x57, 0xa6, 0x55, 0xc3, 0x31, 0x2c, + 0x33, 0x67, 0x56, 0x4a, 0x79, 0x5a, 0x66, 0x28, 0x3b, 0xd5, 0xbd, 0x62, 0xf8, 0x12, 0x1b, 0x0d, + 0x4d, 0x04, 0x3a, 0x9d, 0xe1, 0x89, 0x80, 0xf7, 0x29, 0xc2, 0xd9, 0x24, 0xbc, 0x10, 0x94, 0x7f, + 0xe1, 0x7d, 0xba, 0x78, 0x13, 0x0a, 0xc6, 0xa0, 0xcc, 0x3f, 0x19, 0xb2, 0xf8, 0x64, 0xc8, 0x67, + 0xcd, 0xbb, 0xea, 0x5e, 0x3d, 0xe4, 0x86, 0x8c, 0xe0, 0x5e, 0x08, 0xa4, 0xcf, 0xaa, 0x87, 0x0f, + 0x2c, 0x14, 0x6a, 0xd1, 0xe8, 0x48, 0x8a, 0x46, 0xe7, 0x76, 0xa2, 0x51, 0xc6, 0xa3, 0x8c, 0xdc, + 0xa2, 0xa6, 0xaf, 0x50, 0x77, 0xde, 0x2a, 0x95, 0x0c, 0xb7, 0x44, 0x4d, 0x37, 0x6d, 0x1c, 0x24, + 0xdc, 0xe3, 0x78, 0x2e, 0x4c, 0x9d, 0x42, 0x00, 0xfc, 0xe7, 0xec, 0x27, 0x08, 0x8f, 0xc5, 0x2c, + 0x0a, 0x62, 0xb2, 0x94, 0x25, 0x46, 0xd9, 0xc2, 0x7d, 0x6a, 0x60, 0xa4, 0x95, 0xdb, 0xf3, 0xd3, + 0x38, 0x70, 0x4e, 0x5a, 0x49, 0xc2, 0x79, 0xb6, 0x63, 0xdb, 0x79, 0xf6, 0xa5, 0x48, 0xf9, 0x11, + 0x08, 0xfd, 0x34, 0xbb, 0xbb, 0xa6, 0x96, 0xc8, 0xb4, 0x13, 0x91, 0x99, 0x96, 0x3b, 0xe1, 0x7b, + 0x39, 0x68, 0xf4, 0x2a, 0xa4, 0x59, 0x0b, 0x1f, 0x0c, 0x10, 0x55, 0xa9, 0x4e, 0x0d, 0xbb, 0xa5, + 0x3b, 0xf3, 0x01, 0xc2, 0x52, 0xd4, 0x8a, 0x20, 0xab, 0x84, 0x7b, 0xca, 0xde, 0x50, 0x95, 0x72, + 0xbf, 0x3d, 0xaa, 0xff, 0xdc, 0xca, 0x33, 0x7a, 0x1b, 0x12, 0x26, 0x07, 0x75, 0x56, 0x5f, 0x31, + 0xad, 0xdb, 0xab, 0xb4, 0x50, 0xa4, 0xad, 0x3e, 0xa8, 0x0f, 0x45, 0xea, 0x8b, 0x59, 0x19, 0x64, + 0x99, 0xc4, 0xfb, 0xb4, 0xf0, 0x2b, 0x38, 0xb2, 0xf5, 0xc3, 0xad, 0x3c, 0xb7, 0x2f, 0x12, 0xb1, + 0xbe, 0x2a, 0x87, 0x97, 0x9c, 0xc1, 0x23, 0x36, 0x03, 0x98, 0xab, 0x9d, 0xb5, 0x9c, 0x10, 0xdc, + 0x19, 0xee, 0x9c, 0xe8, 0x98, 0xec, 0x54, 0x0f, 0xda, 0x75, 0x27, 0x7b, 0x49, 0x4c, 0xc8, 0xfe, + 0x86, 0xf0, 0xe1, 0x44, 0x9a, 0x10, 0x93, 0xff, 0xe1, 0xfe, 0x3a, 0xf1, 0xb7, 0x9e, 0x06, 0x1a, + 0x2c, 0x5f, 0x85, 0x5c, 0xf0, 0xb1, 0xc8, 0xcb, 0x57, 0x4d, 0x71, 0xe6, 0x38, 0xe6, 0xd4, 0xa1, + 0xdd, 0x24, 0x24, 0x1d, 0x9b, 0x85, 0xe4, 0x0e, 0xa4, 0xe3, 0x08, 0x60, 0x10, 0x8c, 0x51, 0xdc, + 0x5b, 0xf3, 0x87, 0x98, 0xbf, 0xda, 0x40, 0x40, 0x93, 0xf6, 0x26, 0x35, 0xb9, 0x27, 0xd2, 0x55, + 0x6d, 0xe9, 0xb3, 0xfa, 0x4a, 0x6a, 0x41, 0x4e, 0xe0, 0x41, 0x10, 0x44, 0xd3, 0x57, 0x1a, 0x94, + 0x20, 0xb6, 0xd8, 0x79, 0x35, 0x09, 0x2a, 0x78, 0x24, 0x12, 0x47, 0x8b, 0xf9, 0x5f, 0x87, 0xbb, + 0xf2, 0x25, 0x7a, 0xc7, 0x8f, 0x87, 0xca, 0x01, 0xa4, 0xbd, 0x87, 0x7f, 0x8d, 0xf0, 0x44, 0xbc, + 0x6f, 0xe0, 0x35, 0x8d, 0x87, 0x4c, 0x7a, 0xa7, 0xb6, 0x59, 0x72, 0xc0, 0x9e, 0x2d, 0xd5, 0xa9, + 0x0e, 0x98, 0x8d, 0xb6, 0xad, 0x4c, 0x81, 0xaf, 0xc1, 0x5d, 0x2e, 0x08, 0x79, 0x89, 0x9a, 0x85, + 0xb4, 0x5a, 0x7c, 0x2e, 0x8e, 0x5e, 0xa3, 0x63, 0x10, 0xe2, 0xaf, 0x98, 0x84, 0x85, 0x70, 0xa8, + 0x59, 0x00, 0x15, 0xfa, 0xcd, 0x3a, 0xab, 0x56, 0x4a, 0xa0, 0xe2, 0x61, 0xbe, 0x11, 0x79, 0x83, + 0xe5, 0x3f, 0xe5, 0xb2, 0x55, 0x4e, 0x4b, 0xff, 0x5b, 0x04, 0xd7, 0x90, 0xb0, 0x53, 0x3f, 0xd1, + 0xee, 0xa1, 0xde, 0x00, 0x8f, 0xbd, 0xed, 0xc2, 0xad, 0xff, 0x50, 0x64, 0x96, 0x05, 0x53, 0x36, + 0x11, 0xe0, 0xf7, 0xd1, 0xc0, 0x58, 0x2b, 0xa5, 0x11, 0x5d, 0x26, 0x60, 0x91, 0x56, 0x95, 0xaf, + 0x44, 0x97, 0xc9, 0xf7, 0x07, 0x82, 0x9c, 0xc6, 0xdd, 0xd0, 0xde, 0x4a, 0xec, 0x32, 0x81, 0x19, + 0x20, 0x15, 0x26, 0xad, 0x14, 0x60, 0x04, 0xc2, 0x08, 0x75, 0xdc, 0xa2, 0x56, 0xd6, 0x4a, 0x22, + 0x57, 0x66, 0xaf, 0x40, 0x26, 0xad, 0x7b, 0x09, 0x9c, 0x66, 0x70, 0x97, 0xcd, 0x46, 0x80, 0xd2, + 0x48, 0xcc, 0x37, 0x94, 0x19, 0xc1, 0xd4, 0xe9, 0x9f, 0x47, 0xf0, 0x2e, 0xe6, 0x93, 0x7c, 0x86, + 0x70, 0x37, 0x38, 0x26, 0x93, 0x91, 0xa6, 0x11, 0xfd, 0x3f, 0xe9, 0xe8, 0x16, 0x66, 0x72, 0x7c, + 0xd9, 0xb9, 0xf7, 0x9e, 0xbc, 0x78, 0xd0, 0x7e, 0x9a, 0xfc, 0x53, 0x49, 0xe8, 0x6f, 0x3a, 0xca, + 0x5a, 0x2d, 0xa0, 0xeb, 0x8a, 0x17, 0x66, 0x47, 0x59, 0x83, 0xe0, 0xaf, 0x93, 0xfb, 0x08, 0xf7, + 0x88, 0x7e, 0x0d, 0xd9, 0x7c, 0x6d, 0xa1, 0x9c, 0x74, 0x6c, 0x2b, 0x53, 0x01, 0xe7, 0x9f, 0x19, + 0xce, 0x71, 0x32, 0x96, 0x88, 0x93, 0x7c, 0x83, 0x30, 0x69, 0x6c, 0x22, 0x91, 0x99, 0x84, 0x95, + 0xe2, 0xba, 0x5f, 0xd2, 0xc9, 0xe6, 0x8c, 0x00, 0xe8, 0x19, 0x06, 0x74, 0x96, 0x9c, 0x8a, 0x06, + 0xea, 0x1b, 0x7a, 0x9a, 0xfa, 0x0f, 0xeb, 0x35, 0x06, 0x8f, 0x3d, 0x06, 0x0d, 0x1d, 0x9c, 0x44, + 0x06, 0x71, 0xad, 0xa4, 0x44, 0x06, 0xb1, 0x4d, 0xa2, 0xec, 0x65, 0xc6, 0x60, 0x81, 0x9c, 0xdb, + 0xfe, 0x96, 0x50, 0x82, 0xad, 0x25, 0xf2, 0x61, 0x3b, 0x1e, 0x8a, 0x6c, 0x81, 0x90, 0x53, 0x9b, + 0x03, 0x8c, 0xea, 0xf1, 0x48, 0x7f, 0x6f, 0xda, 0x0e, 0xb8, 0xbd, 0x8f, 0x18, 0xb9, 0x77, 0x11, + 0x79, 0x27, 0x0d, 0xbb, 0x70, 0xbb, 0x46, 0x11, 0x7d, 0x1f, 0x65, 0xad, 0xae, 0x83, 0xb4, 0xae, + 0xf0, 0xb4, 0x13, 0x78, 0xc1, 0x07, 0xd6, 0xc9, 0x53, 0x84, 0xfb, 0xeb, 0xcb, 0x70, 0x32, 0x15, + 0xcf, 0x2b, 0xa6, 0xcd, 0x22, 0x4d, 0x37, 0x63, 0x02, 0x2a, 0xbc, 0xc5, 0x44, 0xb8, 0x41, 0xae, + 0xa5, 0xd0, 0xa0, 0xe1, 0xe2, 0xeb, 0x28, 0x6b, 0xe2, 0x23, 0xbe, 0x4e, 0x9e, 0x20, 0xbc, 0xbf, + 0xa1, 0xc9, 0x40, 0x9a, 0xc0, 0xea, 0x9f, 0xc2, 0x99, 0xa6, 0x6c, 0x80, 0xe0, 0x55, 0x46, 0xf0, + 0x32, 0xb9, 0xb8, 0xa3, 0x04, 0xc9, 0x77, 0x08, 0xef, 0x09, 0xd5, 0xf7, 0x44, 0xde, 0x0c, 0x5d, + 0xb8, 0xf5, 0x20, 0x29, 0x5b, 0x9e, 0x0f, 0x4c, 0xde, 0x60, 0x4c, 0x5e, 0x27, 0x57, 0xd3, 0x33, + 0x81, 0x6b, 0x46, 0x28, 0x4e, 0x1b, 0x08, 0x0f, 0x45, 0xd6, 0x83, 0x49, 0x47, 0x33, 0xa9, 0x9b, + 0x90, 0x74, 0x34, 0x13, 0x7b, 0x01, 0xd9, 0xeb, 0x8c, 0xe9, 0x12, 0xb9, 0x92, 0x9e, 0xa9, 0xa6, + 0xaf, 0x84, 0x58, 0xbe, 0x44, 0xf8, 0x4f, 0xd1, 0x55, 0x2f, 0x69, 0x16, 0xae, 0xbf, 0x2f, 0x67, + 0x9b, 0x37, 0x04, 0xa2, 0x37, 0x18, 0xd1, 0xff, 0x13, 0x75, 0x47, 0x88, 0x86, 0xe9, 0xdc, 0x6b, + 0xc7, 0xfb, 0x1b, 0xaa, 0xc9, 0xa4, 0x73, 0x17, 0x57, 0x13, 0x27, 0x9d, 0xbb, 0xd8, 0x72, 0x75, + 0x87, 0xd2, 0x6b, 0x54, 0x6a, 0x49, 0xa8, 0xb3, 0xd7, 0x95, 0x8a, 0x0f, 0x28, 0x67, 0x03, 0xe5, + 0x5f, 0x11, 0xde, 0x1b, 0xae, 0x29, 0x89, 0xb2, 0x15, 0x46, 0x81, 0x2a, 0x58, 0x3a, 0xb1, 0x75, + 0x03, 0xe0, 0xff, 0x36, 0xa3, 0x5f, 0x25, 0x6e, 0x6b, 0xd8, 0x87, 0x8a, 0xea, 0x10, 0x6d, 0x6f, + 0xc7, 0x93, 0xef, 0x11, 0x1e, 0x88, 0x28, 0x3a, 0x49, 0xc2, 0x35, 0x20, 0xbe, 0xfe, 0x95, 0xfe, + 0xd6, 0xa4, 0x15, 0x48, 0xb0, 0xc8, 0x24, 0xb8, 0x40, 0xce, 0xa7, 0x90, 0x20, 0x54, 0x11, 0x7a, + 0x37, 0xa2, 0xfe, 0xfa, 0xfa, 0x31, 0xe9, 0x4b, 0x19, 0x53, 0xc4, 0x26, 0x7d, 0x29, 0xe3, 0xca, + 0xd3, 0x1d, 0xf9, 0x90, 0x34, 0xd6, 0xb7, 0xde, 0x35, 0xb5, 0x2f, 0x58, 0x13, 0x92, 0xe3, 0x09, + 0x5b, 0xad, 0xb1, 0x20, 0x95, 0xe4, 0xad, 0x4e, 0xdf, 0xc1, 0xa0, 0x40, 0x9d, 0x95, 0x63, 0x55, + 0x27, 0xf9, 0x02, 0xe1, 0x6e, 0x58, 0x2a, 0xa9, 0x30, 0x09, 0x97, 0x8c, 0x49, 0x85, 0x49, 0x5d, + 0x31, 0x98, 0xbd, 0xc0, 0x20, 0xff, 0x9b, 0xcc, 0xa5, 0x87, 0x4c, 0x3e, 0x42, 0x78, 0x4f, 0xa8, + 0x3c, 0x4b, 0xfa, 0x6e, 0x47, 0x15, 0x79, 0x49, 0xdf, 0xed, 0xc8, 0xba, 0x2f, 0x7b, 0x98, 0xc1, + 0x1f, 0x23, 0x23, 0x91, 0xf0, 0x79, 0x9d, 0x37, 0xb7, 0xf4, 0xe8, 0x79, 0x06, 0x3d, 0x7e, 0x9e, + 0x41, 0x3f, 0x3d, 0xcf, 0xa0, 0x0f, 0x36, 0x32, 0x6d, 0x8f, 0x37, 0x32, 0x6d, 0x3f, 0x6c, 0x64, + 0xda, 0x6e, 0xfc, 0xa3, 0x68, 0xb8, 0xcb, 0x95, 0xbc, 0xac, 0x5b, 0x25, 0x05, 0xfe, 0x49, 0xc5, + 0xc8, 0xeb, 0xc7, 0x8b, 0x96, 0x52, 0x9d, 0x55, 0x4a, 0x56, 0xa1, 0xb2, 0x4a, 0x1d, 0xee, 0xf5, + 0xc4, 0xc9, 0xe3, 0xc2, 0xb1, 0x7b, 0xd7, 0xa6, 0x4e, 0xbe, 0x8b, 0xfd, 0xb5, 0x70, 0xe6, 0xf7, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x50, 0xcd, 0xd6, 0x34, 0x23, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1979,6 +2313,12 @@ type QueryClient interface { NextSequenceReceive(ctx context.Context, in *QueryNextSequenceReceiveRequest, opts ...grpc.CallOption) (*QueryNextSequenceReceiveResponse, error) // NextSequenceSend returns the next send sequence for a given channel. NextSequenceSend(ctx context.Context, in *QueryNextSequenceSendRequest, opts ...grpc.CallOption) (*QueryNextSequenceSendResponse, error) + // UpgradeError returns the error receipt if the upgrade handshake failed. + UpgradeError(ctx context.Context, in *QueryUpgradeErrorRequest, opts ...grpc.CallOption) (*QueryUpgradeErrorResponse, error) + // Upgrade returns the upgrade for a given port and channel id. + Upgrade(ctx context.Context, in *QueryUpgradeRequest, opts ...grpc.CallOption) (*QueryUpgradeResponse, error) + // ChannelParams queries all parameters of the ibc channel submodule. + ChannelParams(ctx context.Context, in *QueryChannelParamsRequest, opts ...grpc.CallOption) (*QueryChannelParamsResponse, error) } type queryClient struct { @@ -2115,6 +2455,33 @@ func (c *queryClient) NextSequenceSend(ctx context.Context, in *QueryNextSequenc return out, nil } +func (c *queryClient) UpgradeError(ctx context.Context, in *QueryUpgradeErrorRequest, opts ...grpc.CallOption) (*QueryUpgradeErrorResponse, error) { + out := new(QueryUpgradeErrorResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Query/UpgradeError", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Upgrade(ctx context.Context, in *QueryUpgradeRequest, opts ...grpc.CallOption) (*QueryUpgradeResponse, error) { + out := new(QueryUpgradeResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Query/Upgrade", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ChannelParams(ctx context.Context, in *QueryChannelParamsRequest, opts ...grpc.CallOption) (*QueryChannelParamsResponse, error) { + out := new(QueryChannelParamsResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Query/ChannelParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Channel queries an IBC Channel. @@ -2153,6 +2520,12 @@ type QueryServer interface { NextSequenceReceive(context.Context, *QueryNextSequenceReceiveRequest) (*QueryNextSequenceReceiveResponse, error) // NextSequenceSend returns the next send sequence for a given channel. NextSequenceSend(context.Context, *QueryNextSequenceSendRequest) (*QueryNextSequenceSendResponse, error) + // UpgradeError returns the error receipt if the upgrade handshake failed. + UpgradeError(context.Context, *QueryUpgradeErrorRequest) (*QueryUpgradeErrorResponse, error) + // Upgrade returns the upgrade for a given port and channel id. + Upgrade(context.Context, *QueryUpgradeRequest) (*QueryUpgradeResponse, error) + // ChannelParams queries all parameters of the ibc channel submodule. + ChannelParams(context.Context, *QueryChannelParamsRequest) (*QueryChannelParamsResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -2201,6 +2574,15 @@ func (*UnimplementedQueryServer) NextSequenceReceive(ctx context.Context, req *Q func (*UnimplementedQueryServer) NextSequenceSend(ctx context.Context, req *QueryNextSequenceSendRequest) (*QueryNextSequenceSendResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method NextSequenceSend not implemented") } +func (*UnimplementedQueryServer) UpgradeError(ctx context.Context, req *QueryUpgradeErrorRequest) (*QueryUpgradeErrorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpgradeError not implemented") +} +func (*UnimplementedQueryServer) Upgrade(ctx context.Context, req *QueryUpgradeRequest) (*QueryUpgradeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Upgrade not implemented") +} +func (*UnimplementedQueryServer) ChannelParams(ctx context.Context, req *QueryChannelParamsRequest) (*QueryChannelParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelParams not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -2458,44 +2840,98 @@ func _Query_NextSequenceSend_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } -var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "ibc.core.channel.v1.Query", - HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Channel", - Handler: _Query_Channel_Handler, - }, - { - MethodName: "Channels", - Handler: _Query_Channels_Handler, - }, - { - MethodName: "ConnectionChannels", - Handler: _Query_ConnectionChannels_Handler, - }, - { - MethodName: "ChannelClientState", - Handler: _Query_ChannelClientState_Handler, - }, - { - MethodName: "ChannelConsensusState", - Handler: _Query_ChannelConsensusState_Handler, - }, - { - MethodName: "PacketCommitment", - Handler: _Query_PacketCommitment_Handler, - }, - { - MethodName: "PacketCommitments", - Handler: _Query_PacketCommitments_Handler, - }, - { - MethodName: "PacketReceipt", - Handler: _Query_PacketReceipt_Handler, - }, - { - MethodName: "PacketAcknowledgement", +func _Query_UpgradeError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUpgradeErrorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UpgradeError(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Query/UpgradeError", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UpgradeError(ctx, req.(*QueryUpgradeErrorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Upgrade_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUpgradeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Upgrade(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Query/Upgrade", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Upgrade(ctx, req.(*QueryUpgradeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ChannelParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryChannelParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ChannelParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Query/ChannelParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ChannelParams(ctx, req.(*QueryChannelParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.core.channel.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Channel", + Handler: _Query_Channel_Handler, + }, + { + MethodName: "Channels", + Handler: _Query_Channels_Handler, + }, + { + MethodName: "ConnectionChannels", + Handler: _Query_ConnectionChannels_Handler, + }, + { + MethodName: "ChannelClientState", + Handler: _Query_ChannelClientState_Handler, + }, + { + MethodName: "ChannelConsensusState", + Handler: _Query_ChannelConsensusState_Handler, + }, + { + MethodName: "PacketCommitment", + Handler: _Query_PacketCommitment_Handler, + }, + { + MethodName: "PacketCommitments", + Handler: _Query_PacketCommitments_Handler, + }, + { + MethodName: "PacketReceipt", + Handler: _Query_PacketReceipt_Handler, + }, + { + MethodName: "PacketAcknowledgement", Handler: _Query_PacketAcknowledgement_Handler, }, { @@ -2518,6 +2954,18 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "NextSequenceSend", Handler: _Query_NextSequenceSend_Handler, }, + { + MethodName: "UpgradeError", + Handler: _Query_UpgradeError_Handler, + }, + { + MethodName: "Upgrade", + Handler: _Query_Upgrade_Handler, + }, + { + MethodName: "ChannelParams", + Handler: _Query_ChannelParams_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "ibc/core/channel/v1/query.proto", @@ -3882,115 +4330,347 @@ func (m *QueryNextSequenceSendResponse) MarshalToSizedBuffer(dAtA []byte) (int, 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++ +func (m *QueryUpgradeErrorRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *QueryChannelRequest) 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.ChannelId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n + +func (m *QueryUpgradeErrorRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryChannelResponse) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryUpgradeErrorRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Channel != nil { - l = m.Channel.Size() - n += 1 + l + sovQuery(uint64(l)) + if len(m.ChannelId) > 0 { + i -= len(m.ChannelId) + copy(dAtA[i:], m.ChannelId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChannelId))) + i-- + dAtA[i] = 0x12 } - l = len(m.Proof) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + 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 } - l = m.ProofHeight.Size() - n += 1 + l + sovQuery(uint64(l)) - return n + return len(dAtA) - i, nil } -func (m *QueryChannelsRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) +func (m *QueryUpgradeErrorResponse) 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 n + return dAtA[:n], nil } -func (m *QueryChannelsResponse) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryUpgradeErrorResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradeErrorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.Channels) > 0 { - for _, e := range m.Channels { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) + i-- + dAtA[i] = 0x1a + if len(m.Proof) > 0 { + i -= len(m.Proof) + copy(dAtA[i:], m.Proof) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Proof))) + i-- + dAtA[i] = 0x12 } - l = m.Height.Size() - n += 1 + l + sovQuery(uint64(l)) - return n + { + size, err := m.ErrorReceipt.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 (m *QueryConnectionChannelsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryUpgradeRequest) 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 *QueryUpgradeRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradeRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Connection) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if len(m.ChannelId) > 0 { + i -= len(m.ChannelId) + copy(dAtA[i:], m.ChannelId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChannelId))) + i-- + dAtA[i] = 0x12 } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) + 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 n + return len(dAtA) - i, nil } -func (m *QueryConnectionChannelsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Channels) > 0 { - for _, e := range m.Channels { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) - } +func (m *QueryUpgradeResponse) 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 *QueryUpgradeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.Proof) > 0 { + i -= len(m.Proof) + copy(dAtA[i:], m.Proof) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Proof))) + i-- + dAtA[i] = 0x12 + } + { + size, err := m.Upgrade.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 (m *QueryChannelParamsRequest) 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 *QueryChannelParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryChannelParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryChannelParamsResponse) 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 *QueryChannelParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryChannelParamsResponse) 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 + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryChannelRequest) 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.ChannelId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryChannelResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Channel != nil { + l = m.Channel.Size() + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Proof) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryChannelsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryChannelsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Channels) > 0 { + for _, e := range m.Channels { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + l = m.Height.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryConnectionChannelsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Connection) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryConnectionChannelsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Channels) > 0 { + for _, e := range m.Channels { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } } if m.Pagination != nil { l = m.Pagination.Size() @@ -4444,37 +5124,127 @@ func (m *QueryNextSequenceSendResponse) Size() (n int) { return n } -func sovQuery(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 +func (m *QueryUpgradeErrorRequest) 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.ChannelId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n } -func sozQuery(x uint64) (n int) { - return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + +func (m *QueryUpgradeErrorResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ErrorReceipt.Size() + n += 1 + l + sovQuery(uint64(l)) + l = len(m.Proof) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovQuery(uint64(l)) + return n } -func (m *QueryChannelRequest) 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: QueryChannelRequest: wiretype end group for non-group") - } + +func (m *QueryUpgradeRequest) 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.ChannelId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryUpgradeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Upgrade.Size() + n += 1 + l + sovQuery(uint64(l)) + l = len(m.Proof) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryChannelParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryChannelParamsResponse) 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 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryChannelRequest) 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: QueryChannelRequest: wiretype end group for non-group") + } if fieldNum <= 0 { return fmt.Errorf("proto: QueryChannelRequest: illegal tag %d (wire type %d)", fieldNum, wire) } @@ -7960,44 +8730,544 @@ func (m *QueryUnreceivedAcksResponse) Unmarshal(dAtA []byte) error { if postIndex < 0 { return ErrInvalidLengthQuery } - if postIndex > l { + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.Sequences) == 0 { + m.Sequences = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Sequences = append(m.Sequences, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Sequences", wireType) + } + 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 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 err := m.Height.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 (m *QueryNextSequenceReceiveRequest) 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: QueryNextSequenceReceiveRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryNextSequenceReceiveRequest: 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 ChannelId", 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.ChannelId = 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 *QueryNextSequenceReceiveResponse) 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: QueryNextSequenceReceiveResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryNextSequenceReceiveResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceReceive", wireType) + } + m.NextSequenceReceive = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextSequenceReceive |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Proof = append(m.Proof[:0], dAtA[iNdEx:postIndex]...) + if m.Proof == nil { + m.Proof = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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 err := m.ProofHeight.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 (m *QueryNextSequenceSendRequest) 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: QueryNextSequenceSendRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryNextSequenceSendRequest: 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 ChannelId", 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.ChannelId = 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 *QueryNextSequenceSendResponse) 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: QueryNextSequenceSendResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryNextSequenceSendResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceSend", wireType) + } + m.NextSequenceSend = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - var elementCount int - var count int - for _, integer := range dAtA[iNdEx:postIndex] { - if integer < 128 { - count++ - } + b := dAtA[iNdEx] + iNdEx++ + m.NextSequenceSend |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - elementCount = count - if elementCount != 0 && len(m.Sequences) == 0 { - m.Sequences = make([]uint64, 0, elementCount) + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery } - for iNdEx < postIndex { - var v uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Sequences = append(m.Sequences, v) + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break } - } else { - return fmt.Errorf("proto: wrong wireType = %d for field Sequences", wireType) } - case 2: + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Proof = append(m.Proof[:0], dAtA[iNdEx:postIndex]...) + if m.Proof == nil { + m.Proof = []byte{} + } + iNdEx = postIndex + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -8024,7 +9294,7 @@ func (m *QueryUnreceivedAcksResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Height.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -8049,7 +9319,7 @@ func (m *QueryUnreceivedAcksResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryNextSequenceReceiveRequest) Unmarshal(dAtA []byte) error { +func (m *QueryUpgradeErrorRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8072,10 +9342,10 @@ func (m *QueryNextSequenceReceiveRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryNextSequenceReceiveRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUpgradeErrorRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryNextSequenceReceiveRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUpgradeErrorRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -8163,7 +9433,7 @@ func (m *QueryNextSequenceReceiveRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryNextSequenceReceiveResponse) Unmarshal(dAtA []byte) error { +func (m *QueryUpgradeErrorResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8186,17 +9456,17 @@ func (m *QueryNextSequenceReceiveResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryNextSequenceReceiveResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUpgradeErrorResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryNextSequenceReceiveResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUpgradeErrorResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceReceive", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ErrorReceipt", wireType) } - m.NextSequenceReceive = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -8206,11 +9476,25 @@ func (m *QueryNextSequenceReceiveResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NextSequenceReceive |= uint64(b&0x7F) << shift + 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 err := m.ErrorReceipt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) @@ -8299,7 +9583,7 @@ func (m *QueryNextSequenceReceiveResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryNextSequenceSendRequest) Unmarshal(dAtA []byte) error { +func (m *QueryUpgradeRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8322,10 +9606,10 @@ func (m *QueryNextSequenceSendRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryNextSequenceSendRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUpgradeRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryNextSequenceSendRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUpgradeRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -8413,7 +9697,7 @@ func (m *QueryNextSequenceSendRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryNextSequenceSendResponse) Unmarshal(dAtA []byte) error { +func (m *QueryUpgradeResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8436,17 +9720,17 @@ func (m *QueryNextSequenceSendResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryNextSequenceSendResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUpgradeResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryNextSequenceSendResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUpgradeResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceSend", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Upgrade", wireType) } - m.NextSequenceSend = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -8456,11 +9740,25 @@ func (m *QueryNextSequenceSendResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NextSequenceSend |= uint64(b&0x7F) << shift + 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 err := m.Upgrade.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) @@ -8549,6 +9847,142 @@ func (m *QueryNextSequenceSendResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryChannelParamsRequest) 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: QueryChannelParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryChannelParamsRequest: 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 *QueryChannelParamsResponse) 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: QueryChannelParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryChannelParamsResponse: 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/04-channel/types/query.pb.gw.go b/modules/core/04-channel/types/query.pb.gw.go index 2f9c58f146d..bce31252f8b 100644 --- a/modules/core/04-channel/types/query.pb.gw.go +++ b/modules/core/04-channel/types/query.pb.gw.go @@ -1243,6 +1243,176 @@ func local_request_Query_NextSequenceSend_0(ctx context.Context, marshaler runti } +func request_Query_UpgradeError_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradeErrorRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["channel_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "channel_id") + } + + protoReq.ChannelId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "channel_id", err) + } + + val, ok = pathParams["port_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_id") + } + + protoReq.PortId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err) + } + + msg, err := client.UpgradeError(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_UpgradeError_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradeErrorRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["channel_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "channel_id") + } + + protoReq.ChannelId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "channel_id", err) + } + + val, ok = pathParams["port_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_id") + } + + protoReq.PortId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err) + } + + msg, err := server.UpgradeError(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_Upgrade_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradeRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["channel_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "channel_id") + } + + protoReq.ChannelId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "channel_id", err) + } + + val, ok = pathParams["port_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_id") + } + + protoReq.PortId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err) + } + + msg, err := client.Upgrade(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Upgrade_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradeRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["channel_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "channel_id") + } + + protoReq.ChannelId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "channel_id", err) + } + + val, ok = pathParams["port_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "port_id") + } + + protoReq.PortId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err) + } + + msg, err := server.Upgrade(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_ChannelParams_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryChannelParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.ChannelParams(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ChannelParams_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryChannelParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.ChannelParams(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. @@ -1571,6 +1741,75 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_UpgradeError_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_UpgradeError_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_UpgradeError_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Upgrade_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_Upgrade_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_Upgrade_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ChannelParams_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_ChannelParams_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_ChannelParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1892,6 +2131,66 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_UpgradeError_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_UpgradeError_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_UpgradeError_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Upgrade_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_Upgrade_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_Upgrade_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ChannelParams_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_ChannelParams_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_ChannelParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1923,6 +2222,12 @@ var ( 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))) pattern_Query_NextSequenceSend_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_send"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_UpgradeError_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", "upgrade_error"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Upgrade_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", "upgrade"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_ChannelParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "channel", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -1953,4 +2258,10 @@ var ( forward_Query_NextSequenceReceive_0 = runtime.ForwardResponseMessage forward_Query_NextSequenceSend_0 = runtime.ForwardResponseMessage + + forward_Query_UpgradeError_0 = runtime.ForwardResponseMessage + + forward_Query_Upgrade_0 = runtime.ForwardResponseMessage + + forward_Query_ChannelParams_0 = runtime.ForwardResponseMessage ) diff --git a/modules/core/04-channel/types/timeout.go b/modules/core/04-channel/types/timeout.go new file mode 100644 index 00000000000..dc51c31a78a --- /dev/null +++ b/modules/core/04-channel/types/timeout.go @@ -0,0 +1,60 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" +) + +// NewTimeout returns a new Timeout instance. +func NewTimeout(height clienttypes.Height, timestamp uint64) Timeout { + return Timeout{ + Height: height, + Timestamp: timestamp, + } +} + +// IsValid returns true if either the height or timestamp is non-zero. +func (t Timeout) IsValid() bool { + return !t.Height.IsZero() || t.Timestamp != 0 +} + +// Elapsed returns true if either the provided height or timestamp is past the +// respective absolute timeout values. +func (t Timeout) Elapsed(height clienttypes.Height, timestamp uint64) bool { + return t.heightElapsed(height) || t.timestampElapsed(timestamp) +} + +// ErrTimeoutElapsed returns a timeout elapsed error indicating which timeout value +// has elapsed. +func (t Timeout) ErrTimeoutElapsed(height clienttypes.Height, timestamp uint64) error { + if t.heightElapsed(height) { + return errorsmod.Wrapf(ErrTimeoutElapsed, "current height: %s, timeout height %s", height, t.Height) + } + + return errorsmod.Wrapf(ErrTimeoutElapsed, "current timestamp: %d, timeout timestamp %d", timestamp, t.Timestamp) +} + +// ErrTimeoutNotReached returns a timeout not reached error indicating which timeout value +// has not been reached. +func (t Timeout) ErrTimeoutNotReached(height clienttypes.Height, timestamp uint64) error { + // only return height information if the height is set + // t.heightElapsed() will return false when it is empty + if !t.Height.IsZero() && !t.heightElapsed(height) { + return errorsmod.Wrapf(ErrTimeoutNotReached, "current height: %s, timeout height %s", height, t.Height) + } + + return errorsmod.Wrapf(ErrTimeoutNotReached, "current timestamp: %d, timeout timestamp %d", timestamp, t.Timestamp) +} + +// heightElapsed returns true if the timeout height is non empty +// and the timeout height is greater than or equal to the relative height. +func (t Timeout) heightElapsed(height clienttypes.Height) bool { + return !t.Height.IsZero() && height.GTE(t.Height) +} + +// timestampElapsed returns true if the timeout timestamp is non empty +// and the timeout timestamp is greater than or equal to the relative timestamp. +func (t Timeout) timestampElapsed(timestamp uint64) bool { + return t.Timestamp != 0 && timestamp >= t.Timestamp +} diff --git a/modules/core/04-channel/types/timeout_test.go b/modules/core/04-channel/types/timeout_test.go new file mode 100644 index 00000000000..add2c3c876c --- /dev/null +++ b/modules/core/04-channel/types/timeout_test.go @@ -0,0 +1,238 @@ +package types_test + +import ( + errorsmod "cosmossdk.io/errors" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" +) + +func (suite *TypesTestSuite) TestIsValid() { + var timeout types.Timeout + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success: valid timeout with height and timestamp", + func() { + timeout = types.NewTimeout(clienttypes.NewHeight(1, 100), 100) + }, + true, + }, + { + "success: valid timeout with height and zero timestamp", + func() { + timeout = types.NewTimeout(clienttypes.NewHeight(1, 100), 0) + }, + true, + }, + { + "success: valid timeout with timestamp and zero height", + func() { + timeout = types.NewTimeout(clienttypes.ZeroHeight(), 100) + }, + true, + }, + { + "invalid timeout with zero height and zero timestamp", + func() { + timeout = types.NewTimeout(clienttypes.ZeroHeight(), 0) + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + tc.malleate() + + isValid := timeout.IsValid() + if tc.expPass { + suite.Require().True(isValid) + } else { + suite.Require().False(isValid) + } + }) + } +} + +func (suite *TypesTestSuite) TestElapsed() { + // elapsed is expected to be true when either timeout height or timestamp + // is greater than or equal to 2 + var ( + height = clienttypes.NewHeight(0, 2) + timestamp = uint64(2) + ) + + testCases := []struct { + name string + timeout types.Timeout + expElapsed bool + }{ + { + "elapsed: both timeout with height and timestamp", + types.NewTimeout(height, timestamp), + true, + }, + { + "elapsed: timeout with height and zero timestamp", + types.NewTimeout(height, 0), + true, + }, + { + "elapsed: timeout with timestamp and zero height", + types.NewTimeout(clienttypes.ZeroHeight(), timestamp), + true, + }, + { + "elapsed: height elapsed, timestamp did not", + types.NewTimeout(height, timestamp+1), + true, + }, + { + "elapsed: timestamp elapsed, height did not", + types.NewTimeout(height.Increment().(clienttypes.Height), timestamp), + true, + }, + { + "elapsed: timestamp elapsed when less than current timestamp", + types.NewTimeout(clienttypes.ZeroHeight(), timestamp-1), + true, + }, + { + "elapsed: height elapsed when less than current height", + types.NewTimeout(clienttypes.NewHeight(0, 1), 0), + true, + }, + { + "not elapsed: invalid timeout", + types.NewTimeout(clienttypes.ZeroHeight(), 0), + false, + }, + { + "not elapsed: neither height nor timeout elapsed", + types.NewTimeout(height.Increment().(clienttypes.Height), timestamp+1), + false, + }, + { + "not elapsed: timeout not reached with height and zero timestamp", + types.NewTimeout(height.Increment().(clienttypes.Height), 0), + false, + }, + { + "elapsed: timeout not reached with timestamp and zero height", + types.NewTimeout(clienttypes.ZeroHeight(), timestamp+1), + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + elapsed := tc.timeout.Elapsed(height, timestamp) + suite.Require().Equal(tc.expElapsed, elapsed) + }) + } +} + +func (suite *TypesTestSuite) TestErrTimeoutElapsed() { + // elapsed is expected to be true when either timeout height or timestamp + // is greater than or equal to 2 + var ( + height = clienttypes.NewHeight(0, 2) + timestamp = uint64(2) + ) + + testCases := []struct { + name string + timeout types.Timeout + expError error + }{ + { + "both timeout with height and timestamp", + types.NewTimeout(height, timestamp), + errorsmod.Wrapf(types.ErrTimeoutElapsed, "current height: %s, timeout height %s", height, height), + }, + { + "timeout with height and zero timestamp", + types.NewTimeout(height, 0), + errorsmod.Wrapf(types.ErrTimeoutElapsed, "current height: %s, timeout height %s", height, height), + }, + { + "timeout with timestamp and zero height", + types.NewTimeout(clienttypes.ZeroHeight(), timestamp), + errorsmod.Wrapf(types.ErrTimeoutElapsed, "current timestamp: %d, timeout timestamp %d", timestamp, timestamp), + }, + { + "height elapsed, timestamp did not", + types.NewTimeout(height, timestamp+1), + errorsmod.Wrapf(types.ErrTimeoutElapsed, "current height: %s, timeout height %s", height, height), + }, + { + "timestamp elapsed, height did not", + types.NewTimeout(height.Increment().(clienttypes.Height), timestamp), + errorsmod.Wrapf(types.ErrTimeoutElapsed, "current timestamp: %d, timeout timestamp %d", timestamp, timestamp), + }, + { + "height elapsed when less than current height", + types.NewTimeout(clienttypes.NewHeight(0, 1), 0), + errorsmod.Wrapf(types.ErrTimeoutElapsed, "current height: %s, timeout height %s", height, clienttypes.NewHeight(0, 1)), + }, + { + "timestamp elapsed when less than current timestamp", + types.NewTimeout(clienttypes.ZeroHeight(), timestamp-1), + errorsmod.Wrapf(types.ErrTimeoutElapsed, "current timestamp: %d, timeout timestamp %d", timestamp, timestamp-1), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + err := tc.timeout.ErrTimeoutElapsed(height, timestamp) + suite.Require().Equal(tc.expError.Error(), err.Error()) + }) + } +} + +func (suite *TypesTestSuite) TestErrTimeoutNotReached() { + // elapsed is expected to be true when either timeout height or timestamp + // is greater than or equal to 2 + var ( + height = clienttypes.NewHeight(0, 2) + timestamp = uint64(2) + ) + + testCases := []struct { + name string + timeout types.Timeout + expError error + }{ + { + "neither timeout reached with height and timestamp", + types.NewTimeout(height.Increment().(clienttypes.Height), timestamp+1), + errorsmod.Wrapf(types.ErrTimeoutNotReached, "current height: %s, timeout height %s", height, height.Increment().(clienttypes.Height)), + }, + { + "timeout not reached with height and zero timestamp", + types.NewTimeout(height.Increment().(clienttypes.Height), 0), + errorsmod.Wrapf(types.ErrTimeoutNotReached, "current height: %s, timeout height %s", height, height.Increment().(clienttypes.Height)), + }, + { + "timeout not reached with timestamp and zero height", + types.NewTimeout(clienttypes.ZeroHeight(), timestamp+1), + errorsmod.Wrapf(types.ErrTimeoutNotReached, "current timestamp: %d, timeout timestamp %d", timestamp, timestamp+1), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + err := tc.timeout.ErrTimeoutNotReached(height, timestamp) + suite.Require().Equal(tc.expError.Error(), err.Error()) + }) + } +} diff --git a/modules/core/04-channel/types/tx.pb.go b/modules/core/04-channel/types/tx.pb.go index bd9cd757eb6..20560a7872f 100644 --- a/modules/core/04-channel/types/tx.pb.go +++ b/modules/core/04-channel/types/tx.pb.go @@ -40,18 +40,22 @@ const ( NOOP ResponseResultType = 1 // The message was executed successfully SUCCESS ResponseResultType = 2 + // The message was executed unsuccessfully + FAILURE ResponseResultType = 3 ) var ResponseResultType_name = map[int32]string{ 0: "RESPONSE_RESULT_TYPE_UNSPECIFIED", 1: "RESPONSE_RESULT_TYPE_NOOP", 2: "RESPONSE_RESULT_TYPE_SUCCESS", + 3: "RESPONSE_RESULT_TYPE_FAILURE", } var ResponseResultType_value = map[string]int32{ "RESPONSE_RESULT_TYPE_UNSPECIFIED": 0, "RESPONSE_RESULT_TYPE_NOOP": 1, "RESPONSE_RESULT_TYPE_SUCCESS": 2, + "RESPONSE_RESULT_TYPE_FAILURE": 3, } func (x ResponseResultType) String() string { @@ -473,11 +477,12 @@ var xxx_messageInfo_MsgChannelCloseInitResponse proto.InternalMessageInfo // MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B // to acknowledge the change of channel state to CLOSED on Chain A. type MsgChannelCloseConfirm struct { - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` - ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` - ProofInit []byte `protobuf:"bytes,3,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty"` - ProofHeight types.Height `protobuf:"bytes,4,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` - Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty"` + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + ProofInit []byte `protobuf:"bytes,3,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty"` + ProofHeight types.Height `protobuf:"bytes,4,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` + Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty"` + CounterpartyUpgradeSequence uint64 `protobuf:"varint,6,opt,name=counterparty_upgrade_sequence,json=counterpartyUpgradeSequence,proto3" json:"counterparty_upgrade_sequence,omitempty"` } func (m *MsgChannelCloseConfirm) Reset() { *m = MsgChannelCloseConfirm{} } @@ -712,12 +717,13 @@ var xxx_messageInfo_MsgTimeoutResponse proto.InternalMessageInfo // MsgTimeoutOnClose timed-out packet upon counterparty channel closure. type MsgTimeoutOnClose struct { - Packet Packet `protobuf:"bytes,1,opt,name=packet,proto3" json:"packet"` - ProofUnreceived []byte `protobuf:"bytes,2,opt,name=proof_unreceived,json=proofUnreceived,proto3" json:"proof_unreceived,omitempty"` - ProofClose []byte `protobuf:"bytes,3,opt,name=proof_close,json=proofClose,proto3" json:"proof_close,omitempty"` - ProofHeight types.Height `protobuf:"bytes,4,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` - NextSequenceRecv uint64 `protobuf:"varint,5,opt,name=next_sequence_recv,json=nextSequenceRecv,proto3" json:"next_sequence_recv,omitempty"` - Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty"` + Packet Packet `protobuf:"bytes,1,opt,name=packet,proto3" json:"packet"` + ProofUnreceived []byte `protobuf:"bytes,2,opt,name=proof_unreceived,json=proofUnreceived,proto3" json:"proof_unreceived,omitempty"` + ProofClose []byte `protobuf:"bytes,3,opt,name=proof_close,json=proofClose,proto3" json:"proof_close,omitempty"` + ProofHeight types.Height `protobuf:"bytes,4,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` + NextSequenceRecv uint64 `protobuf:"varint,5,opt,name=next_sequence_recv,json=nextSequenceRecv,proto3" json:"next_sequence_recv,omitempty"` + Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty"` + CounterpartyUpgradeSequence uint64 `protobuf:"varint,7,opt,name=counterparty_upgrade_sequence,json=counterpartyUpgradeSequence,proto3" json:"counterparty_upgrade_sequence,omitempty"` } func (m *MsgTimeoutOnClose) Reset() { *m = MsgTimeoutOnClose{} } @@ -871,1829 +877,6798 @@ func (m *MsgAcknowledgementResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgAcknowledgementResponse proto.InternalMessageInfo -func init() { - proto.RegisterEnum("ibc.core.channel.v1.ResponseResultType", ResponseResultType_name, ResponseResultType_value) - proto.RegisterType((*MsgChannelOpenInit)(nil), "ibc.core.channel.v1.MsgChannelOpenInit") - proto.RegisterType((*MsgChannelOpenInitResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenInitResponse") - proto.RegisterType((*MsgChannelOpenTry)(nil), "ibc.core.channel.v1.MsgChannelOpenTry") - proto.RegisterType((*MsgChannelOpenTryResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenTryResponse") - proto.RegisterType((*MsgChannelOpenAck)(nil), "ibc.core.channel.v1.MsgChannelOpenAck") - proto.RegisterType((*MsgChannelOpenAckResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenAckResponse") - proto.RegisterType((*MsgChannelOpenConfirm)(nil), "ibc.core.channel.v1.MsgChannelOpenConfirm") - proto.RegisterType((*MsgChannelOpenConfirmResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenConfirmResponse") - proto.RegisterType((*MsgChannelCloseInit)(nil), "ibc.core.channel.v1.MsgChannelCloseInit") - proto.RegisterType((*MsgChannelCloseInitResponse)(nil), "ibc.core.channel.v1.MsgChannelCloseInitResponse") - proto.RegisterType((*MsgChannelCloseConfirm)(nil), "ibc.core.channel.v1.MsgChannelCloseConfirm") - proto.RegisterType((*MsgChannelCloseConfirmResponse)(nil), "ibc.core.channel.v1.MsgChannelCloseConfirmResponse") - proto.RegisterType((*MsgRecvPacket)(nil), "ibc.core.channel.v1.MsgRecvPacket") - proto.RegisterType((*MsgRecvPacketResponse)(nil), "ibc.core.channel.v1.MsgRecvPacketResponse") - proto.RegisterType((*MsgTimeout)(nil), "ibc.core.channel.v1.MsgTimeout") - proto.RegisterType((*MsgTimeoutResponse)(nil), "ibc.core.channel.v1.MsgTimeoutResponse") - proto.RegisterType((*MsgTimeoutOnClose)(nil), "ibc.core.channel.v1.MsgTimeoutOnClose") - proto.RegisterType((*MsgTimeoutOnCloseResponse)(nil), "ibc.core.channel.v1.MsgTimeoutOnCloseResponse") - proto.RegisterType((*MsgAcknowledgement)(nil), "ibc.core.channel.v1.MsgAcknowledgement") - proto.RegisterType((*MsgAcknowledgementResponse)(nil), "ibc.core.channel.v1.MsgAcknowledgementResponse") +// MsgChannelUpgradeInit defines the request type for the ChannelUpgradeInit rpc +type MsgChannelUpgradeInit struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + Fields UpgradeFields `protobuf:"bytes,3,opt,name=fields,proto3" json:"fields"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` } -func init() { proto.RegisterFile("ibc/core/channel/v1/tx.proto", fileDescriptor_bc4637e0ac3fc7b7) } - -var fileDescriptor_bc4637e0ac3fc7b7 = []byte{ - // 1191 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xbf, 0x6f, 0xdb, 0x46, - 0x14, 0x16, 0x65, 0x59, 0xb2, 0x9f, 0xdc, 0x48, 0xa1, 0x93, 0x58, 0xa1, 0x6d, 0x49, 0xf5, 0x10, - 0xbb, 0x6e, 0x2d, 0xc5, 0x4a, 0x5b, 0x34, 0x41, 0x81, 0xc2, 0x56, 0x55, 0xd4, 0x40, 0xfd, 0x03, - 0x94, 0x5c, 0xa0, 0x49, 0x51, 0xc1, 0xa2, 0x2e, 0x34, 0x21, 0x89, 0xa7, 0x92, 0x94, 0x12, 0x6d, - 0x45, 0x27, 0xc3, 0x43, 0xd1, 0xa1, 0xab, 0x81, 0x02, 0x9d, 0xba, 0x65, 0xca, 0xde, 0x2d, 0x63, - 0xc6, 0xa2, 0x40, 0x83, 0xc2, 0x1e, 0xf2, 0x6f, 0x14, 0xbc, 0x3b, 0x52, 0x14, 0x45, 0x4a, 0x4c, - 0xac, 0x78, 0x23, 0xdf, 0xfb, 0xee, 0xfd, 0xf8, 0xbe, 0xe3, 0xe3, 0x91, 0xb0, 0xa4, 0xd4, 0xa4, - 0xbc, 0x84, 0x35, 0x94, 0x97, 0x8e, 0x8f, 0x54, 0x15, 0x35, 0xf3, 0xdd, 0xcd, 0xbc, 0xf1, 0x34, - 0xd7, 0xd6, 0xb0, 0x81, 0xf9, 0x79, 0xa5, 0x26, 0xe5, 0x4c, 0x6f, 0x8e, 0x79, 0x73, 0xdd, 0x4d, - 0xe1, 0x86, 0x8c, 0x65, 0x4c, 0xfc, 0x79, 0xf3, 0x8a, 0x42, 0x85, 0x4c, 0x3f, 0x50, 0x53, 0x41, - 0xaa, 0x61, 0xc6, 0xa1, 0x57, 0x0c, 0xf0, 0xbe, 0x57, 0x26, 0x2b, 0x2c, 0x85, 0x2c, 0x48, 0x58, - 0x6f, 0x61, 0x3d, 0xdf, 0xd2, 0x65, 0xd3, 0xd9, 0xd2, 0x65, 0xea, 0x58, 0xf9, 0x8d, 0x03, 0x7e, - 0x57, 0x97, 0x8b, 0x14, 0xbd, 0xdf, 0x46, 0xea, 0x8e, 0xaa, 0x18, 0xfc, 0x02, 0xc4, 0xda, 0x58, - 0x33, 0xaa, 0x4a, 0x3d, 0xc5, 0x65, 0xb9, 0xb5, 0x59, 0x31, 0x6a, 0xde, 0xee, 0xd4, 0xf9, 0xcf, - 0x21, 0xc6, 0x22, 0xa7, 0xc2, 0x59, 0x6e, 0x2d, 0x5e, 0x58, 0xca, 0x79, 0x74, 0x92, 0x63, 0xf1, - 0xb6, 0x23, 0x2f, 0x5e, 0x65, 0x42, 0xa2, 0xb5, 0x84, 0xbf, 0x05, 0x51, 0x5d, 0x91, 0x55, 0xa4, - 0xa5, 0xa6, 0x68, 0x54, 0x7a, 0xf7, 0x20, 0x71, 0xf2, 0x7b, 0x26, 0xf4, 0xf3, 0xeb, 0x67, 0xeb, - 0xcc, 0xb0, 0xf2, 0x08, 0x84, 0xe1, 0xaa, 0x44, 0xa4, 0xb7, 0xb1, 0xaa, 0x23, 0x7e, 0x19, 0x80, - 0x45, 0xec, 0x17, 0x38, 0xcb, 0x2c, 0x3b, 0x75, 0x3e, 0x05, 0xb1, 0x2e, 0xd2, 0x74, 0x05, 0xab, - 0xa4, 0xc6, 0x59, 0xd1, 0xba, 0x7d, 0x10, 0x31, 0xf3, 0xac, 0xbc, 0x0a, 0xc3, 0xf5, 0xc1, 0xe8, - 0x15, 0xad, 0xe7, 0xdf, 0x72, 0x01, 0xe6, 0xdb, 0x1a, 0xea, 0x2a, 0xb8, 0xa3, 0x57, 0x1d, 0x69, - 0x49, 0xe8, 0xed, 0x70, 0x8a, 0x13, 0xaf, 0x5b, 0xee, 0xa2, 0x5d, 0x82, 0x83, 0xa6, 0xa9, 0x37, - 0xa7, 0x69, 0x13, 0x6e, 0x48, 0xb8, 0xa3, 0x1a, 0x48, 0x6b, 0x1f, 0x69, 0x46, 0xaf, 0x6a, 0x75, - 0x13, 0x21, 0x75, 0xcd, 0x3b, 0x7d, 0xdf, 0x52, 0x97, 0x49, 0x49, 0x5b, 0xc3, 0xf8, 0x71, 0x55, - 0x51, 0x15, 0x23, 0x35, 0x9d, 0xe5, 0xd6, 0xe6, 0xc4, 0x59, 0x62, 0x21, 0x7a, 0x16, 0x61, 0x8e, - 0xba, 0x8f, 0x91, 0x22, 0x1f, 0x1b, 0xa9, 0x28, 0x29, 0x4a, 0x70, 0x14, 0x45, 0x37, 0x54, 0x77, - 0x33, 0xf7, 0x35, 0x41, 0xb0, 0x92, 0xe2, 0x64, 0x15, 0x35, 0x39, 0xd4, 0x8b, 0x8d, 0x56, 0xef, - 0x21, 0xdc, 0x1e, 0xe2, 0xd7, 0x16, 0xcf, 0xa1, 0x0e, 0x37, 0xa0, 0x8e, 0x4b, 0xd6, 0xb0, 0x4b, - 0x56, 0x26, 0xde, 0x5f, 0x43, 0xe2, 0x6d, 0x49, 0x0d, 0x7f, 0xf1, 0x46, 0xc7, 0xe4, 0x3f, 0x85, - 0x85, 0x01, 0xa6, 0x1d, 0x58, 0xba, 0x43, 0x6f, 0x3a, 0xdd, 0x7d, 0x7d, 0xdf, 0x42, 0xa1, 0x45, - 0xa0, 0x7a, 0x54, 0x0d, 0xad, 0xc7, 0x04, 0x9a, 0x21, 0x06, 0x73, 0xf3, 0x5d, 0xad, 0x3e, 0x8b, - 0x6e, 0x7d, 0xb6, 0xa4, 0x86, 0xa5, 0xcf, 0xca, 0x3f, 0x1c, 0xdc, 0x1c, 0xf4, 0x16, 0xb1, 0xfa, - 0x58, 0xd1, 0x5a, 0x6f, 0x4d, 0xb2, 0xdd, 0xf9, 0x91, 0xd4, 0x20, 0xb4, 0x5a, 0x9d, 0x9b, 0xca, - 0xb9, 0x3b, 0x8f, 0x5c, 0xae, 0xf3, 0xe9, 0xd1, 0x9d, 0x67, 0x60, 0xd9, 0xb3, 0x37, 0xbb, 0xfb, - 0x2e, 0xcc, 0xf7, 0x01, 0xc5, 0x26, 0xd6, 0xd1, 0xe8, 0x79, 0x38, 0xa6, 0xf5, 0xc0, 0x03, 0x6f, - 0x19, 0x16, 0x3d, 0xf2, 0xda, 0x65, 0xfd, 0xcb, 0xc1, 0x2d, 0x97, 0xff, 0xb2, 0xaa, 0x0c, 0x4e, - 0x8c, 0xa9, 0x71, 0x13, 0xe3, 0xdd, 0xea, 0x92, 0x85, 0xb4, 0x77, 0x7b, 0x36, 0x03, 0x17, 0x1c, - 0xbc, 0xb7, 0xab, 0xcb, 0x22, 0x92, 0xba, 0x07, 0x47, 0x52, 0x03, 0x19, 0xfc, 0x7d, 0x88, 0xb6, - 0xc9, 0x15, 0xe9, 0x3b, 0x5e, 0x58, 0xf4, 0x1c, 0xb1, 0x14, 0xcc, 0x8a, 0x63, 0x0b, 0xf8, 0x0f, - 0x20, 0x49, 0x9b, 0x93, 0x70, 0xab, 0xa5, 0x18, 0x2d, 0xa4, 0x1a, 0x84, 0xa0, 0x39, 0x31, 0x41, - 0xec, 0x45, 0xdb, 0x3c, 0xc4, 0xc3, 0xd4, 0xe5, 0x78, 0x88, 0x8c, 0xe6, 0xe1, 0x07, 0xf2, 0xec, - 0xf5, 0x9b, 0xb4, 0xa7, 0xe6, 0x17, 0x10, 0xd5, 0x90, 0xde, 0x69, 0xd2, 0x66, 0xaf, 0x15, 0x56, - 0x3d, 0x9b, 0xb5, 0xe0, 0x22, 0x81, 0x56, 0x7a, 0x6d, 0x24, 0xb2, 0x65, 0x6c, 0x7a, 0xfe, 0x12, - 0x06, 0xd8, 0xd5, 0xe5, 0x8a, 0xd2, 0x42, 0xb8, 0x33, 0x19, 0x0a, 0x3b, 0xaa, 0x86, 0x24, 0xa4, - 0x74, 0x51, 0x7d, 0x80, 0xc2, 0x43, 0xdb, 0x3c, 0x19, 0x0a, 0x3f, 0x02, 0x5e, 0x45, 0x4f, 0x8d, - 0xaa, 0x8e, 0x7e, 0xec, 0x20, 0x55, 0x42, 0x55, 0x0d, 0x49, 0x5d, 0x42, 0x67, 0x44, 0x4c, 0x9a, - 0x9e, 0x32, 0x73, 0x98, 0xe4, 0x05, 0xdf, 0x78, 0x8f, 0xc8, 0xf1, 0x87, 0xf1, 0x31, 0x69, 0xb6, - 0x9f, 0xd3, 0x77, 0x15, 0x8b, 0xbe, 0xaf, 0x92, 0x8d, 0x7d, 0x45, 0xa4, 0x67, 0x20, 0xce, 0xb6, - 0xb8, 0x99, 0x94, 0x3d, 0xdf, 0xf4, 0x89, 0xa7, 0x65, 0x4c, 0xe4, 0x01, 0xf7, 0x56, 0x65, 0x7a, - 0xac, 0x2a, 0xd1, 0xd1, 0xaa, 0xd4, 0xc8, 0x0b, 0x6a, 0x90, 0xb7, 0x49, 0x8b, 0x73, 0x12, 0x26, - 0xd2, 0x6f, 0x49, 0x0d, 0x15, 0x3f, 0x69, 0xa2, 0xba, 0x8c, 0xc8, 0xf3, 0x7e, 0x09, 0x75, 0xd6, - 0x20, 0x71, 0x34, 0x18, 0xcd, 0x12, 0xc7, 0x65, 0xee, 0x8b, 0x63, 0x2e, 0xac, 0x0f, 0x88, 0xb3, - 0x65, 0x5a, 0xae, 0x78, 0xfa, 0x4a, 0xe4, 0xb4, 0xed, 0x62, 0x62, 0xc2, 0x7c, 0xaf, 0xff, 0xc9, - 0x01, 0x3f, 0x0c, 0xe2, 0x3f, 0x81, 0xac, 0x58, 0x2a, 0x1f, 0xec, 0xef, 0x95, 0x4b, 0x55, 0xb1, - 0x54, 0x3e, 0xfc, 0xa6, 0x52, 0xad, 0x7c, 0x77, 0x50, 0xaa, 0x1e, 0xee, 0x95, 0x0f, 0x4a, 0xc5, - 0x9d, 0xaf, 0x76, 0x4a, 0x5f, 0x26, 0x43, 0x42, 0xe2, 0xf4, 0x2c, 0x1b, 0x77, 0x98, 0xf8, 0x55, - 0xb8, 0xed, 0xb9, 0x6c, 0x6f, 0x7f, 0xff, 0x20, 0xc9, 0x09, 0x33, 0xa7, 0x67, 0xd9, 0x88, 0x79, - 0xcd, 0x6f, 0xc0, 0x92, 0x27, 0xb0, 0x7c, 0x58, 0x2c, 0x96, 0xca, 0xe5, 0x64, 0x58, 0x88, 0x9f, - 0x9e, 0x65, 0x63, 0xec, 0x56, 0x88, 0x9c, 0xfc, 0x91, 0x0e, 0x15, 0x9e, 0xcf, 0xc0, 0xd4, 0xae, - 0x2e, 0xf3, 0x0d, 0x48, 0xb8, 0xbf, 0x8c, 0xbc, 0xbb, 0x1f, 0xfe, 0x58, 0x11, 0xf2, 0x01, 0x81, - 0x36, 0xcf, 0xc7, 0x70, 0xcd, 0xf5, 0x49, 0x72, 0x27, 0x40, 0x88, 0x8a, 0xd6, 0x13, 0x72, 0xc1, - 0x70, 0x3e, 0x99, 0xcc, 0x53, 0x58, 0x90, 0x4c, 0x5b, 0x52, 0x23, 0x50, 0x26, 0xc7, 0x61, 0x92, - 0x37, 0x80, 0xf7, 0x38, 0x48, 0xae, 0x07, 0x88, 0xc2, 0xb0, 0x42, 0x21, 0x38, 0xd6, 0xce, 0xaa, - 0x42, 0x72, 0xe8, 0x04, 0xb7, 0x36, 0x26, 0x8e, 0x8d, 0x14, 0xee, 0x06, 0x45, 0xda, 0xf9, 0x9e, - 0xc0, 0xbc, 0xd7, 0xc9, 0xec, 0xc3, 0x20, 0x81, 0xac, 0x3e, 0xef, 0xbd, 0x01, 0xd8, 0x4e, 0xfc, - 0x3d, 0x80, 0xe3, 0x40, 0xb4, 0xe2, 0x17, 0xa2, 0x8f, 0x11, 0xd6, 0xc7, 0x63, 0xec, 0xe8, 0x65, - 0x88, 0x59, 0x07, 0x85, 0x8c, 0xdf, 0x32, 0x06, 0x10, 0x56, 0xc7, 0x00, 0x9c, 0x7b, 0xcf, 0xf5, - 0x3e, 0xbc, 0x33, 0x66, 0x29, 0xc3, 0xf9, 0xef, 0x3d, 0x9f, 0xf7, 0x44, 0x03, 0x12, 0xee, 0xe1, - 0xee, 0x5b, 0xa5, 0x0b, 0xe8, 0xff, 0xf0, 0xfa, 0x0c, 0x49, 0x61, 0xfa, 0xa7, 0xd7, 0xcf, 0xd6, - 0xb9, 0xed, 0xf2, 0x8b, 0xf3, 0x34, 0xf7, 0xf2, 0x3c, 0xcd, 0xfd, 0x77, 0x9e, 0xe6, 0x7e, 0xbd, - 0x48, 0x87, 0x5e, 0x5e, 0xa4, 0x43, 0x7f, 0x5f, 0xa4, 0x43, 0x0f, 0xef, 0xcb, 0x8a, 0x71, 0xdc, - 0xa9, 0xe5, 0x24, 0xdc, 0xca, 0xb3, 0x9f, 0x31, 0x4a, 0x4d, 0xda, 0x90, 0x71, 0xbe, 0xfb, 0x59, - 0xbe, 0x85, 0xeb, 0x9d, 0x26, 0xd2, 0xe9, 0x4f, 0x9c, 0xbb, 0x1f, 0x6f, 0x58, 0xff, 0x71, 0x8c, - 0x5e, 0x1b, 0xe9, 0xb5, 0x28, 0xf9, 0x55, 0x73, 0xef, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8d, - 0xa0, 0x17, 0x65, 0x52, 0x12, 0x00, 0x00, +func (m *MsgChannelUpgradeInit) Reset() { *m = MsgChannelUpgradeInit{} } +func (m *MsgChannelUpgradeInit) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeInit) ProtoMessage() {} +func (*MsgChannelUpgradeInit) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{20} +} +func (m *MsgChannelUpgradeInit) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeInit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeInit.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 *MsgChannelUpgradeInit) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeInit.Merge(m, src) +} +func (m *MsgChannelUpgradeInit) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeInit) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeInit.DiscardUnknown(m) } -// 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 +var xxx_messageInfo_MsgChannelUpgradeInit proto.InternalMessageInfo -// 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 { - // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. - ChannelOpenInit(ctx context.Context, in *MsgChannelOpenInit, opts ...grpc.CallOption) (*MsgChannelOpenInitResponse, error) - // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. - ChannelOpenTry(ctx context.Context, in *MsgChannelOpenTry, opts ...grpc.CallOption) (*MsgChannelOpenTryResponse, error) - // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. - ChannelOpenAck(ctx context.Context, in *MsgChannelOpenAck, opts ...grpc.CallOption) (*MsgChannelOpenAckResponse, error) - // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. - ChannelOpenConfirm(ctx context.Context, in *MsgChannelOpenConfirm, opts ...grpc.CallOption) (*MsgChannelOpenConfirmResponse, error) - // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. - ChannelCloseInit(ctx context.Context, in *MsgChannelCloseInit, opts ...grpc.CallOption) (*MsgChannelCloseInitResponse, error) - // ChannelCloseConfirm defines a rpc handler method for - // MsgChannelCloseConfirm. - ChannelCloseConfirm(ctx context.Context, in *MsgChannelCloseConfirm, opts ...grpc.CallOption) (*MsgChannelCloseConfirmResponse, error) - // RecvPacket defines a rpc handler method for MsgRecvPacket. - RecvPacket(ctx context.Context, in *MsgRecvPacket, opts ...grpc.CallOption) (*MsgRecvPacketResponse, error) - // Timeout defines a rpc handler method for MsgTimeout. - Timeout(ctx context.Context, in *MsgTimeout, opts ...grpc.CallOption) (*MsgTimeoutResponse, error) - // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. - TimeoutOnClose(ctx context.Context, in *MsgTimeoutOnClose, opts ...grpc.CallOption) (*MsgTimeoutOnCloseResponse, error) - // Acknowledgement defines a rpc handler method for MsgAcknowledgement. - Acknowledgement(ctx context.Context, in *MsgAcknowledgement, opts ...grpc.CallOption) (*MsgAcknowledgementResponse, error) +// MsgChannelUpgradeInitResponse defines the MsgChannelUpgradeInit response type +type MsgChannelUpgradeInitResponse struct { + Upgrade Upgrade `protobuf:"bytes,1,opt,name=upgrade,proto3" json:"upgrade"` + UpgradeSequence uint64 `protobuf:"varint,2,opt,name=upgrade_sequence,json=upgradeSequence,proto3" json:"upgrade_sequence,omitempty"` } -type msgClient struct { - cc grpc1.ClientConn +func (m *MsgChannelUpgradeInitResponse) Reset() { *m = MsgChannelUpgradeInitResponse{} } +func (m *MsgChannelUpgradeInitResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeInitResponse) ProtoMessage() {} +func (*MsgChannelUpgradeInitResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{21} } - -func NewMsgClient(cc grpc1.ClientConn) MsgClient { - return &msgClient{cc} +func (m *MsgChannelUpgradeInitResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } - -func (c *msgClient) ChannelOpenInit(ctx context.Context, in *MsgChannelOpenInit, opts ...grpc.CallOption) (*MsgChannelOpenInitResponse, error) { - out := new(MsgChannelOpenInitResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelOpenInit", in, out, opts...) - if err != nil { - return nil, err +func (m *MsgChannelUpgradeInitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeInitResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return out, nil } - -func (c *msgClient) ChannelOpenTry(ctx context.Context, in *MsgChannelOpenTry, opts ...grpc.CallOption) (*MsgChannelOpenTryResponse, error) { - out := new(MsgChannelOpenTryResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelOpenTry", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +func (m *MsgChannelUpgradeInitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeInitResponse.Merge(m, src) } - -func (c *msgClient) ChannelOpenAck(ctx context.Context, in *MsgChannelOpenAck, opts ...grpc.CallOption) (*MsgChannelOpenAckResponse, error) { - out := new(MsgChannelOpenAckResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelOpenAck", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +func (m *MsgChannelUpgradeInitResponse) XXX_Size() int { + return m.Size() } - -func (c *msgClient) ChannelOpenConfirm(ctx context.Context, in *MsgChannelOpenConfirm, opts ...grpc.CallOption) (*MsgChannelOpenConfirmResponse, error) { - out := new(MsgChannelOpenConfirmResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelOpenConfirm", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +func (m *MsgChannelUpgradeInitResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeInitResponse.DiscardUnknown(m) } -func (c *msgClient) ChannelCloseInit(ctx context.Context, in *MsgChannelCloseInit, opts ...grpc.CallOption) (*MsgChannelCloseInitResponse, error) { - out := new(MsgChannelCloseInitResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelCloseInit", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} +var xxx_messageInfo_MsgChannelUpgradeInitResponse proto.InternalMessageInfo -func (c *msgClient) ChannelCloseConfirm(ctx context.Context, in *MsgChannelCloseConfirm, opts ...grpc.CallOption) (*MsgChannelCloseConfirmResponse, error) { - out := new(MsgChannelCloseConfirmResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelCloseConfirm", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +// MsgChannelUpgradeTry defines the request type for the ChannelUpgradeTry rpc +type MsgChannelUpgradeTry struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + ProposedUpgradeConnectionHops []string `protobuf:"bytes,3,rep,name=proposed_upgrade_connection_hops,json=proposedUpgradeConnectionHops,proto3" json:"proposed_upgrade_connection_hops,omitempty"` + CounterpartyUpgradeFields UpgradeFields `protobuf:"bytes,4,opt,name=counterparty_upgrade_fields,json=counterpartyUpgradeFields,proto3" json:"counterparty_upgrade_fields"` + CounterpartyUpgradeSequence uint64 `protobuf:"varint,5,opt,name=counterparty_upgrade_sequence,json=counterpartyUpgradeSequence,proto3" json:"counterparty_upgrade_sequence,omitempty"` + ProofChannel []byte `protobuf:"bytes,6,opt,name=proof_channel,json=proofChannel,proto3" json:"proof_channel,omitempty"` + ProofUpgrade []byte `protobuf:"bytes,7,opt,name=proof_upgrade,json=proofUpgrade,proto3" json:"proof_upgrade,omitempty"` + ProofHeight types.Height `protobuf:"bytes,8,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` + Signer string `protobuf:"bytes,9,opt,name=signer,proto3" json:"signer,omitempty"` } -func (c *msgClient) RecvPacket(ctx context.Context, in *MsgRecvPacket, opts ...grpc.CallOption) (*MsgRecvPacketResponse, error) { - out := new(MsgRecvPacketResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/RecvPacket", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +func (m *MsgChannelUpgradeTry) Reset() { *m = MsgChannelUpgradeTry{} } +func (m *MsgChannelUpgradeTry) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeTry) ProtoMessage() {} +func (*MsgChannelUpgradeTry) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{22} } - -func (c *msgClient) Timeout(ctx context.Context, in *MsgTimeout, opts ...grpc.CallOption) (*MsgTimeoutResponse, error) { - out := new(MsgTimeoutResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/Timeout", in, out, opts...) - if err != nil { - return nil, err +func (m *MsgChannelUpgradeTry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeTry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeTry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return out, nil +} +func (m *MsgChannelUpgradeTry) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeTry.Merge(m, src) +} +func (m *MsgChannelUpgradeTry) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeTry) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeTry.DiscardUnknown(m) } -func (c *msgClient) TimeoutOnClose(ctx context.Context, in *MsgTimeoutOnClose, opts ...grpc.CallOption) (*MsgTimeoutOnCloseResponse, error) { - out := new(MsgTimeoutOnCloseResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/TimeoutOnClose", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +var xxx_messageInfo_MsgChannelUpgradeTry proto.InternalMessageInfo + +// MsgChannelUpgradeTryResponse defines the MsgChannelUpgradeTry response type +type MsgChannelUpgradeTryResponse struct { + Upgrade Upgrade `protobuf:"bytes,1,opt,name=upgrade,proto3" json:"upgrade"` + UpgradeSequence uint64 `protobuf:"varint,2,opt,name=upgrade_sequence,json=upgradeSequence,proto3" json:"upgrade_sequence,omitempty"` + Result ResponseResultType `protobuf:"varint,3,opt,name=result,proto3,enum=ibc.core.channel.v1.ResponseResultType" json:"result,omitempty"` } -func (c *msgClient) Acknowledgement(ctx context.Context, in *MsgAcknowledgement, opts ...grpc.CallOption) (*MsgAcknowledgementResponse, error) { - out := new(MsgAcknowledgementResponse) - err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/Acknowledgement", in, out, opts...) - if err != nil { - return nil, err +func (m *MsgChannelUpgradeTryResponse) Reset() { *m = MsgChannelUpgradeTryResponse{} } +func (m *MsgChannelUpgradeTryResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeTryResponse) ProtoMessage() {} +func (*MsgChannelUpgradeTryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{23} +} +func (m *MsgChannelUpgradeTryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeTryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeTryResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return out, nil } - -// MsgServer is the server API for Msg service. -type MsgServer interface { - // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. - ChannelOpenInit(context.Context, *MsgChannelOpenInit) (*MsgChannelOpenInitResponse, error) - // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. - ChannelOpenTry(context.Context, *MsgChannelOpenTry) (*MsgChannelOpenTryResponse, error) - // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. - ChannelOpenAck(context.Context, *MsgChannelOpenAck) (*MsgChannelOpenAckResponse, error) - // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. - ChannelOpenConfirm(context.Context, *MsgChannelOpenConfirm) (*MsgChannelOpenConfirmResponse, error) - // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. - ChannelCloseInit(context.Context, *MsgChannelCloseInit) (*MsgChannelCloseInitResponse, error) - // ChannelCloseConfirm defines a rpc handler method for - // MsgChannelCloseConfirm. - ChannelCloseConfirm(context.Context, *MsgChannelCloseConfirm) (*MsgChannelCloseConfirmResponse, error) - // RecvPacket defines a rpc handler method for MsgRecvPacket. - RecvPacket(context.Context, *MsgRecvPacket) (*MsgRecvPacketResponse, error) - // Timeout defines a rpc handler method for MsgTimeout. - Timeout(context.Context, *MsgTimeout) (*MsgTimeoutResponse, error) - // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. - TimeoutOnClose(context.Context, *MsgTimeoutOnClose) (*MsgTimeoutOnCloseResponse, error) - // Acknowledgement defines a rpc handler method for MsgAcknowledgement. - Acknowledgement(context.Context, *MsgAcknowledgement) (*MsgAcknowledgementResponse, error) +func (m *MsgChannelUpgradeTryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeTryResponse.Merge(m, src) +} +func (m *MsgChannelUpgradeTryResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeTryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeTryResponse.DiscardUnknown(m) } -// UnimplementedMsgServer can be embedded to have forward compatible implementations. -type UnimplementedMsgServer struct { +var xxx_messageInfo_MsgChannelUpgradeTryResponse proto.InternalMessageInfo + +// MsgChannelUpgradeAck defines the request type for the ChannelUpgradeAck rpc +type MsgChannelUpgradeAck struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + CounterpartyUpgrade Upgrade `protobuf:"bytes,3,opt,name=counterparty_upgrade,json=counterpartyUpgrade,proto3" json:"counterparty_upgrade"` + ProofChannel []byte `protobuf:"bytes,4,opt,name=proof_channel,json=proofChannel,proto3" json:"proof_channel,omitempty"` + ProofUpgrade []byte `protobuf:"bytes,5,opt,name=proof_upgrade,json=proofUpgrade,proto3" json:"proof_upgrade,omitempty"` + ProofHeight types.Height `protobuf:"bytes,6,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` + Signer string `protobuf:"bytes,7,opt,name=signer,proto3" json:"signer,omitempty"` } -func (*UnimplementedMsgServer) ChannelOpenInit(ctx context.Context, req *MsgChannelOpenInit) (*MsgChannelOpenInitResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ChannelOpenInit not implemented") +func (m *MsgChannelUpgradeAck) Reset() { *m = MsgChannelUpgradeAck{} } +func (m *MsgChannelUpgradeAck) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeAck) ProtoMessage() {} +func (*MsgChannelUpgradeAck) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{24} } -func (*UnimplementedMsgServer) ChannelOpenTry(ctx context.Context, req *MsgChannelOpenTry) (*MsgChannelOpenTryResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ChannelOpenTry not implemented") +func (m *MsgChannelUpgradeAck) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } -func (*UnimplementedMsgServer) ChannelOpenAck(ctx context.Context, req *MsgChannelOpenAck) (*MsgChannelOpenAckResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ChannelOpenAck not implemented") +func (m *MsgChannelUpgradeAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeAck.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 (*UnimplementedMsgServer) ChannelOpenConfirm(ctx context.Context, req *MsgChannelOpenConfirm) (*MsgChannelOpenConfirmResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ChannelOpenConfirm not implemented") +func (m *MsgChannelUpgradeAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeAck.Merge(m, src) } -func (*UnimplementedMsgServer) ChannelCloseInit(ctx context.Context, req *MsgChannelCloseInit) (*MsgChannelCloseInitResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ChannelCloseInit not implemented") +func (m *MsgChannelUpgradeAck) XXX_Size() int { + return m.Size() } -func (*UnimplementedMsgServer) ChannelCloseConfirm(ctx context.Context, req *MsgChannelCloseConfirm) (*MsgChannelCloseConfirmResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ChannelCloseConfirm not implemented") +func (m *MsgChannelUpgradeAck) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeAck.DiscardUnknown(m) } -func (*UnimplementedMsgServer) RecvPacket(ctx context.Context, req *MsgRecvPacket) (*MsgRecvPacketResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RecvPacket not implemented") + +var xxx_messageInfo_MsgChannelUpgradeAck proto.InternalMessageInfo + +// MsgChannelUpgradeAckResponse defines MsgChannelUpgradeAck response type +type MsgChannelUpgradeAckResponse struct { + Result ResponseResultType `protobuf:"varint,1,opt,name=result,proto3,enum=ibc.core.channel.v1.ResponseResultType" json:"result,omitempty"` } -func (*UnimplementedMsgServer) Timeout(ctx context.Context, req *MsgTimeout) (*MsgTimeoutResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Timeout not implemented") + +func (m *MsgChannelUpgradeAckResponse) Reset() { *m = MsgChannelUpgradeAckResponse{} } +func (m *MsgChannelUpgradeAckResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeAckResponse) ProtoMessage() {} +func (*MsgChannelUpgradeAckResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{25} } -func (*UnimplementedMsgServer) TimeoutOnClose(ctx context.Context, req *MsgTimeoutOnClose) (*MsgTimeoutOnCloseResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method TimeoutOnClose not implemented") +func (m *MsgChannelUpgradeAckResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } -func (*UnimplementedMsgServer) Acknowledgement(ctx context.Context, req *MsgAcknowledgement) (*MsgAcknowledgementResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Acknowledgement not implemented") +func (m *MsgChannelUpgradeAckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeAckResponse.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 RegisterMsgServer(s grpc1.Server, srv MsgServer) { - s.RegisterService(&_Msg_serviceDesc, srv) +func (m *MsgChannelUpgradeAckResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeAckResponse.Merge(m, src) +} +func (m *MsgChannelUpgradeAckResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeAckResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeAckResponse.DiscardUnknown(m) } -func _Msg_ChannelOpenInit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgChannelOpenInit) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).ChannelOpenInit(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/ChannelOpenInit", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ChannelOpenInit(ctx, req.(*MsgChannelOpenInit)) - } - return interceptor(ctx, in, info, handler) +var xxx_messageInfo_MsgChannelUpgradeAckResponse proto.InternalMessageInfo + +// MsgChannelUpgradeConfirm defines the request type for the ChannelUpgradeConfirm rpc +type MsgChannelUpgradeConfirm struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + CounterpartyChannelState State `protobuf:"varint,3,opt,name=counterparty_channel_state,json=counterpartyChannelState,proto3,enum=ibc.core.channel.v1.State" json:"counterparty_channel_state,omitempty"` + CounterpartyUpgrade Upgrade `protobuf:"bytes,4,opt,name=counterparty_upgrade,json=counterpartyUpgrade,proto3" json:"counterparty_upgrade"` + ProofChannel []byte `protobuf:"bytes,5,opt,name=proof_channel,json=proofChannel,proto3" json:"proof_channel,omitempty"` + ProofUpgrade []byte `protobuf:"bytes,6,opt,name=proof_upgrade,json=proofUpgrade,proto3" json:"proof_upgrade,omitempty"` + ProofHeight types.Height `protobuf:"bytes,7,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` + Signer string `protobuf:"bytes,8,opt,name=signer,proto3" json:"signer,omitempty"` } -func _Msg_ChannelOpenTry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgChannelOpenTry) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).ChannelOpenTry(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/ChannelOpenTry", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ChannelOpenTry(ctx, req.(*MsgChannelOpenTry)) +func (m *MsgChannelUpgradeConfirm) Reset() { *m = MsgChannelUpgradeConfirm{} } +func (m *MsgChannelUpgradeConfirm) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeConfirm) ProtoMessage() {} +func (*MsgChannelUpgradeConfirm) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{26} +} +func (m *MsgChannelUpgradeConfirm) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeConfirm) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeConfirm.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return interceptor(ctx, in, info, handler) +} +func (m *MsgChannelUpgradeConfirm) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeConfirm.Merge(m, src) +} +func (m *MsgChannelUpgradeConfirm) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeConfirm) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeConfirm.DiscardUnknown(m) } -func _Msg_ChannelOpenAck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgChannelOpenAck) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).ChannelOpenAck(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/ChannelOpenAck", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ChannelOpenAck(ctx, req.(*MsgChannelOpenAck)) - } - return interceptor(ctx, in, info, handler) +var xxx_messageInfo_MsgChannelUpgradeConfirm proto.InternalMessageInfo + +// MsgChannelUpgradeConfirmResponse defines MsgChannelUpgradeConfirm response type +type MsgChannelUpgradeConfirmResponse struct { + Result ResponseResultType `protobuf:"varint,1,opt,name=result,proto3,enum=ibc.core.channel.v1.ResponseResultType" json:"result,omitempty"` } -func _Msg_ChannelOpenConfirm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgChannelOpenConfirm) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).ChannelOpenConfirm(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/ChannelOpenConfirm", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ChannelOpenConfirm(ctx, req.(*MsgChannelOpenConfirm)) +func (m *MsgChannelUpgradeConfirmResponse) Reset() { *m = MsgChannelUpgradeConfirmResponse{} } +func (m *MsgChannelUpgradeConfirmResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeConfirmResponse) ProtoMessage() {} +func (*MsgChannelUpgradeConfirmResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{27} +} +func (m *MsgChannelUpgradeConfirmResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeConfirmResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeConfirmResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return interceptor(ctx, in, info, handler) +} +func (m *MsgChannelUpgradeConfirmResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeConfirmResponse.Merge(m, src) +} +func (m *MsgChannelUpgradeConfirmResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeConfirmResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeConfirmResponse.DiscardUnknown(m) } -func _Msg_ChannelCloseInit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgChannelCloseInit) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).ChannelCloseInit(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/ChannelCloseInit", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ChannelCloseInit(ctx, req.(*MsgChannelCloseInit)) - } - return interceptor(ctx, in, info, handler) +var xxx_messageInfo_MsgChannelUpgradeConfirmResponse proto.InternalMessageInfo + +// MsgChannelUpgradeOpen defines the request type for the ChannelUpgradeOpen rpc +type MsgChannelUpgradeOpen struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + CounterpartyChannelState State `protobuf:"varint,3,opt,name=counterparty_channel_state,json=counterpartyChannelState,proto3,enum=ibc.core.channel.v1.State" json:"counterparty_channel_state,omitempty"` + ProofChannel []byte `protobuf:"bytes,4,opt,name=proof_channel,json=proofChannel,proto3" json:"proof_channel,omitempty"` + ProofHeight types.Height `protobuf:"bytes,5,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` + Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty"` } -func _Msg_ChannelCloseConfirm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgChannelCloseConfirm) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).ChannelCloseConfirm(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/ChannelCloseConfirm", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).ChannelCloseConfirm(ctx, req.(*MsgChannelCloseConfirm)) +func (m *MsgChannelUpgradeOpen) Reset() { *m = MsgChannelUpgradeOpen{} } +func (m *MsgChannelUpgradeOpen) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeOpen) ProtoMessage() {} +func (*MsgChannelUpgradeOpen) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{28} +} +func (m *MsgChannelUpgradeOpen) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeOpen) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeOpen.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return interceptor(ctx, in, info, handler) +} +func (m *MsgChannelUpgradeOpen) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeOpen.Merge(m, src) +} +func (m *MsgChannelUpgradeOpen) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeOpen) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeOpen.DiscardUnknown(m) } -func _Msg_RecvPacket_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgRecvPacket) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).RecvPacket(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/RecvPacket", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).RecvPacket(ctx, req.(*MsgRecvPacket)) - } - return interceptor(ctx, in, info, handler) +var xxx_messageInfo_MsgChannelUpgradeOpen proto.InternalMessageInfo + +// MsgChannelUpgradeOpenResponse defines the MsgChannelUpgradeOpen response type +type MsgChannelUpgradeOpenResponse struct { } -func _Msg_Timeout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgTimeout) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).Timeout(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/Timeout", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).Timeout(ctx, req.(*MsgTimeout)) +func (m *MsgChannelUpgradeOpenResponse) Reset() { *m = MsgChannelUpgradeOpenResponse{} } +func (m *MsgChannelUpgradeOpenResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeOpenResponse) ProtoMessage() {} +func (*MsgChannelUpgradeOpenResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{29} +} +func (m *MsgChannelUpgradeOpenResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeOpenResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeOpenResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return interceptor(ctx, in, info, handler) +} +func (m *MsgChannelUpgradeOpenResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeOpenResponse.Merge(m, src) +} +func (m *MsgChannelUpgradeOpenResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeOpenResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeOpenResponse.DiscardUnknown(m) } -func _Msg_TimeoutOnClose_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgTimeoutOnClose) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).TimeoutOnClose(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/TimeoutOnClose", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).TimeoutOnClose(ctx, req.(*MsgTimeoutOnClose)) - } - return interceptor(ctx, in, info, handler) +var xxx_messageInfo_MsgChannelUpgradeOpenResponse proto.InternalMessageInfo + +// MsgChannelUpgradeTimeout defines the request type for the ChannelUpgradeTimeout rpc +type MsgChannelUpgradeTimeout struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + CounterpartyChannel Channel `protobuf:"bytes,3,opt,name=counterparty_channel,json=counterpartyChannel,proto3" json:"counterparty_channel"` + ProofChannel []byte `protobuf:"bytes,4,opt,name=proof_channel,json=proofChannel,proto3" json:"proof_channel,omitempty"` + ProofHeight types.Height `protobuf:"bytes,5,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` + Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty"` } -func _Msg_Acknowledgement_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgAcknowledgement) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).Acknowledgement(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/ibc.core.channel.v1.Msg/Acknowledgement", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).Acknowledgement(ctx, req.(*MsgAcknowledgement)) +func (m *MsgChannelUpgradeTimeout) Reset() { *m = MsgChannelUpgradeTimeout{} } +func (m *MsgChannelUpgradeTimeout) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeTimeout) ProtoMessage() {} +func (*MsgChannelUpgradeTimeout) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{30} +} +func (m *MsgChannelUpgradeTimeout) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeTimeout) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeTimeout.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return interceptor(ctx, in, info, handler) +} +func (m *MsgChannelUpgradeTimeout) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeTimeout.Merge(m, src) +} +func (m *MsgChannelUpgradeTimeout) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeTimeout) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeTimeout.DiscardUnknown(m) } -var _Msg_serviceDesc = grpc.ServiceDesc{ - ServiceName: "ibc.core.channel.v1.Msg", - HandlerType: (*MsgServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "ChannelOpenInit", - Handler: _Msg_ChannelOpenInit_Handler, - }, - { - MethodName: "ChannelOpenTry", - Handler: _Msg_ChannelOpenTry_Handler, - }, - { - MethodName: "ChannelOpenAck", - Handler: _Msg_ChannelOpenAck_Handler, - }, - { - MethodName: "ChannelOpenConfirm", - Handler: _Msg_ChannelOpenConfirm_Handler, - }, - { - MethodName: "ChannelCloseInit", - Handler: _Msg_ChannelCloseInit_Handler, - }, - { - MethodName: "ChannelCloseConfirm", - Handler: _Msg_ChannelCloseConfirm_Handler, - }, - { - MethodName: "RecvPacket", - Handler: _Msg_RecvPacket_Handler, - }, - { - MethodName: "Timeout", - Handler: _Msg_Timeout_Handler, - }, - { - MethodName: "TimeoutOnClose", - Handler: _Msg_TimeoutOnClose_Handler, - }, - { - MethodName: "Acknowledgement", - Handler: _Msg_Acknowledgement_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "ibc/core/channel/v1/tx.proto", -} +var xxx_messageInfo_MsgChannelUpgradeTimeout proto.InternalMessageInfo -func (m *MsgChannelOpenInit) 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 +// MsgChannelUpgradeTimeoutRepsonse defines the MsgChannelUpgradeTimeout response type +type MsgChannelUpgradeTimeoutResponse struct { } -func (m *MsgChannelOpenInit) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (m *MsgChannelUpgradeTimeoutResponse) Reset() { *m = MsgChannelUpgradeTimeoutResponse{} } +func (m *MsgChannelUpgradeTimeoutResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeTimeoutResponse) ProtoMessage() {} +func (*MsgChannelUpgradeTimeoutResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{31} } - -func (m *MsgChannelOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x1a - } - { - size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) +func (m *MsgChannelUpgradeTimeoutResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeTimeoutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeTimeoutResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) if err != nil { - return 0, err + return nil, err } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - 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] = 0xa + return b[:n], nil } - return len(dAtA) - i, nil } - -func (m *MsgChannelOpenInitResponse) 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 *MsgChannelUpgradeTimeoutResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeTimeoutResponse.Merge(m, src) } - -func (m *MsgChannelOpenInitResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (m *MsgChannelUpgradeTimeoutResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeTimeoutResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeTimeoutResponse.DiscardUnknown(m) } -func (m *MsgChannelOpenInitResponse) 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] = 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 +var xxx_messageInfo_MsgChannelUpgradeTimeoutResponse proto.InternalMessageInfo + +// MsgChannelUpgradeCancel defines the request type for the ChannelUpgradeCancel rpc +type MsgChannelUpgradeCancel struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + ErrorReceipt ErrorReceipt `protobuf:"bytes,3,opt,name=error_receipt,json=errorReceipt,proto3" json:"error_receipt"` + ProofErrorReceipt []byte `protobuf:"bytes,4,opt,name=proof_error_receipt,json=proofErrorReceipt,proto3" json:"proof_error_receipt,omitempty"` + ProofHeight types.Height `protobuf:"bytes,5,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height"` + Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty"` } -func (m *MsgChannelOpenTry) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err +func (m *MsgChannelUpgradeCancel) Reset() { *m = MsgChannelUpgradeCancel{} } +func (m *MsgChannelUpgradeCancel) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeCancel) ProtoMessage() {} +func (*MsgChannelUpgradeCancel) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{32} +} +func (m *MsgChannelUpgradeCancel) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeCancel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeCancel.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return dAtA[:n], nil +} +func (m *MsgChannelUpgradeCancel) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeCancel.Merge(m, src) +} +func (m *MsgChannelUpgradeCancel) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeCancel) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeCancel.DiscardUnknown(m) } -func (m *MsgChannelOpenTry) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +var xxx_messageInfo_MsgChannelUpgradeCancel proto.InternalMessageInfo + +// MsgChannelUpgradeCancelResponse defines the MsgChannelUpgradeCancel response type +type MsgChannelUpgradeCancelResponse struct { } -func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x3a - } - { - size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) +func (m *MsgChannelUpgradeCancelResponse) Reset() { *m = MsgChannelUpgradeCancelResponse{} } +func (m *MsgChannelUpgradeCancelResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChannelUpgradeCancelResponse) ProtoMessage() {} +func (*MsgChannelUpgradeCancelResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{33} +} +func (m *MsgChannelUpgradeCancelResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChannelUpgradeCancelResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChannelUpgradeCancelResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) if err != nil { - return 0, err + return nil, err } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x32 - if len(m.ProofInit) > 0 { - i -= len(m.ProofInit) - copy(dAtA[i:], m.ProofInit) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) - i-- - dAtA[i] = 0x2a - } - if len(m.CounterpartyVersion) > 0 { - i -= len(m.CounterpartyVersion) - copy(dAtA[i:], m.CounterpartyVersion) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyVersion))) - i-- - dAtA[i] = 0x22 + return b[:n], nil } - { - size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) +} +func (m *MsgChannelUpgradeCancelResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChannelUpgradeCancelResponse.Merge(m, src) +} +func (m *MsgChannelUpgradeCancelResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChannelUpgradeCancelResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChannelUpgradeCancelResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChannelUpgradeCancelResponse proto.InternalMessageInfo + +// MsgUpdateParams is the MsgUpdateParams request type. +type MsgUpdateParams struct { + // authority is the address that controls the module (defaults to x/gov unless overwritten). + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the channel parameters to update. + // + // NOTE: All parameters must be supplied. + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{34} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) if err != nil { - return 0, err + return nil, err } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - if len(m.PreviousChannelId) > 0 { - i -= len(m.PreviousChannelId) - copy(dAtA[i:], m.PreviousChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.PreviousChannelId))) - i-- - dAtA[i] = 0x12 - } - 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] = 0xa + return b[:n], nil } - return len(dAtA) - i, nil } - -func (m *MsgChannelOpenTryResponse) 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 *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) } -func (m *MsgChannelOpenTryResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +// MsgUpdateParamsResponse defines the MsgUpdateParams response type. +type MsgUpdateParamsResponse struct { } -func (m *MsgChannelOpenTryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = 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) - i = encodeVarintTx(dAtA, i, uint64(len(m.Version))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{35} } - -func (m *MsgChannelOpenAck) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return dAtA[:n], nil +} +func (m *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) } -func (m *MsgChannelOpenAck) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +// MsgPruneAcknowledgements defines the request type for the PruneAcknowledgements rpc. +type MsgPruneAcknowledgements struct { + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + Limit uint64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` } -func (m *MsgChannelOpenAck) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x3a - } - { - size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) +func (m *MsgPruneAcknowledgements) Reset() { *m = MsgPruneAcknowledgements{} } +func (m *MsgPruneAcknowledgements) String() string { return proto.CompactTextString(m) } +func (*MsgPruneAcknowledgements) ProtoMessage() {} +func (*MsgPruneAcknowledgements) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{36} +} +func (m *MsgPruneAcknowledgements) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgPruneAcknowledgements) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgPruneAcknowledgements.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) if err != nil { - return 0, err + return nil, err } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x32 - if len(m.ProofTry) > 0 { - i -= len(m.ProofTry) - copy(dAtA[i:], m.ProofTry) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofTry))) - i-- - dAtA[i] = 0x2a - } - if len(m.CounterpartyVersion) > 0 { - i -= len(m.CounterpartyVersion) - copy(dAtA[i:], m.CounterpartyVersion) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyVersion))) - i-- - dAtA[i] = 0x22 - } - if len(m.CounterpartyChannelId) > 0 { - i -= len(m.CounterpartyChannelId) - copy(dAtA[i:], m.CounterpartyChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyChannelId))) - i-- - dAtA[i] = 0x1a - } - 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.PortId) > 0 { - i -= len(m.PortId) - copy(dAtA[i:], m.PortId) - i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) - i-- - dAtA[i] = 0xa + return b[:n], nil } - return len(dAtA) - i, nil } - -func (m *MsgChannelOpenAckResponse) 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 *MsgPruneAcknowledgements) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgPruneAcknowledgements.Merge(m, src) } - -func (m *MsgChannelOpenAckResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (m *MsgPruneAcknowledgements) XXX_Size() int { + return m.Size() } - -func (m *MsgChannelOpenAckResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func (m *MsgPruneAcknowledgements) XXX_DiscardUnknown() { + xxx_messageInfo_MsgPruneAcknowledgements.DiscardUnknown(m) } -func (m *MsgChannelOpenConfirm) 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 -} +var xxx_messageInfo_MsgPruneAcknowledgements proto.InternalMessageInfo -func (m *MsgChannelOpenConfirm) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +// MsgPruneAcknowledgementsResponse defines the response type for the PruneAcknowledgements rpc. +type MsgPruneAcknowledgementsResponse struct { + // Number of sequences pruned (includes both packet acknowledgements and packet receipts where appropriate). + TotalPrunedSequences uint64 `protobuf:"varint,1,opt,name=total_pruned_sequences,json=totalPrunedSequences,proto3" json:"total_pruned_sequences,omitempty"` + // Number of sequences left after pruning. + TotalRemainingSequences uint64 `protobuf:"varint,2,opt,name=total_remaining_sequences,json=totalRemainingSequences,proto3" json:"total_remaining_sequences,omitempty"` } -func (m *MsgChannelOpenConfirm) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x2a - } - { - size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) +func (m *MsgPruneAcknowledgementsResponse) Reset() { *m = MsgPruneAcknowledgementsResponse{} } +func (m *MsgPruneAcknowledgementsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgPruneAcknowledgementsResponse) ProtoMessage() {} +func (*MsgPruneAcknowledgementsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bc4637e0ac3fc7b7, []int{37} +} +func (m *MsgPruneAcknowledgementsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgPruneAcknowledgementsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgPruneAcknowledgementsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) if err != nil { - return 0, err + return nil, err } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - if len(m.ProofAck) > 0 { - i -= len(m.ProofAck) - copy(dAtA[i:], m.ProofAck) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofAck))) - i-- - dAtA[i] = 0x1a - } - 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.PortId) > 0 { - i -= len(m.PortId) - copy(dAtA[i:], m.PortId) - i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) - i-- - dAtA[i] = 0xa + return b[:n], nil } - return len(dAtA) - i, nil +} +func (m *MsgPruneAcknowledgementsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgPruneAcknowledgementsResponse.Merge(m, src) +} +func (m *MsgPruneAcknowledgementsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgPruneAcknowledgementsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgPruneAcknowledgementsResponse.DiscardUnknown(m) } -func (m *MsgChannelOpenConfirmResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err +var xxx_messageInfo_MsgPruneAcknowledgementsResponse proto.InternalMessageInfo + +func (m *MsgPruneAcknowledgementsResponse) GetTotalPrunedSequences() uint64 { + if m != nil { + return m.TotalPrunedSequences } - return dAtA[:n], nil + return 0 } -func (m *MsgChannelOpenConfirmResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (m *MsgPruneAcknowledgementsResponse) GetTotalRemainingSequences() uint64 { + if m != nil { + return m.TotalRemainingSequences + } + return 0 } -func (m *MsgChannelOpenConfirmResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func init() { + proto.RegisterEnum("ibc.core.channel.v1.ResponseResultType", ResponseResultType_name, ResponseResultType_value) + proto.RegisterType((*MsgChannelOpenInit)(nil), "ibc.core.channel.v1.MsgChannelOpenInit") + proto.RegisterType((*MsgChannelOpenInitResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenInitResponse") + proto.RegisterType((*MsgChannelOpenTry)(nil), "ibc.core.channel.v1.MsgChannelOpenTry") + proto.RegisterType((*MsgChannelOpenTryResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenTryResponse") + proto.RegisterType((*MsgChannelOpenAck)(nil), "ibc.core.channel.v1.MsgChannelOpenAck") + proto.RegisterType((*MsgChannelOpenAckResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenAckResponse") + proto.RegisterType((*MsgChannelOpenConfirm)(nil), "ibc.core.channel.v1.MsgChannelOpenConfirm") + proto.RegisterType((*MsgChannelOpenConfirmResponse)(nil), "ibc.core.channel.v1.MsgChannelOpenConfirmResponse") + proto.RegisterType((*MsgChannelCloseInit)(nil), "ibc.core.channel.v1.MsgChannelCloseInit") + proto.RegisterType((*MsgChannelCloseInitResponse)(nil), "ibc.core.channel.v1.MsgChannelCloseInitResponse") + proto.RegisterType((*MsgChannelCloseConfirm)(nil), "ibc.core.channel.v1.MsgChannelCloseConfirm") + proto.RegisterType((*MsgChannelCloseConfirmResponse)(nil), "ibc.core.channel.v1.MsgChannelCloseConfirmResponse") + proto.RegisterType((*MsgRecvPacket)(nil), "ibc.core.channel.v1.MsgRecvPacket") + proto.RegisterType((*MsgRecvPacketResponse)(nil), "ibc.core.channel.v1.MsgRecvPacketResponse") + proto.RegisterType((*MsgTimeout)(nil), "ibc.core.channel.v1.MsgTimeout") + proto.RegisterType((*MsgTimeoutResponse)(nil), "ibc.core.channel.v1.MsgTimeoutResponse") + proto.RegisterType((*MsgTimeoutOnClose)(nil), "ibc.core.channel.v1.MsgTimeoutOnClose") + proto.RegisterType((*MsgTimeoutOnCloseResponse)(nil), "ibc.core.channel.v1.MsgTimeoutOnCloseResponse") + proto.RegisterType((*MsgAcknowledgement)(nil), "ibc.core.channel.v1.MsgAcknowledgement") + proto.RegisterType((*MsgAcknowledgementResponse)(nil), "ibc.core.channel.v1.MsgAcknowledgementResponse") + proto.RegisterType((*MsgChannelUpgradeInit)(nil), "ibc.core.channel.v1.MsgChannelUpgradeInit") + proto.RegisterType((*MsgChannelUpgradeInitResponse)(nil), "ibc.core.channel.v1.MsgChannelUpgradeInitResponse") + proto.RegisterType((*MsgChannelUpgradeTry)(nil), "ibc.core.channel.v1.MsgChannelUpgradeTry") + proto.RegisterType((*MsgChannelUpgradeTryResponse)(nil), "ibc.core.channel.v1.MsgChannelUpgradeTryResponse") + proto.RegisterType((*MsgChannelUpgradeAck)(nil), "ibc.core.channel.v1.MsgChannelUpgradeAck") + proto.RegisterType((*MsgChannelUpgradeAckResponse)(nil), "ibc.core.channel.v1.MsgChannelUpgradeAckResponse") + proto.RegisterType((*MsgChannelUpgradeConfirm)(nil), "ibc.core.channel.v1.MsgChannelUpgradeConfirm") + proto.RegisterType((*MsgChannelUpgradeConfirmResponse)(nil), "ibc.core.channel.v1.MsgChannelUpgradeConfirmResponse") + proto.RegisterType((*MsgChannelUpgradeOpen)(nil), "ibc.core.channel.v1.MsgChannelUpgradeOpen") + proto.RegisterType((*MsgChannelUpgradeOpenResponse)(nil), "ibc.core.channel.v1.MsgChannelUpgradeOpenResponse") + proto.RegisterType((*MsgChannelUpgradeTimeout)(nil), "ibc.core.channel.v1.MsgChannelUpgradeTimeout") + proto.RegisterType((*MsgChannelUpgradeTimeoutResponse)(nil), "ibc.core.channel.v1.MsgChannelUpgradeTimeoutResponse") + proto.RegisterType((*MsgChannelUpgradeCancel)(nil), "ibc.core.channel.v1.MsgChannelUpgradeCancel") + proto.RegisterType((*MsgChannelUpgradeCancelResponse)(nil), "ibc.core.channel.v1.MsgChannelUpgradeCancelResponse") + proto.RegisterType((*MsgUpdateParams)(nil), "ibc.core.channel.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "ibc.core.channel.v1.MsgUpdateParamsResponse") + proto.RegisterType((*MsgPruneAcknowledgements)(nil), "ibc.core.channel.v1.MsgPruneAcknowledgements") + proto.RegisterType((*MsgPruneAcknowledgementsResponse)(nil), "ibc.core.channel.v1.MsgPruneAcknowledgementsResponse") } -func (m *MsgChannelCloseInit) 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 init() { proto.RegisterFile("ibc/core/channel/v1/tx.proto", fileDescriptor_bc4637e0ac3fc7b7) } -func (m *MsgChannelCloseInit) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +var fileDescriptor_bc4637e0ac3fc7b7 = []byte{ + // 1963 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcf, 0x6f, 0xe3, 0xc6, + 0x15, 0x36, 0xf5, 0x73, 0xfd, 0xbc, 0x1b, 0x69, 0x29, 0xef, 0x5a, 0xa6, 0x6d, 0x59, 0xab, 0x16, + 0x59, 0xc7, 0xdd, 0x95, 0x62, 0x67, 0xb7, 0x68, 0x16, 0x01, 0x5a, 0xaf, 0xaa, 0x6d, 0x0c, 0xac, + 0xd7, 0x06, 0x65, 0x15, 0x6d, 0x52, 0x54, 0x90, 0xa9, 0x59, 0x8a, 0x90, 0x44, 0x32, 0x24, 0xa5, + 0xc4, 0x05, 0x5a, 0x14, 0x3d, 0x2d, 0xf6, 0x10, 0xb4, 0x40, 0xae, 0x0b, 0xb4, 0xe8, 0x3f, 0x90, + 0x73, 0x9b, 0x1e, 0x7a, 0xcb, 0xa9, 0xc8, 0x31, 0x28, 0xd0, 0xa0, 0xd8, 0x3d, 0xe4, 0xd2, 0xbf, + 0xa0, 0x40, 0x81, 0x82, 0x33, 0x43, 0x8a, 0x22, 0x87, 0x12, 0x65, 0x29, 0x46, 0x6e, 0xe2, 0xcc, + 0x37, 0xef, 0xbd, 0xf9, 0xbe, 0x37, 0x8f, 0x33, 0x43, 0xc1, 0xa6, 0x72, 0x26, 0x55, 0x24, 0xcd, + 0x40, 0x15, 0xa9, 0xd3, 0x52, 0x55, 0xd4, 0xab, 0x0c, 0xf7, 0x2a, 0xd6, 0x47, 0x65, 0xdd, 0xd0, + 0x2c, 0x8d, 0xcf, 0x29, 0x67, 0x52, 0xd9, 0xee, 0x2d, 0xd3, 0xde, 0xf2, 0x70, 0x4f, 0x58, 0x95, + 0x35, 0x59, 0xc3, 0xfd, 0x15, 0xfb, 0x17, 0x81, 0x0a, 0x6b, 0x92, 0x66, 0xf6, 0x35, 0xb3, 0xd2, + 0x37, 0x65, 0xdb, 0x44, 0xdf, 0x94, 0x69, 0xc7, 0xf6, 0xc8, 0x43, 0x4f, 0x41, 0xaa, 0x65, 0xf7, + 0x92, 0x5f, 0x14, 0x70, 0x8b, 0x15, 0x82, 0xe3, 0x6f, 0x02, 0x64, 0xa0, 0xcb, 0x46, 0xab, 0x8d, + 0x08, 0xa4, 0xf4, 0x09, 0x07, 0xfc, 0x91, 0x29, 0x57, 0x49, 0xff, 0xb1, 0x8e, 0xd4, 0x43, 0x55, + 0xb1, 0xf8, 0x35, 0x48, 0xeb, 0x9a, 0x61, 0x35, 0x95, 0x76, 0x9e, 0x2b, 0x72, 0x3b, 0xcb, 0x62, + 0xca, 0x7e, 0x3c, 0x6c, 0xf3, 0xef, 0x40, 0x9a, 0xda, 0xca, 0xc7, 0x8a, 0xdc, 0xce, 0xca, 0xfe, + 0x66, 0x99, 0x31, 0xd9, 0x32, 0xb5, 0xf7, 0x30, 0xf1, 0xf9, 0x57, 0xdb, 0x4b, 0xa2, 0x33, 0x84, + 0xbf, 0x09, 0x29, 0x53, 0x91, 0x55, 0x64, 0xe4, 0xe3, 0xc4, 0x2a, 0x79, 0x7a, 0x90, 0x79, 0xf6, + 0xc7, 0xed, 0xa5, 0xdf, 0x7d, 0xfd, 0xe9, 0x2e, 0x6d, 0x28, 0xbd, 0x0f, 0x42, 0x30, 0x2a, 0x11, + 0x99, 0xba, 0xa6, 0x9a, 0x88, 0xdf, 0x02, 0xa0, 0x16, 0x47, 0x01, 0x2e, 0xd3, 0x96, 0xc3, 0x36, + 0x9f, 0x87, 0xf4, 0x10, 0x19, 0xa6, 0xa2, 0xa9, 0x38, 0xc6, 0x65, 0xd1, 0x79, 0x7c, 0x90, 0xb0, + 0xfd, 0x94, 0xbe, 0x8a, 0xc1, 0xf5, 0x71, 0xeb, 0xa7, 0xc6, 0x79, 0xf8, 0x94, 0xf7, 0x21, 0xa7, + 0x1b, 0x68, 0xa8, 0x68, 0x03, 0xb3, 0xe9, 0x71, 0x8b, 0x4d, 0x3f, 0x8c, 0xe5, 0x39, 0xf1, 0xba, + 0xd3, 0x5d, 0x75, 0x43, 0xf0, 0xd0, 0x14, 0x9f, 0x9d, 0xa6, 0x3d, 0x58, 0x95, 0xb4, 0x81, 0x6a, + 0x21, 0x43, 0x6f, 0x19, 0xd6, 0x79, 0xd3, 0x99, 0x4d, 0x02, 0xc7, 0x95, 0xf3, 0xf6, 0xfd, 0x94, + 0x74, 0xd9, 0x94, 0xe8, 0x86, 0xa6, 0x3d, 0x6d, 0x2a, 0xaa, 0x62, 0xe5, 0x93, 0x45, 0x6e, 0xe7, + 0xaa, 0xb8, 0x8c, 0x5b, 0xb0, 0x9e, 0x55, 0xb8, 0x4a, 0xba, 0x3b, 0x48, 0x91, 0x3b, 0x56, 0x3e, + 0x85, 0x83, 0x12, 0x3c, 0x41, 0x91, 0xd4, 0x1a, 0xee, 0x95, 0xdf, 0xc5, 0x08, 0x1a, 0xd2, 0x0a, + 0x1e, 0x45, 0x9a, 0x3c, 0xea, 0xa5, 0x27, 0xab, 0xf7, 0x1e, 0xac, 0x07, 0xf8, 0x75, 0xc5, 0xf3, + 0xa8, 0xc3, 0x8d, 0xa9, 0xe3, 0x93, 0x35, 0xe6, 0x93, 0x95, 0x8a, 0xf7, 0xf7, 0x80, 0x78, 0x07, + 0x52, 0x37, 0x5c, 0xbc, 0xc9, 0x36, 0xf9, 0xef, 0xc3, 0xda, 0x18, 0xd3, 0x1e, 0x2c, 0xc9, 0xd0, + 0x1b, 0xde, 0xee, 0x91, 0xbe, 0x17, 0x50, 0x68, 0x03, 0x88, 0x1e, 0x4d, 0xcb, 0x38, 0xa7, 0x02, + 0x5d, 0xc1, 0x0d, 0x76, 0xf2, 0x5d, 0xae, 0x3e, 0x1b, 0x7e, 0x7d, 0x0e, 0xa4, 0xae, 0xa3, 0x4f, + 0xe9, 0x9f, 0x1c, 0xdc, 0x18, 0xef, 0xad, 0x6a, 0xea, 0x53, 0xc5, 0xe8, 0x5f, 0x98, 0x64, 0x77, + 0xe6, 0x2d, 0xa9, 0x8b, 0x69, 0x75, 0x66, 0x6e, 0x2b, 0xe7, 0x9f, 0x79, 0x62, 0xbe, 0x99, 0x27, + 0x27, 0xcf, 0x7c, 0x1b, 0xb6, 0x98, 0x73, 0x73, 0x67, 0x3f, 0x84, 0xdc, 0x08, 0x50, 0xed, 0x69, + 0x26, 0x9a, 0x5c, 0x0f, 0xa7, 0x4c, 0x3d, 0x72, 0xc1, 0xdb, 0x82, 0x0d, 0x86, 0x5f, 0x37, 0xac, + 0x3f, 0xc5, 0xe0, 0xa6, 0xaf, 0x7f, 0x5e, 0x55, 0xc6, 0x2b, 0x46, 0x7c, 0x5a, 0xc5, 0x58, 0xa4, + 0x2e, 0xfc, 0x43, 0xd8, 0x1a, 0x5b, 0x3e, 0xf4, 0x9d, 0xd4, 0x34, 0xd1, 0x07, 0x03, 0xa4, 0x4a, + 0x08, 0xe7, 0x7f, 0x42, 0xdc, 0xf0, 0x82, 0x1a, 0x04, 0x53, 0xa7, 0x90, 0x20, 0x85, 0x45, 0x28, + 0xb0, 0x29, 0x72, 0x59, 0x7c, 0xc5, 0xc1, 0xb5, 0x23, 0x53, 0x16, 0x91, 0x34, 0x3c, 0x69, 0x49, + 0x5d, 0x64, 0xf1, 0x6f, 0x43, 0x4a, 0xc7, 0xbf, 0x30, 0x77, 0x2b, 0xfb, 0x1b, 0xcc, 0x32, 0x4d, + 0xc0, 0x74, 0x82, 0x74, 0x00, 0xff, 0x06, 0x64, 0x09, 0x41, 0x92, 0xd6, 0xef, 0x2b, 0x56, 0x1f, + 0xa9, 0x16, 0x26, 0xf9, 0xaa, 0x98, 0xc1, 0xed, 0x55, 0xb7, 0x39, 0xc0, 0x65, 0x7c, 0x3e, 0x2e, + 0x13, 0x93, 0x53, 0xe9, 0x97, 0x78, 0xfd, 0x8e, 0x26, 0xe9, 0x56, 0xde, 0x1f, 0x42, 0xca, 0x40, + 0xe6, 0xa0, 0x47, 0x26, 0xfb, 0xda, 0xfe, 0x6d, 0xe6, 0x64, 0x1d, 0xb8, 0x88, 0xa1, 0xa7, 0xe7, + 0x3a, 0x12, 0xe9, 0x30, 0x5a, 0x81, 0x3f, 0x8e, 0x01, 0x1c, 0x99, 0xf2, 0xa9, 0xd2, 0x47, 0xda, + 0x60, 0x31, 0x14, 0x0e, 0x54, 0x03, 0x49, 0x48, 0x19, 0xa2, 0xf6, 0x18, 0x85, 0x0d, 0xb7, 0x79, + 0x31, 0x14, 0xde, 0x01, 0x5e, 0x45, 0x1f, 0x59, 0x6e, 0x9a, 0x35, 0x0d, 0x24, 0x0d, 0x31, 0x9d, + 0x09, 0x31, 0x6b, 0xf7, 0x38, 0xc9, 0x65, 0x93, 0x17, 0xbd, 0xa8, 0xbc, 0x8f, 0xb7, 0x50, 0x94, + 0x8f, 0x45, 0xb3, 0xfd, 0x5f, 0xf2, 0xbe, 0xa3, 0xd6, 0x8f, 0x55, 0x9c, 0xd8, 0x97, 0x44, 0xfa, + 0x36, 0xac, 0xd0, 0x14, 0xb7, 0x9d, 0xd2, 0x1a, 0x41, 0xaa, 0x06, 0x09, 0x63, 0x21, 0x45, 0x82, + 0xad, 0x4a, 0x72, 0xaa, 0x2a, 0xa9, 0xd9, 0x4a, 0x4a, 0xfa, 0x02, 0x25, 0xe5, 0x0c, 0xbf, 0x28, + 0xc7, 0xb9, 0x5f, 0xb4, 0xc0, 0xcf, 0x62, 0x38, 0x7d, 0x0e, 0xa4, 0xae, 0xaa, 0x7d, 0xd8, 0x43, + 0x6d, 0x19, 0xe1, 0x9a, 0x31, 0x87, 0xc2, 0x3b, 0x90, 0x69, 0x8d, 0x5b, 0x73, 0x04, 0xf6, 0x35, + 0x8f, 0x04, 0xb6, 0x07, 0xb6, 0xc7, 0x04, 0x3e, 0xb0, 0x5b, 0x2e, 0xf9, 0xed, 0x2c, 0xe1, 0x5d, + 0xbf, 0x8f, 0x89, 0x45, 0xf3, 0xfd, 0x97, 0xb1, 0xfd, 0x0d, 0x4d, 0x81, 0xb9, 0x5e, 0xf2, 0x3f, + 0x82, 0xd4, 0x53, 0x05, 0xf5, 0xda, 0x26, 0xad, 0x4a, 0x25, 0x66, 0x60, 0xd4, 0xd3, 0x23, 0x8c, + 0x74, 0x14, 0x23, 0xe3, 0xa2, 0xd7, 0xf6, 0x8f, 0x39, 0xef, 0x06, 0xc6, 0x13, 0xbc, 0xcb, 0xd2, + 0x3b, 0x90, 0xa6, 0xa9, 0x4f, 0x13, 0x67, 0x73, 0x52, 0x34, 0xce, 0xc9, 0x83, 0x0e, 0xb1, 0x8b, + 0x43, 0x60, 0xe1, 0xc4, 0xf0, 0xc2, 0xc9, 0x0c, 0x7c, 0x8b, 0x85, 0xb0, 0xf9, 0xbf, 0x38, 0xac, + 0x06, 0x02, 0x9a, 0x78, 0x9c, 0x9a, 0x42, 0xe6, 0x4f, 0xa0, 0xa8, 0x1b, 0x9a, 0xae, 0x99, 0xa8, + 0xed, 0xae, 0x61, 0x49, 0x53, 0x55, 0x24, 0x59, 0x8a, 0xa6, 0x36, 0x3b, 0x9a, 0x6e, 0xd3, 0x1c, + 0xdf, 0x59, 0x16, 0xb7, 0x1c, 0x1c, 0xf5, 0x5a, 0x75, 0x51, 0xef, 0x6a, 0xba, 0xc9, 0x77, 0x60, + 0x83, 0x59, 0x10, 0xa8, 0x54, 0x89, 0x19, 0xa5, 0x5a, 0x67, 0x14, 0x0e, 0x02, 0x98, 0x5e, 0x7a, + 0x92, 0x53, 0x4b, 0x0f, 0xff, 0x1d, 0xb8, 0x46, 0x4b, 0x2d, 0x3d, 0x36, 0xa6, 0xf0, 0x5a, 0x24, + 0xab, 0x8f, 0xb2, 0x3b, 0x02, 0x39, 0x0a, 0xa7, 0x3d, 0x20, 0x6a, 0x31, 0xb0, 0x64, 0xaf, 0xcc, + 0xb7, 0x64, 0x97, 0x27, 0x27, 0xe4, 0x3f, 0x38, 0xd8, 0x64, 0xe9, 0x7f, 0xe9, 0xf9, 0xe8, 0x29, + 0x0f, 0xf1, 0x79, 0xca, 0xc3, 0xbf, 0x62, 0x8c, 0x84, 0x9e, 0xe7, 0x88, 0xd9, 0xf0, 0x1d, 0x15, + 0x1d, 0x36, 0xe2, 0x91, 0xd9, 0xc8, 0x31, 0x12, 0x27, 0x98, 0x30, 0x89, 0x28, 0x09, 0x93, 0x8c, + 0x90, 0x30, 0xdf, 0xec, 0xd9, 0x13, 0x31, 0xf2, 0xc5, 0x73, 0xfc, 0x5c, 0x54, 0x95, 0xff, 0x6b, + 0x1c, 0xf2, 0x01, 0x3f, 0xf3, 0x1e, 0x99, 0x7e, 0x06, 0x02, 0xf3, 0xb6, 0xc0, 0xb4, 0x5a, 0x16, + 0xa2, 0x69, 0x27, 0x30, 0xe3, 0xad, 0xdb, 0x08, 0x31, 0xcf, 0xb8, 0x4c, 0xc0, 0x3d, 0xa1, 0x49, + 0x92, 0x58, 0x70, 0x92, 0x24, 0xa3, 0x24, 0x49, 0x2a, 0x42, 0x92, 0xa4, 0xe7, 0x4b, 0x92, 0x2b, + 0x93, 0x93, 0x44, 0x81, 0x62, 0x98, 0x78, 0x8b, 0x4e, 0x94, 0xcf, 0x62, 0x8c, 0xed, 0xc0, 0xb1, + 0x8e, 0xd4, 0x6f, 0x61, 0x96, 0x44, 0x5a, 0xf3, 0x7e, 0xa5, 0x92, 0xf3, 0x29, 0x95, 0x9a, 0xe1, + 0x42, 0xc5, 0xc3, 0x9e, 0x7b, 0xe6, 0xfe, 0x2c, 0xc6, 0x58, 0x88, 0xce, 0xd9, 0x71, 0x51, 0x35, + 0x75, 0xf6, 0xbb, 0xd6, 0x1c, 0x83, 0xe4, 0x6f, 0x23, 0xbf, 0x25, 0xc6, 0x4a, 0xf0, 0x9d, 0x34, + 0x4b, 0x7f, 0x8b, 0xc1, 0x5a, 0x70, 0xb9, 0xb4, 0x54, 0x09, 0xf5, 0x2e, 0xcc, 0xf0, 0x63, 0xb8, + 0x86, 0x0c, 0x43, 0x33, 0x9a, 0xf8, 0x30, 0xa8, 0x3b, 0x07, 0xee, 0x5b, 0x4c, 0x6a, 0x6b, 0x36, + 0x52, 0x24, 0x40, 0x3a, 0xdb, 0xab, 0xc8, 0xd3, 0xc6, 0x97, 0x21, 0x47, 0x38, 0x1b, 0xb7, 0x49, + 0xe8, 0xbd, 0x8e, 0xbb, 0xbc, 0x36, 0x2e, 0x99, 0xe3, 0x5b, 0xb0, 0x1d, 0x42, 0x9f, 0x4b, 0xf1, + 0x6f, 0x20, 0x73, 0x64, 0xca, 0x0d, 0xbd, 0xdd, 0xb2, 0xd0, 0x49, 0xcb, 0x68, 0xf5, 0x4d, 0x7e, + 0x13, 0x96, 0x5b, 0x03, 0xab, 0xa3, 0x19, 0x8a, 0x75, 0xee, 0x7c, 0x83, 0x70, 0x1b, 0xc8, 0xf1, + 0xcd, 0xc6, 0xd1, 0xcf, 0x24, 0x61, 0xc7, 0x37, 0x1b, 0x32, 0x3a, 0xbe, 0xd9, 0x4f, 0x0f, 0x78, + 0x27, 0xbe, 0x91, 0xb9, 0xd2, 0x3a, 0x56, 0xd8, 0xeb, 0xdf, 0x0d, 0xed, 0x0f, 0x1c, 0x5e, 0x60, + 0x27, 0xc6, 0x40, 0x45, 0xbe, 0xa3, 0x93, 0x79, 0x61, 0xf9, 0x57, 0x21, 0xd9, 0x53, 0xfa, 0xf4, + 0x5e, 0x30, 0x21, 0x92, 0x87, 0xe8, 0xc7, 0x94, 0x4f, 0x38, 0x9c, 0xb6, 0xcc, 0x98, 0xdc, 0x02, + 0x7e, 0x0f, 0x6e, 0x5a, 0x9a, 0xd5, 0xea, 0x35, 0x75, 0x1b, 0xd6, 0x76, 0x37, 0x78, 0x26, 0x0e, + 0x35, 0x21, 0xae, 0xe2, 0x5e, 0x6c, 0xa3, 0xed, 0xec, 0xf2, 0x4c, 0xfe, 0x01, 0xac, 0x93, 0x51, + 0x06, 0xea, 0xb7, 0x14, 0x55, 0x51, 0x65, 0xcf, 0x40, 0xb2, 0x35, 0x5c, 0xc3, 0x00, 0xd1, 0xe9, + 0x77, 0xc7, 0xee, 0x7e, 0xc9, 0x01, 0x1f, 0x7c, 0x21, 0xf0, 0xf7, 0xa1, 0x28, 0xd6, 0xea, 0x27, + 0xc7, 0x4f, 0xea, 0xb5, 0xa6, 0x58, 0xab, 0x37, 0x1e, 0x9f, 0x36, 0x4f, 0x7f, 0x7e, 0x52, 0x6b, + 0x36, 0x9e, 0xd4, 0x4f, 0x6a, 0xd5, 0xc3, 0x47, 0x87, 0xb5, 0x1f, 0x67, 0x97, 0x84, 0xcc, 0xf3, + 0x17, 0xc5, 0x15, 0x4f, 0x13, 0x7f, 0x1b, 0xd6, 0x99, 0xc3, 0x9e, 0x1c, 0x1f, 0x9f, 0x64, 0x39, + 0xe1, 0xca, 0xf3, 0x17, 0xc5, 0x84, 0xfd, 0x9b, 0xbf, 0x0b, 0x9b, 0x4c, 0x60, 0xbd, 0x51, 0xad, + 0xd6, 0xea, 0xf5, 0x6c, 0x4c, 0x58, 0x79, 0xfe, 0xa2, 0x98, 0xa6, 0x8f, 0xa1, 0xf0, 0x47, 0x07, + 0x87, 0x8f, 0x1b, 0x62, 0x2d, 0x1b, 0x27, 0x70, 0xfa, 0x28, 0x24, 0x9e, 0xfd, 0xb9, 0xb0, 0xb4, + 0xff, 0x9f, 0x2c, 0xc4, 0x8f, 0x4c, 0x99, 0xef, 0x42, 0xc6, 0xff, 0x2d, 0x8f, 0xfd, 0x62, 0x0c, + 0x7e, 0x5e, 0x13, 0x2a, 0x11, 0x81, 0xae, 0x82, 0x1d, 0x78, 0xcd, 0xf7, 0x11, 0xed, 0xf5, 0x08, + 0x26, 0x4e, 0x8d, 0x73, 0xa1, 0x1c, 0x0d, 0x17, 0xe2, 0xc9, 0xde, 0x8e, 0x47, 0xf1, 0x74, 0x20, + 0x75, 0x23, 0x79, 0xf2, 0xee, 0x3f, 0x2d, 0xe0, 0x19, 0x9f, 0x3e, 0x76, 0x23, 0x58, 0xa1, 0x58, + 0x61, 0x3f, 0x3a, 0xd6, 0xf5, 0xaa, 0x42, 0x36, 0xf0, 0xcd, 0x61, 0x67, 0x8a, 0x1d, 0x17, 0x29, + 0xbc, 0x19, 0x15, 0xe9, 0xfa, 0xfb, 0x10, 0x72, 0xac, 0x6f, 0x09, 0xdf, 0x8b, 0x62, 0xc8, 0x99, + 0xe7, 0x5b, 0x33, 0x80, 0x5d, 0xc7, 0xbf, 0x00, 0xf0, 0x5c, 0xbf, 0x97, 0xc2, 0x4c, 0x8c, 0x30, + 0xc2, 0xee, 0x74, 0x8c, 0x6b, 0xbd, 0x0e, 0x69, 0x67, 0x6b, 0xb1, 0x1d, 0x36, 0x8c, 0x02, 0x84, + 0xdb, 0x53, 0x00, 0xde, 0xdc, 0xf3, 0xdd, 0xbe, 0xbe, 0x3e, 0x65, 0x28, 0xc5, 0x85, 0xe7, 0x5e, + 0xc8, 0x8d, 0x62, 0x17, 0x32, 0xfe, 0x6b, 0xc0, 0xd0, 0x28, 0x7d, 0xc0, 0xf0, 0xc5, 0x1b, 0x76, + 0x9d, 0x36, 0x4a, 0x74, 0xef, 0x1d, 0xd8, 0xb4, 0x44, 0xf7, 0x60, 0xa7, 0x26, 0x3a, 0xeb, 0x7a, + 0xea, 0x03, 0xb8, 0x1e, 0xbc, 0x2b, 0x7a, 0x23, 0x9a, 0x21, 0xbb, 0x70, 0xec, 0x45, 0x86, 0x86, + 0xbb, 0xb4, 0xcb, 0x47, 0x44, 0x97, 0x76, 0x05, 0xd9, 0x8b, 0x0c, 0x75, 0x5d, 0xfe, 0x1a, 0x6e, + 0xb0, 0x4f, 0x9e, 0x77, 0xa3, 0xd9, 0x72, 0x96, 0xd8, 0xfd, 0x99, 0xe0, 0xe1, 0xd2, 0xe2, 0xf3, + 0x4c, 0x44, 0x69, 0x6d, 0x6c, 0x54, 0x69, 0xbd, 0x3b, 0xfd, 0xe0, 0xa4, 0x9d, 0xa5, 0x18, 0x71, + 0xd2, 0xce, 0xc2, 0xbc, 0x3f, 0x13, 0xdc, 0x75, 0xff, 0x2b, 0x58, 0x65, 0xee, 0x80, 0xef, 0x44, + 0xe4, 0x10, 0xa3, 0x85, 0x7b, 0xb3, 0xa0, 0x5d, 0xdf, 0x0a, 0xe4, 0xc8, 0xde, 0x8c, 0xa2, 0xe8, + 0x16, 0xf1, 0xbb, 0x61, 0xc6, 0xbc, 0x1b, 0x39, 0xe1, 0x4e, 0x14, 0x94, 0x97, 0x65, 0xf6, 0x56, + 0x2f, 0x94, 0x65, 0x26, 0x3c, 0x9c, 0xe5, 0x89, 0x9b, 0x36, 0x21, 0xf9, 0xdb, 0xaf, 0x3f, 0xdd, + 0xe5, 0x1e, 0xd6, 0x3f, 0x7f, 0x59, 0xe0, 0xbe, 0x78, 0x59, 0xe0, 0xfe, 0xfd, 0xb2, 0xc0, 0xfd, + 0xfe, 0x55, 0x61, 0xe9, 0x8b, 0x57, 0x85, 0xa5, 0x2f, 0x5f, 0x15, 0x96, 0xde, 0x7b, 0x5b, 0x56, + 0xac, 0xce, 0xe0, 0xac, 0x2c, 0x69, 0xfd, 0x0a, 0xfd, 0x6f, 0x93, 0x72, 0x26, 0xdd, 0x95, 0xb5, + 0xca, 0xf0, 0x07, 0x95, 0xbe, 0xd6, 0x1e, 0xf4, 0x90, 0x49, 0xfe, 0x93, 0xf4, 0xe6, 0xbd, 0xbb, + 0xce, 0xdf, 0x92, 0xac, 0x73, 0x1d, 0x99, 0x67, 0x29, 0xfc, 0x97, 0xa4, 0xb7, 0xfe, 0x1f, 0x00, + 0x00, 0xff, 0xff, 0xe5, 0xbe, 0x04, 0xd7, 0x5d, 0x25, 0x00, 0x00, } -func (m *MsgChannelCloseInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x1a +// 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 { + // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. + ChannelOpenInit(ctx context.Context, in *MsgChannelOpenInit, opts ...grpc.CallOption) (*MsgChannelOpenInitResponse, error) + // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. + ChannelOpenTry(ctx context.Context, in *MsgChannelOpenTry, opts ...grpc.CallOption) (*MsgChannelOpenTryResponse, error) + // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. + ChannelOpenAck(ctx context.Context, in *MsgChannelOpenAck, opts ...grpc.CallOption) (*MsgChannelOpenAckResponse, error) + // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. + ChannelOpenConfirm(ctx context.Context, in *MsgChannelOpenConfirm, opts ...grpc.CallOption) (*MsgChannelOpenConfirmResponse, error) + // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. + ChannelCloseInit(ctx context.Context, in *MsgChannelCloseInit, opts ...grpc.CallOption) (*MsgChannelCloseInitResponse, error) + // ChannelCloseConfirm defines a rpc handler method for + // MsgChannelCloseConfirm. + ChannelCloseConfirm(ctx context.Context, in *MsgChannelCloseConfirm, opts ...grpc.CallOption) (*MsgChannelCloseConfirmResponse, error) + // RecvPacket defines a rpc handler method for MsgRecvPacket. + RecvPacket(ctx context.Context, in *MsgRecvPacket, opts ...grpc.CallOption) (*MsgRecvPacketResponse, error) + // Timeout defines a rpc handler method for MsgTimeout. + Timeout(ctx context.Context, in *MsgTimeout, opts ...grpc.CallOption) (*MsgTimeoutResponse, error) + // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. + TimeoutOnClose(ctx context.Context, in *MsgTimeoutOnClose, opts ...grpc.CallOption) (*MsgTimeoutOnCloseResponse, error) + // Acknowledgement defines a rpc handler method for MsgAcknowledgement. + Acknowledgement(ctx context.Context, in *MsgAcknowledgement, opts ...grpc.CallOption) (*MsgAcknowledgementResponse, error) + // ChannelUpgradeInit defines a rpc handler method for MsgChannelUpgradeInit. + ChannelUpgradeInit(ctx context.Context, in *MsgChannelUpgradeInit, opts ...grpc.CallOption) (*MsgChannelUpgradeInitResponse, error) + // ChannelUpgradeTry defines a rpc handler method for MsgChannelUpgradeTry. + ChannelUpgradeTry(ctx context.Context, in *MsgChannelUpgradeTry, opts ...grpc.CallOption) (*MsgChannelUpgradeTryResponse, error) + // ChannelUpgradeAck defines a rpc handler method for MsgChannelUpgradeAck. + ChannelUpgradeAck(ctx context.Context, in *MsgChannelUpgradeAck, opts ...grpc.CallOption) (*MsgChannelUpgradeAckResponse, error) + // ChannelUpgradeConfirm defines a rpc handler method for MsgChannelUpgradeConfirm. + ChannelUpgradeConfirm(ctx context.Context, in *MsgChannelUpgradeConfirm, opts ...grpc.CallOption) (*MsgChannelUpgradeConfirmResponse, error) + // ChannelUpgradeOpen defines a rpc handler method for MsgChannelUpgradeOpen. + ChannelUpgradeOpen(ctx context.Context, in *MsgChannelUpgradeOpen, opts ...grpc.CallOption) (*MsgChannelUpgradeOpenResponse, error) + // ChannelUpgradeTimeout defines a rpc handler method for MsgChannelUpgradeTimeout. + ChannelUpgradeTimeout(ctx context.Context, in *MsgChannelUpgradeTimeout, opts ...grpc.CallOption) (*MsgChannelUpgradeTimeoutResponse, error) + // ChannelUpgradeCancel defines a rpc handler method for MsgChannelUpgradeCancel. + ChannelUpgradeCancel(ctx context.Context, in *MsgChannelUpgradeCancel, opts ...grpc.CallOption) (*MsgChannelUpgradeCancelResponse, error) + // UpdateChannelParams defines a rpc handler method for MsgUpdateParams. + UpdateChannelParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + // PruneAcknowledgements defines a rpc handler method for MsgPruneAcknowledgements. + PruneAcknowledgements(ctx context.Context, in *MsgPruneAcknowledgements, opts ...grpc.CallOption) (*MsgPruneAcknowledgementsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) ChannelOpenInit(ctx context.Context, in *MsgChannelOpenInit, opts ...grpc.CallOption) (*MsgChannelOpenInitResponse, error) { + out := new(MsgChannelOpenInitResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelOpenInit", in, out, opts...) + if err != nil { + return nil, err } - 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 + return out, nil +} + +func (c *msgClient) ChannelOpenTry(ctx context.Context, in *MsgChannelOpenTry, opts ...grpc.CallOption) (*MsgChannelOpenTryResponse, error) { + out := new(MsgChannelOpenTryResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelOpenTry", in, out, opts...) + if err != nil { + return nil, err } - 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] = 0xa + return out, nil +} + +func (c *msgClient) ChannelOpenAck(ctx context.Context, in *MsgChannelOpenAck, opts ...grpc.CallOption) (*MsgChannelOpenAckResponse, error) { + out := new(MsgChannelOpenAckResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelOpenAck", in, out, opts...) + if err != nil { + return nil, err } - return len(dAtA) - i, nil + return out, nil } -func (m *MsgChannelCloseInitResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *msgClient) ChannelOpenConfirm(ctx context.Context, in *MsgChannelOpenConfirm, opts ...grpc.CallOption) (*MsgChannelOpenConfirmResponse, error) { + out := new(MsgChannelOpenConfirmResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelOpenConfirm", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil + return out, nil } -func (m *MsgChannelCloseInitResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (c *msgClient) ChannelCloseInit(ctx context.Context, in *MsgChannelCloseInit, opts ...grpc.CallOption) (*MsgChannelCloseInitResponse, error) { + out := new(MsgChannelCloseInitResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelCloseInit", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *MsgChannelCloseInitResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func (c *msgClient) ChannelCloseConfirm(ctx context.Context, in *MsgChannelCloseConfirm, opts ...grpc.CallOption) (*MsgChannelCloseConfirmResponse, error) { + out := new(MsgChannelCloseConfirmResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelCloseConfirm", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *MsgChannelCloseConfirm) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *msgClient) RecvPacket(ctx context.Context, in *MsgRecvPacket, opts ...grpc.CallOption) (*MsgRecvPacketResponse, error) { + out := new(MsgRecvPacketResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/RecvPacket", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil + return out, nil } -func (m *MsgChannelCloseConfirm) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (c *msgClient) Timeout(ctx context.Context, in *MsgTimeout, opts ...grpc.CallOption) (*MsgTimeoutResponse, error) { + out := new(MsgTimeoutResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/Timeout", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *MsgChannelCloseConfirm) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x2a +func (c *msgClient) TimeoutOnClose(ctx context.Context, in *MsgTimeoutOnClose, opts ...grpc.CallOption) (*MsgTimeoutOnCloseResponse, error) { + out := new(MsgTimeoutOnCloseResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/TimeoutOnClose", in, out, opts...) + if err != nil { + return nil, err } - { - size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) + return out, nil +} + +func (c *msgClient) Acknowledgement(ctx context.Context, in *MsgAcknowledgement, opts ...grpc.CallOption) (*MsgAcknowledgementResponse, error) { + out := new(MsgAcknowledgementResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/Acknowledgement", in, out, opts...) + if err != nil { + return nil, err } - i-- - dAtA[i] = 0x22 - if len(m.ProofInit) > 0 { - i -= len(m.ProofInit) - copy(dAtA[i:], m.ProofInit) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) - i-- - dAtA[i] = 0x1a + return out, nil +} + +func (c *msgClient) ChannelUpgradeInit(ctx context.Context, in *MsgChannelUpgradeInit, opts ...grpc.CallOption) (*MsgChannelUpgradeInitResponse, error) { + out := new(MsgChannelUpgradeInitResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelUpgradeInit", in, out, opts...) + if err != nil { + return nil, err } - 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 + return out, nil +} + +func (c *msgClient) ChannelUpgradeTry(ctx context.Context, in *MsgChannelUpgradeTry, opts ...grpc.CallOption) (*MsgChannelUpgradeTryResponse, error) { + out := new(MsgChannelUpgradeTryResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelUpgradeTry", in, out, opts...) + if err != nil { + return nil, err } - 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] = 0xa + return out, nil +} + +func (c *msgClient) ChannelUpgradeAck(ctx context.Context, in *MsgChannelUpgradeAck, opts ...grpc.CallOption) (*MsgChannelUpgradeAckResponse, error) { + out := new(MsgChannelUpgradeAckResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelUpgradeAck", in, out, opts...) + if err != nil { + return nil, err } - return len(dAtA) - i, nil + return out, nil } -func (m *MsgChannelCloseConfirmResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *msgClient) ChannelUpgradeConfirm(ctx context.Context, in *MsgChannelUpgradeConfirm, opts ...grpc.CallOption) (*MsgChannelUpgradeConfirmResponse, error) { + out := new(MsgChannelUpgradeConfirmResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelUpgradeConfirm", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil + return out, nil } -func (m *MsgChannelCloseConfirmResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (c *msgClient) ChannelUpgradeOpen(ctx context.Context, in *MsgChannelUpgradeOpen, opts ...grpc.CallOption) (*MsgChannelUpgradeOpenResponse, error) { + out := new(MsgChannelUpgradeOpenResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelUpgradeOpen", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *MsgChannelCloseConfirmResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func (c *msgClient) ChannelUpgradeTimeout(ctx context.Context, in *MsgChannelUpgradeTimeout, opts ...grpc.CallOption) (*MsgChannelUpgradeTimeoutResponse, error) { + out := new(MsgChannelUpgradeTimeoutResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelUpgradeTimeout", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *MsgRecvPacket) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *msgClient) ChannelUpgradeCancel(ctx context.Context, in *MsgChannelUpgradeCancel, opts ...grpc.CallOption) (*MsgChannelUpgradeCancelResponse, error) { + out := new(MsgChannelUpgradeCancelResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/ChannelUpgradeCancel", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil + return out, nil } -func (m *MsgRecvPacket) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (c *msgClient) UpdateChannelParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/UpdateChannelParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *MsgRecvPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x22 +func (c *msgClient) PruneAcknowledgements(ctx context.Context, in *MsgPruneAcknowledgements, opts ...grpc.CallOption) (*MsgPruneAcknowledgementsResponse, error) { + out := new(MsgPruneAcknowledgementsResponse) + err := c.cc.Invoke(ctx, "/ibc.core.channel.v1.Msg/PruneAcknowledgements", in, out, opts...) + if err != nil { + return nil, err } - { - size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - if len(m.ProofCommitment) > 0 { - i -= len(m.ProofCommitment) - copy(dAtA[i:], m.ProofCommitment) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofCommitment))) - i-- - dAtA[i] = 0x12 - } - { - size, err := m.Packet.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil + return out, nil } -func (m *MsgRecvPacketResponse) 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 +// MsgServer is the server API for Msg service. +type MsgServer interface { + // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. + ChannelOpenInit(context.Context, *MsgChannelOpenInit) (*MsgChannelOpenInitResponse, error) + // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. + ChannelOpenTry(context.Context, *MsgChannelOpenTry) (*MsgChannelOpenTryResponse, error) + // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. + ChannelOpenAck(context.Context, *MsgChannelOpenAck) (*MsgChannelOpenAckResponse, error) + // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. + ChannelOpenConfirm(context.Context, *MsgChannelOpenConfirm) (*MsgChannelOpenConfirmResponse, error) + // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. + ChannelCloseInit(context.Context, *MsgChannelCloseInit) (*MsgChannelCloseInitResponse, error) + // ChannelCloseConfirm defines a rpc handler method for + // MsgChannelCloseConfirm. + ChannelCloseConfirm(context.Context, *MsgChannelCloseConfirm) (*MsgChannelCloseConfirmResponse, error) + // RecvPacket defines a rpc handler method for MsgRecvPacket. + RecvPacket(context.Context, *MsgRecvPacket) (*MsgRecvPacketResponse, error) + // Timeout defines a rpc handler method for MsgTimeout. + Timeout(context.Context, *MsgTimeout) (*MsgTimeoutResponse, error) + // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. + TimeoutOnClose(context.Context, *MsgTimeoutOnClose) (*MsgTimeoutOnCloseResponse, error) + // Acknowledgement defines a rpc handler method for MsgAcknowledgement. + Acknowledgement(context.Context, *MsgAcknowledgement) (*MsgAcknowledgementResponse, error) + // ChannelUpgradeInit defines a rpc handler method for MsgChannelUpgradeInit. + ChannelUpgradeInit(context.Context, *MsgChannelUpgradeInit) (*MsgChannelUpgradeInitResponse, error) + // ChannelUpgradeTry defines a rpc handler method for MsgChannelUpgradeTry. + ChannelUpgradeTry(context.Context, *MsgChannelUpgradeTry) (*MsgChannelUpgradeTryResponse, error) + // ChannelUpgradeAck defines a rpc handler method for MsgChannelUpgradeAck. + ChannelUpgradeAck(context.Context, *MsgChannelUpgradeAck) (*MsgChannelUpgradeAckResponse, error) + // ChannelUpgradeConfirm defines a rpc handler method for MsgChannelUpgradeConfirm. + ChannelUpgradeConfirm(context.Context, *MsgChannelUpgradeConfirm) (*MsgChannelUpgradeConfirmResponse, error) + // ChannelUpgradeOpen defines a rpc handler method for MsgChannelUpgradeOpen. + ChannelUpgradeOpen(context.Context, *MsgChannelUpgradeOpen) (*MsgChannelUpgradeOpenResponse, error) + // ChannelUpgradeTimeout defines a rpc handler method for MsgChannelUpgradeTimeout. + ChannelUpgradeTimeout(context.Context, *MsgChannelUpgradeTimeout) (*MsgChannelUpgradeTimeoutResponse, error) + // ChannelUpgradeCancel defines a rpc handler method for MsgChannelUpgradeCancel. + ChannelUpgradeCancel(context.Context, *MsgChannelUpgradeCancel) (*MsgChannelUpgradeCancelResponse, error) + // UpdateChannelParams defines a rpc handler method for MsgUpdateParams. + UpdateChannelParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + // PruneAcknowledgements defines a rpc handler method for MsgPruneAcknowledgements. + PruneAcknowledgements(context.Context, *MsgPruneAcknowledgements) (*MsgPruneAcknowledgementsResponse, error) } -func (m *MsgRecvPacketResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { } -func (m *MsgRecvPacketResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Result != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.Result)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil +func (*UnimplementedMsgServer) ChannelOpenInit(ctx context.Context, req *MsgChannelOpenInit) (*MsgChannelOpenInitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelOpenInit not implemented") } - -func (m *MsgTimeout) 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 (*UnimplementedMsgServer) ChannelOpenTry(ctx context.Context, req *MsgChannelOpenTry) (*MsgChannelOpenTryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelOpenTry not implemented") +} +func (*UnimplementedMsgServer) ChannelOpenAck(ctx context.Context, req *MsgChannelOpenAck) (*MsgChannelOpenAckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelOpenAck not implemented") +} +func (*UnimplementedMsgServer) ChannelOpenConfirm(ctx context.Context, req *MsgChannelOpenConfirm) (*MsgChannelOpenConfirmResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelOpenConfirm not implemented") +} +func (*UnimplementedMsgServer) ChannelCloseInit(ctx context.Context, req *MsgChannelCloseInit) (*MsgChannelCloseInitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelCloseInit not implemented") +} +func (*UnimplementedMsgServer) ChannelCloseConfirm(ctx context.Context, req *MsgChannelCloseConfirm) (*MsgChannelCloseConfirmResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelCloseConfirm not implemented") +} +func (*UnimplementedMsgServer) RecvPacket(ctx context.Context, req *MsgRecvPacket) (*MsgRecvPacketResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RecvPacket not implemented") +} +func (*UnimplementedMsgServer) Timeout(ctx context.Context, req *MsgTimeout) (*MsgTimeoutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Timeout not implemented") +} +func (*UnimplementedMsgServer) TimeoutOnClose(ctx context.Context, req *MsgTimeoutOnClose) (*MsgTimeoutOnCloseResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TimeoutOnClose not implemented") +} +func (*UnimplementedMsgServer) Acknowledgement(ctx context.Context, req *MsgAcknowledgement) (*MsgAcknowledgementResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Acknowledgement not implemented") +} +func (*UnimplementedMsgServer) ChannelUpgradeInit(ctx context.Context, req *MsgChannelUpgradeInit) (*MsgChannelUpgradeInitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelUpgradeInit not implemented") +} +func (*UnimplementedMsgServer) ChannelUpgradeTry(ctx context.Context, req *MsgChannelUpgradeTry) (*MsgChannelUpgradeTryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelUpgradeTry not implemented") +} +func (*UnimplementedMsgServer) ChannelUpgradeAck(ctx context.Context, req *MsgChannelUpgradeAck) (*MsgChannelUpgradeAckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelUpgradeAck not implemented") +} +func (*UnimplementedMsgServer) ChannelUpgradeConfirm(ctx context.Context, req *MsgChannelUpgradeConfirm) (*MsgChannelUpgradeConfirmResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelUpgradeConfirm not implemented") +} +func (*UnimplementedMsgServer) ChannelUpgradeOpen(ctx context.Context, req *MsgChannelUpgradeOpen) (*MsgChannelUpgradeOpenResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelUpgradeOpen not implemented") +} +func (*UnimplementedMsgServer) ChannelUpgradeTimeout(ctx context.Context, req *MsgChannelUpgradeTimeout) (*MsgChannelUpgradeTimeoutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelUpgradeTimeout not implemented") +} +func (*UnimplementedMsgServer) ChannelUpgradeCancel(ctx context.Context, req *MsgChannelUpgradeCancel) (*MsgChannelUpgradeCancelResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChannelUpgradeCancel not implemented") +} +func (*UnimplementedMsgServer) UpdateChannelParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateChannelParams not implemented") +} +func (*UnimplementedMsgServer) PruneAcknowledgements(ctx context.Context, req *MsgPruneAcknowledgements) (*MsgPruneAcknowledgementsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PruneAcknowledgements not implemented") } -func (m *MsgTimeout) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) } -func (m *MsgTimeout) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x2a - } - if m.NextSequenceRecv != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.NextSequenceRecv)) - i-- - dAtA[i] = 0x20 +func _Msg_ChannelOpenInit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelOpenInit) + if err := dec(in); err != nil { + return nil, err } - { - size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) + if interceptor == nil { + return srv.(MsgServer).ChannelOpenInit(ctx, in) } - i-- - dAtA[i] = 0x1a - if len(m.ProofUnreceived) > 0 { - i -= len(m.ProofUnreceived) - copy(dAtA[i:], m.ProofUnreceived) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUnreceived))) - i-- - dAtA[i] = 0x12 + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelOpenInit", } - { - size, err := m.Packet.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelOpenInit(ctx, req.(*MsgChannelOpenInit)) } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil + return interceptor(ctx, in, info, handler) } -func (m *MsgTimeoutResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Msg_ChannelOpenTry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelOpenTry) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil -} - -func (m *MsgTimeoutResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MsgTimeoutResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Result != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.Result)) - i-- - dAtA[i] = 0x8 + if interceptor == nil { + return srv.(MsgServer).ChannelOpenTry(ctx, in) } - return len(dAtA) - i, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelOpenTry", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelOpenTry(ctx, req.(*MsgChannelOpenTry)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgTimeoutOnClose) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Msg_ChannelOpenAck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelOpenAck) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(MsgServer).ChannelOpenAck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelOpenAck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelOpenAck(ctx, req.(*MsgChannelOpenAck)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgTimeoutOnClose) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Msg_ChannelOpenConfirm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelOpenConfirm) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ChannelOpenConfirm(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelOpenConfirm", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelOpenConfirm(ctx, req.(*MsgChannelOpenConfirm)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgTimeoutOnClose) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x32 +func _Msg_ChannelCloseInit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelCloseInit) + if err := dec(in); err != nil { + return nil, err } - if m.NextSequenceRecv != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.NextSequenceRecv)) - i-- - dAtA[i] = 0x28 + if interceptor == nil { + return srv.(MsgServer).ChannelCloseInit(ctx, in) } - { - size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelCloseInit", } - i-- - dAtA[i] = 0x22 - if len(m.ProofClose) > 0 { - i -= len(m.ProofClose) - copy(dAtA[i:], m.ProofClose) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofClose))) - i-- - dAtA[i] = 0x1a + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelCloseInit(ctx, req.(*MsgChannelCloseInit)) } - if len(m.ProofUnreceived) > 0 { - i -= len(m.ProofUnreceived) - copy(dAtA[i:], m.ProofUnreceived) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUnreceived))) - i-- - dAtA[i] = 0x12 + return interceptor(ctx, in, info, handler) +} + +func _Msg_ChannelCloseConfirm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelCloseConfirm) + if err := dec(in); err != nil { + return nil, err } - { - size, err := m.Packet.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) + if interceptor == nil { + return srv.(MsgServer).ChannelCloseConfirm(ctx, in) } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelCloseConfirm", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelCloseConfirm(ctx, req.(*MsgChannelCloseConfirm)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgTimeoutOnCloseResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Msg_RecvPacket_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRecvPacket) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(MsgServer).RecvPacket(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/RecvPacket", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RecvPacket(ctx, req.(*MsgRecvPacket)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgTimeoutOnCloseResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Msg_Timeout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgTimeout) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Timeout(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/Timeout", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Timeout(ctx, req.(*MsgTimeout)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgTimeoutOnCloseResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Result != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.Result)) - i-- - dAtA[i] = 0x8 +func _Msg_TimeoutOnClose_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgTimeoutOnClose) + if err := dec(in); err != nil { + return nil, err } - return len(dAtA) - i, nil + if interceptor == nil { + return srv.(MsgServer).TimeoutOnClose(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/TimeoutOnClose", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).TimeoutOnClose(ctx, req.(*MsgTimeoutOnClose)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgAcknowledgement) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Msg_Acknowledgement_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgAcknowledgement) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(MsgServer).Acknowledgement(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/Acknowledgement", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Acknowledgement(ctx, req.(*MsgAcknowledgement)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgAcknowledgement) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Msg_ChannelUpgradeInit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelUpgradeInit) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ChannelUpgradeInit(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelUpgradeInit", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelUpgradeInit(ctx, req.(*MsgChannelUpgradeInit)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgAcknowledgement) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0x2a - } - { - size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) +func _Msg_ChannelUpgradeTry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelUpgradeTry) + if err := dec(in); err != nil { + return nil, err } - i-- - dAtA[i] = 0x22 - if len(m.ProofAcked) > 0 { - i -= len(m.ProofAcked) - copy(dAtA[i:], m.ProofAcked) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofAcked))) - i-- - dAtA[i] = 0x1a + if interceptor == nil { + return srv.(MsgServer).ChannelUpgradeTry(ctx, in) } - if len(m.Acknowledgement) > 0 { - i -= len(m.Acknowledgement) - copy(dAtA[i:], m.Acknowledgement) - i = encodeVarintTx(dAtA, i, uint64(len(m.Acknowledgement))) - i-- - dAtA[i] = 0x12 + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelUpgradeTry", } - { - size, err := m.Packet.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelUpgradeTry(ctx, req.(*MsgChannelUpgradeTry)) } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil + return interceptor(ctx, in, info, handler) } -func (m *MsgAcknowledgementResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Msg_ChannelUpgradeAck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelUpgradeAck) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(MsgServer).ChannelUpgradeAck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelUpgradeAck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelUpgradeAck(ctx, req.(*MsgChannelUpgradeAck)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgAcknowledgementResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Msg_ChannelUpgradeConfirm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelUpgradeConfirm) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ChannelUpgradeConfirm(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelUpgradeConfirm", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelUpgradeConfirm(ctx, req.(*MsgChannelUpgradeConfirm)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgAcknowledgementResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Result != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.Result)) - 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++ +func _Msg_ChannelUpgradeOpen_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelUpgradeOpen) + if err := dec(in); err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base -} -func (m *MsgChannelOpenInit) Size() (n int) { - if m == nil { - return 0 + if interceptor == nil { + return srv.(MsgServer).ChannelUpgradeOpen(ctx, in) } - var l int - _ = l - l = len(m.PortId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelUpgradeOpen", } - l = m.Channel.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelUpgradeOpen(ctx, req.(*MsgChannelUpgradeOpen)) } - return n + return interceptor(ctx, in, info, handler) } -func (m *MsgChannelOpenInitResponse) Size() (n int) { - if m == nil { - return 0 +func _Msg_ChannelUpgradeTimeout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelUpgradeTimeout) + if err := dec(in); err != nil { + return nil, err } - var l int - _ = l - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if interceptor == nil { + return srv.(MsgServer).ChannelUpgradeTimeout(ctx, in) } - l = len(m.Version) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelUpgradeTimeout", } - return n + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelUpgradeTimeout(ctx, req.(*MsgChannelUpgradeTimeout)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgChannelOpenTry) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.PortId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.PreviousChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) +func _Msg_ChannelUpgradeCancel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChannelUpgradeCancel) + if err := dec(in); err != nil { + return nil, err } - l = m.Channel.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.CounterpartyVersion) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if interceptor == nil { + return srv.(MsgServer).ChannelUpgradeCancel(ctx, in) } - l = len(m.ProofInit) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/ChannelUpgradeCancel", } - l = m.ProofHeight.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChannelUpgradeCancel(ctx, req.(*MsgChannelUpgradeCancel)) } - return n + return interceptor(ctx, in, info, handler) } -func (m *MsgChannelOpenTryResponse) Size() (n int) { - if m == nil { - return 0 +func _Msg_UpdateChannelParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err } - var l int - _ = l - l = len(m.Version) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if interceptor == nil { + return srv.(MsgServer).UpdateChannelParams(ctx, in) } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/UpdateChannelParams", } - return n + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateChannelParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) } -func (m *MsgChannelOpenAck) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.PortId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.CounterpartyChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) +func _Msg_PruneAcknowledgements_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgPruneAcknowledgements) + if err := dec(in); err != nil { + return nil, err } - l = len(m.CounterpartyVersion) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if interceptor == nil { + return srv.(MsgServer).PruneAcknowledgements(ctx, in) } - l = len(m.ProofTry) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.channel.v1.Msg/PruneAcknowledgements", } - l = m.ProofHeight.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).PruneAcknowledgements(ctx, req.(*MsgPruneAcknowledgements)) } - return n + return interceptor(ctx, in, info, handler) } -func (m *MsgChannelOpenAckResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.core.channel.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ChannelOpenInit", + Handler: _Msg_ChannelOpenInit_Handler, + }, + { + MethodName: "ChannelOpenTry", + Handler: _Msg_ChannelOpenTry_Handler, + }, + { + MethodName: "ChannelOpenAck", + Handler: _Msg_ChannelOpenAck_Handler, + }, + { + MethodName: "ChannelOpenConfirm", + Handler: _Msg_ChannelOpenConfirm_Handler, + }, + { + MethodName: "ChannelCloseInit", + Handler: _Msg_ChannelCloseInit_Handler, + }, + { + MethodName: "ChannelCloseConfirm", + Handler: _Msg_ChannelCloseConfirm_Handler, + }, + { + MethodName: "RecvPacket", + Handler: _Msg_RecvPacket_Handler, + }, + { + MethodName: "Timeout", + Handler: _Msg_Timeout_Handler, + }, + { + MethodName: "TimeoutOnClose", + Handler: _Msg_TimeoutOnClose_Handler, + }, + { + MethodName: "Acknowledgement", + Handler: _Msg_Acknowledgement_Handler, + }, + { + MethodName: "ChannelUpgradeInit", + Handler: _Msg_ChannelUpgradeInit_Handler, + }, + { + MethodName: "ChannelUpgradeTry", + Handler: _Msg_ChannelUpgradeTry_Handler, + }, + { + MethodName: "ChannelUpgradeAck", + Handler: _Msg_ChannelUpgradeAck_Handler, + }, + { + MethodName: "ChannelUpgradeConfirm", + Handler: _Msg_ChannelUpgradeConfirm_Handler, + }, + { + MethodName: "ChannelUpgradeOpen", + Handler: _Msg_ChannelUpgradeOpen_Handler, + }, + { + MethodName: "ChannelUpgradeTimeout", + Handler: _Msg_ChannelUpgradeTimeout_Handler, + }, + { + MethodName: "ChannelUpgradeCancel", + Handler: _Msg_ChannelUpgradeCancel_Handler, + }, + { + MethodName: "UpdateChannelParams", + Handler: _Msg_UpdateChannelParams_Handler, + }, + { + MethodName: "PruneAcknowledgements", + Handler: _Msg_PruneAcknowledgements_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/core/channel/v1/tx.proto", } -func (m *MsgChannelOpenConfirm) Size() (n int) { - if m == nil { - return 0 +func (m *MsgChannelOpenInit) 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 *MsgChannelOpenInit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.PortId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x1a } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + { + size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) } - l = len(m.ProofAck) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = m.ProofHeight.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + i-- + dAtA[i] = 0x12 + 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] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgChannelOpenConfirmResponse) Size() (n int) { - if m == nil { - return 0 +func (m *MsgChannelOpenInitResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *MsgChannelCloseInit) Size() (n int) { - if m == nil { - return 0 - } +func (m *MsgChannelOpenInitResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelOpenInitResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.PortId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(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] = 0x12 } - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(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] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgChannelCloseInitResponse) Size() (n int) { - if m == nil { - return 0 +func (m *MsgChannelOpenTry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *MsgChannelCloseConfirm) Size() (n int) { - if m == nil { - return 0 - } +func (m *MsgChannelOpenTry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.PortId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x3a } - l = len(m.ProofInit) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) } - l = m.ProofHeight.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + i-- + dAtA[i] = 0x32 + if len(m.ProofInit) > 0 { + i -= len(m.ProofInit) + copy(dAtA[i:], m.ProofInit) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) + i-- + dAtA[i] = 0x2a } - return n -} - -func (m *MsgChannelCloseConfirmResponse) Size() (n int) { - if m == nil { - return 0 + if len(m.CounterpartyVersion) > 0 { + i -= len(m.CounterpartyVersion) + copy(dAtA[i:], m.CounterpartyVersion) + i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyVersion))) + i-- + dAtA[i] = 0x22 } - var l int - _ = l - return n -} - -func (m *MsgRecvPacket) Size() (n int) { - if m == nil { - return 0 + { + size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) } - var l int - _ = l - l = m.Packet.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.ProofCommitment) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + i-- + dAtA[i] = 0x1a + if len(m.PreviousChannelId) > 0 { + i -= len(m.PreviousChannelId) + copy(dAtA[i:], m.PreviousChannelId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PreviousChannelId))) + i-- + dAtA[i] = 0x12 } - l = m.ProofHeight.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(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] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgRecvPacketResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Result != 0 { - n += 1 + sovTx(uint64(m.Result)) +func (m *MsgChannelOpenTryResponse) 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 n + return dAtA[:n], nil } -func (m *MsgTimeout) Size() (n int) { - if m == nil { - return 0 - } +func (m *MsgChannelOpenTryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelOpenTryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = m.Packet.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.ProofUnreceived) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = m.ProofHeight.Size() - n += 1 + l + sovTx(uint64(l)) - if m.NextSequenceRecv != 0 { - n += 1 + sovTx(uint64(m.NextSequenceRecv)) + 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 } - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(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] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgTimeoutResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Result != 0 { - n += 1 + sovTx(uint64(m.Result)) +func (m *MsgChannelOpenAck) 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 n + return dAtA[:n], nil } -func (m *MsgTimeoutOnClose) Size() (n int) { - if m == nil { - return 0 - } +func (m *MsgChannelOpenAck) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelOpenAck) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = m.Packet.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.ProofUnreceived) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x3a } - l = len(m.ProofClose) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) } - l = m.ProofHeight.Size() - n += 1 + l + sovTx(uint64(l)) - if m.NextSequenceRecv != 0 { - n += 1 + sovTx(uint64(m.NextSequenceRecv)) + i-- + dAtA[i] = 0x32 + if len(m.ProofTry) > 0 { + i -= len(m.ProofTry) + copy(dAtA[i:], m.ProofTry) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofTry))) + i-- + dAtA[i] = 0x2a } - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.CounterpartyVersion) > 0 { + i -= len(m.CounterpartyVersion) + copy(dAtA[i:], m.CounterpartyVersion) + i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyVersion))) + i-- + dAtA[i] = 0x22 } - return n + if len(m.CounterpartyChannelId) > 0 { + i -= len(m.CounterpartyChannelId) + copy(dAtA[i:], m.CounterpartyChannelId) + i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyChannelId))) + i-- + dAtA[i] = 0x1a + } + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *MsgTimeoutOnCloseResponse) Size() (n int) { - if m == nil { - return 0 +func (m *MsgChannelOpenAckResponse) 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 *MsgChannelOpenAckResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelOpenAckResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Result != 0 { - n += 1 + sovTx(uint64(m.Result)) - } - return n + return len(dAtA) - i, nil } -func (m *MsgAcknowledgement) Size() (n int) { - if m == nil { - return 0 +func (m *MsgChannelOpenConfirm) 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 *MsgChannelOpenConfirm) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelOpenConfirm) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = m.Packet.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.Acknowledgement) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x2a } - l = len(m.ProofAcked) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) } - l = m.ProofHeight.Size() - n += 1 + l + sovTx(uint64(l)) - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + i-- + dAtA[i] = 0x22 + if len(m.ProofAck) > 0 { + i -= len(m.ProofAck) + copy(dAtA[i:], m.ProofAck) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofAck))) + i-- + dAtA[i] = 0x1a } - return n + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *MsgAcknowledgementResponse) Size() (n int) { - if m == nil { - return 0 +func (m *MsgChannelOpenConfirmResponse) 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 *MsgChannelOpenConfirmResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelOpenConfirmResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Result != 0 { - n += 1 + sovTx(uint64(m.Result)) + return len(dAtA) - i, nil +} + +func (m *MsgChannelCloseInit) 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 n + return dAtA[:n], nil } -func sovTx(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 +func (m *MsgChannelCloseInit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func sozTx(x uint64) (n int) { - return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + +func (m *MsgChannelCloseInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x1a + } + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelCloseInitResponse) 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 *MsgChannelCloseInitResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelCloseInitResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgChannelCloseConfirm) 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 *MsgChannelCloseConfirm) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelCloseConfirm) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CounterpartyUpgradeSequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.CounterpartyUpgradeSequence)) + i-- + dAtA[i] = 0x30 + } + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x2a + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.ProofInit) > 0 { + i -= len(m.ProofInit) + copy(dAtA[i:], m.ProofInit) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) + i-- + dAtA[i] = 0x1a + } + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelCloseConfirmResponse) 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 *MsgChannelCloseConfirmResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelCloseConfirmResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgRecvPacket) 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 *MsgRecvPacket) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRecvPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.ProofCommitment) > 0 { + i -= len(m.ProofCommitment) + copy(dAtA[i:], m.ProofCommitment) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofCommitment))) + i-- + dAtA[i] = 0x12 + } + { + size, err := m.Packet.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MsgRecvPacketResponse) 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 *MsgRecvPacketResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRecvPacketResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgTimeout) 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 *MsgTimeout) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgTimeout) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x2a + } + if m.NextSequenceRecv != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.NextSequenceRecv)) + i-- + dAtA[i] = 0x20 + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.ProofUnreceived) > 0 { + i -= len(m.ProofUnreceived) + copy(dAtA[i:], m.ProofUnreceived) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUnreceived))) + i-- + dAtA[i] = 0x12 + } + { + size, err := m.Packet.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MsgTimeoutResponse) 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 *MsgTimeoutResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgTimeoutResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgTimeoutOnClose) 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 *MsgTimeoutOnClose) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgTimeoutOnClose) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CounterpartyUpgradeSequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.CounterpartyUpgradeSequence)) + i-- + dAtA[i] = 0x38 + } + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x32 + } + if m.NextSequenceRecv != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.NextSequenceRecv)) + i-- + dAtA[i] = 0x28 + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.ProofClose) > 0 { + i -= len(m.ProofClose) + copy(dAtA[i:], m.ProofClose) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofClose))) + i-- + dAtA[i] = 0x1a + } + if len(m.ProofUnreceived) > 0 { + i -= len(m.ProofUnreceived) + copy(dAtA[i:], m.ProofUnreceived) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUnreceived))) + i-- + dAtA[i] = 0x12 + } + { + size, err := m.Packet.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MsgTimeoutOnCloseResponse) 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 *MsgTimeoutOnCloseResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgTimeoutOnCloseResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgAcknowledgement) 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 *MsgAcknowledgement) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAcknowledgement) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x2a + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.ProofAcked) > 0 { + i -= len(m.ProofAcked) + copy(dAtA[i:], m.ProofAcked) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofAcked))) + i-- + dAtA[i] = 0x1a + } + if len(m.Acknowledgement) > 0 { + i -= len(m.Acknowledgement) + copy(dAtA[i:], m.Acknowledgement) + i = encodeVarintTx(dAtA, i, uint64(len(m.Acknowledgement))) + i-- + dAtA[i] = 0x12 + } + { + size, err := m.Packet.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MsgAcknowledgementResponse) 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 *MsgAcknowledgementResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAcknowledgementResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeInit) 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 *MsgChannelUpgradeInit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 + } + { + size, err := m.Fields.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeInitResponse) 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 *MsgChannelUpgradeInitResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeInitResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UpgradeSequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.UpgradeSequence)) + i-- + dAtA[i] = 0x10 + } + { + size, err := m.Upgrade.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeTry) 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 *MsgChannelUpgradeTry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x4a + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + if len(m.ProofUpgrade) > 0 { + i -= len(m.ProofUpgrade) + copy(dAtA[i:], m.ProofUpgrade) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgrade))) + i-- + dAtA[i] = 0x3a + } + if len(m.ProofChannel) > 0 { + i -= len(m.ProofChannel) + copy(dAtA[i:], m.ProofChannel) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofChannel))) + i-- + dAtA[i] = 0x32 + } + if m.CounterpartyUpgradeSequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.CounterpartyUpgradeSequence)) + i-- + dAtA[i] = 0x28 + } + { + size, err := m.CounterpartyUpgradeFields.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.ProposedUpgradeConnectionHops) > 0 { + for iNdEx := len(m.ProposedUpgradeConnectionHops) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ProposedUpgradeConnectionHops[iNdEx]) + copy(dAtA[i:], m.ProposedUpgradeConnectionHops[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProposedUpgradeConnectionHops[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeTryResponse) 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 *MsgChannelUpgradeTryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeTryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x18 + } + if m.UpgradeSequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.UpgradeSequence)) + i-- + dAtA[i] = 0x10 + } + { + size, err := m.Upgrade.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeAck) 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 *MsgChannelUpgradeAck) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeAck) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x3a + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + if len(m.ProofUpgrade) > 0 { + i -= len(m.ProofUpgrade) + copy(dAtA[i:], m.ProofUpgrade) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgrade))) + i-- + dAtA[i] = 0x2a + } + if len(m.ProofChannel) > 0 { + i -= len(m.ProofChannel) + copy(dAtA[i:], m.ProofChannel) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofChannel))) + i-- + dAtA[i] = 0x22 + } + { + size, err := m.CounterpartyUpgrade.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeAckResponse) 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 *MsgChannelUpgradeAckResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeAckResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeConfirm) 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 *MsgChannelUpgradeConfirm) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeConfirm) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x42 + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + if len(m.ProofUpgrade) > 0 { + i -= len(m.ProofUpgrade) + copy(dAtA[i:], m.ProofUpgrade) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgrade))) + i-- + dAtA[i] = 0x32 + } + if len(m.ProofChannel) > 0 { + i -= len(m.ProofChannel) + copy(dAtA[i:], m.ProofChannel) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofChannel))) + i-- + dAtA[i] = 0x2a + } + { + size, err := m.CounterpartyUpgrade.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if m.CounterpartyChannelState != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.CounterpartyChannelState)) + i-- + dAtA[i] = 0x18 + } + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeConfirmResponse) 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 *MsgChannelUpgradeConfirmResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeConfirmResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Result)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeOpen) 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 *MsgChannelUpgradeOpen) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeOpen) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x32 + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if len(m.ProofChannel) > 0 { + i -= len(m.ProofChannel) + copy(dAtA[i:], m.ProofChannel) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofChannel))) + i-- + dAtA[i] = 0x22 + } + if m.CounterpartyChannelState != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.CounterpartyChannelState)) + i-- + dAtA[i] = 0x18 + } + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeOpenResponse) 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 *MsgChannelUpgradeOpenResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeOpenResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeTimeout) 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 *MsgChannelUpgradeTimeout) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeTimeout) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x32 + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if len(m.ProofChannel) > 0 { + i -= len(m.ProofChannel) + copy(dAtA[i:], m.ProofChannel) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofChannel))) + i-- + dAtA[i] = 0x22 + } + { + size, err := m.CounterpartyChannel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeTimeoutResponse) 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 *MsgChannelUpgradeTimeoutResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeTimeoutResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeCancel) 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 *MsgChannelUpgradeCancel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeCancel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x32 + } + { + size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if len(m.ProofErrorReceipt) > 0 { + i -= len(m.ProofErrorReceipt) + copy(dAtA[i:], m.ProofErrorReceipt) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofErrorReceipt))) + i-- + dAtA[i] = 0x22 + } + { + size, err := m.ErrorReceipt.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChannelUpgradeCancelResponse) 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 *MsgChannelUpgradeCancelResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChannelUpgradeCancelResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParams) 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 *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParamsResponse) 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 *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgPruneAcknowledgements) 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 *MsgPruneAcknowledgements) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgPruneAcknowledgements) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 + } + if m.Limit != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Limit)) + i-- + dAtA[i] = 0x18 + } + 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.PortId) > 0 { + i -= len(m.PortId) + copy(dAtA[i:], m.PortId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PortId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgPruneAcknowledgementsResponse) 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 *MsgPruneAcknowledgementsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgPruneAcknowledgementsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.TotalRemainingSequences != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TotalRemainingSequences)) + i-- + dAtA[i] = 0x10 + } + if m.TotalPrunedSequences != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TotalPrunedSequences)) + 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 *MsgChannelOpenInit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Channel.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelOpenInitResponse) 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.Version) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelOpenTry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.PreviousChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Channel.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.CounterpartyVersion) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofInit) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelOpenTryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Version) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelOpenAck) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.CounterpartyChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.CounterpartyVersion) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofTry) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelOpenAckResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgChannelOpenConfirm) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofAck) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelOpenConfirmResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgChannelCloseInit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelCloseInitResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgChannelCloseConfirm) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofInit) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.CounterpartyUpgradeSequence != 0 { + n += 1 + sovTx(uint64(m.CounterpartyUpgradeSequence)) + } + return n +} + +func (m *MsgChannelCloseConfirmResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgRecvPacket) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Packet.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.ProofCommitment) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgRecvPacketResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } + return n +} + +func (m *MsgTimeout) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Packet.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.ProofUnreceived) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + if m.NextSequenceRecv != 0 { + n += 1 + sovTx(uint64(m.NextSequenceRecv)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgTimeoutResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } + return n +} + +func (m *MsgTimeoutOnClose) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Packet.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.ProofUnreceived) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofClose) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + if m.NextSequenceRecv != 0 { + n += 1 + sovTx(uint64(m.NextSequenceRecv)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.CounterpartyUpgradeSequence != 0 { + n += 1 + sovTx(uint64(m.CounterpartyUpgradeSequence)) + } + return n +} + +func (m *MsgTimeoutOnCloseResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } + return n +} + +func (m *MsgAcknowledgement) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Packet.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Acknowledgement) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofAcked) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgAcknowledgementResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } + return n +} + +func (m *MsgChannelUpgradeInit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Fields.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelUpgradeInitResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Upgrade.Size() + n += 1 + l + sovTx(uint64(l)) + if m.UpgradeSequence != 0 { + n += 1 + sovTx(uint64(m.UpgradeSequence)) + } + return n +} + +func (m *MsgChannelUpgradeTry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.ProposedUpgradeConnectionHops) > 0 { + for _, s := range m.ProposedUpgradeConnectionHops { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + l = m.CounterpartyUpgradeFields.Size() + n += 1 + l + sovTx(uint64(l)) + if m.CounterpartyUpgradeSequence != 0 { + n += 1 + sovTx(uint64(m.CounterpartyUpgradeSequence)) + } + l = len(m.ProofChannel) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofUpgrade) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelUpgradeTryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Upgrade.Size() + n += 1 + l + sovTx(uint64(l)) + if m.UpgradeSequence != 0 { + n += 1 + sovTx(uint64(m.UpgradeSequence)) + } + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } + return n +} + +func (m *MsgChannelUpgradeAck) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.CounterpartyUpgrade.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.ProofChannel) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofUpgrade) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelUpgradeAckResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } + return n +} + +func (m *MsgChannelUpgradeConfirm) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.CounterpartyChannelState != 0 { + n += 1 + sovTx(uint64(m.CounterpartyChannelState)) + } + l = m.CounterpartyUpgrade.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.ProofChannel) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofUpgrade) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelUpgradeConfirmResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Result != 0 { + n += 1 + sovTx(uint64(m.Result)) + } + return n +} + +func (m *MsgChannelUpgradeOpen) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.CounterpartyChannelState != 0 { + n += 1 + sovTx(uint64(m.CounterpartyChannelState)) + } + l = len(m.ProofChannel) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelUpgradeOpenResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgChannelUpgradeTimeout) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.CounterpartyChannel.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.ProofChannel) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelUpgradeTimeoutResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgChannelUpgradeCancel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ErrorReceipt.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.ProofErrorReceipt) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.ProofHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChannelUpgradeCancelResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgPruneAcknowledgements) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PortId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChannelId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Limit != 0 { + n += 1 + sovTx(uint64(m.Limit)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgPruneAcknowledgementsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TotalPrunedSequences != 0 { + n += 1 + sovTx(uint64(m.TotalPrunedSequences)) + } + if m.TotalRemainingSequences != 0 { + n += 1 + sovTx(uint64(m.TotalRemainingSequences)) + } + 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 *MsgChannelOpenInit) 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: MsgChannelOpenInit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelOpenInit: 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 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 + 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 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.Channel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = 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 *MsgChannelOpenInitResponse) 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: MsgChannelOpenInitResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelOpenInitResponse: 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 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 *MsgChannelOpenTry) 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: MsgChannelOpenTry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelOpenTry: 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 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 + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PreviousChannelId", 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.PreviousChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + 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 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.Channel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersion", 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.CounterpartyVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", 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.ProofInit = append(m.ProofInit[:0], dAtA[iNdEx:postIndex]...) + if m.ProofInit == nil { + m.ProofInit = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = 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 *MsgChannelOpenTryResponse) 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: MsgChannelOpenTryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelOpenTryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 + 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:]) + 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 *MsgChannelOpenAck) 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: MsgChannelOpenAck: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelOpenAck: 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 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 + 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 + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChannelId", 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.CounterpartyChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersion", 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.CounterpartyVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofTry", 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.ProofTry = append(m.ProofTry[:0], dAtA[iNdEx:postIndex]...) + if m.ProofTry == nil { + m.ProofTry = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = 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 *MsgChannelOpenAckResponse) 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: MsgChannelOpenAckResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelOpenAckResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgChannelOpenConfirm) 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: MsgChannelOpenConfirm: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelOpenConfirm: 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 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 + 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 + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofAck", 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.ProofAck = append(m.ProofAck[:0], dAtA[iNdEx:postIndex]...) + if m.ProofAck == nil { + m.ProofAck = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = 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 *MsgChannelOpenConfirmResponse) 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: MsgChannelOpenConfirmResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelOpenConfirmResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgChannelCloseInit) 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: MsgChannelCloseInit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelCloseInit: 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 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 + 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 + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = 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 *MsgChannelCloseInitResponse) 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: MsgChannelCloseInitResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelCloseInitResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgChannelCloseConfirm) 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: MsgChannelCloseConfirm: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelCloseConfirm: 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 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 + 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 + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", 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.ProofInit = append(m.ProofInit[:0], dAtA[iNdEx:postIndex]...) + if m.ProofInit == nil { + m.ProofInit = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyUpgradeSequence", wireType) + } + m.CounterpartyUpgradeSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CounterpartyUpgradeSequence |= 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 *MsgChannelCloseConfirmResponse) 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: MsgChannelCloseConfirmResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelCloseConfirmResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRecvPacket) 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: MsgRecvPacket: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRecvPacket: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Packet", 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.Packet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofCommitment", 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.ProofCommitment = append(m.ProofCommitment[:0], dAtA[iNdEx:postIndex]...) + if m.ProofCommitment == nil { + m.ProofCommitment = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = 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 *MsgRecvPacketResponse) 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: MsgRecvPacketResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRecvPacketResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(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 *MsgTimeout) 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: MsgTimeout: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgTimeout: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Packet", 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.Packet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofUnreceived", 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.ProofUnreceived = append(m.ProofUnreceived[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUnreceived == nil { + m.ProofUnreceived = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceRecv", wireType) + } + m.NextSequenceRecv = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextSequenceRecv |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = 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 *MsgTimeoutResponse) 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: MsgTimeoutResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgTimeoutResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(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 *MsgTimeoutOnClose) 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: MsgTimeoutOnClose: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgTimeoutOnClose: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Packet", 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.Packet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofUnreceived", 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.ProofUnreceived = append(m.ProofUnreceived[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUnreceived == nil { + m.ProofUnreceived = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofClose", 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.ProofClose = append(m.ProofClose[:0], dAtA[iNdEx:postIndex]...) + if m.ProofClose == nil { + m.ProofClose = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceRecv", wireType) + } + m.NextSequenceRecv = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextSequenceRecv |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyUpgradeSequence", wireType) + } + m.CounterpartyUpgradeSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CounterpartyUpgradeSequence |= 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 *MsgTimeoutOnCloseResponse) 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: MsgTimeoutOnCloseResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgTimeoutOnCloseResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(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 *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { +func (m *MsgAcknowledgement) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2716,17 +7691,17 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelOpenInit: wiretype end group for non-group") + return fmt.Errorf("proto: MsgAcknowledgement: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelOpenInit: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgAcknowledgement: 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) + return fmt.Errorf("proto: wrong wireType = %d for field Packet", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2736,29 +7711,30 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.PortId = string(dAtA[iNdEx:postIndex]) + if err := m.Packet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Acknowledgement", wireType) } - var msglen int + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2768,30 +7744,31 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + if byteLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Channel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.Acknowledgement = append(m.Acknowledgement[:0], dAtA[iNdEx:postIndex]...) + if m.Acknowledgement == nil { + m.Acknowledgement = []byte{} } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofAcked", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2801,79 +7778,31 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.Signer = 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 *MsgChannelOpenInitResponse) 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 + m.ProofAcked = append(m.ProofAcked[:0], dAtA[iNdEx:postIndex]...) + if m.ProofAcked == nil { + m.ProofAcked = []byte{} } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MsgChannelOpenInitResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelOpenInitResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + iNdEx = postIndex + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2883,27 +7812,28 @@ func (m *MsgChannelOpenInitResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.ChannelId = string(dAtA[iNdEx:postIndex]) + if err := m.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 2: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2931,7 +7861,7 @@ func (m *MsgChannelOpenInitResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Version = string(dAtA[iNdEx:postIndex]) + m.Signer = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2954,7 +7884,7 @@ func (m *MsgChannelOpenInitResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { +func (m *MsgAcknowledgementResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2977,49 +7907,17 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelOpenTry: wiretype end group for non-group") + return fmt.Errorf("proto: MsgAcknowledgementResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelOpenTry: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgAcknowledgementResponse: 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 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 - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PreviousChannelId", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) } - var stringLen uint64 + m.Result = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -3029,60 +7927,64 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Result |= ResponseResultType(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + intStringLen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTx } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.PreviousChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - 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 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 + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgChannelUpgradeInit) 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 postIndex > l { + if iNdEx >= l { return io.ErrUnexpectedEOF } - if err := m.Channel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - iNdEx = postIndex - case 4: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgChannelUpgradeInit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelUpgradeInit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersion", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PortId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3110,13 +8012,13 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CounterpartyVersion = string(dAtA[iNdEx:postIndex]) + m.PortId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -3126,29 +8028,27 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofInit = append(m.ProofInit[:0], dAtA[iNdEx:postIndex]...) - if m.ProofInit == nil { - m.ProofInit = []byte{} - } + m.ChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Fields", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3175,11 +8075,11 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Fields.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 7: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -3232,7 +8132,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChannelOpenTryResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeInitResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3255,17 +8155,17 @@ func (m *MsgChannelOpenTryResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelOpenTryResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeInitResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelOpenTryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeInitResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Upgrade", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -3275,29 +8175,30 @@ func (m *MsgChannelOpenTryResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.Version = string(dAtA[iNdEx:postIndex]) + if err := m.Upgrade.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradeSequence", wireType) } - var stringLen uint64 + m.UpgradeSequence = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -3307,24 +8208,11 @@ func (m *MsgChannelOpenTryResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.UpgradeSequence |= 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:]) @@ -3346,7 +8234,7 @@ func (m *MsgChannelOpenTryResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChannelOpenAck) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeTry) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3369,10 +8257,10 @@ func (m *MsgChannelOpenAck) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelOpenAck: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeTry: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelOpenAck: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeTry: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3441,7 +8329,7 @@ func (m *MsgChannelOpenAck) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChannelId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProposedUpgradeConnectionHops", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3469,13 +8357,13 @@ func (m *MsgChannelOpenAck) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CounterpartyChannelId = string(dAtA[iNdEx:postIndex]) + m.ProposedUpgradeConnectionHops = append(m.ProposedUpgradeConnectionHops, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersion", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyUpgradeFields", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -3485,27 +8373,47 @@ func (m *MsgChannelOpenAck) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.CounterpartyVersion = string(dAtA[iNdEx:postIndex]) + if err := m.CounterpartyUpgradeFields.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyUpgradeSequence", wireType) + } + m.CounterpartyUpgradeSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CounterpartyUpgradeSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofTry", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofChannel", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -3532,12 +8440,46 @@ func (m *MsgChannelOpenAck) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofTry = append(m.ProofTry[:0], dAtA[iNdEx:postIndex]...) - if m.ProofTry == nil { - m.ProofTry = []byte{} + m.ProofChannel = append(m.ProofChannel[:0], dAtA[iNdEx:postIndex]...) + if m.ProofChannel == nil { + m.ProofChannel = []byte{} } iNdEx = postIndex - case 6: + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgrade", 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.ProofUpgrade = append(m.ProofUpgrade[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUpgrade == nil { + m.ProofUpgrade = []byte{} + } + iNdEx = postIndex + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -3570,7 +8512,7 @@ func (m *MsgChannelOpenAck) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 7: + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -3623,7 +8565,7 @@ func (m *MsgChannelOpenAck) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChannelOpenAckResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeTryResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3646,12 +8588,83 @@ func (m *MsgChannelOpenAckResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelOpenAckResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeTryResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelOpenAckResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeTryResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Upgrade", 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.Upgrade.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradeSequence", wireType) + } + m.UpgradeSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UpgradeSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -3673,7 +8686,7 @@ func (m *MsgChannelOpenAckResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChannelOpenConfirm) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeAck) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3696,10 +8709,10 @@ func (m *MsgChannelOpenConfirm) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelOpenConfirm: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeAck: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelOpenConfirm: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeAck: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3757,18 +8770,85 @@ func (m *MsgChannelOpenConfirm) Unmarshal(dAtA []byte) error { if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyUpgrade", 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.CounterpartyUpgrade.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofChannel", 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.ChannelId = string(dAtA[iNdEx:postIndex]) + m.ProofChannel = append(m.ProofChannel[:0], dAtA[iNdEx:postIndex]...) + if m.ProofChannel == nil { + m.ProofChannel = []byte{} + } iNdEx = postIndex - case 3: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofAck", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgrade", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -3795,12 +8875,12 @@ func (m *MsgChannelOpenConfirm) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofAck = append(m.ProofAck[:0], dAtA[iNdEx:postIndex]...) - if m.ProofAck == nil { - m.ProofAck = []byte{} + m.ProofUpgrade = append(m.ProofUpgrade[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUpgrade == nil { + m.ProofUpgrade = []byte{} } iNdEx = postIndex - case 4: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -3833,7 +8913,7 @@ func (m *MsgChannelOpenConfirm) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -3886,7 +8966,7 @@ func (m *MsgChannelOpenConfirm) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChannelOpenConfirmResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeAckResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3909,12 +8989,31 @@ func (m *MsgChannelOpenConfirmResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelOpenConfirmResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeAckResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelOpenConfirmResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeAckResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -3936,7 +9035,7 @@ func (m *MsgChannelOpenConfirmResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChannelCloseInit) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeConfirm) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3959,10 +9058,10 @@ func (m *MsgChannelCloseInit) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelCloseInit: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeConfirm: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelCloseInit: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeConfirm: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -4030,10 +9129,10 @@ func (m *MsgChannelCloseInit) Unmarshal(dAtA []byte) error { m.ChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChannelState", wireType) } - var stringLen uint64 + m.CounterpartyChannelState = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4043,129 +9142,16 @@ func (m *MsgChannelCloseInit) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.CounterpartyChannelState |= State(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.Signer = 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 *MsgChannelCloseInitResponse) 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: MsgChannelCloseInitResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelCloseInitResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipTx(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MsgChannelCloseConfirm) 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: MsgChannelCloseConfirm: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelCloseConfirm: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PortId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyUpgrade", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4175,29 +9161,30 @@ func (m *MsgChannelCloseConfirm) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.PortId = string(dAtA[iNdEx:postIndex]) + if err := m.CounterpartyUpgrade.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 2: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofChannel", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4207,27 +9194,29 @@ func (m *MsgChannelCloseConfirm) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.ChannelId = string(dAtA[iNdEx:postIndex]) + m.ProofChannel = append(m.ProofChannel[:0], dAtA[iNdEx:postIndex]...) + if m.ProofChannel == nil { + m.ProofChannel = []byte{} + } iNdEx = postIndex - case 3: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgrade", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -4254,12 +9243,12 @@ func (m *MsgChannelCloseConfirm) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofInit = append(m.ProofInit[:0], dAtA[iNdEx:postIndex]...) - if m.ProofInit == nil { - m.ProofInit = []byte{} + m.ProofUpgrade = append(m.ProofUpgrade[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUpgrade == nil { + m.ProofUpgrade = []byte{} } iNdEx = postIndex - case 4: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -4292,7 +9281,7 @@ func (m *MsgChannelCloseConfirm) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -4345,7 +9334,7 @@ func (m *MsgChannelCloseConfirm) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChannelCloseConfirmResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeConfirmResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4368,12 +9357,31 @@ func (m *MsgChannelCloseConfirmResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChannelCloseConfirmResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeConfirmResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChannelCloseConfirmResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeConfirmResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + m.Result = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Result |= ResponseResultType(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -4395,7 +9403,7 @@ func (m *MsgChannelCloseConfirmResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgRecvPacket) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeOpen) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4405,30 +9413,62 @@ func (m *MsgRecvPacket) Unmarshal(dAtA []byte) error { if shift >= 64 { return ErrIntOverflowTx } - if iNdEx >= l { - return io.ErrUnexpectedEOF + 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: MsgChannelUpgradeOpen: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChannelUpgradeOpen: 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 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 } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if postIndex > l { + return io.ErrUnexpectedEOF } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MsgRecvPacket: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgRecvPacket: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + m.PortId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Packet", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4438,28 +9478,46 @@ func (m *MsgRecvPacket) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Packet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChannelState", wireType) + } + m.CounterpartyChannelState = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CounterpartyChannelState |= State(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofCommitment", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofChannel", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -4486,12 +9544,12 @@ func (m *MsgRecvPacket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofCommitment = append(m.ProofCommitment[:0], dAtA[iNdEx:postIndex]...) - if m.ProofCommitment == nil { - m.ProofCommitment = []byte{} + m.ProofChannel = append(m.ProofChannel[:0], dAtA[iNdEx:postIndex]...) + if m.ProofChannel == nil { + m.ProofChannel = []byte{} } iNdEx = postIndex - case 3: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -4524,7 +9582,7 @@ func (m *MsgRecvPacket) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -4577,7 +9635,7 @@ func (m *MsgRecvPacket) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgRecvPacketResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeOpenResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4600,31 +9658,12 @@ func (m *MsgRecvPacketResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgRecvPacketResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeOpenResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgRecvPacketResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeOpenResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) - } - m.Result = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Result |= ResponseResultType(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -4646,7 +9685,7 @@ func (m *MsgRecvPacketResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgTimeout) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeTimeout) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4669,17 +9708,17 @@ func (m *MsgTimeout) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgTimeout: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeTimeout: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgTimeout: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeTimeout: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Packet", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PortId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4689,30 +9728,29 @@ func (m *MsgTimeout) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Packet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.PortId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofUnreceived", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4722,29 +9760,27 @@ func (m *MsgTimeout) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofUnreceived = append(m.ProofUnreceived[:0], dAtA[iNdEx:postIndex]...) - if m.ProofUnreceived == nil { - m.ProofUnreceived = []byte{} - } + m.ChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChannel", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4771,15 +9807,15 @@ func (m *MsgTimeout) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.CounterpartyChannel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceRecv", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofChannel", wireType) } - m.NextSequenceRecv = 0 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4789,12 +9825,60 @@ func (m *MsgTimeout) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NextSequenceRecv |= uint64(b&0x7F) << shift + 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.ProofChannel = append(m.ProofChannel[:0], dAtA[iNdEx:postIndex]...) + if m.ProofChannel == nil { + m.ProofChannel = []byte{} + } + iNdEx = postIndex case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", 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.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -4847,7 +9931,7 @@ func (m *MsgTimeout) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgTimeoutResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeTimeoutResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4870,31 +9954,12 @@ func (m *MsgTimeoutResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgTimeoutResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeTimeoutResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgTimeoutResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeTimeoutResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) - } - m.Result = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Result |= ResponseResultType(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -4916,7 +9981,7 @@ func (m *MsgTimeoutResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgTimeoutOnClose) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeCancel) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4939,17 +10004,17 @@ func (m *MsgTimeoutOnClose) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgTimeoutOnClose: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeCancel: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgTimeoutOnClose: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeCancel: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Packet", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PortId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4959,30 +10024,29 @@ func (m *MsgTimeoutOnClose) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Packet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.PortId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofUnreceived", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -4992,29 +10056,60 @@ func (m *MsgTimeoutOnClose) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + 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 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ErrorReceipt", 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 byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofUnreceived = append(m.ProofUnreceived[:0], dAtA[iNdEx:postIndex]...) - if m.ProofUnreceived == nil { - m.ProofUnreceived = []byte{} + if err := m.ErrorReceipt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofClose", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofErrorReceipt", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -5041,12 +10136,12 @@ func (m *MsgTimeoutOnClose) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofClose = append(m.ProofClose[:0], dAtA[iNdEx:postIndex]...) - if m.ProofClose == nil { - m.ProofClose = []byte{} + m.ProofErrorReceipt = append(m.ProofErrorReceipt[:0], dAtA[iNdEx:postIndex]...) + if m.ProofErrorReceipt == nil { + m.ProofErrorReceipt = []byte{} } iNdEx = postIndex - case 4: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -5079,25 +10174,6 @@ func (m *MsgTimeoutOnClose) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceRecv", wireType) - } - m.NextSequenceRecv = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.NextSequenceRecv |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) @@ -5151,7 +10227,7 @@ func (m *MsgTimeoutOnClose) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgTimeoutOnCloseResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChannelUpgradeCancelResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5174,31 +10250,12 @@ func (m *MsgTimeoutOnCloseResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgTimeoutOnCloseResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChannelUpgradeCancelResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgTimeoutOnCloseResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChannelUpgradeCancelResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) - } - m.Result = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Result |= ResponseResultType(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -5220,7 +10277,7 @@ func (m *MsgTimeoutOnCloseResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgAcknowledgement) Unmarshal(dAtA []byte) error { +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5243,17 +10300,17 @@ func (m *MsgAcknowledgement) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgAcknowledgement: wiretype end group for non-group") + return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgAcknowledgement: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Packet", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -5263,30 +10320,29 @@ func (m *MsgAcknowledgement) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Packet.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Authority = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Acknowledgement", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -5296,31 +10352,130 @@ func (m *MsgAcknowledgement) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.Acknowledgement = append(m.Acknowledgement[:0], dAtA[iNdEx:postIndex]...) - if m.Acknowledgement == nil { - m.Acknowledgement = []byte{} + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex - case 3: + 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 *MsgUpdateParamsResponse) 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: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgPruneAcknowledgements) 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: MsgPruneAcknowledgements: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgPruneAcknowledgements: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofAcked", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PortId", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -5330,31 +10485,29 @@ func (m *MsgAcknowledgement) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofAcked = append(m.ProofAcked[:0], dAtA[iNdEx:postIndex]...) - if m.ProofAcked == nil { - m.ProofAcked = []byte{} - } + m.PortId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -5364,26 +10517,44 @@ func (m *MsgAcknowledgement) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ProofHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -5436,7 +10607,7 @@ func (m *MsgAcknowledgement) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgAcknowledgementResponse) Unmarshal(dAtA []byte) error { +func (m *MsgPruneAcknowledgementsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5459,17 +10630,17 @@ func (m *MsgAcknowledgementResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgAcknowledgementResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgPruneAcknowledgementsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgAcknowledgementResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgPruneAcknowledgementsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TotalPrunedSequences", wireType) } - m.Result = 0 + m.TotalPrunedSequences = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -5479,7 +10650,26 @@ func (m *MsgAcknowledgementResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Result |= ResponseResultType(b&0x7F) << shift + m.TotalPrunedSequences |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalRemainingSequences", wireType) + } + m.TotalRemainingSequences = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalRemainingSequences |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/modules/core/04-channel/types/upgrade.go b/modules/core/04-channel/types/upgrade.go new file mode 100644 index 00000000000..d96e41f5e3c --- /dev/null +++ b/modules/core/04-channel/types/upgrade.go @@ -0,0 +1,126 @@ +package types + +import ( + "errors" + "fmt" + "slices" + "strings" + + errorsmod "cosmossdk.io/errors" + + connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" +) + +// NewUpgrade creates a new Upgrade instance. +func NewUpgrade(upgradeFields UpgradeFields, timeout Timeout, nextSequenceSend uint64) Upgrade { + return Upgrade{ + Fields: upgradeFields, + Timeout: timeout, + NextSequenceSend: nextSequenceSend, + } +} + +// NewUpgradeFields returns a new ModifiableUpgradeFields instance. +func NewUpgradeFields(ordering Order, connectionHops []string, version string) UpgradeFields { + return UpgradeFields{ + Ordering: ordering, + ConnectionHops: connectionHops, + Version: version, + } +} + +// ValidateBasic performs a basic validation of the upgrade fields +func (u Upgrade) ValidateBasic() error { + if err := u.Fields.ValidateBasic(); err != nil { + return errorsmod.Wrap(err, "proposed upgrade fields are invalid") + } + + if !u.Timeout.IsValid() { + return errorsmod.Wrap(ErrInvalidUpgrade, "upgrade timeout height and upgrade timeout timestamp cannot both be 0") + } + + return nil +} + +// ValidateBasic performs a basic validation of the proposed upgrade fields +func (uf UpgradeFields) ValidateBasic() error { + if !slices.Contains(connectiontypes.SupportedOrderings, uf.Ordering.String()) { + return errorsmod.Wrap(ErrInvalidChannelOrdering, uf.Ordering.String()) + } + + if len(uf.ConnectionHops) != 1 { + return errorsmod.Wrap(ErrTooManyConnectionHops, "current IBC version only supports one connection hop") + } + + if strings.TrimSpace(uf.Version) == "" { + return errorsmod.Wrap(ErrInvalidChannelVersion, "version cannot be empty") + } + + return nil +} + +// UpgradeError defines an error that occurs during an upgrade. +type UpgradeError struct { + // err is the underlying error that caused the upgrade to fail. + // this error should not be written to state. + err error + // sequence is the upgrade sequence number of the upgrade that failed. + sequence uint64 +} + +var _ error = &UpgradeError{} + +// NewUpgradeError returns a new UpgradeError instance. +func NewUpgradeError(upgradeSequence uint64, err error) *UpgradeError { + return &UpgradeError{ + err: err, + sequence: upgradeSequence, + } +} + +// Error implements the error interface, returning the underlying error which caused the upgrade to fail. +func (u *UpgradeError) Error() string { + return u.err.Error() +} + +// Is returns true if the underlying error is of the given err type. +func (u *UpgradeError) Is(err error) bool { + return errors.Is(u.err, err) +} + +// Unwrap returns the base error that caused the upgrade to fail. +func (u *UpgradeError) Unwrap() error { + baseError := u.err + for { + if err := errors.Unwrap(baseError); err != nil { + baseError = err + } else { + return baseError + } + } +} + +// Cause implements the sdk error interface which uses this function to unwrap the error in various functions such as `wrappedError.Is()`. +// Cause returns the underlying error which caused the upgrade to fail. +func (u *UpgradeError) Cause() error { + return u.err +} + +// GetErrorReceipt returns an error receipt with the code from the underlying error type stripped. +func (u *UpgradeError) GetErrorReceipt() ErrorReceipt { + // restoreErrorString defines a string constant included in error receipts. + // NOTE: Changing this const is state machine breaking as it is written into state. + const restoreErrorString = "restored channel to pre-upgrade state" + + _, code, _ := errorsmod.ABCIInfo(u, false) // discard non-determinstic codespace and log values + return ErrorReceipt{ + Sequence: u.sequence, + Message: fmt.Sprintf("ABCI code: %d: %s", code, restoreErrorString), + } +} + +// IsUpgradeError returns true if err is of type UpgradeError, otherwise false. +func IsUpgradeError(err error) bool { + _, ok := err.(*UpgradeError) + return ok +} diff --git a/modules/core/04-channel/types/upgrade.pb.go b/modules/core/04-channel/types/upgrade.pb.go new file mode 100644 index 00000000000..e7931817125 --- /dev/null +++ b/modules/core/04-channel/types/upgrade.pb.go @@ -0,0 +1,842 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/core/channel/v1/upgrade.proto + +package types + +import ( + fmt "fmt" + _ "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 + +// Upgrade is a verifiable type which contains the relevant information +// for an attempted upgrade. It provides the proposed changes to the channel +// end, the timeout for this upgrade attempt and the next packet sequence +// which allows the counterparty to efficiently know the highest sequence it has received. +// The next sequence send is used for pruning and upgrading from unordered to ordered channels. +type Upgrade struct { + Fields UpgradeFields `protobuf:"bytes,1,opt,name=fields,proto3" json:"fields"` + Timeout Timeout `protobuf:"bytes,2,opt,name=timeout,proto3" json:"timeout"` + NextSequenceSend uint64 `protobuf:"varint,3,opt,name=next_sequence_send,json=nextSequenceSend,proto3" json:"next_sequence_send,omitempty"` +} + +func (m *Upgrade) Reset() { *m = Upgrade{} } +func (m *Upgrade) String() string { return proto.CompactTextString(m) } +func (*Upgrade) ProtoMessage() {} +func (*Upgrade) Descriptor() ([]byte, []int) { + return fileDescriptor_fb1cef68588848b2, []int{0} +} +func (m *Upgrade) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Upgrade) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Upgrade.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 *Upgrade) XXX_Merge(src proto.Message) { + xxx_messageInfo_Upgrade.Merge(m, src) +} +func (m *Upgrade) XXX_Size() int { + return m.Size() +} +func (m *Upgrade) XXX_DiscardUnknown() { + xxx_messageInfo_Upgrade.DiscardUnknown(m) +} + +var xxx_messageInfo_Upgrade proto.InternalMessageInfo + +// UpgradeFields are the fields in a channel end which may be changed +// during a channel upgrade. +type UpgradeFields struct { + Ordering Order `protobuf:"varint,1,opt,name=ordering,proto3,enum=ibc.core.channel.v1.Order" json:"ordering,omitempty"` + ConnectionHops []string `protobuf:"bytes,2,rep,name=connection_hops,json=connectionHops,proto3" json:"connection_hops,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` +} + +func (m *UpgradeFields) Reset() { *m = UpgradeFields{} } +func (m *UpgradeFields) String() string { return proto.CompactTextString(m) } +func (*UpgradeFields) ProtoMessage() {} +func (*UpgradeFields) Descriptor() ([]byte, []int) { + return fileDescriptor_fb1cef68588848b2, []int{1} +} +func (m *UpgradeFields) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UpgradeFields) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UpgradeFields.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 *UpgradeFields) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpgradeFields.Merge(m, src) +} +func (m *UpgradeFields) XXX_Size() int { + return m.Size() +} +func (m *UpgradeFields) XXX_DiscardUnknown() { + xxx_messageInfo_UpgradeFields.DiscardUnknown(m) +} + +var xxx_messageInfo_UpgradeFields proto.InternalMessageInfo + +// 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. +type ErrorReceipt struct { + // the channel upgrade sequence + Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` + // the error message detailing the cause of failure + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` +} + +func (m *ErrorReceipt) Reset() { *m = ErrorReceipt{} } +func (m *ErrorReceipt) String() string { return proto.CompactTextString(m) } +func (*ErrorReceipt) ProtoMessage() {} +func (*ErrorReceipt) Descriptor() ([]byte, []int) { + return fileDescriptor_fb1cef68588848b2, []int{2} +} +func (m *ErrorReceipt) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ErrorReceipt) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ErrorReceipt.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 *ErrorReceipt) XXX_Merge(src proto.Message) { + xxx_messageInfo_ErrorReceipt.Merge(m, src) +} +func (m *ErrorReceipt) XXX_Size() int { + return m.Size() +} +func (m *ErrorReceipt) XXX_DiscardUnknown() { + xxx_messageInfo_ErrorReceipt.DiscardUnknown(m) +} + +var xxx_messageInfo_ErrorReceipt proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Upgrade)(nil), "ibc.core.channel.v1.Upgrade") + proto.RegisterType((*UpgradeFields)(nil), "ibc.core.channel.v1.UpgradeFields") + proto.RegisterType((*ErrorReceipt)(nil), "ibc.core.channel.v1.ErrorReceipt") +} + +func init() { proto.RegisterFile("ibc/core/channel/v1/upgrade.proto", fileDescriptor_fb1cef68588848b2) } + +var fileDescriptor_fb1cef68588848b2 = []byte{ + // 406 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0xc7, 0xe3, 0xad, 0x5a, 0x57, 0x03, 0x03, 0x19, 0x0e, 0x51, 0x85, 0xb2, 0xd2, 0x0b, 0x3d, + 0xb0, 0x98, 0x0d, 0x84, 0x00, 0x71, 0x40, 0x93, 0x40, 0x88, 0x0b, 0x92, 0x0b, 0x17, 0x2e, 0x55, + 0xe3, 0x3c, 0x52, 0x4b, 0x8d, 0x5f, 0xb0, 0x9d, 0x08, 0xbe, 0x01, 0xc7, 0x7d, 0x04, 0xbe, 0x08, + 0xf7, 0x1d, 0x77, 0xe4, 0x84, 0x50, 0xfb, 0x45, 0x50, 0x9c, 0xa4, 0x68, 0x52, 0x6e, 0x7e, 0x7e, + 0xbf, 0xff, 0xdf, 0xff, 0xe7, 0x47, 0x1f, 0xa8, 0x44, 0x72, 0x89, 0x06, 0xb8, 0x5c, 0x2d, 0xb5, + 0x86, 0x35, 0xaf, 0x4e, 0x79, 0x59, 0x64, 0x66, 0x99, 0x42, 0x5c, 0x18, 0x74, 0xc8, 0xee, 0xaa, + 0x44, 0xc6, 0x35, 0x12, 0xb7, 0x48, 0x5c, 0x9d, 0x8e, 0xef, 0x65, 0x98, 0xa1, 0xef, 0xf3, 0xfa, + 0xd4, 0xa0, 0xe3, 0x5e, 0xb7, 0x4e, 0xe5, 0x91, 0xe9, 0x2f, 0x42, 0x87, 0x9f, 0x1a, 0x7f, 0xf6, + 0x9a, 0x1e, 0x7c, 0x51, 0xb0, 0x4e, 0x6d, 0x48, 0x26, 0x64, 0x76, 0xe3, 0x6c, 0x1a, 0xf7, 0x3c, + 0x15, 0xb7, 0xf4, 0x5b, 0x4f, 0x9e, 0x0f, 0x2e, 0xff, 0x1c, 0x07, 0xa2, 0xd5, 0xb1, 0x57, 0x74, + 0xe8, 0x54, 0x0e, 0x58, 0xba, 0x70, 0xcf, 0x5b, 0xdc, 0xef, 0xb5, 0xf8, 0xd8, 0x30, 0xad, 0xb8, + 0x93, 0xb0, 0x47, 0x94, 0x69, 0xf8, 0xe6, 0x16, 0x16, 0xbe, 0x96, 0xa0, 0x25, 0x2c, 0x2c, 0xe8, + 0x34, 0xdc, 0x9f, 0x90, 0xd9, 0x40, 0xdc, 0xa9, 0x3b, 0xf3, 0xb6, 0x31, 0x07, 0x9d, 0xbe, 0x1c, + 0xfc, 0xf8, 0x79, 0x1c, 0x4c, 0x2f, 0x08, 0xbd, 0x75, 0x2d, 0x11, 0x7b, 0x46, 0x0f, 0xd1, 0xa4, + 0x60, 0x94, 0xce, 0xfc, 0x1c, 0x47, 0x67, 0xe3, 0xde, 0x10, 0x1f, 0x6a, 0x48, 0xec, 0x58, 0xf6, + 0x90, 0xde, 0x96, 0xa8, 0x35, 0x48, 0xa7, 0x50, 0x2f, 0x56, 0x58, 0xd8, 0x70, 0x6f, 0xb2, 0x3f, + 0x1b, 0x89, 0xa3, 0xff, 0xd7, 0xef, 0xb0, 0xb0, 0x2c, 0xa4, 0xc3, 0x0a, 0x8c, 0x55, 0xa8, 0x7d, + 0xb6, 0x91, 0xe8, 0xca, 0x36, 0xd2, 0x7b, 0x7a, 0xf3, 0x8d, 0x31, 0x68, 0x04, 0x48, 0x50, 0x85, + 0x63, 0x63, 0x7a, 0xd8, 0x4d, 0xe4, 0x03, 0x0d, 0xc4, 0xae, 0xae, 0xbd, 0x72, 0xb0, 0x76, 0x99, + 0x81, 0xff, 0xb0, 0x91, 0xe8, 0xca, 0xc6, 0xeb, 0x7c, 0x7e, 0xb9, 0x89, 0xc8, 0xd5, 0x26, 0x22, + 0x7f, 0x37, 0x11, 0xb9, 0xd8, 0x46, 0xc1, 0xd5, 0x36, 0x0a, 0x7e, 0x6f, 0xa3, 0xe0, 0xf3, 0x8b, + 0x4c, 0xb9, 0x55, 0x99, 0xc4, 0x12, 0x73, 0x2e, 0xd1, 0xe6, 0x68, 0xb9, 0x4a, 0xe4, 0x49, 0x86, + 0xbc, 0x7a, 0xce, 0x73, 0x4c, 0xcb, 0x35, 0xd8, 0x66, 0xf7, 0x8f, 0x9f, 0x9e, 0x74, 0xeb, 0x77, + 0xdf, 0x0b, 0xb0, 0xc9, 0x81, 0x5f, 0xfd, 0x93, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x31, + 0xc0, 0xc6, 0x6d, 0x02, 0x00, 0x00, +} + +func (m *Upgrade) 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 *Upgrade) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Upgrade) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.NextSequenceSend != 0 { + i = encodeVarintUpgrade(dAtA, i, uint64(m.NextSequenceSend)) + i-- + dAtA[i] = 0x18 + } + { + size, err := m.Timeout.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintUpgrade(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.Fields.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintUpgrade(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *UpgradeFields) 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 *UpgradeFields) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UpgradeFields) 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 = encodeVarintUpgrade(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x1a + } + if len(m.ConnectionHops) > 0 { + for iNdEx := len(m.ConnectionHops) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ConnectionHops[iNdEx]) + copy(dAtA[i:], m.ConnectionHops[iNdEx]) + i = encodeVarintUpgrade(dAtA, i, uint64(len(m.ConnectionHops[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if m.Ordering != 0 { + i = encodeVarintUpgrade(dAtA, i, uint64(m.Ordering)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ErrorReceipt) 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 *ErrorReceipt) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ErrorReceipt) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Message) > 0 { + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarintUpgrade(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x12 + } + if m.Sequence != 0 { + i = encodeVarintUpgrade(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintUpgrade(dAtA []byte, offset int, v uint64) int { + offset -= sovUpgrade(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Upgrade) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Fields.Size() + n += 1 + l + sovUpgrade(uint64(l)) + l = m.Timeout.Size() + n += 1 + l + sovUpgrade(uint64(l)) + if m.NextSequenceSend != 0 { + n += 1 + sovUpgrade(uint64(m.NextSequenceSend)) + } + return n +} + +func (m *UpgradeFields) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Ordering != 0 { + n += 1 + sovUpgrade(uint64(m.Ordering)) + } + if len(m.ConnectionHops) > 0 { + for _, s := range m.ConnectionHops { + l = len(s) + n += 1 + l + sovUpgrade(uint64(l)) + } + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovUpgrade(uint64(l)) + } + return n +} + +func (m *ErrorReceipt) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sequence != 0 { + n += 1 + sovUpgrade(uint64(m.Sequence)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + sovUpgrade(uint64(l)) + } + return n +} + +func sovUpgrade(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozUpgrade(x uint64) (n int) { + return sovUpgrade(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Upgrade) 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 ErrIntOverflowUpgrade + } + 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: Upgrade: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Upgrade: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Fields", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUpgrade + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthUpgrade + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthUpgrade + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Fields.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timeout", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUpgrade + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthUpgrade + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthUpgrade + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Timeout.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextSequenceSend", wireType) + } + m.NextSequenceSend = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUpgrade + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextSequenceSend |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipUpgrade(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthUpgrade + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UpgradeFields) 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 ErrIntOverflowUpgrade + } + 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: UpgradeFields: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UpgradeFields: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowUpgrade + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ordering |= Order(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionHops", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUpgrade + } + 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 ErrInvalidLengthUpgrade + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthUpgrade + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConnectionHops = append(m.ConnectionHops, 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 ErrIntOverflowUpgrade + } + 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 ErrInvalidLengthUpgrade + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthUpgrade + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipUpgrade(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthUpgrade + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ErrorReceipt) 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 ErrIntOverflowUpgrade + } + 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: ErrorReceipt: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ErrorReceipt: 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 ErrIntOverflowUpgrade + } + 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 Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowUpgrade + } + 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 ErrInvalidLengthUpgrade + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthUpgrade + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipUpgrade(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthUpgrade + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipUpgrade(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, ErrIntOverflowUpgrade + } + 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, ErrIntOverflowUpgrade + } + 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, ErrIntOverflowUpgrade + } + 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, ErrInvalidLengthUpgrade + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupUpgrade + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthUpgrade + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthUpgrade = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowUpgrade = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupUpgrade = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/core/04-channel/types/upgrade_test.go b/modules/core/04-channel/types/upgrade_test.go new file mode 100644 index 00000000000..3bf7cf67d54 --- /dev/null +++ b/modules/core/04-channel/types/upgrade_test.go @@ -0,0 +1,215 @@ +package types_test + +import ( + "errors" + + errorsmod "cosmossdk.io/errors" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + "github.com/cosmos/ibc-go/v8/testing/mock" +) + +func (suite *TypesTestSuite) TestUpgradeValidateBasic() { + var upgrade types.Upgrade + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid ordering", + func() { + upgrade.Fields.Ordering = types.NONE + }, + false, + }, + { + "connection hops length not equal to 1", + func() { + upgrade.Fields.ConnectionHops = []string{"connection-0", "connection-1"} + }, + false, + }, + { + "empty version", + func() { + upgrade.Fields.Version = " " + }, + false, + }, + { + "invalid timeout", + func() { + upgrade.Timeout.Height = clienttypes.ZeroHeight() + upgrade.Timeout.Timestamp = 0 + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + upgrade = types.NewUpgrade( + types.NewUpgradeFields(types.ORDERED, []string{ibctesting.FirstConnectionID}, mock.Version), + types.NewTimeout(clienttypes.NewHeight(0, 100), 0), + 0, + ) + + tc.malleate() + + err := upgrade.ValidateBasic() + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} + +func (suite *TypesTestSuite) TestUpgradeErrorIsOf() { + var ( + upgradeError *types.UpgradeError + inputErr error + ) + + testCases := []struct { + msg string + malleate func() + expPass bool + }{ + { + msg: "standard sdk error", + malleate: func() {}, + expPass: true, + }, + { + msg: "input is upgrade error", + malleate: func() { + inputErr = types.NewUpgradeError(1, types.ErrInvalidChannel) + }, + expPass: true, + }, + { + msg: "input has wrapped upgrade error", + malleate: func() { + wrappedErr := errorsmod.Wrap(types.ErrInvalidChannel, "wrapped upgrade error") + inputErr = types.NewUpgradeError(1, wrappedErr) + }, + expPass: true, + }, + { + msg: "not equal to nil error", + malleate: func() { + upgradeError = &types.UpgradeError{} + }, + expPass: false, + }, + { + msg: "wrapped upgrade error", + malleate: func() { + wrappedErr := errorsmod.Wrap(upgradeError, "wrapped upgrade error") + upgradeError = types.NewUpgradeError(1, wrappedErr) + }, + expPass: true, + }, + { + msg: "empty upgrade and non nil target", + malleate: func() { + upgradeError = &types.UpgradeError{} + }, + expPass: false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.msg, func() { + upgradeError = types.NewUpgradeError(1, types.ErrInvalidChannel) + inputErr = types.ErrInvalidChannel + + tc.malleate() + + res := errorsmod.IsOf(upgradeError, inputErr) + suite.Require().Equal(tc.expPass, res) + }) + } +} + +// TestGetErrorReceipt tests that the error receipt message is the same for both wrapped and unwrapped errors. +func (suite *TypesTestSuite) TestGetErrorReceipt() { + upgradeError := types.NewUpgradeError(1, types.ErrInvalidChannel) + + wrappedErr := errorsmod.Wrap(upgradeError, "wrapped upgrade error") + suite.Require().True(errorsmod.IsOf(wrappedErr, types.ErrInvalidChannel)) + + upgradeError2 := types.NewUpgradeError(1, wrappedErr) + + suite.Require().Equal(upgradeError2.GetErrorReceipt().Message, upgradeError.GetErrorReceipt().Message) +} + +// TestUpgradeErrorUnwrap tests that the underlying error is not modified when Unwrap is called. +func (suite *TypesTestSuite) TestUpgradeErrorUnwrap() { + baseUnderlyingError := errorsmod.Wrap(types.ErrInvalidChannel, "base error") + wrappedErr := errorsmod.Wrap(baseUnderlyingError, "wrapped error") + upgradeError := types.NewUpgradeError(1, wrappedErr) + + originalUpgradeError := upgradeError.Error() + unWrapped := errors.Unwrap(upgradeError) + postUnwrapUpgradeError := upgradeError.Error() + + suite.Require().Equal(types.ErrInvalidChannel, unWrapped, "unwrapped error was not equal to base underlying error") + suite.Require().Equal(originalUpgradeError, postUnwrapUpgradeError, "original error was modified when unwrapped") +} + +func (suite *TypesTestSuite) TestIsUpgradeError() { + var err error + + testCases := []struct { + msg string + malleate func() + expPass bool + }{ + { + "true", + func() {}, + true, + }, + { + "false with non upgrade error", + func() { + err = errors.New("error") + }, + false, + }, + { + "false with nil error", + func() { + err = nil + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.msg, func() { + err = types.NewUpgradeError(1, types.ErrInvalidChannel) + + tc.malleate() + + res := types.IsUpgradeError(err) + suite.Require().Equal(tc.expPass, res) + }) + } +} diff --git a/modules/core/05-port/types/module.go b/modules/core/05-port/types/module.go index a72ff9658ec..a5c6386f926 100644 --- a/modules/core/05-port/types/module.go +++ b/modules/core/05-port/types/module.go @@ -106,6 +106,52 @@ type IBCModule interface { ) error } +// UpgradableModule defines the callbacks required to perform a channel upgrade. +type UpgradableModule interface { + // OnChanUpgradeInit initializes the channel upgrade handshake. + OnChanUpgradeInit( + ctx sdk.Context, + portID, channelID string, + order channeltypes.Order, + connectionHops []string, + version string, + ) (string, error) + + // OnChanUpgradeTry verifies the counterparty upgrade and sets the upgrade on TRY chain + OnChanUpgradeTry( + ctx sdk.Context, + portID, channelID string, + order channeltypes.Order, + connectionHops []string, + counterpartyVersion string, + ) (string, error) + + // OnChanUpgradeAck TODO + OnChanUpgradeAck( + ctx sdk.Context, + portID, + channelID, + counterpartyVersion string, + ) error + + // OnChanUpgradeOpen TODO + OnChanUpgradeOpen( + ctx sdk.Context, + portID, + channelID string, + order channeltypes.Order, + connectionHops []string, + version string, + ) + + // OnChanUpgradeRestore TODO + OnChanUpgradeRestore( + ctx sdk.Context, + portID, + channelID string, + ) +} + // ICS4Wrapper implements the ICS4 interfaces that IBC applications use to send packets and acknowledgements. type ICS4Wrapper interface { SendPacket( diff --git a/modules/core/24-host/channel_keys.go b/modules/core/24-host/channel_keys.go new file mode 100644 index 00000000000..b21666dd3b6 --- /dev/null +++ b/modules/core/24-host/channel_keys.go @@ -0,0 +1,66 @@ +package host + +import "fmt" + +const ( + KeyChannelEndPrefix = "channelEnds" + KeyChannelPrefix = "channels" + KeyChannelUpgradePrefix = "channelUpgrades" + KeyUpgradePrefix = "upgrades" + KeyUpgradeErrorPrefix = "upgradeError" + KeyCounterpartyUpgrade = "counterpartyUpgrade" + KeyChannelCapabilityPrefix = "capabilities" +) + +// ICS04 +// The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#store-paths + +// ChannelPath defines the path under which channels are stored +func ChannelPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s", KeyChannelEndPrefix, channelPath(portID, channelID)) +} + +// ChannelKey returns the store key for a particular channel +func ChannelKey(portID, channelID string) []byte { + return []byte(ChannelPath(portID, channelID)) +} + +// ChannelCapabilityPath defines the path under which capability keys associated +// with a channel are stored +func ChannelCapabilityPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s", KeyChannelCapabilityPrefix, channelPath(portID, channelID)) +} + +// ChannelUpgradeErrorPath defines the path under which the ErrorReceipt is stored in the case that a chain does not accept the proposed upgrade +func ChannelUpgradeErrorPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s/%s", KeyChannelUpgradePrefix, KeyUpgradeErrorPrefix, channelPath(portID, channelID)) +} + +// ChannelUpgradeErrorKey returns the store key for a particular channelEnd used to stor the ErrorReceipt in the case that a chain does not accept the proposed upgrade +func ChannelUpgradeErrorKey(portID, channelID string) []byte { + return []byte(ChannelUpgradeErrorPath(portID, channelID)) +} + +// ChannelUpgradePath defines the path which stores the information related to an upgrade attempt +func ChannelUpgradePath(portID, channelID string) string { + return fmt.Sprintf("%s/%s/%s", KeyChannelUpgradePrefix, KeyUpgradePrefix, channelPath(portID, channelID)) +} + +// ChannelUpgradeKey returns the store key for a particular channel upgrade attempt +func ChannelUpgradeKey(portID, channelID string) []byte { + return []byte(ChannelUpgradePath(portID, channelID)) +} + +// ChannelCounterpartyUpgradeKey returns the store key for the upgrade used on the counterparty channel. +func ChannelCounterpartyUpgradeKey(portID, channelID string) []byte { + return []byte(ChannelCounterpartyUpgradePath(portID, channelID)) +} + +// ChannelCounterpartyUpgradePath defines the path under which the upgrade used on the counterparty channel is stored. +func ChannelCounterpartyUpgradePath(portID, channelID string) string { + return fmt.Sprintf("%s/%s/%s", KeyChannelUpgradePrefix, KeyCounterpartyUpgrade, channelPath(portID, channelID)) +} + +func channelPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s/%s/%s", KeyPortPrefix, portID, KeyChannelPrefix, channelID) +} diff --git a/modules/core/24-host/client_keys.go b/modules/core/24-host/client_keys.go new file mode 100644 index 00000000000..4b12bc63e5a --- /dev/null +++ b/modules/core/24-host/client_keys.go @@ -0,0 +1,86 @@ +package host + +import ( + "fmt" + + "github.com/cosmos/ibc-go/v8/modules/core/exported" +) + +// KeyClientStorePrefix defines the KVStore key prefix for IBC clients +var KeyClientStorePrefix = []byte("clients") + +const ( + KeyClientState = "clientState" + KeyConsensusStatePrefix = "consensusStates" +) + +// FullClientPath returns the full path of a specific client path in the format: +// "clients/{clientID}/{path}" as a string. +func FullClientPath(clientID string, path string) string { + return fmt.Sprintf("%s/%s/%s", KeyClientStorePrefix, clientID, path) +} + +// FullClientKey returns the full path of specific client path in the format: +// "clients/{clientID}/{path}" as a byte array. +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 + +// FullClientStatePath takes a client identifier and returns a Path under which to store a +// particular client state +func FullClientStatePath(clientID string) string { + return FullClientPath(clientID, KeyClientState) +} + +// FullClientStateKey takes a client identifier and returns a Key under which to store a +// particular client state. +func FullClientStateKey(clientID string) []byte { + return FullClientKey(clientID, []byte(KeyClientState)) +} + +// ClientStateKey returns a store key under which a particular client state is stored +// in a client prefixed store +func ClientStateKey() []byte { + return []byte(KeyClientState) +} + +// FullConsensusStatePath takes a client identifier and returns a Path under which to +// store the consensus state of a client. +func FullConsensusStatePath(clientID string, height exported.Height) string { + return FullClientPath(clientID, ConsensusStatePath(height)) +} + +// FullConsensusStateKey returns the store key for the consensus state of a particular +// client. +func FullConsensusStateKey(clientID string, height exported.Height) []byte { + return []byte(FullConsensusStatePath(clientID, height)) +} + +// ConsensusStatePath returns the suffix store key for the consensus state at a +// particular height stored in a client prefixed store. +func ConsensusStatePath(height exported.Height) string { + return fmt.Sprintf("%s/%s", KeyConsensusStatePrefix, height) +} + +// ConsensusStateKey returns the store key for a the consensus state of a particular +// client stored in a client prefixed store. +func ConsensusStateKey(height exported.Height) []byte { + return []byte(ConsensusStatePath(height)) +} diff --git a/modules/core/24-host/connection_keys.go b/modules/core/24-host/connection_keys.go new file mode 100644 index 00000000000..fde9ee3b730 --- /dev/null +++ b/modules/core/24-host/connection_keys.go @@ -0,0 +1,28 @@ +package host + +import "fmt" + +const KeyConnectionPrefix = "connections" + +// ICS03 +// The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics#store-paths + +// ClientConnectionsPath defines a reverse mapping from clients to a set of connections +func ClientConnectionsPath(clientID string) string { + return FullClientPath(clientID, KeyConnectionPrefix) +} + +// ClientConnectionsKey returns the store key for the connections of a given client +func ClientConnectionsKey(clientID string) []byte { + return []byte(ClientConnectionsPath(clientID)) +} + +// ConnectionPath defines the path under which connection paths are stored +func ConnectionPath(connectionID string) string { + return fmt.Sprintf("%s/%s", KeyConnectionPrefix, connectionID) +} + +// ConnectionKey returns the store key for a particular connection +func ConnectionKey(connectionID string) []byte { + return []byte(ConnectionPath(connectionID)) +} diff --git a/modules/core/24-host/keys.go b/modules/core/24-host/keys.go deleted file mode 100644 index 9e018f8f0d8..00000000000 --- a/modules/core/24-host/keys.go +++ /dev/null @@ -1,235 +0,0 @@ -package host - -import ( - "fmt" - - "github.com/cosmos/ibc-go/v8/modules/core/exported" -) - -// KVStore key prefixes for IBC -var ( - KeyClientStorePrefix = []byte("clients") -) - -// KVStore key prefixes for IBC -const ( - KeyClientState = "clientState" - KeyConsensusStatePrefix = "consensusStates" - KeyConnectionPrefix = "connections" - KeyChannelEndPrefix = "channelEnds" - KeyChannelPrefix = "channels" - KeyPortPrefix = "ports" - KeySequencePrefix = "sequences" - KeyChannelCapabilityPrefix = "capabilities" - KeyNextSeqSendPrefix = "nextSequenceSend" - KeyNextSeqRecvPrefix = "nextSequenceRecv" - KeyNextSeqAckPrefix = "nextSequenceAck" - KeyPacketCommitmentPrefix = "commitments" - KeyPacketAckPrefix = "acks" - KeyPacketReceiptPrefix = "receipts" -) - -// FullClientPath returns the full path of a specific client path in the format: -// "clients/{clientID}/{path}" as a string. -func FullClientPath(clientID string, path string) string { - return fmt.Sprintf("%s/%s/%s", KeyClientStorePrefix, clientID, path) -} - -// FullClientKey returns the full path of specific client path in the format: -// "clients/{clientID}/{path}" as a byte array. -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 - -// FullClientStatePath takes a client identifier and returns a Path under which to store a -// particular client state -func FullClientStatePath(clientID string) string { - return FullClientPath(clientID, KeyClientState) -} - -// FullClientStateKey takes a client identifier and returns a Key under which to store a -// particular client state. -func FullClientStateKey(clientID string) []byte { - return FullClientKey(clientID, []byte(KeyClientState)) -} - -// ClientStateKey returns a store key under which a particular client state is stored -// in a client prefixed store -func ClientStateKey() []byte { - return []byte(KeyClientState) -} - -// FullConsensusStatePath takes a client identifier and returns a Path under which to -// store the consensus state of a client. -func FullConsensusStatePath(clientID string, height exported.Height) string { - return FullClientPath(clientID, ConsensusStatePath(height)) -} - -// FullConsensusStateKey returns the store key for the consensus state of a particular -// client. -func FullConsensusStateKey(clientID string, height exported.Height) []byte { - return []byte(FullConsensusStatePath(clientID, height)) -} - -// ConsensusStatePath returns the suffix store key for the consensus state at a -// particular height stored in a client prefixed store. -func ConsensusStatePath(height exported.Height) string { - return fmt.Sprintf("%s/%s", KeyConsensusStatePrefix, height) -} - -// ConsensusStateKey returns the store key for a the consensus state of a particular -// client stored in a client prefixed store. -func ConsensusStateKey(height exported.Height) []byte { - return []byte(ConsensusStatePath(height)) -} - -// ICS03 -// The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics#store-paths - -// ClientConnectionsPath defines a reverse mapping from clients to a set of connections -func ClientConnectionsPath(clientID string) string { - return FullClientPath(clientID, KeyConnectionPrefix) -} - -// ClientConnectionsKey returns the store key for the connections of a given client -func ClientConnectionsKey(clientID string) []byte { - return []byte(ClientConnectionsPath(clientID)) -} - -// ConnectionPath defines the path under which connection paths are stored -func ConnectionPath(connectionID string) string { - return fmt.Sprintf("%s/%s", KeyConnectionPrefix, connectionID) -} - -// ConnectionKey returns the store key for a particular connection -func ConnectionKey(connectionID string) []byte { - return []byte(ConnectionPath(connectionID)) -} - -// ICS04 -// The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#store-paths - -// ChannelPath defines the path under which channels are stored -func ChannelPath(portID, channelID string) string { - return fmt.Sprintf("%s/%s", KeyChannelEndPrefix, channelPath(portID, channelID)) -} - -// ChannelKey returns the store key for a particular channel -func ChannelKey(portID, channelID string) []byte { - return []byte(ChannelPath(portID, channelID)) -} - -// ChannelCapabilityPath defines the path under which capability keys associated -// with a channel are stored -func ChannelCapabilityPath(portID, channelID string) string { - return fmt.Sprintf("%s/%s", KeyChannelCapabilityPrefix, channelPath(portID, channelID)) -} - -// NextSequenceSendPath defines the next send sequence counter store path -func NextSequenceSendPath(portID, channelID string) string { - return fmt.Sprintf("%s/%s", KeyNextSeqSendPrefix, channelPath(portID, channelID)) -} - -// NextSequenceSendKey returns the store key for the send sequence of a particular -// channel binded to a specific port. -func NextSequenceSendKey(portID, channelID string) []byte { - return []byte(NextSequenceSendPath(portID, channelID)) -} - -// NextSequenceRecvPath defines the next receive sequence counter store path. -func NextSequenceRecvPath(portID, channelID string) string { - return fmt.Sprintf("%s/%s", KeyNextSeqRecvPrefix, channelPath(portID, channelID)) -} - -// NextSequenceRecvKey returns the store key for the receive sequence of a particular -// channel binded to a specific port -func NextSequenceRecvKey(portID, channelID string) []byte { - return []byte(NextSequenceRecvPath(portID, channelID)) -} - -// NextSequenceAckPath defines the next acknowledgement sequence counter store path -func NextSequenceAckPath(portID, channelID string) string { - return fmt.Sprintf("%s/%s", KeyNextSeqAckPrefix, channelPath(portID, channelID)) -} - -// NextSequenceAckKey returns the store key for the acknowledgement sequence of -// a particular channel binded to a specific port. -func NextSequenceAckKey(portID, channelID string) []byte { - return []byte(NextSequenceAckPath(portID, channelID)) -} - -// PacketCommitmentPath defines the commitments to packet data fields store path -func PacketCommitmentPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/%d", PacketCommitmentPrefixPath(portID, channelID), sequence) -} - -// PacketCommitmentKey returns the store key of under which a packet commitment -// is stored -func PacketCommitmentKey(portID, channelID string, sequence uint64) []byte { - return []byte(PacketCommitmentPath(portID, channelID, sequence)) -} - -// PacketCommitmentPrefixPath defines the prefix for commitments to packet data fields store path. -func PacketCommitmentPrefixPath(portID, channelID string) string { - return fmt.Sprintf("%s/%s/%s", KeyPacketCommitmentPrefix, channelPath(portID, channelID), KeySequencePrefix) -} - -// PacketAcknowledgementPath defines the packet acknowledgement store path -func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/%d", PacketAcknowledgementPrefixPath(portID, channelID), sequence) -} - -// PacketAcknowledgementKey returns the store key of under which a packet -// acknowledgement is stored -func PacketAcknowledgementKey(portID, channelID string, sequence uint64) []byte { - return []byte(PacketAcknowledgementPath(portID, channelID, sequence)) -} - -// PacketAcknowledgementPrefixPath defines the prefix for commitments to packet data fields store path. -func PacketAcknowledgementPrefixPath(portID, channelID string) string { - return fmt.Sprintf("%s/%s/%s", KeyPacketAckPrefix, channelPath(portID, channelID), KeySequencePrefix) -} - -// PacketReceiptPath defines the packet receipt store path -func PacketReceiptPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/%s/%s", KeyPacketReceiptPrefix, channelPath(portID, channelID), sequencePath(sequence)) -} - -// PacketReceiptKey returns the store key of under which a packet -// receipt is stored -func PacketReceiptKey(portID, channelID string, sequence uint64) []byte { - return []byte(PacketReceiptPath(portID, channelID, sequence)) -} - -func channelPath(portID, channelID string) string { - return fmt.Sprintf("%s/%s/%s/%s", KeyPortPrefix, portID, KeyChannelPrefix, channelID) -} - -func sequencePath(sequence uint64) string { - return fmt.Sprintf("%s/%d", KeySequencePrefix, sequence) -} - -// ICS05 -// The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-005-port-allocation#store-paths - -// PortPath defines the path under which ports paths are stored on the capability module -func PortPath(portID string) string { - return fmt.Sprintf("%s/%s", KeyPortPrefix, portID) -} diff --git a/modules/core/24-host/packet_keys.go b/modules/core/24-host/packet_keys.go new file mode 100644 index 00000000000..75730e57d73 --- /dev/null +++ b/modules/core/24-host/packet_keys.go @@ -0,0 +1,118 @@ +package host + +import "fmt" + +const ( + KeySequencePrefix = "sequences" + KeyNextSeqSendPrefix = "nextSequenceSend" + KeyNextSeqRecvPrefix = "nextSequenceRecv" + KeyNextSeqAckPrefix = "nextSequenceAck" + KeyPacketCommitmentPrefix = "commitments" + KeyPacketAckPrefix = "acks" + KeyPacketReceiptPrefix = "receipts" + KeyPruningSequenceStart = "pruningSequenceStart" + KeyPruningSequenceEnd = "pruningSequenceEnd" +) + +// ICS04 +// The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#store-paths + +// NextSequenceSendPath defines the next send sequence counter store path +func NextSequenceSendPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s", KeyNextSeqSendPrefix, channelPath(portID, channelID)) +} + +// NextSequenceSendKey returns the store key for the send sequence of a particular +// channel binded to a specific port. +func NextSequenceSendKey(portID, channelID string) []byte { + return []byte(NextSequenceSendPath(portID, channelID)) +} + +// NextSequenceRecvPath defines the next receive sequence counter store path. +func NextSequenceRecvPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s", KeyNextSeqRecvPrefix, channelPath(portID, channelID)) +} + +// NextSequenceRecvKey returns the store key for the receive sequence of a particular +// channel binded to a specific port +func NextSequenceRecvKey(portID, channelID string) []byte { + return []byte(NextSequenceRecvPath(portID, channelID)) +} + +// NextSequenceAckPath defines the next acknowledgement sequence counter store path +func NextSequenceAckPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s", KeyNextSeqAckPrefix, channelPath(portID, channelID)) +} + +// NextSequenceAckKey returns the store key for the acknowledgement sequence of +// a particular channel binded to a specific port. +func NextSequenceAckKey(portID, channelID string) []byte { + return []byte(NextSequenceAckPath(portID, channelID)) +} + +// PacketCommitmentPath defines the commitments to packet data fields store path +func PacketCommitmentPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%s/%d", PacketCommitmentPrefixPath(portID, channelID), sequence) +} + +// PacketCommitmentKey returns the store key of under which a packet commitment +// is stored +func PacketCommitmentKey(portID, channelID string, sequence uint64) []byte { + return []byte(PacketCommitmentPath(portID, channelID, sequence)) +} + +// PacketCommitmentPrefixPath defines the prefix for commitments to packet data fields store path. +func PacketCommitmentPrefixPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s/%s", KeyPacketCommitmentPrefix, channelPath(portID, channelID), KeySequencePrefix) +} + +// PacketAcknowledgementPath defines the packet acknowledgement store path +func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%s/%d", PacketAcknowledgementPrefixPath(portID, channelID), sequence) +} + +// PacketAcknowledgementKey returns the store key of under which a packet +// acknowledgement is stored +func PacketAcknowledgementKey(portID, channelID string, sequence uint64) []byte { + return []byte(PacketAcknowledgementPath(portID, channelID, sequence)) +} + +// PacketAcknowledgementPrefixPath defines the prefix for commitments to packet data fields store path. +func PacketAcknowledgementPrefixPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s/%s", KeyPacketAckPrefix, channelPath(portID, channelID), KeySequencePrefix) +} + +// PacketReceiptPath defines the packet receipt store path +func PacketReceiptPath(portID, channelID string, sequence uint64) string { + return fmt.Sprintf("%s/%s/%s", KeyPacketReceiptPrefix, channelPath(portID, channelID), sequencePath(sequence)) +} + +// PacketReceiptKey returns the store key of under which a packet +// receipt is stored +func PacketReceiptKey(portID, channelID string, sequence uint64) []byte { + return []byte(PacketReceiptPath(portID, channelID, sequence)) +} + +// PruningSequenceStartPath defines the path under which the pruning sequence starting value is stored +func PruningSequenceStartPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s", KeyPruningSequenceStart, channelPath(portID, channelID)) +} + +// PruningSequenceStartKey returns the store key for the pruning sequence start of a particular channel +func PruningSequenceStartKey(portID, channelID string) []byte { + return []byte(PruningSequenceStartPath(portID, channelID)) +} + +// PruningSequenceEndPath defines the path under which the pruning sequence end is stored +func PruningSequenceEndPath(portID, channelID string) string { + return fmt.Sprintf("%s/%s", KeyPruningSequenceEnd, channelPath(portID, channelID)) +} + +// PruningSequenceEndKey returns the store key for the pruning sequence end of a particular channel +func PruningSequenceEndKey(portID, channelID string) []byte { + return []byte(PruningSequenceEndPath(portID, channelID)) +} + +func sequencePath(sequence uint64) string { + return fmt.Sprintf("%s/%d", KeySequencePrefix, sequence) +} diff --git a/modules/core/24-host/port_keys.go b/modules/core/24-host/port_keys.go new file mode 100644 index 00000000000..9bd720065c2 --- /dev/null +++ b/modules/core/24-host/port_keys.go @@ -0,0 +1,15 @@ +package host + +import "fmt" + +const ( + KeyPortPrefix = "ports" +) + +// ICS05 +// The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-005-port-allocation#store-paths + +// PortPath defines the path under which ports paths are stored on the capability module +func PortPath(portID string) string { + return fmt.Sprintf("%s/%s", KeyPortPrefix, portID) +} diff --git a/modules/core/keeper/grpc_query.go b/modules/core/keeper/grpc_query.go index bfdce2c6015..59807638af0 100644 --- a/modules/core/keeper/grpc_query.go +++ b/modules/core/keeper/grpc_query.go @@ -152,3 +152,18 @@ func (k Keeper) NextSequenceReceive(c context.Context, req *channeltypes.QueryNe func (k Keeper) NextSequenceSend(c context.Context, req *channeltypes.QueryNextSequenceSendRequest) (*channeltypes.QueryNextSequenceSendResponse, error) { return k.ChannelKeeper.NextSequenceSend(c, req) } + +// UpgradeError implements the IBC QueryServer interface +func (k Keeper) UpgradeError(c context.Context, req *channeltypes.QueryUpgradeErrorRequest) (*channeltypes.QueryUpgradeErrorResponse, error) { + return k.ChannelKeeper.UpgradeErrorReceipt(c, req) +} + +// Upgrade implements the IBC QueryServer interface +func (k Keeper) Upgrade(c context.Context, req *channeltypes.QueryUpgradeRequest) (*channeltypes.QueryUpgradeResponse, error) { + return k.ChannelKeeper.Upgrade(c, req) +} + +// ChannelParams implements the IBC QueryServer interface +func (k Keeper) ChannelParams(c context.Context, req *channeltypes.QueryChannelParamsRequest) (*channeltypes.QueryChannelParamsResponse, error) { + return k.ChannelKeeper.ChannelParams(c, req) +} diff --git a/modules/core/keeper/msg_server.go b/modules/core/keeper/msg_server.go index 922c365842b..dfa2c0a9342 100644 --- a/modules/core/keeper/msg_server.go +++ b/modules/core/keeper/msg_server.go @@ -12,6 +12,7 @@ import ( clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + "github.com/cosmos/ibc-go/v8/modules/core/04-channel/keeper" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" @@ -431,7 +432,7 @@ func (k Keeper) ChannelCloseConfirm(goCtx context.Context, msg *channeltypes.Msg 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, capability, msg.ProofInit, msg.ProofHeight) + err = k.ChannelKeeper.ChanCloseConfirmWithCounterpartyUpgradeSequence(ctx, msg.PortId, msg.ChannelId, capability, msg.ProofInit, msg.ProofHeight, msg.CounterpartyUpgradeSequence) if err != nil { ctx.Logger().Error("channel close confirm failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) return nil, errorsmod.Wrap(err, "channel handshake close confirm failed") @@ -621,7 +622,7 @@ func (k Keeper) TimeoutOnClose(goCtx context.Context, msg *channeltypes.MsgTimeo // If the timeout was already received, perform a no-op // Use a cached context to prevent accidental state changes cacheCtx, writeFn := ctx.CacheContext() - err = k.ChannelKeeper.TimeoutOnClose(cacheCtx, capability, msg.Packet, msg.ProofUnreceived, msg.ProofClose, msg.ProofHeight, msg.NextSequenceRecv) + err = k.ChannelKeeper.TimeoutOnCloseWithCounterpartyUpgradeSequence(cacheCtx, capability, msg.Packet, msg.ProofUnreceived, msg.ProofClose, msg.ProofHeight, msg.NextSequenceRecv, msg.CounterpartyUpgradeSequence) switch err { case nil: @@ -733,6 +734,381 @@ func (k Keeper) Acknowledgement(goCtx context.Context, msg *channeltypes.MsgAckn return &channeltypes.MsgAcknowledgementResponse{Result: channeltypes.SUCCESS}, nil } +// ChannelUpgradeInit defines a rpc handler method for MsgChannelUpgradeInit. +func (k Keeper) ChannelUpgradeInit(goCtx context.Context, msg *channeltypes.MsgChannelUpgradeInit) (*channeltypes.MsgChannelUpgradeInitResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if k.GetAuthority() != msg.Signer { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Signer) + } + + module, _, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) + if err != nil { + ctx.Logger().Error("channel upgrade init 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") + } + + app, ok := k.Router.GetRoute(module) + if !ok { + ctx.Logger().Error("channel upgrade init 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) + } + + cbs, ok := app.(porttypes.UpgradableModule) + if !ok { + ctx.Logger().Error("channel upgrade init failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module) + } + + upgrade, err := k.ChannelKeeper.ChanUpgradeInit(ctx, msg.PortId, msg.ChannelId, msg.Fields) + if err != nil { + ctx.Logger().Error("channel upgrade init failed", "error", errorsmod.Wrap(err, "channel upgrade init failed")) + return nil, errorsmod.Wrap(err, "channel upgrade init failed") + } + + upgradeVersion, err := cbs.OnChanUpgradeInit( + ctx, + msg.PortId, + msg.ChannelId, + upgrade.Fields.Ordering, + upgrade.Fields.ConnectionHops, + upgrade.Fields.Version, + ) + if err != nil { + ctx.Logger().Error("channel upgrade init callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + return nil, errorsmod.Wrapf(err, "channel upgrade init callback failed for port ID: %s, channel ID: %s", msg.PortId, msg.ChannelId) + } + + channel, upgrade := k.ChannelKeeper.WriteUpgradeInitChannel(ctx, msg.PortId, msg.ChannelId, upgrade, upgradeVersion) + + ctx.Logger().Info("channel upgrade init succeeded", "channel-id", msg.ChannelId, "version", upgradeVersion) + keeper.EmitChannelUpgradeInitEvent(ctx, msg.PortId, msg.ChannelId, channel, upgrade) + + return &channeltypes.MsgChannelUpgradeInitResponse{ + Upgrade: upgrade, + UpgradeSequence: channel.UpgradeSequence, + }, nil +} + +// ChannelUpgradeTry defines a rpc handler method for MsgChannelUpgradeTry. +func (k Keeper) ChannelUpgradeTry(goCtx context.Context, msg *channeltypes.MsgChannelUpgradeTry) (*channeltypes.MsgChannelUpgradeTryResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + module, _, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) + if err != nil { + ctx.Logger().Error("channel upgrade try 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") + } + + app, ok := k.Router.GetRoute(module) + if !ok { + ctx.Logger().Error("channel upgrade try 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) + } + + cbs, ok := app.(porttypes.UpgradableModule) + if !ok { + ctx.Logger().Error("channel upgrade try failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module) + } + + channel, upgrade, err := k.ChannelKeeper.ChanUpgradeTry(ctx, msg.PortId, msg.ChannelId, msg.ProposedUpgradeConnectionHops, msg.CounterpartyUpgradeFields, msg.CounterpartyUpgradeSequence, msg.ProofChannel, msg.ProofUpgrade, msg.ProofHeight) + if err != nil { + ctx.Logger().Error("channel upgrade try failed", "error", errorsmod.Wrap(err, "channel upgrade try failed")) + if channeltypes.IsUpgradeError(err) { + k.ChannelKeeper.SetUpgradeErrorReceipt(ctx, msg.PortId, msg.ChannelId, err.(*channeltypes.UpgradeError).GetErrorReceipt()) + keeper.EmitErrorReceiptEvent(ctx, msg.PortId, msg.ChannelId, channel, err) + // NOTE: a FAILURE result is returned to the client and an error receipt is written to state. + // This signals to the relayer to begin the cancel upgrade handshake subprotocol. + return &channeltypes.MsgChannelUpgradeTryResponse{Result: channeltypes.FAILURE}, nil + } + + // NOTE: an error is returned to baseapp and transaction state is not committed. + return nil, errorsmod.Wrap(err, "channel upgrade try failed") + } + + upgradeVersion, err := cbs.OnChanUpgradeTry(ctx, msg.PortId, msg.ChannelId, upgrade.Fields.Ordering, upgrade.Fields.ConnectionHops, upgrade.Fields.Version) + if err != nil { + ctx.Logger().Error("channel upgrade try callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + return nil, err + } + + channel, upgrade = k.ChannelKeeper.WriteUpgradeTryChannel(ctx, msg.PortId, msg.ChannelId, upgrade, upgradeVersion) + + ctx.Logger().Info("channel upgrade try succeeded", "port-id", msg.PortId, "channel-id", msg.ChannelId) + keeper.EmitChannelUpgradeTryEvent(ctx, msg.PortId, msg.ChannelId, channel, upgrade) + + return &channeltypes.MsgChannelUpgradeTryResponse{ + Result: channeltypes.SUCCESS, + Upgrade: upgrade, + UpgradeSequence: channel.UpgradeSequence, + }, nil +} + +// ChannelUpgradeAck defines a rpc handler method for MsgChannelUpgradeAck. +func (k Keeper) ChannelUpgradeAck(goCtx context.Context, msg *channeltypes.MsgChannelUpgradeAck) (*channeltypes.MsgChannelUpgradeAckResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + module, _, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) + if err != nil { + ctx.Logger().Error("channel upgrade ack 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") + } + + app, ok := k.Router.GetRoute(module) + if !ok { + ctx.Logger().Error("channel upgrade ack 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) + } + + cbs, ok := app.(porttypes.UpgradableModule) + if !ok { + ctx.Logger().Error("channel upgrade ack failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module) + } + + err = k.ChannelKeeper.ChanUpgradeAck(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyUpgrade, msg.ProofChannel, msg.ProofUpgrade, msg.ProofHeight) + if err != nil { + ctx.Logger().Error("channel upgrade ack failed", "error", errorsmod.Wrap(err, "channel upgrade ack failed")) + if channeltypes.IsUpgradeError(err) { + k.ChannelKeeper.MustAbortUpgrade(ctx, msg.PortId, msg.ChannelId, err) + cbs.OnChanUpgradeRestore(ctx, msg.PortId, msg.ChannelId) + + // NOTE: a FAILURE result is returned to the client and an error receipt is written to state. + // This signals to the relayer to begin the cancel upgrade handshake subprotocol. + return &channeltypes.MsgChannelUpgradeAckResponse{Result: channeltypes.FAILURE}, nil + } + + // NOTE: an error is returned to baseapp and transaction state is not committed. + return nil, errorsmod.Wrap(err, "channel upgrade ack failed") + } + + cacheCtx, writeFn := ctx.CacheContext() + err = cbs.OnChanUpgradeAck(cacheCtx, msg.PortId, msg.ChannelId, msg.CounterpartyUpgrade.Fields.Version) + if err != nil { + ctx.Logger().Error("channel upgrade ack callback failed", "port-id", msg.PortId, "channel-id", msg.ChannelId, "error", err.Error()) + k.ChannelKeeper.MustAbortUpgrade(ctx, msg.PortId, msg.ChannelId, err) + cbs.OnChanUpgradeRestore(ctx, msg.PortId, msg.ChannelId) + + return &channeltypes.MsgChannelUpgradeAckResponse{Result: channeltypes.FAILURE}, nil + } + + writeFn() + + channel, upgrade := k.ChannelKeeper.WriteUpgradeAckChannel(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyUpgrade) + + ctx.Logger().Info("channel upgrade ack succeeded", "port-id", msg.PortId, "channel-id", msg.ChannelId) + keeper.EmitChannelUpgradeAckEvent(ctx, msg.PortId, msg.ChannelId, channel, upgrade) + + return &channeltypes.MsgChannelUpgradeAckResponse{Result: channeltypes.SUCCESS}, nil +} + +// ChannelUpgradeConfirm defines a rpc handler method for MsgChannelUpgradeConfirm. +func (k Keeper) ChannelUpgradeConfirm(goCtx context.Context, msg *channeltypes.MsgChannelUpgradeConfirm) (*channeltypes.MsgChannelUpgradeConfirmResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + module, _, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) + if err != nil { + ctx.Logger().Error("channel upgrade confirm 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") + } + + app, ok := k.Router.GetRoute(module) + if !ok { + ctx.Logger().Error("channel upgrade confirm 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) + } + + cbs, ok := app.(porttypes.UpgradableModule) + if !ok { + ctx.Logger().Error("channel upgrade confirm failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module) + } + + err = k.ChannelKeeper.ChanUpgradeConfirm(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyChannelState, msg.CounterpartyUpgrade, msg.ProofChannel, msg.ProofUpgrade, msg.ProofHeight) + if err != nil { + ctx.Logger().Error("channel upgrade confirm failed", "error", errorsmod.Wrap(err, "channel upgrade confirm failed")) + if channeltypes.IsUpgradeError(err) { + k.ChannelKeeper.MustAbortUpgrade(ctx, msg.PortId, msg.ChannelId, err) + cbs.OnChanUpgradeRestore(ctx, msg.PortId, msg.ChannelId) + + // NOTE: a FAILURE result is returned to the client and an error receipt is written to state. + // This signals to the relayer to begin the cancel upgrade handshake subprotocol. + return &channeltypes.MsgChannelUpgradeConfirmResponse{Result: channeltypes.FAILURE}, nil + } + + // NOTE: an error is returned to baseapp and transaction state is not committed. + return nil, errorsmod.Wrap(err, "channel upgrade confirm failed") + } + + channel := k.ChannelKeeper.WriteUpgradeConfirmChannel(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyUpgrade) + ctx.Logger().Info("channel upgrade confirm succeeded", "port-id", msg.PortId, "channel-id", msg.ChannelId) + keeper.EmitChannelUpgradeConfirmEvent(ctx, msg.PortId, msg.ChannelId, channel) + + // Move channel to OPEN state if both chains have finished flushing in-flight packets. + // Counterparty channel state has been verified in ChanUpgradeConfirm. + if msg.CounterpartyChannelState == channeltypes.FLUSHCOMPLETE && !k.ChannelKeeper.HasInflightPackets(ctx, msg.PortId, msg.ChannelId) { + upgrade, found := k.ChannelKeeper.GetUpgrade(ctx, msg.PortId, msg.ChannelId) + if !found { + return nil, errorsmod.Wrapf(channeltypes.ErrUpgradeNotFound, "failed to retrieve channel upgrade: port ID (%s) channel ID (%s)", msg.PortId, msg.ChannelId) + } + + k.ChannelKeeper.WriteUpgradeOpenChannel(ctx, msg.PortId, msg.ChannelId) + cbs.OnChanUpgradeOpen(ctx, msg.PortId, msg.ChannelId, upgrade.Fields.Ordering, upgrade.Fields.ConnectionHops, upgrade.Fields.Version) + + ctx.Logger().Info("channel upgrade open succeeded", "port-id", msg.PortId, "channel-id", msg.ChannelId) + keeper.EmitChannelUpgradeOpenEvent(ctx, msg.PortId, msg.ChannelId, channel) + } + + return &channeltypes.MsgChannelUpgradeConfirmResponse{Result: channeltypes.SUCCESS}, nil +} + +// ChannelUpgradeOpen defines a rpc handler method for MsgChannelUpgradeOpen. +func (k Keeper) ChannelUpgradeOpen(goCtx context.Context, msg *channeltypes.MsgChannelUpgradeOpen) (*channeltypes.MsgChannelUpgradeOpenResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + module, _, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) + if err != nil { + ctx.Logger().Error("channel upgrade open 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") + } + + app, ok := k.Router.GetRoute(module) + if !ok { + ctx.Logger().Error("channel upgrade open 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) + } + + cbs, ok := app.(porttypes.UpgradableModule) + if !ok { + ctx.Logger().Error("channel upgrade open failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module) + } + + if err = k.ChannelKeeper.ChanUpgradeOpen(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyChannelState, msg.ProofChannel, msg.ProofHeight); err != nil { + ctx.Logger().Error("channel upgrade open failed", "error", errorsmod.Wrap(err, "channel upgrade open failed")) + return nil, errorsmod.Wrap(err, "channel upgrade open failed") + } + + upgrade, found := k.ChannelKeeper.GetUpgrade(ctx, msg.PortId, msg.ChannelId) + if !found { + return nil, errorsmod.Wrapf(channeltypes.ErrUpgradeNotFound, "failed to retrieve channel upgrade: port ID (%s) channel ID (%s)", msg.PortId, msg.ChannelId) + } + + cbs.OnChanUpgradeOpen(ctx, msg.PortId, msg.ChannelId, upgrade.Fields.Ordering, upgrade.Fields.ConnectionHops, upgrade.Fields.Version) + + channel := k.ChannelKeeper.WriteUpgradeOpenChannel(ctx, msg.PortId, msg.ChannelId) + + ctx.Logger().Info("channel upgrade open succeeded", "port-id", msg.PortId, "channel-id", msg.ChannelId) + keeper.EmitChannelUpgradeOpenEvent(ctx, msg.PortId, msg.ChannelId, channel) + + return &channeltypes.MsgChannelUpgradeOpenResponse{}, nil +} + +// ChannelUpgradeTimeout defines a rpc handler method for MsgChannelUpgradeTimeout. +func (k Keeper) ChannelUpgradeTimeout(goCtx context.Context, msg *channeltypes.MsgChannelUpgradeTimeout) (*channeltypes.MsgChannelUpgradeTimeoutResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + module, _, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) + if err != nil { + ctx.Logger().Error("channel upgrade timeout 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") + } + + app, ok := k.Router.GetRoute(module) + if !ok { + ctx.Logger().Error("channel upgrade timeout 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) + } + + cbs, ok := app.(porttypes.UpgradableModule) + if !ok { + ctx.Logger().Error("channel upgrade timeout failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module) + } + + err = k.ChannelKeeper.ChanUpgradeTimeout(ctx, msg.PortId, msg.ChannelId, msg.CounterpartyChannel, msg.ProofChannel, msg.ProofHeight) + if err != nil { + return nil, errorsmod.Wrapf(err, "could not timeout upgrade for channel: %s", msg.ChannelId) + } + + channel, upgrade := k.ChannelKeeper.WriteUpgradeTimeoutChannel(ctx, msg.PortId, msg.ChannelId) + + cbs.OnChanUpgradeRestore(ctx, msg.PortId, msg.ChannelId) + + ctx.Logger().Info("channel upgrade timeout callback succeeded: portID %s, channelID %s", msg.PortId, msg.ChannelId) + keeper.EmitChannelUpgradeTimeoutEvent(ctx, msg.PortId, msg.ChannelId, channel, upgrade) + + return &channeltypes.MsgChannelUpgradeTimeoutResponse{}, nil +} + +// ChannelUpgradeCancel defines a rpc handler method for MsgChannelUpgradeCancel. +func (k Keeper) ChannelUpgradeCancel(goCtx context.Context, msg *channeltypes.MsgChannelUpgradeCancel) (*channeltypes.MsgChannelUpgradeCancelResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + module, _, err := k.ChannelKeeper.LookupModuleByChannel(ctx, msg.PortId, msg.ChannelId) + if err != nil { + ctx.Logger().Error("channel upgrade cancel 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") + } + + app, ok := k.Router.GetRoute(module) + if !ok { + ctx.Logger().Error("channel upgrade cancel 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) + } + + cbs, ok := app.(porttypes.UpgradableModule) + if !ok { + ctx.Logger().Error("channel upgrade cancel failed", "port-id", msg.PortId, "error", errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module)) + return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "upgrade route not found to module: %s", module) + } + + channel, found := k.ChannelKeeper.GetChannel(ctx, msg.PortId, msg.ChannelId) + if !found { + return nil, errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "port ID (%s) channel ID (%s)", msg.PortId, msg.ChannelId) + } + + // if the msgSender is authorized to make and cancel upgrades AND the current channel has not already reached FLUSHCOMPLETE + // then we can restore immediately without any additional checks + isAuthority := k.GetAuthority() == msg.Signer + if isAuthority && channel.State != channeltypes.FLUSHCOMPLETE { + k.ChannelKeeper.WriteUpgradeCancelChannel(ctx, msg.PortId, msg.ChannelId, channel.UpgradeSequence) + + cbs.OnChanUpgradeRestore(ctx, msg.PortId, msg.ChannelId) + + ctx.Logger().Info("channel upgrade cancel succeeded", "port-id", msg.PortId, "channel-id", msg.ChannelId) + + return &channeltypes.MsgChannelUpgradeCancelResponse{}, nil + } + + if err := k.ChannelKeeper.ChanUpgradeCancel(ctx, msg.PortId, msg.ChannelId, msg.ErrorReceipt, msg.ProofErrorReceipt, msg.ProofHeight); err != nil { + ctx.Logger().Error("channel upgrade cancel failed", "port-id", msg.PortId, "error", err.Error()) + return nil, errorsmod.Wrap(err, "channel upgrade cancel failed") + } + + k.ChannelKeeper.WriteUpgradeCancelChannel(ctx, msg.PortId, msg.ChannelId, msg.ErrorReceipt.Sequence) + + cbs.OnChanUpgradeRestore(ctx, msg.PortId, msg.ChannelId) + + ctx.Logger().Info("channel upgrade cancel succeeded", "port-id", msg.PortId, "channel-id", msg.ChannelId) + + return &channeltypes.MsgChannelUpgradeCancelResponse{}, nil +} + +// PruneAcknowledgements defines a rpc handler method for MsgPruneAcknowledgements. +func (k Keeper) PruneAcknowledgements(goCtx context.Context, msg *channeltypes.MsgPruneAcknowledgements) (*channeltypes.MsgPruneAcknowledgementsResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + pruned, remaining, err := k.ChannelKeeper.PruneAcknowledgements(ctx, msg.PortId, msg.ChannelId, msg.Limit) + if err != nil { + return nil, err + } + + return &channeltypes.MsgPruneAcknowledgementsResponse{ + TotalPrunedSequences: pruned, + TotalRemainingSequences: remaining, + }, nil +} + // UpdateClientParams defines a rpc handler method for MsgUpdateParams. func (k Keeper) UpdateClientParams(goCtx context.Context, msg *clienttypes.MsgUpdateParams) (*clienttypes.MsgUpdateParamsResponse, error) { if k.GetAuthority() != msg.Signer { @@ -756,3 +1132,15 @@ func (k Keeper) UpdateConnectionParams(goCtx context.Context, msg *connectiontyp return &connectiontypes.MsgUpdateParamsResponse{}, nil } + +// UpdateChannelParams defines a rpc handler method for MsgUpdateParams. +func (k Keeper) UpdateChannelParams(goCtx context.Context, msg *channeltypes.MsgUpdateParams) (*channeltypes.MsgUpdateParamsResponse, error) { + if k.GetAuthority() != msg.Authority { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + k.ChannelKeeper.SetParams(ctx, msg.Params) + + return &channeltypes.MsgUpdateParamsResponse{}, nil +} diff --git a/modules/core/keeper/msg_server_test.go b/modules/core/keeper/msg_server_test.go index 84298ae0481..6ae1f45af1a 100644 --- a/modules/core/keeper/msg_server_test.go +++ b/modules/core/keeper/msg_server_test.go @@ -2,11 +2,14 @@ package keeper_test import ( "errors" + "fmt" upgradetypes "cosmossdk.io/x/upgrade/types" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" @@ -202,6 +205,82 @@ func (suite *KeeperTestSuite) TestHandleRecvPacket() { } } +func (suite *KeeperTestSuite) TestRecoverClient() { + var msg *clienttypes.MsgRecoverClient + + testCases := []struct { + name string + malleate func() + expErr error + }{ + { + "success: recover client", + func() {}, + nil, + }, + { + "signer doesn't match authority", + func() { + msg.Signer = ibctesting.InvalidID + }, + ibcerrors.ErrUnauthorized, + }, + { + "invalid subject client", + func() { + msg.SubjectClientId = ibctesting.InvalidID + }, + clienttypes.ErrClientNotFound, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + subjectPath := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupClients(subjectPath) + subject := subjectPath.EndpointA.ClientID + subjectClientState := suite.chainA.GetClientState(subject) + + substitutePath := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupClients(substitutePath) + substitute := substitutePath.EndpointA.ClientID + + // update substitute twice + err := substitutePath.EndpointA.UpdateClient() + suite.Require().NoError(err) + err = substitutePath.EndpointA.UpdateClient() + suite.Require().NoError(err) + + tmClientState, ok := subjectClientState.(*ibctm.ClientState) + suite.Require().True(ok) + tmClientState.FrozenHeight = tmClientState.LatestHeight + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState) + + msg = clienttypes.NewMsgRecoverClient(suite.chainA.App.GetIBCKeeper().GetAuthority(), subject, substitute) + + tc.malleate() + + _, err = keeper.Keeper.RecoverClient(*suite.chainA.App.GetIBCKeeper(), suite.chainA.GetContext(), msg) + + expPass := tc.expErr == nil + if expPass { + suite.Require().NoError(err) + + // Assert that client status is now Active + clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), subjectPath.EndpointA.ClientID) + tmClientState := subjectPath.EndpointA.GetClientState().(*ibctm.ClientState) + suite.Require().Equal(tmClientState.Status(suite.chainA.GetContext(), clientStore, suite.chainA.App.AppCodec()), exported.Active) + } else { + suite.Require().Error(err) + suite.Require().ErrorIs(err, tc.expErr) + } + }) + } +} + // tests the IBC handler acknowledgement of a packet on ordered and unordered // channels. It verifies that the deletion of packet commitments from state // occurs. It test high level properties like ordering and basic sanity @@ -499,9 +578,10 @@ func (suite *KeeperTestSuite) TestHandleTimeoutPacket() { // 'TimeoutExecuted' can be found in the 04-channel/keeper/timeout_test.go. func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { var ( - packet channeltypes.Packet - packetKey []byte - path *ibctesting.Path + packet channeltypes.Packet + packetKey []byte + path *ibctesting.Path + counterpartyUpgradeSequence uint64 ) testCases := []struct { @@ -638,7 +718,7 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { channelKey := host.ChannelKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) proofClosed, _ := suite.chainB.QueryProof(channelKey) - msg := channeltypes.NewMsgTimeoutOnClose(packet, 1, proof, proofClosed, proofHeight, suite.chainA.SenderAccount.GetAddress().String()) + msg := channeltypes.NewMsgTimeoutOnCloseWithCounterpartyUpgradeSequence(packet, 1, proof, proofClosed, proofHeight, suite.chainA.SenderAccount.GetAddress().String(), counterpartyUpgradeSequence) _, err := keeper.Keeper.TimeoutOnClose(*suite.chainA.App.GetIBCKeeper(), suite.chainA.GetContext(), msg) @@ -780,187 +860,1083 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { } } -func (suite *KeeperTestSuite) TestRecoverClient() { - var msg *clienttypes.MsgRecoverClient +func (suite *KeeperTestSuite) TestChannelUpgradeInit() { + var ( + path *ibctesting.Path + msg *channeltypes.MsgChannelUpgradeInit + ) - testCases := []struct { - name string - malleate func() - expErr error + cases := []struct { + name string + malleate func() + expResult func(res *channeltypes.MsgChannelUpgradeInitResponse, err error) }{ { - "success: recover client", - func() {}, - nil, - }, - { - "signer doesn't match authority", + "success", func() { - msg.Signer = ibctesting.InvalidID + msg = channeltypes.NewMsgChannelUpgradeInit( + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + path.EndpointA.GetProposedUpgrade().Fields, + path.EndpointA.Chain.GetSimApp().IBCKeeper.GetAuthority(), + ) + }, + func(res *channeltypes.MsgChannelUpgradeInitResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(uint64(1), res.UpgradeSequence) }, - ibcerrors.ErrUnauthorized, }, { - "invalid subject client", + "authority is not signer of the upgrade init msg", func() { - msg.SubjectClientId = ibctesting.InvalidID + msg = channeltypes.NewMsgChannelUpgradeInit( + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + path.EndpointA.GetProposedUpgrade().Fields, + path.EndpointA.Chain.SenderAccount.String(), + ) + }, + func(res *channeltypes.MsgChannelUpgradeInitResponse, err error) { + suite.Require().Error(err) + suite.Require().ErrorContains(err, ibcerrors.ErrUnauthorized.Error()) + suite.Require().Nil(res) }, - clienttypes.ErrClientNotFound, }, } - for _, tc := range testCases { + for _, tc := range cases { tc := tc suite.Run(tc.name, func() { suite.SetupTest() - subjectPath := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(subjectPath) - subject := subjectPath.EndpointA.ClientID - subjectClientState := suite.chainA.GetClientState(subject) - - substitutePath := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(substitutePath) - substitute := substitutePath.EndpointA.ClientID - - // update substitute twice - err := substitutePath.EndpointA.UpdateClient() - suite.Require().NoError(err) - err = substitutePath.EndpointA.UpdateClient() - suite.Require().NoError(err) - - tmClientState, ok := subjectClientState.(*ibctm.ClientState) - suite.Require().True(ok) - tmClientState.FrozenHeight = tmClientState.LatestHeight - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState) + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) - msg = clienttypes.NewMsgRecoverClient(suite.chainA.App.GetIBCKeeper().GetAuthority(), subject, substitute) + // configure the channel upgrade version on testing endpoints + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion tc.malleate() - _, err = keeper.Keeper.RecoverClient(*suite.chainA.App.GetIBCKeeper(), suite.chainA.GetContext(), msg) - - expPass := tc.expErr == nil - if expPass { - suite.Require().NoError(err) + res, err := keeper.Keeper.ChannelUpgradeInit(*suite.chainA.App.GetIBCKeeper(), suite.chainA.GetContext(), msg) - // Assert that client status is now Active - clientStore := suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), subjectPath.EndpointA.ClientID) - tmClientState := subjectPath.EndpointA.GetClientState().(*ibctm.ClientState) - suite.Require().Equal(tmClientState.Status(suite.chainA.GetContext(), clientStore, suite.chainA.App.AppCodec()), exported.Active) - } else { - suite.Require().Error(err) - suite.Require().ErrorIs(err, tc.expErr) - } + tc.expResult(res, err) }) } } -// TestIBCSoftwareUpgrade tests the IBCSoftwareUpgrade rpc handler -func (suite *KeeperTestSuite) TestIBCSoftwareUpgrade() { - var msg *clienttypes.MsgIBCSoftwareUpgrade - testCases := []struct { - name string - malleate func() - expError error +func (suite *KeeperTestSuite) TestChannelUpgradeTry() { + var ( + path *ibctesting.Path + msg *channeltypes.MsgChannelUpgradeTry + ) + + cases := []struct { + name string + malleate func() + expResult func(res *channeltypes.MsgChannelUpgradeTryResponse, err error) }{ { - "success: valid authority and client upgrade", + "success", func() {}, - nil, - }, - { - "failure: invalid authority address", - func() { - msg.Signer = suite.chainA.SenderAccount.GetAddress().String() + func(res *channeltypes.MsgChannelUpgradeTryResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.SUCCESS, res.Result) + + channel := path.EndpointB.GetChannel() + suite.Require().Equal(channeltypes.FLUSHING, channel.State) + suite.Require().Equal(uint64(1), channel.UpgradeSequence) }, - ibcerrors.ErrUnauthorized, }, { - "failure: invalid clientState", + "module capability not found", func() { - msg.UpgradedClientState = nil + msg.PortId = "invalid-port" + msg.ChannelId = "invalid-channel" + }, + func(res *channeltypes.MsgChannelUpgradeTryResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + + suite.Require().ErrorIs(err, capabilitytypes.ErrCapabilityNotFound) }, - clienttypes.ErrInvalidClientType, }, { - "failure: failed to schedule client upgrade", + "unsynchronized upgrade sequence writes upgrade error receipt", func() { - msg.Plan.Height = 0 + channel := path.EndpointB.GetChannel() + channel.UpgradeSequence = 99 + + path.EndpointB.SetChannel(channel) + }, + func(res *channeltypes.MsgChannelUpgradeTryResponse, err error) { + suite.Require().NoError(err) + + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.FAILURE, res.Result) + + errorReceipt, found := suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(99), errorReceipt.Sequence) }, - sdkerrors.ErrInvalidRequest, }, } - for _, tc := range testCases { + for _, tc := range cases { tc := tc suite.Run(tc.name, func() { - path := ibctesting.NewPath(suite.chainA, suite.chainB) - suite.coordinator.SetupClients(path) - validAuthority := suite.chainA.App.GetIBCKeeper().GetAuthority() - plan := upgradetypes.Plan{ - Name: "upgrade IBC clients", - Height: 1000, - } - // update trusting period - clientState := path.EndpointB.GetClientState() - clientState.(*ibctm.ClientState).TrustingPeriod += 100 + suite.SetupTest() - var err error - msg, err = clienttypes.NewMsgIBCSoftwareUpgrade( - validAuthority, - plan, - clientState, - ) + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade version on testing endpoints + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + err := path.EndpointA.ChanUpgradeInit() suite.Require().NoError(err) - tc.malleate() + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) - _, err = keeper.Keeper.IBCSoftwareUpgrade(*suite.chainA.App.GetIBCKeeper(), suite.chainA.GetContext(), msg) + counterpartySequence := path.EndpointA.GetChannel().UpgradeSequence + counterpartyUpgrade, found := suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + + proofChannel, proofUpgrade, proofHeight := path.EndpointA.QueryChannelUpgradeProof() + + msg = &channeltypes.MsgChannelUpgradeTry{ + PortId: path.EndpointB.ChannelConfig.PortID, + ChannelId: path.EndpointB.ChannelID, + ProposedUpgradeConnectionHops: []string{ibctesting.FirstConnectionID}, + CounterpartyUpgradeSequence: counterpartySequence, + CounterpartyUpgradeFields: counterpartyUpgrade.Fields, + ProofChannel: proofChannel, + ProofUpgrade: proofUpgrade, + ProofHeight: proofHeight, + Signer: suite.chainB.SenderAccount.GetAddress().String(), + } - if tc.expError == nil { - suite.Require().NoError(err) - // upgrade plan is stored - storedPlan, err := suite.chainA.GetSimApp().UpgradeKeeper.GetUpgradePlan(suite.chainA.GetContext()) - suite.Require().NoError(err) - suite.Require().Equal(plan, storedPlan) + tc.malleate() - // upgraded client state is stored - bz, err := suite.chainA.GetSimApp().UpgradeKeeper.GetUpgradedClient(suite.chainA.GetContext(), plan.Height) - suite.Require().NoError(err) - upgradedClientState, err := clienttypes.UnmarshalClientState(suite.chainA.App.AppCodec(), bz) - suite.Require().NoError(err) - suite.Require().Equal(clientState.ZeroCustomFields(), upgradedClientState) - } else { - suite.Require().True(errors.Is(err, tc.expError)) - } + res, err := suite.chainB.GetSimApp().GetIBCKeeper().ChannelUpgradeTry(suite.chainB.GetContext(), msg) + + tc.expResult(res, err) }) } } -// TestUpdateClientParams tests the UpdateClientParams rpc handler -func (suite *KeeperTestSuite) TestUpdateClientParams() { - signer := suite.chainA.App.GetIBCKeeper().GetAuthority() - testCases := []struct { - name string - msg *clienttypes.MsgUpdateParams - expPass bool +func (suite *KeeperTestSuite) TestChannelUpgradeAck() { + var ( + path *ibctesting.Path + msg *channeltypes.MsgChannelUpgradeAck + ) + + cases := []struct { + name string + malleate func() + expResult func(res *channeltypes.MsgChannelUpgradeAckResponse, err error) }{ { - "success: valid signer and default params", - clienttypes.NewMsgUpdateParams(signer, clienttypes.DefaultParams()), - true, - }, - { - "failure: malformed signer address", - clienttypes.NewMsgUpdateParams(ibctesting.InvalidID, clienttypes.DefaultParams()), - false, + "success, no pending in-flight packets", + func() {}, + func(res *channeltypes.MsgChannelUpgradeAckResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.SUCCESS, res.Result) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(channeltypes.FLUSHCOMPLETE, channel.State) + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, }, { - "failure: empty signer address", - clienttypes.NewMsgUpdateParams("", clienttypes.DefaultParams()), - false, + "success, pending in-flight packets", + func() { + portID := path.EndpointA.ChannelConfig.PortID + channelID := path.EndpointA.ChannelID + // Set a dummy packet commitment to simulate in-flight packets + suite.chainA.GetSimApp().IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), portID, channelID, 1, []byte("hash")) + }, + func(res *channeltypes.MsgChannelUpgradeAckResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.SUCCESS, res.Result) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(channeltypes.FLUSHING, channel.State) + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, + }, + { + "module capability not found", + func() { + msg.PortId = ibctesting.InvalidID + msg.ChannelId = ibctesting.InvalidID + }, + func(res *channeltypes.MsgChannelUpgradeAckResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + + suite.Require().ErrorIs(err, capabilitytypes.ErrCapabilityNotFound) + }, + }, + { + "core handler returns error and no upgrade error receipt is written", + func() { + // force an error by overriding the channel state to an invalid value + channel := path.EndpointA.GetChannel() + channel.State = channeltypes.CLOSED + + path.EndpointA.SetChannel(channel) + }, + func(res *channeltypes.MsgChannelUpgradeAckResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + suite.Require().ErrorIs(err, channeltypes.ErrInvalidChannelState) + + errorReceipt, found := suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().Empty(errorReceipt) + suite.Require().False(found) + }, + }, + { + "core handler returns error and writes upgrade error receipt", + func() { + // force an upgrade error by modifying the channel upgrade ordering to an incompatible value + upgrade := path.EndpointA.GetChannelUpgrade() + upgrade.Fields.Ordering = channeltypes.NONE + + path.EndpointA.SetChannelUpgrade(upgrade) + }, + func(res *channeltypes.MsgChannelUpgradeAckResponse, err error) { + suite.Require().NoError(err) + + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.FAILURE, res.Result) + + errorReceipt, found := suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(1), errorReceipt.Sequence) + }, + }, + { + "application callback returns error and error receipt is written", + func() { + suite.chainA.GetSimApp().IBCMockModule.IBCApp.OnChanUpgradeAck = func( + ctx sdk.Context, portID, channelID, counterpartyVersion string, + ) error { + // set arbitrary value in store to mock application state changes + store := ctx.KVStore(suite.chainA.GetSimApp().GetKey(exported.ModuleName)) + store.Set([]byte("foo"), []byte("bar")) + return fmt.Errorf("mock app callback failed") + } + }, + func(res *channeltypes.MsgChannelUpgradeAckResponse, err error) { + suite.Require().NoError(err) + + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.FAILURE, res.Result) + + errorReceipt, found := suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(1), errorReceipt.Sequence) + + // assert application state changes are not committed + store := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetKey(exported.ModuleName)) + suite.Require().False(store.Has([]byte("foo"))) + }, + }, + } + + for _, tc := range cases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade version on testing endpoints + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + counterpartyUpgrade := path.EndpointB.GetChannelUpgrade() + + proofChannel, proofUpgrade, proofHeight := path.EndpointB.QueryChannelUpgradeProof() + + msg = &channeltypes.MsgChannelUpgradeAck{ + PortId: path.EndpointA.ChannelConfig.PortID, + ChannelId: path.EndpointA.ChannelID, + CounterpartyUpgrade: counterpartyUpgrade, + ProofChannel: proofChannel, + ProofUpgrade: proofUpgrade, + ProofHeight: proofHeight, + Signer: suite.chainA.SenderAccount.GetAddress().String(), + } + + tc.malleate() + + res, err := suite.chainA.GetSimApp().GetIBCKeeper().ChannelUpgradeAck(suite.chainA.GetContext(), msg) + + tc.expResult(res, err) + }) + } +} + +func (suite *KeeperTestSuite) TestChannelUpgradeConfirm() { + var ( + path *ibctesting.Path + msg *channeltypes.MsgChannelUpgradeConfirm + ) + + cases := []struct { + name string + malleate func() + expResult func(res *channeltypes.MsgChannelUpgradeConfirmResponse, err error) + }{ + { + "success, no pending in-flight packets", + func() {}, + func(res *channeltypes.MsgChannelUpgradeConfirmResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.SUCCESS, res.Result) + + channel := path.EndpointB.GetChannel() + suite.Require().Equal(channeltypes.OPEN, channel.State) + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, + }, + { + "success, pending in-flight packets on init chain", + func() { + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + seq, err := path.EndpointA.SendPacket(path.EndpointB.Chain.GetTimeoutHeight(), 0, ibctesting.MockPacketData) + suite.Require().Equal(uint64(1), seq) + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + counterpartyChannelState := path.EndpointA.GetChannel().State + counterpartyUpgrade := path.EndpointA.GetChannelUpgrade() + + proofChannel, proofUpgrade, proofHeight := path.EndpointA.QueryChannelUpgradeProof() + + msg = &channeltypes.MsgChannelUpgradeConfirm{ + PortId: path.EndpointB.ChannelConfig.PortID, + ChannelId: path.EndpointB.ChannelID, + CounterpartyChannelState: counterpartyChannelState, + CounterpartyUpgrade: counterpartyUpgrade, + ProofChannel: proofChannel, + ProofUpgrade: proofUpgrade, + ProofHeight: proofHeight, + Signer: suite.chainA.SenderAccount.GetAddress().String(), + } + }, + func(res *channeltypes.MsgChannelUpgradeConfirmResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.SUCCESS, res.Result) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(channeltypes.FLUSHING, channel.State) + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + + channel = path.EndpointB.GetChannel() + suite.Require().Equal(channeltypes.FLUSHCOMPLETE, channel.State) + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, + }, + { + "success, pending in-flight packets on try chain", + func() { + portID, channelID := path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID + suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainB.GetContext(), portID, channelID, 1, []byte("hash")) + }, + func(res *channeltypes.MsgChannelUpgradeConfirmResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.SUCCESS, res.Result) + + channel := path.EndpointB.GetChannel() + suite.Require().Equal(channeltypes.FLUSHING, channel.State) + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, + }, + { + "module capability not found", + func() { + msg.PortId = ibctesting.InvalidID + msg.ChannelId = ibctesting.InvalidID + }, + func(res *channeltypes.MsgChannelUpgradeConfirmResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + + suite.Require().ErrorIs(err, capabilitytypes.ErrCapabilityNotFound) + }, + }, + { + "core handler returns error and no upgrade error receipt is written", + func() { + // force an error by overriding the channel state to an invalid value + channel := path.EndpointB.GetChannel() + channel.State = channeltypes.CLOSED + + path.EndpointB.SetChannel(channel) + }, + func(res *channeltypes.MsgChannelUpgradeConfirmResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + suite.Require().ErrorIs(err, channeltypes.ErrInvalidChannelState) + + errorReceipt, found := suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().Empty(errorReceipt) + suite.Require().False(found) + }, + }, + { + "core handler returns error and writes upgrade error receipt", + func() { + // force an upgrade error by modifying the counterparty channel upgrade timeout to be elapsed + upgrade := path.EndpointA.GetChannelUpgrade() + upgrade.Timeout = channeltypes.NewTimeout(clienttypes.ZeroHeight(), uint64(path.EndpointB.Chain.CurrentHeader.Time.UnixNano())) + + path.EndpointA.SetChannelUpgrade(upgrade) + + suite.coordinator.CommitBlock(suite.chainA) + + err := path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + proofChannel, proofUpgrade, proofHeight := path.EndpointA.QueryChannelUpgradeProof() + + msg.CounterpartyUpgrade = upgrade + msg.ProofChannel = proofChannel + msg.ProofUpgrade = proofUpgrade + msg.ProofHeight = proofHeight + }, + func(res *channeltypes.MsgChannelUpgradeConfirmResponse, err error) { + suite.Require().NoError(err) + + suite.Require().NotNil(res) + suite.Require().Equal(channeltypes.FAILURE, res.Result) + + errorReceipt, found := suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(found) + suite.Require().Equal(uint64(1), errorReceipt.Sequence) + }, + }, + } + + for _, tc := range cases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade version on testing endpoints + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.UpdateClient() + suite.Require().NoError(err) + + counterpartyChannelState := path.EndpointA.GetChannel().State + counterpartyUpgrade := path.EndpointA.GetChannelUpgrade() + + proofChannel, proofUpgrade, proofHeight := path.EndpointA.QueryChannelUpgradeProof() + + msg = &channeltypes.MsgChannelUpgradeConfirm{ + PortId: path.EndpointB.ChannelConfig.PortID, + ChannelId: path.EndpointB.ChannelID, + CounterpartyChannelState: counterpartyChannelState, + CounterpartyUpgrade: counterpartyUpgrade, + ProofChannel: proofChannel, + ProofUpgrade: proofUpgrade, + ProofHeight: proofHeight, + Signer: suite.chainA.SenderAccount.GetAddress().String(), + } + + tc.malleate() + + res, err := suite.chainB.GetSimApp().GetIBCKeeper().ChannelUpgradeConfirm(suite.chainB.GetContext(), msg) + + tc.expResult(res, err) + }) + } +} + +func (suite *KeeperTestSuite) TestChannelUpgradeOpen() { + var ( + path *ibctesting.Path + msg *channeltypes.MsgChannelUpgradeOpen + ) + + cases := []struct { + name string + malleate func() + expResult func(res *channeltypes.MsgChannelUpgradeOpenResponse, err error) + }{ + { + "success", + func() {}, + func(res *channeltypes.MsgChannelUpgradeOpenResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + channel := path.EndpointA.GetChannel() + suite.Require().Equal(channeltypes.OPEN, channel.State) + }, + }, + { + "module capability not found", + func() { + msg.PortId = ibctesting.InvalidID + msg.ChannelId = ibctesting.InvalidID + }, + func(res *channeltypes.MsgChannelUpgradeOpenResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + + suite.Require().ErrorIs(err, capabilitytypes.ErrCapabilityNotFound) + }, + }, + { + "core handler fails", + func() { + channel := path.EndpointA.GetChannel() + channel.State = channeltypes.FLUSHING + path.EndpointA.SetChannel(channel) + }, + func(res *channeltypes.MsgChannelUpgradeOpenResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + + suite.Require().ErrorIs(err, channeltypes.ErrInvalidChannelState) + }, + }, + } + + for _, tc := range cases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade version on testing endpoints + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeConfirm() + suite.Require().NoError(err) + + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + counterpartyChannel := path.EndpointB.GetChannel() + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + proofChannel, proofHeight := path.EndpointB.QueryProof(channelKey) + + msg = &channeltypes.MsgChannelUpgradeOpen{ + PortId: path.EndpointA.ChannelConfig.PortID, + ChannelId: path.EndpointA.ChannelID, + CounterpartyChannelState: counterpartyChannel.State, + ProofChannel: proofChannel, + ProofHeight: proofHeight, + Signer: suite.chainA.SenderAccount.GetAddress().String(), + } + + tc.malleate() + + res, err := suite.chainA.GetSimApp().GetIBCKeeper().ChannelUpgradeOpen(suite.chainA.GetContext(), msg) + + tc.expResult(res, err) + }) + } +} + +func (suite *KeeperTestSuite) TestChannelUpgradeCancel() { + var ( + path *ibctesting.Path + msg *channeltypes.MsgChannelUpgradeCancel + ) + + cases := []struct { + name string + malleate func() + expResult func(res *channeltypes.MsgChannelUpgradeCancelResponse, err error) + }{ + { + "success: keeper is not authority, valid error receipt so channnel changed to match error receipt seq", + func() {}, + func(res *channeltypes.MsgChannelUpgradeCancelResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + channel := path.EndpointA.GetChannel() + // Channel state should be reverted back to open. + suite.Require().Equal(channeltypes.OPEN, channel.State) + // Upgrade sequence should be changed to match sequence on error receipt. + suite.Require().Equal(uint64(2), channel.UpgradeSequence) + }, + }, + { + "success: keeper is authority & channel state in FLUSHING, so error receipt is ignored and channel is restored to initial upgrade sequence", + func() { + msg.Signer = suite.chainA.App.GetIBCKeeper().GetAuthority() + + channel := path.EndpointA.GetChannel() + channel.State = channeltypes.FLUSHING + channel.UpgradeSequence = uint64(3) + path.EndpointA.SetChannel(channel) + }, + func(res *channeltypes.MsgChannelUpgradeCancelResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + channel := path.EndpointA.GetChannel() + // Channel state should be reverted back to open. + suite.Require().Equal(channeltypes.OPEN, channel.State) + // Upgrade sequence should be changed to match initial upgrade sequence. + suite.Require().Equal(uint64(3), channel.UpgradeSequence) + }, + }, + { + "success: keeper is authority & channel state in FLUSHING, can be cancelled even with invalid error receipt", + func() { + msg.Signer = suite.chainA.App.GetIBCKeeper().GetAuthority() + msg.ProofErrorReceipt = []byte("invalid proof") + + channel := path.EndpointA.GetChannel() + channel.State = channeltypes.FLUSHING + channel.UpgradeSequence = uint64(1) + path.EndpointA.SetChannel(channel) + }, + func(res *channeltypes.MsgChannelUpgradeCancelResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + channel := path.EndpointA.GetChannel() + // Channel state should be reverted back to open. + suite.Require().Equal(channeltypes.OPEN, channel.State) + // Upgrade sequence should be changed to match initial upgrade sequence. + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, + }, + { + "success: keeper is authority & channel state in FLUSHING, can be cancelled even with empty error receipt", + func() { + msg.Signer = suite.chainA.App.GetIBCKeeper().GetAuthority() + msg.ProofErrorReceipt = nil + + channel := path.EndpointA.GetChannel() + channel.State = channeltypes.FLUSHING + channel.UpgradeSequence = uint64(1) + path.EndpointA.SetChannel(channel) + }, + func(res *channeltypes.MsgChannelUpgradeCancelResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + channel := path.EndpointA.GetChannel() + // Channel state should be reverted back to open. + suite.Require().Equal(channeltypes.OPEN, channel.State) + // Upgrade sequence should be changed to match initial upgrade sequence. + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, + }, + { + "success: keeper is authority but channel state in FLUSHCOMPLETE, requires valid error receipt", + func() { + msg.Signer = suite.chainA.App.GetIBCKeeper().GetAuthority() + + channel := path.EndpointA.GetChannel() + channel.State = channeltypes.FLUSHCOMPLETE + channel.UpgradeSequence = uint64(1) + path.EndpointA.SetChannel(channel) + }, + func(res *channeltypes.MsgChannelUpgradeCancelResponse, err error) { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + channel := path.EndpointA.GetChannel() + // Channel state should be reverted back to open. + suite.Require().Equal(channeltypes.OPEN, channel.State) + // Upgrade sequence should be changed to match error receipt sequence. + suite.Require().Equal(uint64(2), channel.UpgradeSequence) + }, + }, + { + "capability not found", + func() { + msg.ChannelId = ibctesting.InvalidID + }, + func(res *channeltypes.MsgChannelUpgradeCancelResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + + channel := path.EndpointA.GetChannel() + suite.Require().ErrorIs(err, capabilitytypes.ErrCapabilityNotFound) + suite.Require().Equal(channeltypes.OPEN, channel.State) + // Upgrade sequence should not be changed. + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, + }, + { + "core handler fails: invalid proof", + func() { + msg.ProofErrorReceipt = []byte("invalid proof") + // Force set to STATE_FLUSHCOMPLETE to check that state is not changed. + suite.Require().NoError(path.EndpointA.SetChannelState(channeltypes.FLUSHCOMPLETE)) + }, + func(res *channeltypes.MsgChannelUpgradeCancelResponse, err error) { + suite.Require().Error(err) + suite.Require().Nil(res) + + channel := path.EndpointA.GetChannel() + suite.Require().ErrorIs(err, commitmenttypes.ErrInvalidProof) + // Channel state should not be changed. + suite.Require().Equal(channeltypes.FLUSHCOMPLETE, channel.State) + // Upgrade sequence should not be changed. + suite.Require().Equal(uint64(1), channel.UpgradeSequence) + }, + }, + } + for _, tc := range cases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade version on testing endpoints + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + // cause the upgrade to fail on chain b so an error receipt is written. + // if the counterparty (chain A) upgrade sequence is less than the current sequence, (chain B) + // an upgrade error will be returned by chain B during ChanUpgradeTry. + channel := path.EndpointA.GetChannel() + channel.UpgradeSequence = 1 + path.EndpointA.SetChannel(channel) + + channel = path.EndpointB.GetChannel() + channel.UpgradeSequence = 2 + path.EndpointB.SetChannel(channel) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + suite.Require().NoError(path.EndpointB.UpdateClient()) + + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + upgradeErrorReceiptKey := host.ChannelUpgradeErrorKey(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + errorReceiptProof, proofHeight := path.EndpointB.QueryProof(upgradeErrorReceiptKey) + + errorReceipt, ok := suite.chainB.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgradeErrorReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) + suite.Require().True(ok) + + msg = &channeltypes.MsgChannelUpgradeCancel{ + PortId: path.EndpointA.ChannelConfig.PortID, + ChannelId: path.EndpointA.ChannelID, + ErrorReceipt: errorReceipt, + ProofErrorReceipt: errorReceiptProof, + ProofHeight: proofHeight, + Signer: suite.chainA.SenderAccount.GetAddress().String(), + } + + tc.malleate() + + res, err := suite.chainA.GetSimApp().GetIBCKeeper().ChannelUpgradeCancel(suite.chainA.GetContext(), msg) + tc.expResult(res, err) + }) + } +} + +func (suite *KeeperTestSuite) TestChannelUpgradeTimeout() { + var ( + path *ibctesting.Path + msg *channeltypes.MsgChannelUpgradeTimeout + ) + + timeoutUpgrade := func() { + upgrade := path.EndpointA.GetProposedUpgrade() + upgrade.Timeout = channeltypes.NewTimeout(clienttypes.ZeroHeight(), 1) + path.EndpointA.SetChannelUpgrade(upgrade) + suite.Require().NoError(path.EndpointB.UpdateClient()) + } + + cases := []struct { + name string + malleate func() + expResult func(res *channeltypes.MsgChannelUpgradeTimeoutResponse, err error) + }{ + { + "success", + func() { + timeoutUpgrade() + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + channelProof, proofHeight := path.EndpointB.QueryProof(channelKey) + + msg.ProofChannel = channelProof + msg.ProofHeight = proofHeight + }, + func(res *channeltypes.MsgChannelUpgradeTimeoutResponse, err error) { + suite.Require().NoError(err) + channel := path.EndpointA.GetChannel() + + suite.Require().Equalf(channeltypes.OPEN, channel.State, "channel state should be %s", channeltypes.OPEN.String()) + + _, found := path.EndpointA.Chain.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().False(found, "channel upgrade should be nil") + + suite.Require().NotNil(res) + }, + }, + { + "capability not found", + func() { + msg.ChannelId = ibctesting.InvalidID + }, + func(res *channeltypes.MsgChannelUpgradeTimeoutResponse, err error) { + suite.Require().Error(err) + suite.Require().ErrorIs(err, capabilitytypes.ErrCapabilityNotFound) + + channel := path.EndpointA.GetChannel() + suite.Require().Equalf(channeltypes.FLUSHCOMPLETE, channel.State, "channel state should be %s", channeltypes.OPEN) + suite.Require().Equal(uint64(1), channel.UpgradeSequence, "channel upgrade sequence should not incremented") + + _, found := path.EndpointA.Chain.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found, "channel upgrade should not be nil") + }, + }, + { + "core handler fails: invalid proof", + func() { + timeoutUpgrade() + + suite.Require().NoError(path.EndpointA.UpdateClient()) + + _, _, proofHeight := path.EndpointB.QueryChannelUpgradeProof() + + msg.ProofHeight = proofHeight + msg.ProofChannel = []byte("invalid proof") + }, + func(res *channeltypes.MsgChannelUpgradeTimeoutResponse, err error) { + suite.Require().Error(err) + suite.Require().ErrorIs(err, commitmenttypes.ErrInvalidProof) + + channel := path.EndpointA.GetChannel() + suite.Require().Equalf(channeltypes.FLUSHCOMPLETE, channel.State, "channel state should be %s", channeltypes.OPEN) + suite.Require().Equal(uint64(1), channel.UpgradeSequence, "channel upgrade sequence should not incremented") + + _, found := path.EndpointA.Chain.GetSimApp().IBCKeeper.ChannelKeeper.GetUpgrade(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + suite.Require().True(found, "channel upgrade should not be nil") + }, + }, + } + + for _, tc := range cases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path = ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + + suite.Require().NoError(path.EndpointA.ChanUpgradeInit()) + suite.Require().NoError(path.EndpointB.ChanUpgradeTry()) + suite.Require().NoError(path.EndpointA.ChanUpgradeAck()) + + channelKey := host.ChannelKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) + channelProof, proofHeight := path.EndpointB.QueryProof(channelKey) + + msg = &channeltypes.MsgChannelUpgradeTimeout{ + PortId: path.EndpointA.ChannelConfig.PortID, + ChannelId: path.EndpointA.ChannelID, + CounterpartyChannel: path.EndpointB.GetChannel(), + ProofChannel: channelProof, + ProofHeight: proofHeight, + Signer: suite.chainA.SenderAccount.GetAddress().String(), + } + + tc.malleate() + + ctx := suite.chainA.GetContext() + res, err := suite.chainA.GetSimApp().GetIBCKeeper().ChannelUpgradeTimeout(ctx, msg) + + tc.expResult(res, err) + }) + } +} + +// TestIBCSoftwareUpgrade tests the IBCSoftwareUpgrade rpc handler +func (suite *KeeperTestSuite) TestIBCSoftwareUpgrade() { + var msg *clienttypes.MsgIBCSoftwareUpgrade + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success: valid authority and client upgrade", + func() {}, + nil, + }, + { + "failure: invalid authority address", + func() { + msg.Signer = suite.chainA.SenderAccount.GetAddress().String() + }, + ibcerrors.ErrUnauthorized, + }, + { + "failure: invalid clientState", + func() { + msg.UpgradedClientState = nil + }, + clienttypes.ErrInvalidClientType, + }, + { + "failure: failed to schedule client upgrade", + func() { + msg.Plan.Height = 0 + }, + sdkerrors.ErrInvalidRequest, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupClients(path) + validAuthority := suite.chainA.App.GetIBCKeeper().GetAuthority() + plan := upgradetypes.Plan{ + Name: "upgrade IBC clients", + Height: 1000, + } + // update trusting period + clientState := path.EndpointB.GetClientState() + clientState.(*ibctm.ClientState).TrustingPeriod += 100 + + var err error + msg, err = clienttypes.NewMsgIBCSoftwareUpgrade( + validAuthority, + plan, + clientState, + ) + + suite.Require().NoError(err) + + tc.malleate() + + _, err = keeper.Keeper.IBCSoftwareUpgrade(*suite.chainA.App.GetIBCKeeper(), suite.chainA.GetContext(), msg) + + if tc.expError == nil { + suite.Require().NoError(err) + // upgrade plan is stored + storedPlan, err := suite.chainA.GetSimApp().UpgradeKeeper.GetUpgradePlan(suite.chainA.GetContext()) + suite.Require().NoError(err) + suite.Require().Equal(plan, storedPlan) + + // upgraded client state is stored + bz, err := suite.chainA.GetSimApp().UpgradeKeeper.GetUpgradedClient(suite.chainA.GetContext(), plan.Height) + suite.Require().NoError(err) + upgradedClientState, err := clienttypes.UnmarshalClientState(suite.chainA.App.AppCodec(), bz) + suite.Require().NoError(err) + suite.Require().Equal(clientState.ZeroCustomFields(), upgradedClientState) + } else { + suite.Require().True(errors.Is(err, tc.expError)) + } + }) + } +} + +// TestUpdateClientParams tests the UpdateClientParams rpc handler +func (suite *KeeperTestSuite) TestUpdateClientParams() { + signer := suite.chainA.App.GetIBCKeeper().GetAuthority() + testCases := []struct { + name string + msg *clienttypes.MsgUpdateParams + expPass bool + }{ + { + "success: valid signer and default params", + clienttypes.NewMsgUpdateParams(signer, clienttypes.DefaultParams()), + true, + }, + { + "failure: malformed signer address", + clienttypes.NewMsgUpdateParams(ibctesting.InvalidID, clienttypes.DefaultParams()), + false, + }, + { + "failure: empty signer address", + clienttypes.NewMsgUpdateParams("", clienttypes.DefaultParams()), + false, }, { "failure: whitespace signer address", @@ -1040,3 +2016,77 @@ func (suite *KeeperTestSuite) TestUpdateConnectionParams() { }) } } + +func (suite *KeeperTestSuite) TestPruneAcknowledgements() { + var msg *channeltypes.MsgPruneAcknowledgements + + testCases := []struct { + name string + malleate func() + expErr error + }{ + { + "success", + func() {}, + nil, + }, + { + "failure: core keeper function fails, pruning sequence end not found", + func() { + msg.PortId = "portidone" + }, + channeltypes.ErrPruningSequenceEndNotFound, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() + + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.Setup(path) + + // configure the channel upgrade version on testing endpoints + path.EndpointA.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + path.EndpointB.ChannelConfig.ProposedUpgrade.Fields.Version = ibcmock.UpgradeVersion + + err := path.EndpointA.ChanUpgradeInit() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeTry() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeAck() + suite.Require().NoError(err) + + err = path.EndpointB.ChanUpgradeConfirm() + suite.Require().NoError(err) + + err = path.EndpointA.ChanUpgradeOpen() + suite.Require().NoError(err) + + err = path.EndpointA.UpdateClient() + suite.Require().NoError(err) + + msg = channeltypes.NewMsgPruneAcknowledgements( + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + 10, + suite.chainA.SenderAccount.GetAddress().String(), + ) + + tc.malleate() + + resp, err := suite.chainA.App.GetIBCKeeper().PruneAcknowledgements(suite.chainA.GetContext(), msg) + + if tc.expErr == nil { + suite.Require().NoError(err) + suite.Require().NotNil(resp) + } else { + suite.Require().Error(err) + suite.Require().Nil(resp) + } + }) + } +} diff --git a/modules/light-clients/09-localhost/client_state_test.go b/modules/light-clients/09-localhost/client_state_test.go index d1059fac5e2..7764289768d 100644 --- a/modules/light-clients/09-localhost/client_state_test.go +++ b/modules/light-clients/09-localhost/client_state_test.go @@ -281,7 +281,8 @@ func (suite *LocalhostTestSuite) TestVerifyMembership() { path = merklePath - channel.State = channeltypes.CLOSED // modify the channel before marshalling to value bz + // modify the channel before marshalling to value bz + channel.State = channeltypes.CLOSED value = suite.chain.Codec.MustMarshal(&channel) }, false, diff --git a/proto/ibc/applications/transfer/v1/transfer.proto b/proto/ibc/applications/transfer/v1/transfer.proto index 12914b7a4b8..7f77237621f 100644 --- a/proto/ibc/applications/transfer/v1/transfer.proto +++ b/proto/ibc/applications/transfer/v1/transfer.proto @@ -25,4 +25,4 @@ message Params { // receive_enabled enables or disables all cross-chain token transfers to this // chain. bool receive_enabled = 2; -} \ No newline at end of file +} diff --git a/proto/ibc/core/channel/v1/channel.proto b/proto/ibc/core/channel/v1/channel.proto index 44c3240e2bc..05a18fefb78 100644 --- a/proto/ibc/core/channel/v1/channel.proto +++ b/proto/ibc/core/channel/v1/channel.proto @@ -24,6 +24,9 @@ message Channel { repeated string connection_hops = 4; // opaque channel version, which is agreed upon during the handshake string version = 5; + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + uint64 upgrade_sequence = 6; } // IdentifiedChannel defines a channel with additional port and channel @@ -46,10 +49,13 @@ message IdentifiedChannel { string port_id = 6; // channel identifier string channel_id = 7; + // upgrade sequence indicates the latest upgrade attempt performed by this channel + // the value of 0 indicates the channel has never been upgraded + uint64 upgrade_sequence = 8; } // State defines if a channel is in one of the following states: -// CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. +// CLOSED, INIT, TRYOPEN, OPEN, FLUSHING, FLUSHCOMPLETE or UNINITIALIZED. enum State { option (gogoproto.goproto_enum_prefix) = false; @@ -65,6 +71,10 @@ enum State { // A channel has been closed and can no longer be used to send or receive // packets. STATE_CLOSED = 4 [(gogoproto.enumvalue_customname) = "CLOSED"]; + // A channel has just accepted the upgrade handshake attempt and is flushing in-flight packets. + STATE_FLUSHING = 5 [(gogoproto.enumvalue_customname) = "FLUSHING"]; + // A channel has just completed flushing any in-flight packets. + STATE_FLUSHCOMPLETE = 6 [(gogoproto.enumvalue_customname) = "FLUSHCOMPLETE"]; } // Order defines if a channel is ORDERED or UNORDERED @@ -169,3 +179,9 @@ message Timeout { // block timestamp (in nanoseconds) after which the packet or upgrade times out uint64 timestamp = 2; } + +// Params defines the set of IBC channel parameters. +message Params { + // the relative timeout after which channel upgrades will time out. + Timeout upgrade_timeout = 1 [(gogoproto.nullable) = false]; +} diff --git a/proto/ibc/core/channel/v1/genesis.proto b/proto/ibc/core/channel/v1/genesis.proto index 382a8048d45..665b2b1562f 100644 --- a/proto/ibc/core/channel/v1/genesis.proto +++ b/proto/ibc/core/channel/v1/genesis.proto @@ -18,6 +18,7 @@ message GenesisState { repeated PacketSequence ack_sequences = 7 [(gogoproto.nullable) = false]; // the sequence for the next generated channel identifier uint64 next_channel_sequence = 8; + Params params = 9 [(gogoproto.nullable) = false]; } // PacketSequence defines the genesis type necessary to retrieve and store diff --git a/proto/ibc/core/channel/v1/query.proto b/proto/ibc/core/channel/v1/query.proto index 42c4caea7d0..f89d212736a 100644 --- a/proto/ibc/core/channel/v1/query.proto +++ b/proto/ibc/core/channel/v1/query.proto @@ -10,6 +10,7 @@ import "ibc/core/channel/v1/channel.proto"; import "google/api/annotations.proto"; import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/upgrade.proto"; // Query provides defines the gRPC querier service service Query { @@ -104,6 +105,23 @@ service Query { option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" "ports/{port_id}/next_sequence_send"; } + + // UpgradeError returns the error receipt if the upgrade handshake failed. + rpc UpgradeError(QueryUpgradeErrorRequest) returns (QueryUpgradeErrorResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/upgrade_error"; + } + + // Upgrade returns the upgrade for a given port and channel id. + rpc Upgrade(QueryUpgradeRequest) returns (QueryUpgradeResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/upgrade"; + } + + // ChannelParams queries all parameters of the ibc channel submodule. + rpc ChannelParams(QueryChannelParamsRequest) returns (QueryChannelParamsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/params"; + } } // QueryChannelRequest is the request type for the Query/Channel RPC method @@ -370,7 +388,7 @@ message QueryNextSequenceReceiveRequest { string channel_id = 2; } -// QuerySequenceResponse is the request type for the +// QuerySequenceResponse is the response type for the // Query/QueryNextSequenceReceiveResponse RPC method message QueryNextSequenceReceiveResponse { // next sequence receive number @@ -399,4 +417,43 @@ message QueryNextSequenceSendResponse { bytes proof = 2; // height at which the proof was retrieved ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUpgradeErrorRequest is the request type for the Query/QueryUpgradeError RPC method +message QueryUpgradeErrorRequest { + string port_id = 1; + string channel_id = 2; +} + +// QueryUpgradeErrorResponse is the response type for the Query/QueryUpgradeError RPC method +message QueryUpgradeErrorResponse { + ErrorReceipt error_receipt = 1 [(gogoproto.nullable) = false]; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUpgradeRequest is the request type for the QueryUpgradeRequest RPC method +message QueryUpgradeRequest { + string port_id = 1; + string channel_id = 2; +} + +// QueryUpgradeResponse is the response type for the QueryUpgradeResponse RPC method +message QueryUpgradeResponse { + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelParamsRequest is the request type for the Query/ChannelParams RPC method. +message QueryChannelParamsRequest {} + +// QueryChannelParamsResponse is the response type for the Query/ChannelParams RPC method. +message QueryChannelParamsResponse { + // params defines the parameters of the module. + Params params = 1; } \ No newline at end of file diff --git a/proto/ibc/core/channel/v1/tx.proto b/proto/ibc/core/channel/v1/tx.proto index 4b9ad3d75cd..c87510c3570 100644 --- a/proto/ibc/core/channel/v1/tx.proto +++ b/proto/ibc/core/channel/v1/tx.proto @@ -5,9 +5,10 @@ package ibc.core.channel.v1; option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; import "ibc/core/client/v1/client.proto"; import "ibc/core/channel/v1/channel.proto"; -import "cosmos/msg/v1/msg.proto"; +import "ibc/core/channel/v1/upgrade.proto"; // Msg defines the ibc/channel Msg service. service Msg { @@ -43,6 +44,33 @@ service Msg { // Acknowledgement defines a rpc handler method for MsgAcknowledgement. rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse); + + // ChannelUpgradeInit defines a rpc handler method for MsgChannelUpgradeInit. + rpc ChannelUpgradeInit(MsgChannelUpgradeInit) returns (MsgChannelUpgradeInitResponse); + + // ChannelUpgradeTry defines a rpc handler method for MsgChannelUpgradeTry. + rpc ChannelUpgradeTry(MsgChannelUpgradeTry) returns (MsgChannelUpgradeTryResponse); + + // ChannelUpgradeAck defines a rpc handler method for MsgChannelUpgradeAck. + rpc ChannelUpgradeAck(MsgChannelUpgradeAck) returns (MsgChannelUpgradeAckResponse); + + // ChannelUpgradeConfirm defines a rpc handler method for MsgChannelUpgradeConfirm. + rpc ChannelUpgradeConfirm(MsgChannelUpgradeConfirm) returns (MsgChannelUpgradeConfirmResponse); + + // ChannelUpgradeOpen defines a rpc handler method for MsgChannelUpgradeOpen. + rpc ChannelUpgradeOpen(MsgChannelUpgradeOpen) returns (MsgChannelUpgradeOpenResponse); + + // ChannelUpgradeTimeout defines a rpc handler method for MsgChannelUpgradeTimeout. + rpc ChannelUpgradeTimeout(MsgChannelUpgradeTimeout) returns (MsgChannelUpgradeTimeoutResponse); + + // ChannelUpgradeCancel defines a rpc handler method for MsgChannelUpgradeCancel. + rpc ChannelUpgradeCancel(MsgChannelUpgradeCancel) returns (MsgChannelUpgradeCancelResponse); + + // UpdateChannelParams defines a rpc handler method for MsgUpdateParams. + rpc UpdateChannelParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); + + // PruneAcknowledgements defines a rpc handler method for MsgPruneAcknowledgements. + rpc PruneAcknowledgements(MsgPruneAcknowledgements) returns (MsgPruneAcknowledgementsResponse); } // ResponseResultType defines the possible outcomes of the execution of a message @@ -55,6 +83,8 @@ enum ResponseResultType { RESPONSE_RESULT_TYPE_NOOP = 1 [(gogoproto.enumvalue_customname) = "NOOP"]; // The message was executed successfully RESPONSE_RESULT_TYPE_SUCCESS = 2 [(gogoproto.enumvalue_customname) = "SUCCESS"]; + // The message was executed unsuccessfully + RESPONSE_RESULT_TYPE_FAILURE = 3 [(gogoproto.enumvalue_customname) = "FAILURE"]; } // MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It @@ -163,11 +193,12 @@ message MsgChannelCloseConfirm { option (gogoproto.goproto_getters) = false; - string port_id = 1; - string channel_id = 2; - bytes proof_init = 3; - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; - string signer = 5; + string port_id = 1; + string channel_id = 2; + bytes proof_init = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + string signer = 5; + uint64 counterparty_upgrade_sequence = 6; } // MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response @@ -219,12 +250,13 @@ message MsgTimeoutOnClose { option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2; - bytes proof_close = 3; - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; - uint64 next_sequence_recv = 5; - string signer = 6; + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2; + bytes proof_close = 3; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; + uint64 next_sequence_recv = 5; + string signer = 6; + uint64 counterparty_upgrade_sequence = 7; } // MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. @@ -253,3 +285,179 @@ message MsgAcknowledgementResponse { ResponseResultType result = 1; } + +// MsgChannelUpgradeInit defines the request type for the ChannelUpgradeInit rpc +message MsgChannelUpgradeInit { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + UpgradeFields fields = 3 [(gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgChannelUpgradeInitResponse defines the MsgChannelUpgradeInit response type +message MsgChannelUpgradeInitResponse { + option (gogoproto.goproto_getters) = false; + + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + uint64 upgrade_sequence = 2; +} + +// MsgChannelUpgradeTry defines the request type for the ChannelUpgradeTry rpc +message MsgChannelUpgradeTry { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + repeated string proposed_upgrade_connection_hops = 3; + UpgradeFields counterparty_upgrade_fields = 4 [(gogoproto.nullable) = false]; + uint64 counterparty_upgrade_sequence = 5; + bytes proof_channel = 6; + bytes proof_upgrade = 7; + ibc.core.client.v1.Height proof_height = 8 [(gogoproto.nullable) = false]; + string signer = 9; +} + +// MsgChannelUpgradeTryResponse defines the MsgChannelUpgradeTry response type +message MsgChannelUpgradeTryResponse { + option (gogoproto.goproto_getters) = false; + + Upgrade upgrade = 1 [(gogoproto.nullable) = false]; + uint64 upgrade_sequence = 2; + ResponseResultType result = 3; +} + +// MsgChannelUpgradeAck defines the request type for the ChannelUpgradeAck rpc +message MsgChannelUpgradeAck { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + Upgrade counterparty_upgrade = 3 [(gogoproto.nullable) = false]; + bytes proof_channel = 4; + bytes proof_upgrade = 5; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelUpgradeAckResponse defines MsgChannelUpgradeAck response type +message MsgChannelUpgradeAckResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgChannelUpgradeConfirm defines the request type for the ChannelUpgradeConfirm rpc +message MsgChannelUpgradeConfirm { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + State counterparty_channel_state = 3; + Upgrade counterparty_upgrade = 4 [(gogoproto.nullable) = false]; + bytes proof_channel = 5; + bytes proof_upgrade = 6; + ibc.core.client.v1.Height proof_height = 7 [(gogoproto.nullable) = false]; + string signer = 8; +} + +// MsgChannelUpgradeConfirmResponse defines MsgChannelUpgradeConfirm response type +message MsgChannelUpgradeConfirmResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgChannelUpgradeOpen defines the request type for the ChannelUpgradeOpen rpc +message MsgChannelUpgradeOpen { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + string port_id = 1; + string channel_id = 2; + State counterparty_channel_state = 3; + bytes proof_channel = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; + string signer = 6; +} + +// MsgChannelUpgradeOpenResponse defines the MsgChannelUpgradeOpen response type +message MsgChannelUpgradeOpenResponse {} + +// MsgChannelUpgradeTimeout defines the request type for the ChannelUpgradeTimeout rpc +message MsgChannelUpgradeTimeout { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + Channel counterparty_channel = 3 [(gogoproto.nullable) = false]; + bytes proof_channel = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; + string signer = 6; +} + +// MsgChannelUpgradeTimeoutRepsonse defines the MsgChannelUpgradeTimeout response type +message MsgChannelUpgradeTimeoutResponse {} + +// MsgChannelUpgradeCancel defines the request type for the ChannelUpgradeCancel rpc +message MsgChannelUpgradeCancel { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + ErrorReceipt error_receipt = 3 [(gogoproto.nullable) = false]; + bytes proof_error_receipt = 4; + ibc.core.client.v1.Height proof_height = 5 [(gogoproto.nullable) = false]; + string signer = 6; +} + +// MsgChannelUpgradeCancelResponse defines the MsgChannelUpgradeCancel response type +message MsgChannelUpgradeCancelResponse {} + +// MsgUpdateParams is the MsgUpdateParams request type. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + + option (gogoproto.goproto_getters) = false; + + // authority is the address that controls the module (defaults to x/gov unless overwritten). + string authority = 1; + + // params defines the channel parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the MsgUpdateParams response type. +message MsgUpdateParamsResponse {} + +// MsgPruneAcknowledgements defines the request type for the PruneAcknowledgements rpc. +message MsgPruneAcknowledgements { + option (cosmos.msg.v1.signer) = "signer"; + option (gogoproto.goproto_getters) = false; + + string port_id = 1; + string channel_id = 2; + uint64 limit = 3; + string signer = 4; +} + +// MsgPruneAcknowledgementsResponse defines the response type for the PruneAcknowledgements rpc. +message MsgPruneAcknowledgementsResponse { + // Number of sequences pruned (includes both packet acknowledgements and packet receipts where appropriate). + uint64 total_pruned_sequences = 1; + // Number of sequences left after pruning. + uint64 total_remaining_sequences = 2; +} \ No newline at end of file diff --git a/proto/ibc/core/channel/v1/upgrade.proto b/proto/ibc/core/channel/v1/upgrade.proto new file mode 100644 index 00000000000..81530ed2a28 --- /dev/null +++ b/proto/ibc/core/channel/v1/upgrade.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// Upgrade is a verifiable type which contains the relevant information +// for an attempted upgrade. It provides the proposed changes to the channel +// end, the timeout for this upgrade attempt and the next packet sequence +// which allows the counterparty to efficiently know the highest sequence it has received. +// The next sequence send is used for pruning and upgrading from unordered to ordered channels. +message Upgrade { + option (gogoproto.goproto_getters) = false; + + UpgradeFields fields = 1 [(gogoproto.nullable) = false]; + Timeout timeout = 2 [(gogoproto.nullable) = false]; + uint64 next_sequence_send = 3; +} + +// UpgradeFields are the fields in a channel end which may be changed +// during a channel upgrade. +message UpgradeFields { + option (gogoproto.goproto_getters) = false; + + Order ordering = 1; + repeated string connection_hops = 2; + string version = 3; +} + +// 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. +message ErrorReceipt { + option (gogoproto.goproto_getters) = false; + + // the channel upgrade sequence + uint64 sequence = 1; + // the error message detailing the cause of failure + string message = 2; +} diff --git a/testing/chain.go b/testing/chain.go index 01dcd491855..42eae7d7260 100644 --- a/testing/chain.go +++ b/testing/chain.go @@ -344,6 +344,14 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*abci.ExecTxResult, error) { // ensure the chain has the latest time chain.Coordinator.UpdateTimeForChain(chain) + // increment acc sequence regardless of success or failure tx execution + defer func() { + err := chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) + if err != nil { + panic(err) + } + }() + resp, err := simapp.SignAndDeliver( chain.TB, chain.TxConfig, @@ -370,12 +378,6 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*abci.ExecTxResult, error) { return txResult, fmt.Errorf("%s/%d: %q", txResult.Codespace, txResult.Code, txResult.Log) } - // increment sequence for successful transaction execution - err = chain.SenderAccount.SetSequence(chain.SenderAccount.GetSequence() + 1) - if err != nil { - return nil, err - } - chain.Coordinator.IncrementTime() return txResult, nil @@ -638,3 +640,10 @@ func (chain *TestChain) GetChannelCapability(portID, channelID string) *capabili func (chain *TestChain) GetTimeoutHeight() clienttypes.Height { return clienttypes.NewHeight(clienttypes.ParseChainID(chain.ChainID), uint64(chain.GetContext().BlockHeight())+100) } + +// DeleteKey deletes the specified key from the ibc store. +func (chain *TestChain) DeleteKey(key []byte) { + storeKey := chain.GetSimApp().GetKey(exported.StoreKey) + kvStore := chain.GetContext().KVStore(storeKey) + kvStore.Delete(key) +} diff --git a/testing/config.go b/testing/config.go index 46dae7899d9..4c1cba8005b 100644 --- a/testing/config.go +++ b/testing/config.go @@ -47,9 +47,10 @@ func NewConnectionConfig() *ConnectionConfig { } type ChannelConfig struct { - PortID string - Version string - Order channeltypes.Order + PortID string + Version string + Order channeltypes.Order + ProposedUpgrade channeltypes.Upgrade } func NewChannelConfig() *ChannelConfig { diff --git a/testing/endpoint.go b/testing/endpoint.go index 9e7363a6c4a..f84e5ae70f6 100644 --- a/testing/endpoint.go +++ b/testing/endpoint.go @@ -7,6 +7,8 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" abci "github.com/cometbft/cometbft/abci/types" @@ -559,14 +561,205 @@ func (endpoint *Endpoint) TimeoutOnClose(packet channeltypes.Packet) error { nextSeqRecv, found := endpoint.Counterparty.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextSequenceRecv(endpoint.Counterparty.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) require.True(endpoint.Chain.TB, found) - timeoutOnCloseMsg := channeltypes.NewMsgTimeoutOnClose( + timeoutOnCloseMsg := channeltypes.NewMsgTimeoutOnCloseWithCounterpartyUpgradeSequence( packet, nextSeqRecv, proof, proofClosed, proofHeight, endpoint.Chain.SenderAccount.GetAddress().String(), + endpoint.Counterparty.GetChannel().UpgradeSequence, ) return endpoint.Chain.sendMsgs(timeoutOnCloseMsg) } +// QueryChannelUpgradeProof returns all the proofs necessary to execute UpgradeTry/UpgradeAck/UpgradeOpen. +// It returns the proof for the channel on the endpoint's chain, the proof for the upgrade attempt on the +// endpoint's chain, and the height at which the proof was queried. +func (endpoint *Endpoint) QueryChannelUpgradeProof() ([]byte, []byte, clienttypes.Height) { + channelKey := host.ChannelKey(endpoint.ChannelConfig.PortID, endpoint.ChannelID) + proofChannel, height := endpoint.QueryProof(channelKey) + + upgradeKey := host.ChannelUpgradeKey(endpoint.ChannelConfig.PortID, endpoint.ChannelID) + proofUpgrade, _ := endpoint.QueryProof(upgradeKey) + + return proofChannel, proofUpgrade, height +} + +// ChanUpgradeInit sends a MsgChannelUpgradeInit on the associated endpoint. +// A default upgrade proposal is used with overrides from the ProposedUpgrade +// in the channel config, and submitted via governance proposal +func (endpoint *Endpoint) ChanUpgradeInit() error { + upgrade := endpoint.GetProposedUpgrade() + + // create upgrade init message via gov proposal and submit the proposal + msg := channeltypes.NewMsgChannelUpgradeInit( + endpoint.ChannelConfig.PortID, + endpoint.ChannelID, + upgrade.Fields, + endpoint.Chain.GetSimApp().IBCKeeper.GetAuthority(), + ) + + proposal, err := govtypesv1.NewMsgSubmitProposal( + []sdk.Msg{msg}, + sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, govtypesv1.DefaultMinDepositTokens)), + endpoint.Chain.SenderAccount.GetAddress().String(), + endpoint.ChannelID, + "upgrade-init", + fmt.Sprintf("gov proposal for initialising channel upgrade: %s", endpoint.ChannelID), + false, + ) + require.NoError(endpoint.Chain.TB, err) + + var proposalID uint64 + res, err := endpoint.Chain.SendMsgs(proposal) + if err != nil { + return err + } + + proposalID, err = ParseProposalIDFromEvents(res.Events) + require.NoError(endpoint.Chain.TB, err) + + return VoteAndCheckProposalStatus(endpoint, proposalID) +} + +// ChanUpgradeTry sends a MsgChannelUpgradeTry on the associated endpoint. +func (endpoint *Endpoint) ChanUpgradeTry() error { + err := endpoint.UpdateClient() + require.NoError(endpoint.Chain.TB, err) + + upgrade := endpoint.GetProposedUpgrade() + proofChannel, proofUpgrade, height := endpoint.Counterparty.QueryChannelUpgradeProof() + + counterpartyUpgrade, found := endpoint.Counterparty.Chain.App.GetIBCKeeper().ChannelKeeper.GetUpgrade(endpoint.Counterparty.Chain.GetContext(), endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) + require.True(endpoint.Chain.TB, found) + + if !found { + return fmt.Errorf("could not find upgrade for channel %s", endpoint.ChannelID) + } + + msg := channeltypes.NewMsgChannelUpgradeTry( + endpoint.ChannelConfig.PortID, + endpoint.ChannelID, + upgrade.Fields.ConnectionHops, + counterpartyUpgrade.Fields, + endpoint.Counterparty.GetChannel().UpgradeSequence, + proofChannel, + proofUpgrade, + height, + endpoint.Chain.SenderAccount.GetAddress().String(), + ) + + return endpoint.Chain.sendMsgs(msg) +} + +// ChanUpgradeAck sends a MsgChannelUpgradeAck to the associated endpoint. +func (endpoint *Endpoint) ChanUpgradeAck() error { + err := endpoint.UpdateClient() + require.NoError(endpoint.Chain.TB, err) + + proofChannel, proofUpgrade, height := endpoint.Counterparty.QueryChannelUpgradeProof() + + counterpartyUpgrade, found := endpoint.Counterparty.Chain.App.GetIBCKeeper().ChannelKeeper.GetUpgrade(endpoint.Counterparty.Chain.GetContext(), endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) + require.True(endpoint.Chain.TB, found) + + msg := channeltypes.NewMsgChannelUpgradeAck( + endpoint.ChannelConfig.PortID, + endpoint.ChannelID, + counterpartyUpgrade, + proofChannel, + proofUpgrade, + height, + endpoint.Chain.SenderAccount.GetAddress().String(), + ) + + return endpoint.Chain.sendMsgs(msg) +} + +// ChanUpgradeConfirm sends a MsgChannelUpgradeConfirm to the associated endpoint. +func (endpoint *Endpoint) ChanUpgradeConfirm() error { + err := endpoint.UpdateClient() + require.NoError(endpoint.Chain.TB, err) + + proofChannel, proofUpgrade, height := endpoint.Counterparty.QueryChannelUpgradeProof() + + counterpartyUpgrade, found := endpoint.Counterparty.Chain.App.GetIBCKeeper().ChannelKeeper.GetUpgrade(endpoint.Counterparty.Chain.GetContext(), endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) + require.True(endpoint.Chain.TB, found) + + msg := channeltypes.NewMsgChannelUpgradeConfirm( + endpoint.ChannelConfig.PortID, + endpoint.ChannelID, + endpoint.Counterparty.GetChannel().State, + counterpartyUpgrade, + proofChannel, + proofUpgrade, + height, + endpoint.Chain.SenderAccount.GetAddress().String(), + ) + + return endpoint.Chain.sendMsgs(msg) +} + +// ChanUpgradeOpen sends a MsgChannelUpgradeOpen to the associated endpoint. +func (endpoint *Endpoint) ChanUpgradeOpen() error { + err := endpoint.UpdateClient() + require.NoError(endpoint.Chain.TB, err) + + channelKey := host.ChannelKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) + proofChannel, height := endpoint.Counterparty.QueryProof(channelKey) + + msg := channeltypes.NewMsgChannelUpgradeOpen( + endpoint.ChannelConfig.PortID, + endpoint.ChannelID, + endpoint.Counterparty.GetChannel().State, + proofChannel, + height, + endpoint.Chain.SenderAccount.GetAddress().String(), + ) + + return endpoint.Chain.sendMsgs(msg) +} + +// ChanUpgradeTimeout sends a MsgChannelUpgradeTimeout to the associated endpoint. +func (endpoint *Endpoint) ChanUpgradeTimeout() error { + err := endpoint.UpdateClient() + require.NoError(endpoint.Chain.TB, err) + + channelKey := host.ChannelKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) + proofChannel, height := endpoint.Counterparty.Chain.QueryProof(channelKey) + + msg := channeltypes.NewMsgChannelUpgradeTimeout( + endpoint.ChannelConfig.PortID, + endpoint.ChannelID, + endpoint.Counterparty.GetChannel(), + proofChannel, + height, + endpoint.Chain.SenderAccount.GetAddress().String(), + ) + + return endpoint.Chain.sendMsgs(msg) +} + +// ChanUpgradeCancel sends a MsgChannelUpgradeCancel to the associated endpoint. +func (endpoint *Endpoint) ChanUpgradeCancel() error { + err := endpoint.UpdateClient() + require.NoError(endpoint.Chain.TB, err) + + errorReceiptKey := host.ChannelUpgradeErrorKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) + proofErrorReceipt, height := endpoint.Counterparty.Chain.QueryProof(errorReceiptKey) + + errorReceipt, found := endpoint.Counterparty.Chain.App.GetIBCKeeper().ChannelKeeper.GetUpgradeErrorReceipt(endpoint.Counterparty.Chain.GetContext(), endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) + require.True(endpoint.Chain.TB, found) + + msg := channeltypes.NewMsgChannelUpgradeCancel( + endpoint.ChannelConfig.PortID, + endpoint.ChannelID, + errorReceipt, + proofErrorReceipt, + height, + endpoint.Chain.SenderAccount.GetAddress().String(), + ) + + return endpoint.Chain.sendMsgs(msg) +} + // SetChannelState sets a channel state func (endpoint *Endpoint) SetChannelState(state channeltypes.State) error { channel := endpoint.GetChannel() @@ -632,6 +825,25 @@ func (endpoint *Endpoint) SetChannel(channel channeltypes.Channel) { endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.SetChannel(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID, channel) } +// GetChannelUpgrade retrieves an IBC Channel Upgrade for the endpoint. The upgrade +// is expected to exist otherwise testing will fail. +func (endpoint *Endpoint) GetChannelUpgrade() channeltypes.Upgrade { + upgrade, found := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetUpgrade(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) + require.True(endpoint.Chain.TB, found) + + return upgrade +} + +// SetChannelUpgrade sets the channel upgrade for this endpoint. +func (endpoint *Endpoint) SetChannelUpgrade(upgrade channeltypes.Upgrade) { + endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.SetUpgrade(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID, upgrade) +} + +// SetChannelCounterpartyUpgrade sets the channel counterparty upgrade for this endpoint. +func (endpoint *Endpoint) SetChannelCounterpartyUpgrade(upgrade channeltypes.Upgrade) { + endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.SetCounterpartyUpgrade(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID, upgrade) +} + // QueryClientStateProof performs and abci query for a client stat associated // with this endpoint and returns the ClientState along with the proof. func (endpoint *Endpoint) QueryClientStateProof() (exported.ClientState, []byte) { @@ -643,3 +855,40 @@ func (endpoint *Endpoint) QueryClientStateProof() (exported.ClientState, []byte) return clientState, proofClient } + +// GetProposedUpgrade returns a valid upgrade which can be used for UpgradeInit and UpgradeTry. +// By default, the endpoint's existing channel fields will be used for the upgrade fields and +// a sane default timeout will be used by querying the counterparty's latest height. +// If any non-empty values are specified in the ChannelConfig's ProposedUpgrade, +// those values will be used in the returned upgrade. +func (endpoint *Endpoint) GetProposedUpgrade() channeltypes.Upgrade { + // create a default upgrade + upgrade := channeltypes.Upgrade{ + Fields: channeltypes.UpgradeFields{ + Ordering: endpoint.ChannelConfig.Order, + ConnectionHops: []string{endpoint.ConnectionID}, + Version: endpoint.ChannelConfig.Version, + }, + Timeout: channeltypes.NewTimeout(endpoint.Counterparty.Chain.GetTimeoutHeight(), 0), + NextSequenceSend: 0, + } + + override := endpoint.ChannelConfig.ProposedUpgrade + if override.Timeout.IsValid() { + upgrade.Timeout = override.Timeout + } + + if override.Fields.Ordering != channeltypes.NONE { + upgrade.Fields.Ordering = override.Fields.Ordering + } + + if override.Fields.Version != "" { + upgrade.Fields.Version = override.Fields.Version + } + + if len(override.Fields.ConnectionHops) != 0 { + upgrade.Fields.ConnectionHops = override.Fields.ConnectionHops + } + + return upgrade +} diff --git a/testing/events.go b/testing/events.go index 9ccfaea96fa..b26b970659e 100644 --- a/testing/events.go +++ b/testing/events.go @@ -135,6 +135,19 @@ func ParseAckFromEvents(events []abci.Event) ([]byte, error) { return nil, fmt.Errorf("acknowledgement event attribute not found") } +// ParseProposalIDFromEvents parses events emitted from MsgSubmitProposal and returns proposalID +func ParseProposalIDFromEvents(events []abci.Event) (uint64, error) { + for _, event := range events { + for _, attribute := range event.Attributes { + if attribute.Key == "proposal_id" { + return strconv.ParseUint(attribute.Value, 10, 64) + } + } + } + + return 0, fmt.Errorf("proposalID event attribute not found") +} + // AssertEventsLegacy asserts that expected events are present in the actual events. // Expected map needs to be a subset of actual events to pass. func AssertEventsLegacy( diff --git a/testing/mock/ibc_app.go b/testing/mock/ibc_app.go index 72b6d4da100..a49a834ef96 100644 --- a/testing/mock/ibc_app.go +++ b/testing/mock/ibc_app.go @@ -85,6 +85,44 @@ type IBCApp struct { packet channeltypes.Packet, relayer sdk.AccAddress, ) error + + OnChanUpgradeInit func( + ctx sdk.Context, + portID, channelID string, + order channeltypes.Order, + connectionHops []string, + version string, + ) (string, error) + + OnChanUpgradeTry func( + ctx sdk.Context, + portID, channelID string, + order channeltypes.Order, + connectionHops []string, + counterpartyVersion string, + ) (string, error) + + OnChanUpgradeAck func( + ctx sdk.Context, + portID, + channelID, + counterpartyVersion string, + ) error + + OnChanUpgradeOpen func( + ctx sdk.Context, + portID, + channelID string, + order channeltypes.Order, + connectionHops []string, + version string, + ) + + OnChanUpgradeRestore func( + ctx sdk.Context, + portID, + channelID string, + ) } // NewIBCApp returns a IBCApp. An empty PortID indicates the mock app doesn't bind/claim ports. diff --git a/testing/mock/ibc_module.go b/testing/mock/ibc_module.go index 5a01fa2cb47..c0a153918bf 100644 --- a/testing/mock/ibc_module.go +++ b/testing/mock/ibc_module.go @@ -19,6 +19,7 @@ import ( var ( _ porttypes.IBCModule = (*IBCModule)(nil) _ porttypes.PacketDataUnmarshaler = (*IBCModule)(nil) + _ porttypes.UpgradableModule = (*IBCModule)(nil) ) // applicationCallbackError is a custom error type that will be unique for testing purposes. @@ -176,6 +177,47 @@ func (im IBCModule) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, return nil } +// OnChanUpgradeInit implements the IBCModule interface +func (im IBCModule) OnChanUpgradeInit(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) (string, error) { + if im.IBCApp.OnChanUpgradeInit != nil { + return im.IBCApp.OnChanUpgradeInit(ctx, portID, channelID, order, connectionHops, version) + } + + return version, nil +} + +// OnChanUpgradeTry implements the IBCModule interface +func (im IBCModule) OnChanUpgradeTry(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, counterpartyVersion string) (string, error) { + if im.IBCApp.OnChanUpgradeTry != nil { + return im.IBCApp.OnChanUpgradeTry(ctx, portID, channelID, order, connectionHops, counterpartyVersion) + } + + return counterpartyVersion, nil +} + +// OnChanUpgradeAck implements the IBCModule interface +func (im IBCModule) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, counterpartyVersion string) error { + if im.IBCApp.OnChanUpgradeAck != nil { + return im.IBCApp.OnChanUpgradeAck(ctx, portID, channelID, counterpartyVersion) + } + + return nil +} + +// OnChanUpgradeOpen implements the IBCModule interface +func (im IBCModule) OnChanUpgradeOpen(ctx sdk.Context, portID, channelID string, order channeltypes.Order, connectionHops []string, version string) { + if im.IBCApp.OnChanUpgradeOpen != nil { + im.IBCApp.OnChanUpgradeOpen(ctx, portID, channelID, order, connectionHops, version) + } +} + +// OnChanUpgradeRestore implements the IBCModule interface +func (im IBCModule) OnChanUpgradeRestore(ctx sdk.Context, portID, channelID string) { + if im.IBCApp.OnChanUpgradeRestore != nil { + im.IBCApp.OnChanUpgradeRestore(ctx, portID, channelID) + } +} + // UnmarshalPacketData returns the MockPacketData. This function implements the optional // PacketDataUnmarshaler interface required for ADR 008 support. func (IBCModule) UnmarshalPacketData(bz []byte) (interface{}, error) { diff --git a/testing/mock/mock.go b/testing/mock/mock.go index e73be083edf..89ca0db03a7 100644 --- a/testing/mock/mock.go +++ b/testing/mock/mock.go @@ -43,6 +43,7 @@ var ( MockRecvCanaryCapabilityName = "mock receive canary capability name" MockAckCanaryCapabilityName = "mock acknowledgement canary capability name" MockTimeoutCanaryCapabilityName = "mock timeout canary capability name" + UpgradeVersion = fmt.Sprintf("%s-v2", Version) // MockApplicationCallbackError should be returned when an application callback should fail. It is possible to // test that this error was returned using ErrorIs. MockApplicationCallbackError error = &applicationCallbackError{} diff --git a/testing/simapp/app.go b/testing/simapp/app.go index 754353c6ba2..7c63fc97340 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -214,6 +214,7 @@ type SimApp struct { // make IBC modules public for test purposes // these modules are never directly routed to by the IBC Router + IBCMockModule ibcmock.IBCModule ICAAuthModule ibcmock.IBCModule FeeMockModule ibcmock.IBCModule @@ -485,6 +486,7 @@ func NewSimApp( // The mock module is used for testing IBC mockIBCModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewIBCApp(ibcmock.ModuleName, scopedIBCMockKeeper)) + app.IBCMockModule = mockIBCModule ibcRouter.AddRoute(ibcmock.ModuleName, mockIBCModule) // Create Transfer Stack diff --git a/testing/utils.go b/testing/utils.go index a1178929e3f..907dae0f0e7 100644 --- a/testing/utils.go +++ b/testing/utils.go @@ -1,11 +1,14 @@ package ibctesting import ( + "fmt" "math/rand" "testing" "github.com/stretchr/testify/require" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" ) @@ -25,6 +28,29 @@ func ApplyValSetChanges(tb testing.TB, valSet *tmtypes.ValidatorSet, valUpdates return newVals } +// VoteAndCheckProposalStatus votes on a gov proposal, checks if the proposal has passed, and returns an error if it has not with the failure reason. +func VoteAndCheckProposalStatus(endpoint *Endpoint, proposalID uint64) error { + // vote on proposal + ctx := endpoint.Chain.GetContext() + require.NoError(endpoint.Chain.TB, endpoint.Chain.GetSimApp().GovKeeper.AddVote(ctx, proposalID, endpoint.Chain.SenderAccount.GetAddress(), govtypesv1.NewNonSplitVoteOption(govtypesv1.OptionYes), "")) + + // fast forward the chain context to end the voting period + params, err := endpoint.Chain.GetSimApp().GovKeeper.Params.Get(ctx) + require.NoError(endpoint.Chain.TB, err) + + endpoint.Chain.Coordinator.IncrementTimeBy(*params.VotingPeriod + *params.MaxDepositPeriod) + endpoint.Chain.NextBlock() + + // check if proposal passed or failed on msg execution + // we need to grab the context again since the previous context is no longer valid as the chain header time has been incremented + p, err := endpoint.Chain.GetSimApp().GovKeeper.Proposals.Get(endpoint.Chain.GetContext(), proposalID) + require.NoError(endpoint.Chain.TB, err) + if p.Status != govtypesv1.StatusPassed { + return fmt.Errorf("proposal failed: %s", p.FailedReason) + } + return nil +} + // GenerateString generates a random string of the given length in bytes func GenerateString(length uint) string { bytes := make([]byte, length)