From 415646aefe7978b823b24a25bd68321f5cc9dffc Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 21 Dec 2023 16:33:29 +0100 Subject: [PATCH] feat: channel upgradability (#1613) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Damian Nolan Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: Aditya Sripal Co-authored-by: Charly Co-authored-by: Cian Hatton Co-authored-by: sangier Co-authored-by: Jim Fasarakis-Hilliard Co-authored-by: Carlos Rodriguez Co-authored-by: Susannah Evans <65018876+womensrights@users.noreply.github.com> Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com> Co-authored-by: Du Nguyen Co-authored-by: Đỗ Việt Hoàng (cherry picked from commit 28f757a52c1075e78aa16322f1adab35a6e94e7d) # Conflicts: # docs/client/swagger-ui/swagger.yaml # e2e/go.mod # e2e/go.sum # e2e/sample.config.yaml # e2e/tests/interchain_accounts/localhost_test.go # e2e/tests/wasm/grandpa_test.go # e2e/testsuite/grpc_query.go # e2e/testsuite/testconfig.go # e2e/testsuite/testsuite.go # modules/apps/transfer/types/authz.pb.go # modules/core/04-channel/keeper/packet_test.go # modules/core/04-channel/types/msgs.go # modules/core/04-channel/types/msgs_test.go # testing/utils.go --- .github/mergify.yml | 4 +- .github/workflows/golangci-feature.yml | 31 + README.md | 2 +- docs/client/swagger-ui/swagger.yaml | 2139 +++- docs/docs/01-ibc/06-channel-upgrades.md | 92 + .../{06-proposals.md => 07-proposals.md} | 2 +- .../01-ibc/{07-relayer.md => 08-relayer.md} | 2 +- .../{08-proto-docs.md => 09-proto-docs.md} | 2 +- .../01-ibc/{09-roadmap.md => 10-roadmap.md} | 2 +- ...oubleshooting.md => 11-troubleshooting.md} | 2 +- ...lity-module.md => 12-capability-module.md} | 2 +- docs/docs/05-migrations/02-sdk-to-v1.md | 2 +- e2e/go.mod | 281 + e2e/go.sum | 1845 ++++ e2e/sample.config.yaml | 47 + e2e/tests/core/04-channel/upgrades_test.go | 141 + .../interchain_accounts/localhost_test.go | 477 + e2e/tests/wasm/grandpa_test.go | 844 ++ e2e/testsuite/grpc_query.go | 451 + e2e/testsuite/testconfig.go | 675 ++ e2e/testsuite/testsuite.go | 425 + .../controller/ibc_middleware.go | 95 + .../controller/ibc_middleware_test.go | 330 +- .../controller/keeper/export_test.go | 12 +- .../controller/keeper/handshake.go | 98 +- .../controller/keeper/handshake_test.go | 260 + .../controller/keeper/keeper.go | 11 + .../27-interchain-accounts/host/ibc_module.go | 27 + .../host/ibc_module_test.go | 69 + .../host/keeper/handshake.go | 60 +- .../host/keeper/handshake_test.go | 140 + .../host/keeper/keeper.go | 10 +- .../27-interchain-accounts/types/metadata.go | 13 +- modules/apps/29-fee/ibc_middleware.go | 124 + modules/apps/29-fee/ibc_middleware_test.go | 437 +- modules/apps/29-fee/transfer_test.go | 95 + modules/apps/callbacks/ibc_middleware.go | 51 + modules/apps/transfer/ibc_module.go | 43 + modules/apps/transfer/ibc_module_test.go | 220 + modules/apps/transfer/transfer_test.go | 10 + modules/apps/transfer/types/authz.pb.go | 6 + .../core/02-client/keeper/grpc_query_test.go | 1 - modules/core/03-connection/keeper/verify.go | 121 + .../core/03-connection/keeper/verify_test.go | 233 + modules/core/04-channel/client/cli/cli.go | 3 + modules/core/04-channel/client/cli/query.go | 93 + modules/core/04-channel/client/utils/utils.go | 86 + modules/core/04-channel/genesis.go | 7 + modules/core/04-channel/keeper/events.go | 184 + modules/core/04-channel/keeper/export_test.go | 36 + modules/core/04-channel/keeper/grpc_query.go | 72 + .../core/04-channel/keeper/grpc_query_test.go | 194 + modules/core/04-channel/keeper/handshake.go | 13 +- .../core/04-channel/keeper/handshake_test.go | 33 +- modules/core/04-channel/keeper/keeper.go | 204 + modules/core/04-channel/keeper/keeper_test.go | 395 + modules/core/04-channel/keeper/packet.go | 65 +- modules/core/04-channel/keeper/packet_test.go | 275 +- modules/core/04-channel/keeper/timeout.go | 57 +- .../core/04-channel/keeper/timeout_test.go | 386 +- modules/core/04-channel/keeper/upgrade.go | 1015 ++ .../core/04-channel/keeper/upgrade_test.go | 2892 +++++ modules/core/04-channel/types/channel.go | 17 +- modules/core/04-channel/types/channel.pb.go | 358 +- modules/core/04-channel/types/channel_test.go | 35 + modules/core/04-channel/types/codec.go | 8 + modules/core/04-channel/types/errors.go | 22 +- modules/core/04-channel/types/events.go | 32 +- .../core/04-channel/types/expected_keepers.go | 26 + modules/core/04-channel/types/genesis.go | 3 + modules/core/04-channel/types/genesis.pb.go | 113 +- modules/core/04-channel/types/genesis_test.go | 3 + modules/core/04-channel/types/keys.go | 3 + modules/core/04-channel/types/msgs.go | 407 +- modules/core/04-channel/types/msgs_test.go | 881 +- modules/core/04-channel/types/params.go | 36 + modules/core/04-channel/types/query.go | 18 + modules/core/04-channel/types/query.pb.go | 2034 +++- modules/core/04-channel/types/query.pb.gw.go | 311 + modules/core/04-channel/types/timeout.go | 60 + modules/core/04-channel/types/timeout_test.go | 238 + modules/core/04-channel/types/tx.pb.go | 9384 +++++++++++++---- modules/core/04-channel/types/upgrade.go | 126 + modules/core/04-channel/types/upgrade.pb.go | 842 ++ modules/core/04-channel/types/upgrade_test.go | 215 + modules/core/05-port/types/module.go | 46 + modules/core/24-host/channel_keys.go | 66 + modules/core/24-host/client_keys.go | 86 + modules/core/24-host/connection_keys.go | 28 + modules/core/24-host/keys.go | 235 - modules/core/24-host/packet_keys.go | 118 + modules/core/24-host/port_keys.go | 15 + modules/core/ante/ante_test.go | 2 +- modules/core/genesis_test.go | 2 + modules/core/keeper/grpc_query.go | 15 + modules/core/keeper/msg_server.go | 392 +- modules/core/keeper/msg_server_test.go | 1306 ++- .../09-localhost/client_state_test.go | 3 +- .../applications/transfer/v1/transfer.proto | 2 +- proto/ibc/core/channel/v1/channel.proto | 18 +- proto/ibc/core/channel/v1/genesis.proto | 1 + proto/ibc/core/channel/v1/query.proto | 59 +- proto/ibc/core/channel/v1/tx.proto | 232 +- proto/ibc/core/channel/v1/upgrade.proto | 43 + testing/chain.go | 21 +- testing/config.go | 7 +- testing/endpoint.go | 249 + testing/events.go | 13 + testing/mock/ibc_app.go | 38 + testing/mock/ibc_module.go | 42 + testing/mock/mock.go | 1 + testing/simapp/app.go | 2 + testing/solomachine.go | 2 + testing/utils.go | 30 + 114 files changed, 30902 insertions(+), 3288 deletions(-) create mode 100644 .github/workflows/golangci-feature.yml create mode 100644 docs/docs/01-ibc/06-channel-upgrades.md rename docs/docs/01-ibc/{06-proposals.md => 07-proposals.md} (99%) rename docs/docs/01-ibc/{07-relayer.md => 08-relayer.md} (99%) rename docs/docs/01-ibc/{08-proto-docs.md => 09-proto-docs.md} (91%) rename docs/docs/01-ibc/{09-roadmap.md => 10-roadmap.md} (99%) rename docs/docs/01-ibc/{10-troubleshooting.md => 11-troubleshooting.md} (95%) rename docs/docs/01-ibc/{11-capability-module.md => 12-capability-module.md} (99%) create mode 100644 e2e/go.mod create mode 100644 e2e/go.sum create mode 100644 e2e/sample.config.yaml create mode 100644 e2e/tests/core/04-channel/upgrades_test.go create mode 100644 e2e/tests/interchain_accounts/localhost_test.go create mode 100644 e2e/tests/wasm/grandpa_test.go create mode 100644 e2e/testsuite/grpc_query.go create mode 100644 e2e/testsuite/testconfig.go create mode 100644 e2e/testsuite/testsuite.go create mode 100644 modules/core/04-channel/keeper/export_test.go create mode 100644 modules/core/04-channel/keeper/upgrade.go create mode 100644 modules/core/04-channel/keeper/upgrade_test.go create mode 100644 modules/core/04-channel/types/params.go create mode 100644 modules/core/04-channel/types/timeout.go create mode 100644 modules/core/04-channel/types/timeout_test.go create mode 100644 modules/core/04-channel/types/upgrade.go create mode 100644 modules/core/04-channel/types/upgrade.pb.go create mode 100644 modules/core/04-channel/types/upgrade_test.go create mode 100644 modules/core/24-host/channel_keys.go create mode 100644 modules/core/24-host/client_keys.go create mode 100644 modules/core/24-host/connection_keys.go delete mode 100644 modules/core/24-host/keys.go create mode 100644 modules/core/24-host/packet_keys.go create mode 100644 modules/core/24-host/port_keys.go create mode 100644 proto/ibc/core/channel/v1/upgrade.proto 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..e3208453eb9 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). diff --git a/docs/client/swagger-ui/swagger.yaml b/docs/client/swagger-ui/swagger.yaml index 1a6b9d8f140..4ea6826e0c6 100644 --- a/docs/client/swagger-ui/swagger.yaml +++ b/docs/client/swagger-ui/swagger.yaml @@ -8943,12 +8943,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 +8960,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 +9008,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 @@ -9343,12 +9357,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 +9374,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 +9415,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 @@ -10584,7 +10612,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. @@ -13108,129 +13136,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 +13277,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 +13393,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 +13436,6 @@ paths: name "y.z". - JSON @@ -13453,74 +13475,1143 @@ 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 - should be set. - in: query - required: false + - name: port_id + in: path + required: true type: string - format: byte - - name: pagination.offset - 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 + 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 - 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. + upgrade handshake failure. When a channel upgrade handshake is + aborted both chains are expected to increment to the - 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 + 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 - a count of the total number of items available for pagination in - UIs. + RevisionNumber the same. However some consensus algorithms may + choose to - count_total is only respected when offset is used. It is ignored - when key + reset the height in certain conditions e.g. hard forks, + state-machine - 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. + breaking changes In these cases, the RevisionNumber is + incremented so that + height continues to be monitonically increasing even as the + RevisionHeight - Since: cosmos-sdk 0.43 - in: query - required: false - type: boolean - tags: - - Query -definitions: - cosmos.base.query.v1beta1.PageRequest: - type: object - properties: - key: + 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); + } + + 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 + type: string + format: byte + - name: pagination.offset + 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 + + 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 +<<<<<<< HEAD +======= + /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. + + + 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" + } + tags: + - Query + /ibc/lightclients/wasm/v1/checksums: + get: + summary: Get all Wasm checksums + operationId: Checksums + responses: + '200': + description: A successful response. + schema: + type: object + properties: + checksums: + type: array + items: + type: string + description: >- + checksums is a list of the hex encoded checksums of all wasm + codes stored. + pagination: + description: pagination defines the pagination in the 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: >- + QueryChecksumsResponse is the response type for the + Query/Checksums 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 + value: + type: string + format: byte + parameters: + - 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 + type: string + format: byte + - name: pagination.offset + 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 + + 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/lightclients/wasm/v1/checksums/{checksum}/code: + get: + summary: Get Wasm code for given checksum + operationId: Code + responses: + '200': + description: A successful response. + schema: + type: object + properties: + data: + type: string + format: byte + description: >- + QueryCodeResponse is the response type for the Query/Code 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 + value: + type: string + format: byte + parameters: + - name: checksum + description: checksum is a hex encoded string of the code stored. + in: path + required: true + type: string + tags: + - Query +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) +definitions: + cosmos.base.query.v1beta1.PageRequest: + type: object + properties: + key: type: string format: byte description: |- @@ -17683,10 +18774,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 +18788,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 +18825,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 +18849,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 +18879,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 +18893,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 +18936,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 +18982,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: @@ -18268,6 +19452,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 +19525,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 +19541,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 +19580,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 +19651,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 +19667,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 +19714,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 +19801,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 +19817,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 +19864,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 +19974,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 @@ -19000,14 +20283,154 @@ definitions: gets reset title: |- - QueryPacketCommitmentsResponse is the request type for the - Query/QueryPacketCommitments RPC method - ibc.core.channel.v1.QueryPacketReceiptResponse: + QueryPacketCommitmentsResponse is the request type for the + Query/QueryPacketCommitments RPC method + ibc.core.channel.v1.QueryPacketReceiptResponse: + type: object + properties: + received: + type: boolean + title: success flag for if receipt exists + 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: >- + QueryPacketReceiptResponse defines the client query response for a packet + + receipt which also includes a proof, and the height from which the proof + was + + retrieved + ibc.core.channel.v1.QueryUnreceivedAcksResponse: + type: object + properties: + sequences: + type: array + items: + type: string + format: uint64 + title: list of unreceived acknowledgement sequences + 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: |- + QueryUnreceivedAcksResponse is the response type for the + Query/UnreceivedAcks RPC method + ibc.core.channel.v1.QueryUnreceivedPacketsResponse: + type: object + properties: + sequences: + type: array + items: + type: string + format: uint64 + title: list of unreceived packet sequences + 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: |- + QueryUnreceivedPacketsResponse is the response type for the + Query/UnreceivedPacketCommitments RPC method + ibc.core.channel.v1.QueryUpgradeErrorResponse: type: object properties: - received: - type: boolean - title: success flag for if receipt exists + 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 @@ -19041,23 +20464,108 @@ definitions: gets reset title: >- - QueryPacketReceiptResponse defines the client query response for a packet - - receipt which also includes a proof, and the height from which the proof - was - - retrieved - ibc.core.channel.v1.QueryUnreceivedAcksResponse: + QueryUpgradeErrorResponse is the response type for the + Query/QueryUpgradeError RPC method + ibc.core.channel.v1.QueryUpgradeResponse: type: object properties: - sequences: - type: array - items: - type: string - format: uint64 - title: list of unreceived acknowledgement sequences - height: - title: query block height + 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: @@ -19084,20 +20592,41 @@ definitions: RevisionHeight gets reset - title: |- - QueryUnreceivedAcksResponse is the response type for the - Query/UnreceivedAcks RPC method - ibc.core.channel.v1.QueryUnreceivedPacketsResponse: + title: >- + QueryUpgradeResponse is the response type for the QueryUpgradeResponse RPC + method + ibc.core.channel.v1.State: + 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 +<<<<<<< HEAD + packets. +======= + 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: - sequences: - type: array - items: - type: string - format: uint64 - title: list of unreceived packet sequences height: - title: query block height + title: block height after which the packet or upgrade times out type: object properties: revision_number: @@ -19124,26 +20653,172 @@ definitions: RevisionHeight gets reset - title: |- - QueryUnreceivedPacketsResponse is the response type for the - Query/UnreceivedPacketCommitments RPC method - ibc.core.channel.v1.State: - type: string - enum: - - STATE_UNINITIALIZED_UNSPECIFIED - - STATE_INIT - - STATE_TRYOPEN - - STATE_OPEN - - STATE_CLOSED - default: STATE_UNINITIALIZED_UNSPECIFIED + 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: |- - State defines if a channel is in one of the following states: - CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. + UpgradeFields are the fields in a channel end which may be changed + during a channel upgrade. + ibc.lightclients.wasm.v1.QueryChecksumsResponse: + type: object + properties: + checksums: + type: array + items: + type: string + description: >- + checksums is a list of the hex encoded checksums of all wasm codes + stored. + pagination: + description: pagination defines the pagination in the 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 - - 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. \ No newline at end of file + was set, its value is undefined otherwise + description: >- + QueryChecksumsResponse is the response type for the Query/Checksums RPC + method. + ibc.lightclients.wasm.v1.QueryCodeResponse: + type: object + properties: + data: + type: string + format: byte + description: QueryCodeResponse is the response type for the Query/Code RPC method. +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) 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 99% rename from docs/docs/01-ibc/06-proposals.md rename to docs/docs/01-ibc/07-proposals.md index 2d8d8ba1e06..e87a487bb10 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 --- 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/e2e/go.mod b/e2e/go.mod new file mode 100644 index 00000000000..ed34baa0542 --- /dev/null +++ b/e2e/go.mod @@ -0,0 +1,281 @@ +module github.com/cosmos/ibc-go/e2e + +go 1.21 + +require ( + cosmossdk.io/errors v1.0.0 + cosmossdk.io/math v1.2.0 + cosmossdk.io/x/upgrade v0.1.1 + github.com/cometbft/cometbft v0.38.2 + github.com/cosmos/cosmos-sdk v0.50.2 + github.com/cosmos/gogoproto v1.4.11 + github.com/cosmos/ibc-go/modules/light-clients/08-wasm v0.0.0-00010101000000-000000000000 + github.com/cosmos/ibc-go/v8 v8.0.0 + github.com/docker/docker v24.0.7+incompatible + github.com/strangelove-ventures/interchaintest/v8 v8.0.1-0.20231206154526-2f014d308bea + github.com/stretchr/testify v1.8.4 + go.uber.org/zap v1.26.0 + golang.org/x/mod v0.14.0 + google.golang.org/grpc v1.60.1 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + cloud.google.com/go v0.111.0 // indirect + cloud.google.com/go/compute v1.23.3 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v1.1.5 // indirect + cloud.google.com/go/storage v1.35.1 // indirect + cosmossdk.io/api v0.7.2 // indirect + cosmossdk.io/client/v2 v2.0.0-beta.1 // indirect + cosmossdk.io/collections v0.4.0 // indirect + cosmossdk.io/core v0.11.0 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/log v1.2.1 // indirect + cosmossdk.io/store v1.0.1 // indirect + cosmossdk.io/x/circuit v0.1.0 // indirect + cosmossdk.io/x/evidence v0.1.0 // indirect + cosmossdk.io/x/feegrant v0.1.0 // indirect + cosmossdk.io/x/tx v0.13.0 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.2 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/ChainSafe/go-schnorrkel v1.1.0 // indirect + github.com/ChainSafe/go-schnorrkel/1 v0.0.0-00010101000000-000000000000 // indirect + github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 // indirect + github.com/CosmWasm/wasmvm v1.5.0 // indirect + github.com/DataDog/datadog-go v4.8.3+incompatible // indirect + github.com/DataDog/zstd v1.5.5 // indirect + github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect + github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/StirlingMarketingGroup/go-namecase v1.0.0 // indirect + github.com/avast/retry-go/v4 v4.5.1 // indirect + github.com/aws/aws-sdk-go v1.49.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect + github.com/bits-and-blooms/bitset v1.12.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chzyer/readline v1.5.1 // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/cockroachdb/errors v1.11.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v0.0.0-20231211223132-9848bcdb0fe9 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect + github.com/cometbft/cometbft-db v0.9.1 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect + github.com/cosmos/cosmos-db v1.0.0 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.3 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect + github.com/cosmos/iavl v1.0.0 // indirect + github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect + github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect + github.com/danieljoos/wincred v1.2.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deckarep/golang-set v1.8.0 // indirect + github.com/decred/base58 v1.0.5 // indirect + github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/emicklei/dot v1.6.0 // indirect + github.com/ethereum/go-ethereum v1.13.5 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/getsentry/sentry-go v0.25.0 // indirect + github.com/go-kit/kit v0.13.0 // indirect + github.com/go-kit/log v0.2.1 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-stack/stack v1.8.1 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/gogo/googleapis v1.4.1 // indirect + github.com/gogo/protobuf v1.3.3 // indirect + github.com/golang/glog v1.2.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/orderedcode v0.0.1 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/google/uuid v1.5.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/gorilla/handlers v1.5.2 // indirect + github.com/gorilla/mux v1.8.1 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.7.3 // indirect + github.com/hashicorp/go-hclog v1.6.1 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-metrics v0.5.3 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/hdevalence/ed25519consensus v0.1.0 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/huandu/skiplist v1.2.0 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect + github.com/icza/dyno v0.0.0-20230330125955-09f820a8d9c0 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.32.1 // indirect + github.com/linxGnu/grocksdb v1.8.9 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect + github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/mtibben/percent v0.2.1 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multiaddr v0.12.0 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multicodec v0.9.0 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect + github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect + github.com/pierrec/xxHash v0.1.5 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.17.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rs/cors v1.10.1 // indirect + github.com/rs/zerolog v1.31.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.18.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tendermint/go-amino v0.16.0 // indirect + github.com/tidwall/btree v1.7.0 // indirect + github.com/tyler-smith/go-bip32 v1.0.0 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect + go.etcd.io/bbolt v1.3.8 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.16.0 // indirect + golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/oauth2 v0.15.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.16.0 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + google.golang.org/api v0.154.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + gotest.tools/v3 v3.5.1 // indirect + lukechampine.com/blake3 v1.2.1 // indirect + lukechampine.com/uint128 v1.3.0 // indirect + modernc.org/cc/v3 v3.41.0 // indirect + modernc.org/ccgo/v3 v3.16.15 // indirect + modernc.org/libc v1.37.1 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.7.2 // indirect + modernc.org/opt v0.1.3 // indirect + modernc.org/sqlite v1.27.0 // indirect + modernc.org/strutil v1.2.0 // indirect + modernc.org/token v1.1.0 // indirect + nhooyr.io/websocket v1.8.10 // indirect + pgregory.net/rapid v1.1.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) + +// TODO: using version v1.0.0 causes a build failure. This is the previous version which compiles successfully. +replace ( + github.com/ChainSafe/go-schnorrkel => github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d + github.com/ChainSafe/go-schnorrkel/1 => github.com/ChainSafe/go-schnorrkel v1.0.0 + github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7 +) + +// uncomment to use the local version of ibc-go, you will need to run `go mod tidy` in e2e directory. +replace github.com/cosmos/ibc-go/v8 => ../ + +replace github.com/cosmos/ibc-go/modules/light-clients/08-wasm => ../modules/light-clients/08-wasm + +replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + +replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 diff --git a/e2e/go.sum b/e2e/go.sum new file mode 100644 index 00000000000..ab89db3b690 --- /dev/null +++ b/e2e/go.sum @@ -0,0 +1,1845 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM= +cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= +cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= +cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cosmossdk.io/api v0.7.2 h1:BO3i5fvKMKvfaUiMkCznxViuBEfyWA/k6w2eAF6q1C4= +cosmossdk.io/api v0.7.2/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= +cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= +cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= +cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= +cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo= +cosmossdk.io/core v0.11.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= +cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= +cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= +cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= +cosmossdk.io/log v1.2.1 h1:Xc1GgTCicniwmMiKwDxUjO4eLhPxoVdI9vtMW8Ti/uk= +cosmossdk.io/log v1.2.1/go.mod h1:GNSCc/6+DhFIj1aLn/j7Id7PaO8DzNylUZoOYBL9+I4= +cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= +cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= +cosmossdk.io/store v1.0.1 h1:XBDhCqlL+2MUgE8CHWwndKVJ4beX+TyaPIjB5SV62dM= +cosmossdk.io/store v1.0.1/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= +cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= +cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= +cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= +cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= +cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= +cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= +cosmossdk.io/x/tx v0.13.0 h1:8lzyOh3zONPpZv2uTcUmsv0WTXy6T1/aCVDCqShmpzU= +cosmossdk.io/x/tx v0.13.0/go.mod h1:CpNQtmoqbXa33/DVxWQNx5Dcnbkv2xGUhL7tYQ5wUsY= +cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= +cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= +github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= +github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= +github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= +github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420 h1:oknQF/iIhf5lVjbwjsVDzDByupRhga8nhA3NAmwyHDA= +github.com/ComposableFi/go-subkey/v2 v2.0.0-tm03420/go.mod h1:KYkiMX5AbOlXXYfxkrYPrRPV6EbVUALTQh5ptUOJzu8= +github.com/CosmWasm/wasmvm v1.5.0 h1:3hKeT9SfwfLhxTGKH3vXaKFzBz1yuvP8SlfwfQXbQfw= +github.com/CosmWasm/wasmvm v1.5.0/go.mod h1:fXB+m2gyh4v9839zlIXdMZGeLAxqUdYdFQqYsTha2hc= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q= +github.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/StirlingMarketingGroup/go-namecase v1.0.0 h1:2CzaNtCzc4iNHirR+5ru9OzGg8rQp860gqLBFqRI02Y= +github.com/StirlingMarketingGroup/go-namecase v1.0.0/go.mod h1:ZsoSKcafcAzuBx+sndbxHu/RjDcDTrEdT4UvhniHfio= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= +github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= +github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.49.0 h1:g9BkW1fo9GqKfwg2+zCD+TW/D36Ux+vtfJ8guF4AYmY= +github.com/aws/aws-sdk-go v1.49.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.12.0 h1:U/q1fAF7xXRhFCrhROzIfffYnu+dlS38vCZtmFVPHmA= +github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= +github.com/btcsuite/btcd/btcutil v1.1.3/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= +github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY= +github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= +github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895 h1:XANOgPYtvELQ/h4IrmPAohXqe2pWA8Bwhejr3VQoZsA= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895/go.mod h1:aPd7gM9ov9M8v32Yy5NJrDyOcD8z642dqs+F0CeNXfA= +github.com/cockroachdb/pebble v0.0.0-20231211223132-9848bcdb0fe9 h1:f3eH58jJkWd70J3E6BNQPNjMEorA9l72dLBJCoX/UEc= +github.com/cockroachdb/pebble v0.0.0-20231211223132-9848bcdb0fe9/go.mod h1:BHuaMa/lK7fUe75BlsteiiTu8ptIG+qSAuDtGMArP18= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/cometbft/cometbft v0.38.2 h1:io0JCh5EPxINKN5ZMI5hCdpW3QVZRy+o8qWe3mlJa/8= +github.com/cometbft/cometbft v0.38.2/go.mod h1:PIi48BpzwlHqtV3mzwPyQgOyOnU94BNBimLS2ebBHOg= +github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= +github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0E= +github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= +github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= +github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= +github.com/cosmos/cosmos-sdk v0.50.2 h1:u52xPZXLfeuR1HbGPCyOsMQvAbCtvoJbpfH5diBPVuc= +github.com/cosmos/cosmos-sdk v0.50.2/go.mod h1:n/WQqDh73qdtBmY9Op3sYgiBgTujSfGSd6CNh6GfqvQ= +github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= +github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= +github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= +github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= +github.com/cosmos/iavl v1.0.0 h1:bw6t0Mv/mVCJvlMTOPHWLs5uUE3BRBfVWCRelOzl+so= +github.com/cosmos/iavl v1.0.0/go.mod h1:CmTGqMnRnucjxbjduneZXT+0vPgNElYvdefjX2q9tYc= +github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= +github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= +github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= +github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= +github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= +github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= +github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/base58 v1.0.5 h1:hwcieUM3pfPnE/6p3J100zoRfGkQxBulZHo7GZfOqic= +github.com/decred/base58 v1.0.5/go.mod h1:s/8lukEHFA6bUQQb/v3rjUySJ2hu+RioCzLukAVkrfw= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.1 h1:18HurQ6DfHeNvwIjvOmrgr44bPdtVaQAe/WWwHg9goM= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.1/go.mod h1:XmyzkaXBy7ZvHdrTAlXAjpog8qKSAWa3ze7yqzWmgmc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= +github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/emicklei/dot v1.6.0 h1:vUzuoVE8ipzS7QkES4UfxdpCwdU2U97m2Pb2tQCoYRY= +github.com/emicklei/dot v1.6.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/ethereum/go-ethereum v1.13.5 h1:U6TCRciCqZRe4FPXmy1sMGxTfuk8P7u2UoinF3VbaFk= +github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84abZexQmTgenWk0= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= +github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= +github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= +github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b h1:RMpPgZTSApbPf7xaVel+QkoGPRLFLrwFO89uDUHEGf0= +github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= +github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-hclog v1.6.1 h1:pa92nu9bPoAqI7p+uPDCIWGAibUdlCi6TYWJEQQkLf8= +github.com/hashicorp/go-hclog v1.6.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-metrics v0.5.3 h1:M5uADWMOGCTUNU1YuC4hfknOeHNaX54LDm4oYSucoNE= +github.com/hashicorp/go-metrics v0.5.3/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= +github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= +github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/icza/dyno v0.0.0-20230330125955-09f820a8d9c0 h1:nHoRIX8iXob3Y2kdt9KsjyIb7iApSvb3vgsd93xb5Ow= +github.com/icza/dyno v0.0.0-20230330125955-09f820a8d9c0/go.mod h1:c1tRKs5Tx7E2+uHGSyyncziFjvGpgv4H2HrqXeUQ/Uk= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= +github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= +github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-libp2p v0.32.1 h1:wy1J4kZIZxOaej6NveTWCZmHiJ/kY7GoAqXgqNCnPps= +github.com/libp2p/go-libp2p v0.32.1/go.mod h1:hXXC3kXPlBZ1eu8Q2hptGrMB4mZ3048JUoS4EKaHW5c= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linxGnu/grocksdb v1.8.9 h1:/s352A7OI/+tOxeecK21qJyLJ0YHI7J8gN/cXOKzEis= +github.com/linxGnu/grocksdb v1.8.9/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b h1:QrHweqAtyJ9EwCaGHBu1fghwxIPiopAHV06JlXrMHjk= +github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b/go.mod h1:xxLb2ip6sSUts3g1irPVHyk/DGslwQsNOo9I7smJfNU= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2 h1:G/cVeTAbB9S/6FSWWqpFV0v49hiuHLbJPu9hTZ0UR2A= +github.com/misko9/go-substrate-rpc-client/v4 v4.0.0-20230913220906-b988ea7da0c2/go.mod h1:Q5BxOd9FxJqYp4vCiLGVdetecPcWTmUQIu0bRigYosU= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multiaddr v0.12.0 h1:1QlibTFkoXJuDjjYsMHhE73TnzJQl8FSWatk/0gxGzE= +github.com/multiformats/go-multiaddr v0.12.0/go.mod h1:WmZXgObOQOYp9r3cslLlppkrz1FYSHmE834dfz/lWu8= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= +github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= +github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= +github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= +github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= +github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 h1:jik8PHtAIsPlCRJjJzl4udgEf7hawInF9texMeO2jrU= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/xxHash v0.1.5 h1:n/jBpwTHiER4xYvK3/CdPVnLDPchj8eTJFFLUb4QHBo= +github.com/pierrec/xxHash v0.1.5/go.mod h1:w2waW5Zoa/Wc4Yqe0wgrIYAGKqRMf7czn2HNKXmuL+I= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= +github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/strangelove-ventures/interchaintest/v8 v8.0.1-0.20231206154526-2f014d308bea h1:02x9Eh/BrvstT3LiobBVsHIi8NGN7owFq1WmVTerC1g= +github.com/strangelove-ventures/interchaintest/v8 v8.0.1-0.20231206154526-2f014d308bea/go.mod h1:jRhLAQ+HuxZf7yqp5C1ZksMsT0FOpmHtExdcbA6aOi8= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= +github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= +github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= +github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= +github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8= +golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.154.0 h1:X7QkVKZBskztmpPKWQXgjJRPA2dJYrL6r+sYPRLj050= +google.golang.org/api v0.154.0/go.mod h1:qhSMkM85hgqiokIYsrRyKxrjfBeIhgl4Z2JmeRkYylc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos= +google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY= +google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 h1:s1w3X6gQxwrLEpxnLd/qXTVLgQE2yXwaOaoa6IlY/+o= +google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= +modernc.org/ccgo/v3 v3.16.15 h1:KbDR3ZAVU+wiLyMESPtbtE/Add4elztFyfsWoNTgxS0= +modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI= +modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v1.37.1 h1:Wi3qhejztgB3hOYQGMc8NwePETHAWXmlU+GQnBNTrw8= +modernc.org/libc v1.37.1/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.27.0 h1:MpKAHoyYB7xqcwnUwkuD+npwEa0fojF0B5QRbN+auJ8= +modernc.org/sqlite v1.27.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= +modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= +modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= +nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/e2e/sample.config.yaml b/e2e/sample.config.yaml new file mode 100644 index 00000000000..4c9a750013c --- /dev/null +++ b/e2e/sample.config.yaml @@ -0,0 +1,47 @@ +# This file contains configuration for running e2e tests. +# Many of these fields can be overridden with environment variables. +# All fields that support this have the corresponding environment variable name in a comment beside the field. + +--- +chains: + # the entry at index 0 corresponds to CHAIN_A +- chainId: chainA-1 + numValidators: 1 + numFullNodes: 0 + image: ghcr.io/cosmos/ibc-go-simd # override with CHAIN_IMAGE + tag: main # override with CHAIN_A_TAG + binary: simd # override with CHAIN_BINARY + + # the entry at index 1 corresponds to CHAIN_B +- chainId: chainB-1 + numValidators: 1 + numFullNodes: 0 + image: ghcr.io/cosmos/ibc-go-simd # override with CHAIN_IMAGE + tag: main # override with CHAIN_B_TAG + binary: simd # override with CHAIN_BINARY + +activeRelayer: hermes # override with RELAYER_ID +relayers: + - id: hermes + image: ghcr.io/informalsystems/hermes + tag: "v1.7.0" + - id: rly + image: ghcr.io/cosmos/relayer + tag: "latest" + - id: hyperspace + image: ghcr.io/misko9/hyperspace + tag: "20231122v39" + +cometbft: + logLevel: info + +debug: + # setting this value to true will force log collection even if the test passes. + dumpLogs: false + +# Required only for upgrade tests. +# Chain A will be upgraded the specified tag. +# The plan name must be registered as an upgrade handler in the given tag. +upgrade: + planName: "" + tag: "" diff --git a/e2e/tests/core/04-channel/upgrades_test.go b/e2e/tests/core/04-channel/upgrades_test.go new file mode 100644 index 00000000000..cb44b549a50 --- /dev/null +++ b/e2e/tests/core/04-channel/upgrades_test.go @@ -0,0 +1,141 @@ +//go:build !test_e2e + +package channel + +import ( + "context" + "testing" + + "github.com/strangelove-ventures/interchaintest/v8/ibc" + test "github.com/strangelove-ventures/interchaintest/v8/testutil" + testifysuite "github.com/stretchr/testify/suite" + + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + feetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" +) + +func TestChannelTestSuite(t *testing.T) { + testifysuite.Run(t, new(ChannelTestSuite)) +} + +type ChannelTestSuite struct { + testsuite.E2ETestSuite +} + +// TestChannelUpgrade_WithFeeMiddleware_Succeeds tests upgrading a transfer channel to wire up fee middleware +func (s *ChannelTestSuite) TestChannelUpgrade_WithFeeMiddleware_Succeeds() { + t := s.T() + ctx := context.TODO() + + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + channelB := channelA.Counterparty + chainA, chainB := s.GetChains() + + chainADenom := chainA.Config().Denom + chainBDenom := chainB.Config().Denom + chainAIBCToken := testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) + chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelB.PortID, channelB.ChannelID) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + // trying to create some inflight packets, although they might get relayed before the upgrade starts + t.Run("create inflight transfer packets between chain A and chain B", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.AssertTxSuccess(transferTxResp) + + transferTxResp = s.Transfer(ctx, chainB, chainBWallet, channelB.PortID, channelB.ChannelID, testvalues.DefaultTransferAmount(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") + s.AssertTxSuccess(transferTxResp) + }) + + t.Run("execute gov proposal to initiate channel upgrade", func(t *testing.T) { + chA, err := s.QueryChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + + s.initiateChannelUpgrade(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, s.createUpgradeFields(chA)) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") + + t.Run("packets are relayed between chain A and chain B", func(t *testing.T) { + // packet from chain A to chain B + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + actualBalance, err := s.QueryBalance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance.Int64()) + + // packet from chain B to chain A + s.AssertPacketRelayed(ctx, chainB, channelB.PortID, channelB.ChannelID, 1) + actualBalance, err = s.QueryBalance(ctx, chainA, chainAAddress, chainAIBCToken.IBCDenom()) + s.Require().NoError(err) + expected = testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance.Int64()) + }) + + t.Run("verify channel A upgraded and is fee enabled", func(t *testing.T) { + channel, err := s.QueryChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + + // check the channel version include the fee version + version, err := feetypes.MetadataFromVersion(channel.Version) + s.Require().NoError(err) + s.Require().Equal(feetypes.Version, version.FeeVersion, "the channel version did not include ics29") + + // extra check + feeEnabled, err := s.QueryFeeEnabledChannel(ctx, chainA, channelA.PortID, channelA.ChannelID) + s.Require().NoError(err) + s.Require().Equal(true, feeEnabled) + }) + + t.Run("verify channel B upgraded and has version with ics29", func(t *testing.T) { + channel, err := s.QueryChannel(ctx, chainB, channelB.PortID, channelB.ChannelID) + s.Require().NoError(err) + + // check the channel version include the fee version + version, err := feetypes.MetadataFromVersion(channel.Version) + s.Require().NoError(err) + s.Require().Equal(feetypes.Version, version.FeeVersion, "the channel version did not include ics29") + + // extra check + feeEnabled, err := s.QueryFeeEnabledChannel(ctx, chainB, channelB.PortID, channelB.ChannelID) + s.Require().NoError(err) + s.Require().Equal(true, feeEnabled) + }) +} + +// createUpgradeFields created the upgrade fields for channel +func (s *ChannelTestSuite) createUpgradeFields(channel channeltypes.Channel) channeltypes.UpgradeFields { + versionMetadata := feetypes.Metadata{ + FeeVersion: feetypes.Version, + AppVersion: transfertypes.Version, + } + versionBytes, err := feetypes.ModuleCdc.MarshalJSON(&versionMetadata) + s.Require().NoError(err) + + return channeltypes.NewUpgradeFields(channel.Ordering, channel.ConnectionHops, string(versionBytes)) +} + +// initiateChannelUpgrade creates and submits a governance proposal to execute the message to initiate a channel upgrade +func (s *ChannelTestSuite) initiateChannelUpgrade(ctx context.Context, chain ibc.Chain, wallet ibc.Wallet, portID, channelID string, upgradeFields channeltypes.UpgradeFields) { + govModuleAddress, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, chain) + s.Require().NoError(err) + s.Require().NotNil(govModuleAddress) + + msg := channeltypes.NewMsgChannelUpgradeInit(portID, channelID, upgradeFields, govModuleAddress.String()) + s.ExecuteAndPassGovV1Proposal(ctx, msg, chain, wallet) +} diff --git a/e2e/tests/interchain_accounts/localhost_test.go b/e2e/tests/interchain_accounts/localhost_test.go new file mode 100644 index 00000000000..99dbc591eb1 --- /dev/null +++ b/e2e/tests/interchain_accounts/localhost_test.go @@ -0,0 +1,477 @@ +//go:build !test_e2e + +package interchainaccounts + +import ( + "context" + "testing" + "time" + + "github.com/cosmos/gogoproto/proto" + "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + test "github.com/strangelove-ventures/interchaintest/v8/testutil" + testifysuite "github.com/stretchr/testify/suite" + + sdkmath "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + controllertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" + icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/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" + "github.com/cosmos/ibc-go/v8/modules/core/exported" + localhost "github.com/cosmos/ibc-go/v8/modules/light-clients/09-localhost" + ibctesting "github.com/cosmos/ibc-go/v8/testing" +) + +func TestInterchainAccountsLocalhostTestSuite(t *testing.T) { + testifysuite.Run(t, new(LocalhostInterchainAccountsTestSuite)) +} + +type LocalhostInterchainAccountsTestSuite struct { + testsuite.E2ETestSuite +} + +func (s *LocalhostInterchainAccountsTestSuite) TestInterchainAccounts_Localhost() { + t := s.T() + ctx := context.TODO() + + _, _ = s.SetupChainsRelayerAndChannel(ctx, nil) + chainA, _ := s.GetChains() + + chainADenom := chainA.Config().Denom + + rlyWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + userAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + userBWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + var ( + msgChanOpenInitRes channeltypes.MsgChannelOpenInitResponse + msgChanOpenTryRes channeltypes.MsgChannelOpenTryResponse + ack []byte + packet channeltypes.Packet + ) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA), "failed to wait for blocks") + + version := icatypes.NewDefaultMetadataString(exported.LocalhostConnectionID, exported.LocalhostConnectionID) + controllerPortID, err := icatypes.NewControllerPortID(userAWallet.FormattedAddress()) + s.Require().NoError(err) + + t.Run("channel open init localhost - broadcast MsgRegisterInterchainAccount", func(t *testing.T) { + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(exported.LocalhostConnectionID, userAWallet.FormattedAddress(), version) + + txResp := s.BroadcastMessages(ctx, chainA, userAWallet, msgRegisterAccount) + s.AssertTxSuccess(txResp) + + s.Require().NoError(testsuite.UnmarshalMsgResponses(txResp, &msgChanOpenInitRes)) + }) + + t.Run("channel open try localhost", func(t *testing.T) { + msgChanOpenTry := channeltypes.NewMsgChannelOpenTry( + icatypes.HostPortID, icatypes.Version, + channeltypes.ORDERED, []string{exported.LocalhostConnectionID}, + controllerPortID, msgChanOpenInitRes.ChannelId, + version, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenTry) + s.AssertTxSuccess(txResp) + + s.Require().NoError(testsuite.UnmarshalMsgResponses(txResp, &msgChanOpenTryRes)) + }) + + t.Run("channel open ack localhost", func(t *testing.T) { + msgChanOpenAck := channeltypes.NewMsgChannelOpenAck( + controllerPortID, msgChanOpenInitRes.ChannelId, + msgChanOpenTryRes.ChannelId, msgChanOpenTryRes.Version, + localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenAck) + s.AssertTxSuccess(txResp) + }) + + t.Run("channel open confirm localhost", func(t *testing.T) { + msgChanOpenConfirm := channeltypes.NewMsgChannelOpenConfirm( + icatypes.HostPortID, msgChanOpenTryRes.ChannelId, + localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenConfirm) + s.AssertTxSuccess(txResp) + }) + + t.Run("query localhost interchain accounts channel ends", func(t *testing.T) { + channelEndA, err := s.QueryChannel(ctx, chainA, controllerPortID, msgChanOpenInitRes.ChannelId) + s.Require().NoError(err) + s.Require().NotNil(channelEndA) + + channelEndB, err := s.QueryChannel(ctx, chainA, icatypes.HostPortID, msgChanOpenTryRes.ChannelId) + s.Require().NoError(err) + s.Require().NotNil(channelEndB) + + s.Require().Equal(channelEndA.GetConnectionHops(), channelEndB.GetConnectionHops()) + }) + + t.Run("verify interchain account registration and deposit funds", func(t *testing.T) { + interchainAccAddress, err := s.QueryInterchainAccount(ctx, chainA, userAWallet.FormattedAddress(), exported.LocalhostConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAccAddress)) + + walletAmount := ibc.WalletAmount{ + Address: interchainAccAddress, + Amount: sdkmath.NewInt(testvalues.StartingTokenAmount), + Denom: chainADenom, + } + + s.Require().NoError(chainA.SendFunds(ctx, interchaintest.FaucetAccountKeyName, walletAmount)) + }) + + t.Run("send packet localhost interchain accounts", func(t *testing.T) { + interchainAccAddress, err := s.QueryInterchainAccount(ctx, chainA, userAWallet.FormattedAddress(), exported.LocalhostConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAccAddress)) + + msgSend := &banktypes.MsgSend{ + FromAddress: interchainAccAddress, + ToAddress: userBWallet.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainADenom)), + } + + cdc := testsuite.Codec() + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}, icatypes.EncodingProtobuf) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(userAWallet.FormattedAddress(), exported.LocalhostConnectionID, uint64(time.Hour.Nanoseconds()), packetData) + + txResp := s.BroadcastMessages(ctx, chainA, userAWallet, msgSendTx) + s.AssertTxSuccess(txResp) + + packet, err = ibctesting.ParsePacketFromEvents(txResp.Events) + s.Require().NoError(err) + s.Require().NotNil(packet) + }) + + t.Run("recv packet localhost interchain accounts", func(t *testing.T) { + msgRecvPacket := channeltypes.NewMsgRecvPacket(packet, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress()) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgRecvPacket) + s.AssertTxSuccess(txResp) + + ack, err = ibctesting.ParseAckFromEvents(txResp.Events) + s.Require().NoError(err) + s.Require().NotNil(ack) + }) + + t.Run("acknowledge packet localhost interchain accounts", func(t *testing.T) { + msgAcknowledgement := channeltypes.NewMsgAcknowledgement(packet, ack, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress()) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgAcknowledgement) + s.AssertTxSuccess(txResp) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + balance, err := s.QueryBalance(ctx, chainA, userBWallet.FormattedAddress(), chainADenom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance.Int64()) + }) +} + +func (s *LocalhostInterchainAccountsTestSuite) TestInterchainAccounts_ReopenChannel_Localhost() { + t := s.T() + ctx := context.TODO() + + // relayer and channel output is discarded, only a single chain is required + _, _ = s.SetupChainsRelayerAndChannel(ctx, nil) + chainA, _ := s.GetChains() + + chainADenom := chainA.Config().Denom + + rlyWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + userAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + userBWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + var ( + msgChanOpenInitRes channeltypes.MsgChannelOpenInitResponse + msgChanOpenTryRes channeltypes.MsgChannelOpenTryResponse + ack []byte + packet channeltypes.Packet + ) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA), "failed to wait for blocks") + + version := icatypes.NewDefaultMetadataString(exported.LocalhostConnectionID, exported.LocalhostConnectionID) + controllerPortID, err := icatypes.NewControllerPortID(userAWallet.FormattedAddress()) + s.Require().NoError(err) + + t.Run("channel open init localhost - broadcast MsgRegisterInterchainAccount", func(t *testing.T) { + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(exported.LocalhostConnectionID, userAWallet.FormattedAddress(), version) + + txResp := s.BroadcastMessages(ctx, chainA, userAWallet, msgRegisterAccount) + s.AssertTxSuccess(txResp) + + s.Require().NoError(testsuite.UnmarshalMsgResponses(txResp, &msgChanOpenInitRes)) + }) + + t.Run("channel open try localhost", func(t *testing.T) { + msgChanOpenTry := channeltypes.NewMsgChannelOpenTry( + icatypes.HostPortID, icatypes.Version, + channeltypes.ORDERED, []string{exported.LocalhostConnectionID}, + controllerPortID, msgChanOpenInitRes.ChannelId, + version, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenTry) + s.AssertTxSuccess(txResp) + + s.Require().NoError(testsuite.UnmarshalMsgResponses(txResp, &msgChanOpenTryRes)) + }) + + t.Run("channel open ack localhost", func(t *testing.T) { + msgChanOpenAck := channeltypes.NewMsgChannelOpenAck( + controllerPortID, msgChanOpenInitRes.ChannelId, + msgChanOpenTryRes.ChannelId, msgChanOpenTryRes.Version, + localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenAck) + s.AssertTxSuccess(txResp) + }) + + t.Run("channel open confirm localhost", func(t *testing.T) { + msgChanOpenConfirm := channeltypes.NewMsgChannelOpenConfirm( + icatypes.HostPortID, msgChanOpenTryRes.ChannelId, + localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenConfirm) + s.AssertTxSuccess(txResp) + }) + + t.Run("query localhost interchain accounts channel ends", func(t *testing.T) { + channelEndA, err := s.QueryChannel(ctx, chainA, controllerPortID, msgChanOpenInitRes.ChannelId) + s.Require().NoError(err) + s.Require().NotNil(channelEndA) + + channelEndB, err := s.QueryChannel(ctx, chainA, icatypes.HostPortID, msgChanOpenTryRes.ChannelId) + s.Require().NoError(err) + s.Require().NotNil(channelEndB) + + s.Require().Equal(channelEndA.GetConnectionHops(), channelEndB.GetConnectionHops()) + }) + + t.Run("verify interchain account registration and deposit funds", func(t *testing.T) { + interchainAccAddress, err := s.QueryInterchainAccount(ctx, chainA, userAWallet.FormattedAddress(), exported.LocalhostConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAccAddress)) + + walletAmount := ibc.WalletAmount{ + Address: interchainAccAddress, + Amount: sdkmath.NewInt(testvalues.StartingTokenAmount), + Denom: chainADenom, + } + + s.Require().NoError(chainA.SendFunds(ctx, interchaintest.FaucetAccountKeyName, walletAmount)) + }) + + t.Run("send localhost interchain accounts packet with timeout", func(t *testing.T) { + interchainAccAddress, err := s.QueryInterchainAccount(ctx, chainA, userAWallet.FormattedAddress(), exported.LocalhostConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAccAddress)) + + msgSend := &banktypes.MsgSend{ + FromAddress: interchainAccAddress, + ToAddress: userBWallet.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainADenom)), + } + + cdc := testsuite.Codec() + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}, icatypes.EncodingProtobuf) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(userAWallet.FormattedAddress(), exported.LocalhostConnectionID, uint64(1), packetData) + + txResp := s.BroadcastMessages(ctx, chainA, userAWallet, msgSendTx) + s.AssertTxSuccess(txResp) + + packet, err = ibctesting.ParsePacketFromEvents(txResp.Events) + s.Require().NoError(err) + s.Require().NotNil(packet) + }) + + t.Run("timeout localhost interchain accounts packet", func(t *testing.T) { + msgTimeout := channeltypes.NewMsgTimeout(packet, 1, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress()) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgTimeout) + s.AssertTxSuccess(txResp) + }) + + t.Run("close interchain accounts host channel end", func(t *testing.T) { + // Pass in zero for counterpartyUpgradeSequence given that channel has not undergone any upgrades. + msgCloseConfirm := channeltypes.NewMsgChannelCloseConfirm(icatypes.HostPortID, msgChanOpenTryRes.ChannelId, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), 0) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgCloseConfirm) + s.AssertTxSuccess(txResp) + }) + + t.Run("verify localhost interchain accounts channel is closed", func(t *testing.T) { + channelEndA, err := s.QueryChannel(ctx, chainA, controllerPortID, msgChanOpenInitRes.ChannelId) + s.Require().NoError(err) + + s.Require().Equal(channeltypes.CLOSED, channelEndA.State, "the channel was not in an expected state") + + channelEndB, err := s.QueryChannel(ctx, chainA, icatypes.HostPortID, msgChanOpenTryRes.ChannelId) + s.Require().NoError(err) + + s.Require().Equal(channeltypes.CLOSED, channelEndB.State, "the channel was not in an expected state") + }) + + t.Run("channel open init localhost: create new channel for existing account", func(t *testing.T) { + msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(exported.LocalhostConnectionID, userAWallet.FormattedAddress(), version) + + txResp := s.BroadcastMessages(ctx, chainA, userAWallet, msgRegisterAccount) + s.AssertTxSuccess(txResp) + + // note: response values are updated here in msgChanOpenInitRes + s.Require().NoError(testsuite.UnmarshalMsgResponses(txResp, &msgChanOpenInitRes)) + }) + + t.Run("channel open try localhost", func(t *testing.T) { + msgChanOpenTry := channeltypes.NewMsgChannelOpenTry( + icatypes.HostPortID, icatypes.Version, + channeltypes.ORDERED, []string{exported.LocalhostConnectionID}, + controllerPortID, msgChanOpenInitRes.ChannelId, + version, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenTry) + s.AssertTxSuccess(txResp) + + // note: response values are updated here in msgChanOpenTryRes + s.Require().NoError(testsuite.UnmarshalMsgResponses(txResp, &msgChanOpenTryRes)) + }) + + t.Run("channel open ack localhost", func(t *testing.T) { + msgChanOpenAck := channeltypes.NewMsgChannelOpenAck( + controllerPortID, msgChanOpenInitRes.ChannelId, + msgChanOpenTryRes.ChannelId, msgChanOpenTryRes.Version, + localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenAck) + s.AssertTxSuccess(txResp) + }) + + t.Run("channel open confirm localhost", func(t *testing.T) { + msgChanOpenConfirm := channeltypes.NewMsgChannelOpenConfirm( + icatypes.HostPortID, msgChanOpenTryRes.ChannelId, + localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress(), + ) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgChanOpenConfirm) + s.AssertTxSuccess(txResp) + }) + + t.Run("query localhost interchain accounts channel ends", func(t *testing.T) { + channelEndA, err := s.QueryChannel(ctx, chainA, controllerPortID, msgChanOpenInitRes.ChannelId) + s.Require().NoError(err) + s.Require().NotNil(channelEndA) + + channelEndB, err := s.QueryChannel(ctx, chainA, icatypes.HostPortID, msgChanOpenTryRes.ChannelId) + s.Require().NoError(err) + s.Require().NotNil(channelEndB) + + s.Require().Equal(channelEndA.GetConnectionHops(), channelEndB.GetConnectionHops()) + }) + + t.Run("verify interchain account and existing balance", func(t *testing.T) { + interchainAccAddress, err := s.QueryInterchainAccount(ctx, chainA, userAWallet.FormattedAddress(), exported.LocalhostConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAccAddress)) + + balance, err := s.QueryBalance(ctx, chainA, interchainAccAddress, chainADenom) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount + s.Require().Equal(expected, balance.Int64()) + }) + + t.Run("send packet localhost interchain accounts", func(t *testing.T) { + interchainAccAddress, err := s.QueryInterchainAccount(ctx, chainA, userAWallet.FormattedAddress(), exported.LocalhostConnectionID) + s.Require().NoError(err) + s.Require().NotZero(len(interchainAccAddress)) + + msgSend := &banktypes.MsgSend{ + FromAddress: interchainAccAddress, + ToAddress: userBWallet.FormattedAddress(), + Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainADenom)), + } + + cdc := testsuite.Codec() + bz, err := icatypes.SerializeCosmosTx(cdc, []proto.Message{msgSend}, icatypes.EncodingProtobuf) + s.Require().NoError(err) + + packetData := icatypes.InterchainAccountPacketData{ + Type: icatypes.EXECUTE_TX, + Data: bz, + Memo: "e2e", + } + + msgSendTx := controllertypes.NewMsgSendTx(userAWallet.FormattedAddress(), exported.LocalhostConnectionID, uint64(time.Hour.Nanoseconds()), packetData) + + txResp := s.BroadcastMessages(ctx, chainA, userAWallet, msgSendTx) + s.AssertTxSuccess(txResp) + + packet, err = ibctesting.ParsePacketFromEvents(txResp.Events) + s.Require().NoError(err) + s.Require().NotNil(packet) + }) + + t.Run("recv packet localhost interchain accounts", func(t *testing.T) { + msgRecvPacket := channeltypes.NewMsgRecvPacket(packet, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress()) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgRecvPacket) + s.AssertTxSuccess(txResp) + + ack, err = ibctesting.ParseAckFromEvents(txResp.Events) + s.Require().NoError(err) + s.Require().NotNil(ack) + }) + + t.Run("acknowledge packet localhost interchain accounts", func(t *testing.T) { + msgAcknowledgement := channeltypes.NewMsgAcknowledgement(packet, ack, localhost.SentinelProof, clienttypes.ZeroHeight(), rlyWallet.FormattedAddress()) + + txResp := s.BroadcastMessages(ctx, chainA, rlyWallet, msgAcknowledgement) + s.AssertTxSuccess(txResp) + }) + + t.Run("verify tokens transferred", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, controllerPortID, msgChanOpenInitRes.ChannelId, 1) + + balance, err := s.QueryBalance(ctx, chainA, userBWallet.FormattedAddress(), chainADenom) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount + s.Require().Equal(expected, balance.Int64()) + }) +} diff --git a/e2e/tests/wasm/grandpa_test.go b/e2e/tests/wasm/grandpa_test.go new file mode 100644 index 00000000000..1db15f28d20 --- /dev/null +++ b/e2e/tests/wasm/grandpa_test.go @@ -0,0 +1,844 @@ +//go:build !test_e2e + +package wasm + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "os" + "testing" + "time" + + "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v8/chain/polkadot" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + "github.com/strangelove-ventures/interchaintest/v8/testutil" + testifysuite "github.com/stretchr/testify/suite" + + sdkmath "cosmossdk.io/math" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + + cmtjson "github.com/cometbft/cometbft/libs/json" + + "github.com/cosmos/ibc-go/e2e/testsuite" + "github.com/cosmos/ibc-go/e2e/testvalues" + wasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v8/testing" +) + +const ( + composable = "composable" + simd = "simd" + wasmSimdImage = "ghcr.io/cosmos/ibc-go-wasm-simd" + + defaultWasmClientID = "08-wasm-0" +) + +func TestGrandpaTestSuite(t *testing.T) { + // this test suite only works with the hyperspace relayer, for now hard code this here. + // this will enforce that the hyperspace relayer is used in CI. + t.Setenv(testsuite.RelayerIDEnv, "hyperspace") + + // TODO: this value should be passed in via the config file / CI, not hard coded in the test. + // This configuration can be handled in https://github.com/cosmos/ibc-go/issues/4697 + if testsuite.IsCI() && !testsuite.IsFork() { + t.Setenv(testsuite.ChainImageEnv, wasmSimdImage) + } + + // wasm tests require a longer voting period to account for the time it takes to upload a contract. + testvalues.VotingPeriod = time.Minute * 5 + + validateTestConfig() + testifysuite.Run(t, new(GrandpaTestSuite)) +} + +type GrandpaTestSuite struct { + testsuite.E2ETestSuite +} + +// TestMsgTransfer_Succeeds_GrandpaContract features +// * sets up a Polkadot parachain +// * sets up a Cosmos chain +// * sets up the Hyperspace relayer +// * Funds a user wallet on both chains +// * Pushes a wasm client contract to the Cosmos chain +// * create client, connection, and channel in relayer +// * start relayer +// * send transfer over ibc +func (s *GrandpaTestSuite) TestMsgTransfer_Succeeds_GrandpaContract() { + ctx := context.Background() + t := s.T() + + chainA, chainB := s.GetGrandpaTestChains() + + polkadotChain := chainA.(*polkadot.PolkadotChain) + cosmosChain := chainB.(*cosmos.CosmosChain) + + // we explicitly skip path creation as the contract needs to be uploaded before we can create clients. + r := s.ConfigureRelayer(ctx, polkadotChain, cosmosChain, nil, func(options *interchaintest.InterchainBuildOptions) { + options.SkipPathCreation = true + }) + + s.InitGRPCClients(cosmosChain) + + cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + file, err := os.Open("contracts/ics10_grandpa_cw.wasm.gz") + s.Require().NoError(err) + + checksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) + + s.Require().NotEmpty(checksum, "checksum was empty but should not have been") + + eRep := s.GetRelayerExecReporter() + + // Set client contract hash in cosmos chain config + err = r.SetClientContractHash(ctx, eRep, cosmosChain.Config(), checksum) + s.Require().NoError(err) + + // Ensure parachain has started (starts 1 session/epoch after relay chain) + err = testutil.WaitForBlocks(ctx, 1, polkadotChain) + s.Require().NoError(err, "polkadot chain failed to make blocks") + + // Fund users on both cosmos and parachain, mints Asset 1 for Alice + fundAmount := int64(12_333_000_000_000) + polkadotUser, cosmosUser := s.fundUsers(ctx, fundAmount, polkadotChain, cosmosChain) + + // TODO: this can be refactored to broadcast a MsgTransfer instead of CLI. + // https://github.com/cosmos/ibc-go/issues/4963 + amountToSend := int64(1_770_000) + transfer := ibc.WalletAmount{ + Address: polkadotUser.FormattedAddress(), + Denom: cosmosChain.Config().Denom, + Amount: sdkmath.NewInt(amountToSend), + } + + pathName := s.GetPathName(0) + + err = r.GeneratePath(ctx, eRep, cosmosChain.Config().ChainID, polkadotChain.Config().ChainID, pathName) + s.Require().NoError(err) + + t.Run("add 08-wasm to list of allowed clients", func(t *testing.T) { + allowedClients := s.queryAllowedClientsParam(ctx, cosmosChain) + s.allowWasmClients(ctx, cosmosChain, cosmosWallet, allowedClients) + }) + + // Create new clients + err = r.CreateClients(ctx, eRep, pathName, ibc.DefaultClientOpts()) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) // these 1 block waits seem to be needed to reduce flakiness + s.Require().NoError(err) + + // Create a new connection + err = r.CreateConnections(ctx, eRep, pathName) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) + s.Require().NoError(err) + + // Create a new channel & get channels from each chain + err = r.CreateChannel(ctx, eRep, pathName, ibc.DefaultChannelOpts()) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) + s.Require().NoError(err) + + // Start relayer + s.Require().NoError(r.StartRelayer(ctx, eRep, pathName)) + + t.Run("send successful IBC transfer from Cosmos to Polkadot parachain", func(t *testing.T) { + // Send 1.77 stake from cosmosUser to parachainUser + tx, err := cosmosChain.SendIBCTransfer(ctx, "channel-0", cosmosUser.KeyName(), transfer, ibc.TransferOptions{}) + s.Require().NoError(tx.Validate(), "source ibc transfer tx is invalid") + s.Require().NoError(err) + // verify token balance for cosmos user has decreased + balance, err := cosmosChain.GetBalance(ctx, cosmosUser.FormattedAddress(), cosmosChain.Config().Denom) + s.Require().NoError(err) + s.Require().Equal(balance, sdkmath.NewInt(fundAmount-amountToSend), "unexpected cosmos user balance after first tx") + err = testutil.WaitForBlocks(ctx, 15, cosmosChain, polkadotChain) + s.Require().NoError(err) + + // Verify tokens arrived on parachain user + parachainUserStake, err := polkadotChain.GetIbcBalance(ctx, string(polkadotUser.Address()), 2) + s.Require().NoError(err) + s.Require().Equal(amountToSend, parachainUserStake.Amount.Int64(), "unexpected parachain user balance after first tx") + }) + + t.Run("send two successful IBC transfers from Polkadot parachain to Cosmos, first with ibc denom, second with parachain denom", func(t *testing.T) { + // Send 1.16 stake from parachainUser to cosmosUser + amountToReflect := int64(1_160_000) + reflectTransfer := ibc.WalletAmount{ + Address: cosmosUser.FormattedAddress(), + Denom: "2", // stake + Amount: sdkmath.NewInt(amountToReflect), + } + _, err := polkadotChain.SendIBCTransfer(ctx, "channel-0", polkadotUser.KeyName(), reflectTransfer, ibc.TransferOptions{}) + s.Require().NoError(err) + + // Send 1.88 "UNIT" from Alice to cosmosUser + amountUnits := sdkmath.NewInt(1_880_000_000_000) + unitTransfer := ibc.WalletAmount{ + Address: cosmosUser.FormattedAddress(), + Denom: "1", // UNIT + Amount: amountUnits, + } + _, err = polkadotChain.SendIBCTransfer(ctx, "channel-0", "alice", unitTransfer, ibc.TransferOptions{}) + s.Require().NoError(err) + + // Wait for MsgRecvPacket on cosmos chain + finalStakeBal := sdkmath.NewInt(fundAmount - amountToSend + amountToReflect) + err = cosmos.PollForBalance(ctx, cosmosChain, 20, ibc.WalletAmount{ + Address: cosmosUser.FormattedAddress(), + Denom: cosmosChain.Config().Denom, + Amount: finalStakeBal, + }) + s.Require().NoError(err) + + // Wait for a new update state + err = testutil.WaitForBlocks(ctx, 5, cosmosChain, polkadotChain) + s.Require().NoError(err) + + // Verify cosmos user's final "stake" balance + cosmosUserStakeBal, err := cosmosChain.GetBalance(ctx, cosmosUser.FormattedAddress(), cosmosChain.Config().Denom) + s.Require().NoError(err) + s.Require().True(cosmosUserStakeBal.Equal(finalStakeBal)) + + // Verify cosmos user's final "unit" balance + unitDenomTrace := transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom("transfer", "channel-0", "UNIT")) + cosmosUserUnitBal, err := cosmosChain.GetBalance(ctx, cosmosUser.FormattedAddress(), unitDenomTrace.IBCDenom()) + s.Require().NoError(err) + s.Require().True(cosmosUserUnitBal.Equal(amountUnits)) + + // Verify parachain user's final "unit" balance (will be less than expected due gas costs for stake tx) + parachainUserUnits, err := polkadotChain.GetIbcBalance(ctx, string(polkadotUser.Address()), 1) + s.Require().NoError(err) + s.Require().True(parachainUserUnits.Amount.LTE(sdkmath.NewInt(fundAmount)), "parachain user's final unit amount not expected") + + // Verify parachain user's final "stake" balance + parachainUserStake, err := polkadotChain.GetIbcBalance(ctx, string(polkadotUser.Address()), 2) + s.Require().NoError(err) + s.Require().True(parachainUserStake.Amount.Equal(sdkmath.NewInt(amountToSend-amountToReflect)), "parachain user's final stake amount not expected") + }) +} + +// TestMsgTransfer_TimesOut_GrandpaContract +// sets up cosmos and polkadot chains, hyperspace relayer, and funds users on both chains +// * sends transfer over ibc channel, this transfer should timeout +func (s *GrandpaTestSuite) TestMsgTransfer_TimesOut_GrandpaContract() { + ctx := context.Background() + t := s.T() + + chainA, chainB := s.GetGrandpaTestChains() + + polkadotChain := chainA.(*polkadot.PolkadotChain) + cosmosChain := chainB.(*cosmos.CosmosChain) + + // we explicitly skip path creation as the contract needs to be uploaded before we can create clients. + r := s.ConfigureRelayer(ctx, polkadotChain, cosmosChain, nil, func(options *interchaintest.InterchainBuildOptions) { + options.SkipPathCreation = true + }) + + s.InitGRPCClients(cosmosChain) + + cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + file, err := os.Open("contracts/ics10_grandpa_cw.wasm.gz") + s.Require().NoError(err) + + checksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) + + s.Require().NotEmpty(checksum, "checksum was empty but should not have been") + + eRep := s.GetRelayerExecReporter() + + // Set client contract hash in cosmos chain config + err = r.SetClientContractHash(ctx, eRep, cosmosChain.Config(), checksum) + s.Require().NoError(err) + + // Ensure parachain has started (starts 1 session/epoch after relay chain) + err = testutil.WaitForBlocks(ctx, 1, polkadotChain) + s.Require().NoError(err, "polkadot chain failed to make blocks") + + // Fund users on both cosmos and parachain, mints Asset 1 for Alice + fundAmount := int64(12_333_000_000_000) + polkadotUser, cosmosUser := s.fundUsers(ctx, fundAmount, polkadotChain, cosmosChain) + + // TODO: this can be refactored to broadcast a MsgTransfer instead of CLI. + // https://github.com/cosmos/ibc-go/issues/4963 + amountToSend := int64(1_770_000) + transfer := ibc.WalletAmount{ + Address: polkadotUser.FormattedAddress(), + Denom: cosmosChain.Config().Denom, + Amount: sdkmath.NewInt(amountToSend), + } + + pathName := s.GetPathName(0) + + err = r.GeneratePath(ctx, eRep, cosmosChain.Config().ChainID, polkadotChain.Config().ChainID, pathName) + s.Require().NoError(err) + + t.Run("add 08-wasm to list of allowed clients", func(t *testing.T) { + allowedClients := s.queryAllowedClientsParam(ctx, cosmosChain) + s.allowWasmClients(ctx, cosmosChain, cosmosWallet, allowedClients) + }) + + // Create new clients + err = r.CreateClients(ctx, eRep, pathName, ibc.DefaultClientOpts()) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) // these 1 block waits seem to be needed to reduce flakiness + s.Require().NoError(err) + + // Create a new connection + err = r.CreateConnections(ctx, eRep, pathName) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) + s.Require().NoError(err) + + // Create a new channel & get channels from each chain + err = r.CreateChannel(ctx, eRep, pathName, ibc.DefaultChannelOpts()) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) + s.Require().NoError(err) + + // Start relayer + s.Require().NoError(r.StartRelayer(ctx, eRep, pathName)) + + t.Run("IBC transfer from Cosmos chain to Polkadot parachain times out", func(t *testing.T) { + // Stop relayer + s.Require().NoError(r.StopRelayer(ctx, s.GetRelayerExecReporter())) + + tx, err := cosmosChain.SendIBCTransfer(ctx, "channel-0", cosmosUser.KeyName(), transfer, ibc.TransferOptions{Timeout: testvalues.ImmediatelyTimeout()}) + s.Require().NoError(err) + s.Require().NoError(tx.Validate(), "source ibc transfer tx is invalid") + time.Sleep(time.Nanosecond * 1) // want it to timeout immediately + + // check that tokens are escrowed + actualBalance, err := cosmosChain.GetBalance(ctx, cosmosUser.FormattedAddress(), cosmosChain.Config().Denom) + s.Require().NoError(err) + expected := fundAmount - amountToSend + s.Require().Equal(expected, actualBalance.Int64()) + + // start relayer + s.Require().NoError(r.StartRelayer(ctx, s.GetRelayerExecReporter(), s.GetPathName(0))) + err = testutil.WaitForBlocks(ctx, 15, polkadotChain, cosmosChain) + s.Require().NoError(err) + + // ensure that receiver on parachain did not receive any tokens + receiverBalance, err := polkadotChain.GetIbcBalance(ctx, polkadotUser.FormattedAddress(), 2) + s.Require().NoError(err) + s.Require().Equal(int64(0), receiverBalance.Amount.Int64()) + + // check that tokens have been refunded to sender address + senderBalance, err := cosmosChain.GetBalance(ctx, cosmosUser.FormattedAddress(), cosmosChain.Config().Denom) + s.Require().NoError(err) + s.Require().Equal(fundAmount, senderBalance.Int64()) + }) +} + +// TestMsgMigrateContract_Success_GrandpaContract features +// * sets up a Polkadot parachain +// * sets up a Cosmos chain +// * sets up the Hyperspace relayer +// * Funds a user wallet on both chains +// * Pushes a wasm client contract to the Cosmos chain +// * create client in relayer +// * Pushes a new wasm client contract to the Cosmos chain +// * Migrates the wasm client contract +func (s *GrandpaTestSuite) TestMsgMigrateContract_Success_GrandpaContract() { + ctx := context.Background() + t := s.T() + + chainA, chainB := s.GetGrandpaTestChains() + + polkadotChain := chainA.(*polkadot.PolkadotChain) + cosmosChain := chainB.(*cosmos.CosmosChain) + + // we explicitly skip path creation as the contract needs to be uploaded before we can create clients. + r := s.ConfigureRelayer(ctx, polkadotChain, cosmosChain, nil, func(options *interchaintest.InterchainBuildOptions) { + options.SkipPathCreation = true + }) + + s.InitGRPCClients(cosmosChain) + + cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + file, err := os.Open("contracts/ics10_grandpa_cw.wasm.gz") + s.Require().NoError(err) + + checksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) + + s.Require().NotEmpty(checksum, "checksum was empty but should not have been") + + eRep := s.GetRelayerExecReporter() + + // Set client contract hash in cosmos chain config + err = r.SetClientContractHash(ctx, eRep, cosmosChain.Config(), checksum) + s.Require().NoError(err) + + // Ensure parachain has started (starts 1 session/epoch after relay chain) + err = testutil.WaitForBlocks(ctx, 1, polkadotChain) + s.Require().NoError(err, "polkadot chain failed to make blocks") + + pathName := s.GetPathName(0) + + err = r.GeneratePath(ctx, eRep, cosmosChain.Config().ChainID, polkadotChain.Config().ChainID, pathName) + s.Require().NoError(err) + + t.Run("add 08-wasm to list of allowed clients", func(t *testing.T) { + allowedClients := s.queryAllowedClientsParam(ctx, cosmosChain) + s.allowWasmClients(ctx, cosmosChain, cosmosWallet, allowedClients) + }) + + // Create new clients + err = r.CreateClients(ctx, eRep, pathName, ibc.DefaultClientOpts()) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) // these 1 block waits seem to be needed to reduce flakiness + s.Require().NoError(err) + + // Do not start relayer + + // This contract is a dummy contract that will always succeed migration. + // Other entry points are unimplemented. + migrateFile, err := os.Open("contracts/migrate_success.wasm.gz") + s.Require().NoError(err) + + // First Store the code + newChecksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, migrateFile) + s.Require().NotEmpty(newChecksum, "checksum was empty but should not have been") + + newChecksumBz, err := hex.DecodeString(newChecksum) + s.Require().NoError(err) + + // Attempt to migrate the contract + message := wasmtypes.NewMsgMigrateContract( + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + defaultWasmClientID, + newChecksumBz, + []byte("{}"), + ) + + s.ExecuteAndPassGovV1Proposal(ctx, message, cosmosChain, cosmosWallet) + + clientState, err := s.QueryClientState(ctx, cosmosChain, defaultWasmClientID) + s.Require().NoError(err) + + wasmClientState, ok := clientState.(*wasmtypes.ClientState) + s.Require().True(ok) + + s.Require().Equal(newChecksumBz, wasmClientState.Checksum) +} + +// TestMsgMigrateContract_ContractError_GrandpaContract features +// * sets up a Polkadot parachain +// * sets up a Cosmos chain +// * sets up the Hyperspace relayer +// * Funds a user wallet on both chains +// * Pushes a wasm client contract to the Cosmos chain +// * create client in relayer +// * Pushes a new wasm client contract to the Cosmos chain +// * Migrates the wasm client contract with a contract that will always fail migration +func (s *GrandpaTestSuite) TestMsgMigrateContract_ContractError_GrandpaContract() { + ctx := context.Background() + t := s.T() + + chainA, chainB := s.GetGrandpaTestChains() + + polkadotChain := chainA.(*polkadot.PolkadotChain) + cosmosChain := chainB.(*cosmos.CosmosChain) + + // we explicitly skip path creation as the contract needs to be uploaded before we can create clients. + r := s.ConfigureRelayer(ctx, polkadotChain, cosmosChain, nil, func(options *interchaintest.InterchainBuildOptions) { + options.SkipPathCreation = true + }) + + s.InitGRPCClients(cosmosChain) + + cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + file, err := os.Open("contracts/ics10_grandpa_cw.wasm.gz") + s.Require().NoError(err) + checksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) + + s.Require().NotEmpty(checksum, "checksum was empty but should not have been") + + eRep := s.GetRelayerExecReporter() + + // Set client contract hash in cosmos chain config + err = r.SetClientContractHash(ctx, eRep, cosmosChain.Config(), checksum) + s.Require().NoError(err) + + // Ensure parachain has started (starts 1 session/epoch after relay chain) + err = testutil.WaitForBlocks(ctx, 1, polkadotChain) + s.Require().NoError(err, "polkadot chain failed to make blocks") + + pathName := s.GetPathName(0) + + err = r.GeneratePath(ctx, eRep, cosmosChain.Config().ChainID, polkadotChain.Config().ChainID, pathName) + s.Require().NoError(err) + + t.Run("add 08-wasm to list of allowed clients", func(t *testing.T) { + allowedClients := s.queryAllowedClientsParam(ctx, cosmosChain) + s.allowWasmClients(ctx, cosmosChain, cosmosWallet, allowedClients) + }) + + // Create new clients + err = r.CreateClients(ctx, eRep, pathName, ibc.DefaultClientOpts()) + s.Require().NoError(err) + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) // these 1 block waits seem to be needed to reduce flakiness + s.Require().NoError(err) + + // Do not start the relayer + + // This contract is a dummy contract that will always fail migration. + // Other entry points are unimplemented. + migrateFile, err := os.Open("contracts/migrate_error.wasm.gz") + s.Require().NoError(err) + + // First Store the code + newChecksum := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, migrateFile) + s.Require().NotEmpty(newChecksum, "checksum was empty but should not have been") + + newChecksumBz, err := hex.DecodeString(newChecksum) + s.Require().NoError(err) + + // Attempt to migrate the contract + message := wasmtypes.NewMsgMigrateContract( + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + defaultWasmClientID, + newChecksumBz, + []byte("{}"), + ) + + err = s.ExecuteGovV1Proposal(ctx, message, cosmosChain, cosmosWallet) + s.Require().Error(err) + + version := cosmosChain.Nodes()[0].Image.Version + if govV1FailedReasonFeatureReleases.IsSupported(version) { + // This is the error string that is returned from the contract + s.Require().ErrorContains(err, "migration not supported") + } +} + +// TestRecoverClient_Succeeds_GrandpaContract features: +// * setup cosmos and polkadot substrates nodes +// * funds test user wallets on both chains +// * stores a wasm client contract on the cosmos chain +// * creates a subject client using the hyperspace relayer +// * waits the expiry period and asserts the subject client status has expired +// * creates a substitute client using the hyperspace relayer +// * executes a gov proposal to recover the expired client +// * asserts the status of the subject client has been restored to active +// NOTE: The testcase features a modified grandpa client contract compiled as: +// - ics10_grandpa_cw_expiry.wasm.gz +// This contract modifies the unbonding period to 1600s with the trusting period being calculated as (unbonding period / 3). +func (s *GrandpaTestSuite) TestRecoverClient_Succeeds_GrandpaContract() { + ctx := context.Background() + t := s.T() + + // set the trusting period to a value which will still be valid upon client creation, but invalid before the first update + // the contract uses 1600s as the unbonding period with the trusting period evaluating to (unbonding period / 3) + modifiedTrustingPeriod := (1600 * time.Second) / 3 + + chainA, chainB := s.GetGrandpaTestChains() + + polkadotChain := chainA.(*polkadot.PolkadotChain) + cosmosChain := chainB.(*cosmos.CosmosChain) + + // we explicitly skip path creation as the contract needs to be uploaded before we can create clients. + r := s.ConfigureRelayer(ctx, polkadotChain, cosmosChain, nil, func(options *interchaintest.InterchainBuildOptions) { + options.SkipPathCreation = true + }) + + s.InitGRPCClients(cosmosChain) + + cosmosWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + file, err := os.Open("contracts/ics10_grandpa_cw_expiry.wasm.gz") + s.Require().NoError(err) + + codeHash := s.PushNewWasmClientProposal(ctx, cosmosChain, cosmosWallet, file) + s.Require().NotEmpty(codeHash, "codehash was empty but should not have been") + + eRep := s.GetRelayerExecReporter() + + // Set client contract hash in cosmos chain config + err = r.SetClientContractHash(ctx, eRep, cosmosChain.Config(), codeHash) + s.Require().NoError(err) + + // Ensure parachain has started (starts 1 session/epoch after relay chain) + err = testutil.WaitForBlocks(ctx, 1, polkadotChain) + s.Require().NoError(err, "polkadot chain failed to make blocks") + + // Fund users on both cosmos and parachain, mints Asset 1 for Alice + fundAmount := int64(12_333_000_000_000) + _, cosmosUser := s.fundUsers(ctx, fundAmount, polkadotChain, cosmosChain) + + pathName := s.GetPathName(0) + err = r.GeneratePath(ctx, eRep, cosmosChain.Config().ChainID, polkadotChain.Config().ChainID, pathName) + s.Require().NoError(err) + + t.Run("add 08-wasm to list of allowed clients", func(t *testing.T) { + allowedClients := s.queryAllowedClientsParam(ctx, cosmosChain) + s.allowWasmClients(ctx, cosmosChain, cosmosWallet, allowedClients) + }) + + // create client pair with subject (bad trusting period) + subjectClientID := clienttypes.FormatClientIdentifier(wasmtypes.Wasm, 0) + // TODO: The hyperspace relayer makes no use of create client opts + // https://github.com/strangelove-ventures/interchaintest/blob/main/relayer/hyperspace/hyperspace_commander.go#L83 + s.SetupClients(ctx, r, ibc.CreateClientOptions{ + TrustingPeriod: modifiedTrustingPeriod.String(), // NOTE: this is hardcoded within the cw contract: ics10_grapnda_cw_expiry.wasm + }) + + // wait for block + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) + s.Require().NoError(err) + + // wait the bad trusting period + time.Sleep(modifiedTrustingPeriod) + + // create client pair with substitute + substituteClientID := clienttypes.FormatClientIdentifier(wasmtypes.Wasm, 1) + s.SetupClients(ctx, r, ibc.DefaultClientOpts()) + + // wait for block + err = testutil.WaitForBlocks(ctx, 1, cosmosChain, polkadotChain) + s.Require().NoError(err) + + // ensure subject client is expired + status, err := s.clientStatus(ctx, cosmosChain, subjectClientID) + s.Require().NoError(err) + s.Require().Equal(ibcexported.Expired.String(), status, "unexpected subject client status") + + // ensure substitute client is active + status, err = s.clientStatus(ctx, cosmosChain, substituteClientID) + s.Require().NoError(err) + s.Require().Equal(ibcexported.Active.String(), status, "unexpected substitute client status") + + version := cosmosChain.Nodes()[0].Image.Version + if govV1FeatureReleases.IsSupported(version) { + // create and execute a client recovery proposal + authority, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, cosmosChain) + s.Require().NoError(err) + + msgRecoverClient := clienttypes.NewMsgRecoverClient(authority.String(), subjectClientID, substituteClientID) + s.Require().NotNil(msgRecoverClient) + s.ExecuteAndPassGovV1Proposal(ctx, msgRecoverClient, cosmosChain, cosmosUser) + } else { + proposal := clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subjectClientID, substituteClientID) + s.ExecuteAndPassGovV1Beta1Proposal(ctx, cosmosChain, cosmosWallet, proposal) + } + + // ensure subject client is active + status, err = s.clientStatus(ctx, cosmosChain, subjectClientID) + s.Require().NoError(err) + s.Require().Equal(ibcexported.Active.String(), status) + + // ensure substitute client is active + status, err = s.clientStatus(ctx, cosmosChain, substituteClientID) + s.Require().NoError(err) + s.Require().Equal(ibcexported.Active.String(), status) +} + +// extractChecksumFromGzippedContent takes a gzipped wasm contract and returns the checksum. +func (s *GrandpaTestSuite) extractChecksumFromGzippedContent(zippedContent []byte) string { + content, err := wasmtypes.Uncompress(zippedContent, wasmtypes.MaxWasmByteSize()) + s.Require().NoError(err) + + checksum32 := sha256.Sum256(content) + return hex.EncodeToString(checksum32[:]) +} + +// PushNewWasmClientProposal submits a new wasm client governance proposal to the chain. +func (s *GrandpaTestSuite) PushNewWasmClientProposal(ctx context.Context, chain *cosmos.CosmosChain, wallet ibc.Wallet, proposalContentReader io.Reader) string { + zippedContent, err := io.ReadAll(proposalContentReader) + s.Require().NoError(err) + + computedChecksum := s.extractChecksumFromGzippedContent(zippedContent) + + s.Require().NoError(err) + message := wasmtypes.MsgStoreCode{ + Signer: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + WasmByteCode: zippedContent, + } + + s.ExecuteAndPassGovV1Proposal(ctx, &message, chain, wallet) + + checksumBz, err := s.QueryWasmCode(ctx, chain, computedChecksum) + s.Require().NoError(err) + + checksum32 := sha256.Sum256(checksumBz) + actualChecksum := hex.EncodeToString(checksum32[:]) + s.Require().Equal(computedChecksum, actualChecksum, "checksum returned from query did not match the computed checksum") + + return actualChecksum +} + +func (s *GrandpaTestSuite) clientStatus(ctx context.Context, chain ibc.Chain, clientID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.ClientStatus(ctx, &clienttypes.QueryClientStatusRequest{ + ClientId: clientID, + }) + if err != nil { + return "", err + } + + return res.Status, nil +} + +func (s *GrandpaTestSuite) fundUsers(ctx context.Context, fundAmount int64, polkadotChain ibc.Chain, cosmosChain ibc.Chain) (ibc.Wallet, ibc.Wallet) { + users := interchaintest.GetAndFundTestUsers(s.T(), ctx, "user", sdkmath.NewInt(fundAmount), polkadotChain, cosmosChain) + polkadotUser, cosmosUser := users[0], users[1] + err := testutil.WaitForBlocks(ctx, 2, polkadotChain, cosmosChain) // Only waiting 1 block is flaky for parachain + s.Require().NoError(err, "cosmos or polkadot chain failed to make blocks") + + // Check balances are correct + amount := sdkmath.NewInt(fundAmount) + polkadotUserAmount, err := polkadotChain.GetBalance(ctx, polkadotUser.FormattedAddress(), polkadotChain.Config().Denom) + s.Require().NoError(err) + s.Require().True(polkadotUserAmount.Equal(amount), "Initial polkadot user amount not expected") + + parachainUserAmount, err := polkadotChain.GetBalance(ctx, polkadotUser.FormattedAddress(), "") + s.Require().NoError(err) + s.Require().True(parachainUserAmount.Equal(amount), "Initial parachain user amount not expected") + + cosmosUserAmount, err := cosmosChain.GetBalance(ctx, cosmosUser.FormattedAddress(), cosmosChain.Config().Denom) + s.Require().NoError(err) + s.Require().True(cosmosUserAmount.Equal(amount), "Initial cosmos user amount not expected") + + return polkadotUser, cosmosUser +} + +// validateTestConfig ensures that the given test config is valid for this test suite. +func validateTestConfig() { + tc := testsuite.LoadConfig() + if tc.ActiveRelayer != "hyperspace" { + panic(fmt.Errorf("hyperspace relayer must be specified")) + } +} + +// getConfigOverrides returns configuration overrides that will be applied to the simapp. +func getConfigOverrides() map[string]any { + consensusOverrides := make(testutil.Toml) + blockTime := 5 + blockT := (time.Duration(blockTime) * time.Second).String() + consensusOverrides["timeout_commit"] = blockT + consensusOverrides["timeout_propose"] = blockT + + configTomlOverrides := make(testutil.Toml) + configTomlOverrides["consensus"] = consensusOverrides + configTomlOverrides["log_level"] = "info" + + configFileOverrides := make(map[string]any) + configFileOverrides["config/config.toml"] = configTomlOverrides + return configFileOverrides +} + +// GetGrandpaTestChains returns the configured chains for the grandpa test suite. +func (s *GrandpaTestSuite) GetGrandpaTestChains() (ibc.Chain, ibc.Chain) { + return s.GetChains(func(options *testsuite.ChainOptions) { + // configure chain A (polkadot) + options.ChainASpec.ChainName = composable + options.ChainASpec.Type = "polkadot" + options.ChainASpec.ChainID = "rococo-local" + options.ChainASpec.Name = "composable" + options.ChainASpec.Images = []ibc.DockerImage{ + // TODO: https://github.com/cosmos/ibc-go/issues/4965 + { + Repository: "ghcr.io/misko9/polkadot-node", + Version: "v39", + UidGid: "1000:1000", + }, + { + Repository: "ghcr.io/misko9/parachain-node", + Version: "20231122v39", + UidGid: "1000:1000", + }, + } + options.ChainASpec.Bin = "polkadot" + options.ChainASpec.Bech32Prefix = composable + options.ChainASpec.Denom = "uDOT" + options.ChainASpec.GasPrices = "" + options.ChainASpec.GasAdjustment = 0 + options.ChainASpec.TrustingPeriod = "" + options.ChainASpec.CoinType = "354" + + // these values are set by default for our cosmos chains, we need to explicitly remove them here. + options.ChainASpec.ModifyGenesis = nil + options.ChainASpec.ConfigFileOverrides = nil + options.ChainASpec.EncodingConfig = nil + + // configure chain B (cosmos) + options.ChainBSpec.ChainName = simd // Set chain name so that a suffix with a "dash" is not appended (required for hyperspace) + options.ChainBSpec.Type = "cosmos" + options.ChainBSpec.Name = "simd" + options.ChainBSpec.ChainID = simd + options.ChainBSpec.Bin = simd + options.ChainBSpec.Bech32Prefix = "cosmos" + + // TODO: hyperspace relayer assumes a denom of "stake", hard code this here right now. + // https://github.com/cosmos/ibc-go/issues/4964 + options.ChainBSpec.Denom = "stake" + options.ChainBSpec.GasPrices = "0.00stake" + options.ChainBSpec.GasAdjustment = 1 + options.ChainBSpec.TrustingPeriod = "504h" + options.ChainBSpec.CoinType = "118" + + options.ChainBSpec.ChainConfig.NoHostMount = false + options.ChainBSpec.ConfigFileOverrides = getConfigOverrides() + options.ChainBSpec.EncodingConfig = testsuite.SDKEncodingConfig() + }) +} + +// queryAllowedClientsParam queries the on-chain allowed clients param for 02-client +func (s *GrandpaTestSuite) queryAllowedClientsParam(ctx context.Context, chain ibc.Chain) []string { + if testvalues.SelfParamsFeatureReleases.IsSupported(chain.Config().Images[0].Version) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.ClientParams(ctx, &clienttypes.QueryClientParamsRequest{}) + s.Require().NoError(err) + + return res.Params.AllowedClients + } + queryClient := s.GetChainGRCPClients(chain).ParamsQueryClient + res, err := queryClient.Params(ctx, ¶msproposaltypes.QueryParamsRequest{ + Subspace: ibcexported.ModuleName, + Key: string(clienttypes.KeyAllowedClients), + }) + s.Require().NoError(err) + + var allowedClients []string + err = cmtjson.Unmarshal([]byte(res.Param.Value), &allowedClients) + s.Require().NoError(err) + + return allowedClients +} + +// allowWasmClients adds 08-wasm to the on-chain allowed clients param for 02-client +func (s *GrandpaTestSuite) allowWasmClients(ctx context.Context, chain ibc.Chain, wallet ibc.Wallet, allowedClients []string) { + govModuleAddress, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, chain) + s.Require().NoError(err) + s.Require().NotNil(govModuleAddress) + + allowedClients = append(allowedClients, wasmtypes.Wasm) + if testvalues.SelfParamsFeatureReleases.IsSupported(chain.Config().Images[0].Version) { + msg := clienttypes.NewMsgUpdateParams(govModuleAddress.String(), clienttypes.NewParams(allowedClients...)) + s.ExecuteAndPassGovV1Proposal(ctx, msg, chain, wallet) + } else { + value, err := cmtjson.Marshal(allowedClients) + s.Require().NoError(err) + changes := []paramsproposaltypes.ParamChange{ + paramsproposaltypes.NewParamChange(ibcexported.ModuleName, string(clienttypes.KeyAllowedClients), string(value)), + } + + proposal := paramsproposaltypes.NewParameterChangeProposal(ibctesting.Title, ibctesting.Description, changes) + s.ExecuteAndPassGovV1Beta1Proposal(ctx, chain, wallet, proposal) + } +} diff --git a/e2e/testsuite/grpc_query.go b/e2e/testsuite/grpc_query.go new file mode 100644 index 00000000000..23e9a5fa5f8 --- /dev/null +++ b/e2e/testsuite/grpc_query.go @@ -0,0 +1,451 @@ +package testsuite + +import ( + "context" + "fmt" + "sort" + "time" + + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + "cosmossdk.io/math" + upgradetypes "cosmossdk.io/x/upgrade/types" + + "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/authz" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + grouptypes "github.com/cosmos/cosmos-sdk/x/group" + paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + + wasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" + controllertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" + hosttypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types" + feetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/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" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" +) + +// GRPCClients holds a reference to any GRPC clients that are needed by the tests. +// These should typically be used for query clients only. If we need to make changes, we should +// use E2ETestSuite.BroadcastMessages to broadcast transactions instead. +type GRPCClients struct { + ClientQueryClient clienttypes.QueryClient + ConnectionQueryClient connectiontypes.QueryClient + ChannelQueryClient channeltypes.QueryClient + TransferQueryClient transfertypes.QueryClient + FeeQueryClient feetypes.QueryClient + ICAControllerQueryClient controllertypes.QueryClient + ICAHostQueryClient hosttypes.QueryClient + WasmQueryClient wasmtypes.QueryClient + + // SDK query clients + BankQueryClient banktypes.QueryClient + GovQueryClient govtypesv1beta1.QueryClient + GovQueryClientV1 govtypesv1.QueryClient + GroupsQueryClient grouptypes.QueryClient + ParamsQueryClient paramsproposaltypes.QueryClient + AuthQueryClient authtypes.QueryClient + AuthZQueryClient authz.QueryClient + UpgradeQueryClient upgradetypes.QueryClient + + ConsensusServiceClient cmtservice.ServiceClient +} + +// InitGRPCClients establishes GRPC clients with the given chain. +// The created GRPCClients can be retrieved with GetChainGRCPClients. +func (s *E2ETestSuite) InitGRPCClients(chain ibc.Chain) { + _, ok := chain.(*cosmos.CosmosChain) + if !ok { + return + } + + // Create a connection to the gRPC server. + grpcConn, err := grpc.Dial( + chain.GetHostGRPCAddress(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + s.Require().NoError(err) + s.T().Cleanup(func() { + if err := grpcConn.Close(); err != nil { + s.T().Logf("failed closing GRPC connection to chain %s: %s", chain.Config().ChainID, err) + } + }) + + if s.grpcClients == nil { + s.grpcClients = make(map[string]GRPCClients) + } + + s.grpcClients[chain.Config().ChainID] = GRPCClients{ + ClientQueryClient: clienttypes.NewQueryClient(grpcConn), + ConnectionQueryClient: connectiontypes.NewQueryClient(grpcConn), + ChannelQueryClient: channeltypes.NewQueryClient(grpcConn), + TransferQueryClient: transfertypes.NewQueryClient(grpcConn), + FeeQueryClient: feetypes.NewQueryClient(grpcConn), + ICAControllerQueryClient: controllertypes.NewQueryClient(grpcConn), + ICAHostQueryClient: hosttypes.NewQueryClient(grpcConn), + WasmQueryClient: wasmtypes.NewQueryClient(grpcConn), + BankQueryClient: banktypes.NewQueryClient(grpcConn), + GovQueryClient: govtypesv1beta1.NewQueryClient(grpcConn), + GovQueryClientV1: govtypesv1.NewQueryClient(grpcConn), + GroupsQueryClient: grouptypes.NewQueryClient(grpcConn), + ParamsQueryClient: paramsproposaltypes.NewQueryClient(grpcConn), + AuthQueryClient: authtypes.NewQueryClient(grpcConn), + AuthZQueryClient: authz.NewQueryClient(grpcConn), + ConsensusServiceClient: cmtservice.NewServiceClient(grpcConn), + UpgradeQueryClient: upgradetypes.NewQueryClient(grpcConn), + } +} + +// Header defines an interface which is implemented by both the sdk block header and the cometbft Block Header. +// this interfaces allows us to use the same function to fetch the block header for both chains. +type Header interface { + GetTime() time.Time + GetLastCommitHash() []byte +} + +// QueryClientState queries the client state on the given chain for the provided clientID. +func (s *E2ETestSuite) QueryClientState(ctx context.Context, chain ibc.Chain, clientID string) (ibcexported.ClientState, error) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.ClientState(ctx, &clienttypes.QueryClientStateRequest{ + ClientId: clientID, + }) + if err != nil { + return nil, err + } + + cfg := EncodingConfig() + var clientState ibcexported.ClientState + if err := cfg.InterfaceRegistry.UnpackAny(res.ClientState, &clientState); err != nil { + return nil, err + } + + return clientState, nil +} + +// QueryUpgradedClientState queries the upgraded client state on the given chain for the provided clientID. +func (s *E2ETestSuite) QueryUpgradedClientState(ctx context.Context, chain ibc.Chain, clientID string) (ibcexported.ClientState, error) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.UpgradedClientState(ctx, &clienttypes.QueryUpgradedClientStateRequest{}) + if err != nil { + return nil, err + } + + cfg := EncodingConfig() + var clientState ibcexported.ClientState + if err := cfg.InterfaceRegistry.UnpackAny(res.UpgradedClientState, &clientState); err != nil { + return nil, err + } + + return clientState, nil +} + +// QueryClientStatus queries the status of the client by clientID +func (s *E2ETestSuite) QueryClientStatus(ctx context.Context, chain ibc.Chain, clientID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).ClientQueryClient + res, err := queryClient.ClientStatus(ctx, &clienttypes.QueryClientStatusRequest{ + ClientId: clientID, + }) + if err != nil { + return "", err + } + + return res.Status, nil +} + +// QueryCurrentUpgradePlan queries the currently scheduled upgrade plans. +func (s *E2ETestSuite) QueryCurrentUpgradePlan(ctx context.Context, chain ibc.Chain) (upgradetypes.Plan, error) { + queryClient := s.GetChainGRCPClients(chain).UpgradeQueryClient + res, err := queryClient.CurrentPlan(ctx, &upgradetypes.QueryCurrentPlanRequest{}) + if err != nil { + return upgradetypes.Plan{}, err + } + + return *res.Plan, nil +} + +// QueryConnection queries the connection end using the given chain and connection id. +func (s *E2ETestSuite) QueryConnection(ctx context.Context, chain ibc.Chain, connectionID string) (connectiontypes.ConnectionEnd, error) { + queryClient := s.GetChainGRCPClients(chain).ConnectionQueryClient + res, err := queryClient.Connection(ctx, &connectiontypes.QueryConnectionRequest{ + ConnectionId: connectionID, + }) + if err != nil { + return connectiontypes.ConnectionEnd{}, err + } + + return *res.Connection, nil +} + +// QueryChannel queries the channel on a given chain for the provided portID and channelID +func (s *E2ETestSuite) QueryChannel(ctx context.Context, chain ibc.Chain, portID, channelID string) (channeltypes.Channel, error) { + queryClient := s.GetChainGRCPClients(chain).ChannelQueryClient + res, err := queryClient.Channel(ctx, &channeltypes.QueryChannelRequest{ + PortId: portID, + ChannelId: channelID, + }) + if err != nil { + return channeltypes.Channel{}, err + } + + return *res.Channel, nil +} + +// QueryPacketCommitment queries the packet commitment on the given chain for the provided channel and sequence. +func (s *E2ETestSuite) QueryPacketCommitment(ctx context.Context, chain ibc.Chain, portID, channelID string, sequence uint64) ([]byte, error) { + queryClient := s.GetChainGRCPClients(chain).ChannelQueryClient + res, err := queryClient.PacketCommitment(ctx, &channeltypes.QueryPacketCommitmentRequest{ + PortId: portID, + ChannelId: channelID, + Sequence: sequence, + }) + if err != nil { + return nil, err + } + return res.Commitment, nil +} + +// QueryTotalEscrowForDenom queries the total amount of tokens in escrow for a denom +func (s *E2ETestSuite) QueryTotalEscrowForDenom(ctx context.Context, chain ibc.Chain, denom string) (sdk.Coin, error) { + queryClient := s.GetChainGRCPClients(chain).TransferQueryClient + res, err := queryClient.TotalEscrowForDenom(ctx, &transfertypes.QueryTotalEscrowForDenomRequest{ + Denom: denom, + }) + if err != nil { + return sdk.Coin{}, err + } + + return res.Amount, nil +} + +// QueryInterchainAccount queries the interchain account for the given owner and connectionID. +func (s *E2ETestSuite) QueryInterchainAccount(ctx context.Context, chain ibc.Chain, owner, connectionID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).ICAControllerQueryClient + res, err := queryClient.InterchainAccount(ctx, &controllertypes.QueryInterchainAccountRequest{ + Owner: owner, + ConnectionId: connectionID, + }) + if err != nil { + return "", err + } + return res.Address, nil +} + +// QueryIncentivizedPacketsForChannel queries the incentivized packets on the specified channel. +func (s *E2ETestSuite) QueryIncentivizedPacketsForChannel( + ctx context.Context, + chain ibc.Chain, + portID, + channelID string, +) ([]*feetypes.IdentifiedPacketFees, error) { + queryClient := s.GetChainGRCPClients(chain).FeeQueryClient + res, err := queryClient.IncentivizedPacketsForChannel(ctx, &feetypes.QueryIncentivizedPacketsForChannelRequest{ + PortId: portID, + ChannelId: channelID, + }) + if err != nil { + return nil, err + } + return res.IncentivizedPackets, err +} + +// QueryFeeEnabledChannel queries the fee-enabled status of a channel. +func (s *E2ETestSuite) QueryFeeEnabledChannel(ctx context.Context, chain ibc.Chain, portID, channelID string) (bool, error) { + queryClient := s.GetChainGRCPClients(chain).FeeQueryClient + res, err := queryClient.FeeEnabledChannel(ctx, &feetypes.QueryFeeEnabledChannelRequest{ + PortId: portID, + ChannelId: channelID, + }) + if err != nil { + return false, err + } + return res.FeeEnabled, nil +} + +// QueryCounterPartyPayee queries the counterparty payee of the given chain and relayer address on the specified channel. +func (s *E2ETestSuite) QueryCounterPartyPayee(ctx context.Context, chain ibc.Chain, relayerAddress, channelID string) (string, error) { + queryClient := s.GetChainGRCPClients(chain).FeeQueryClient + res, err := queryClient.CounterpartyPayee(ctx, &feetypes.QueryCounterpartyPayeeRequest{ + ChannelId: channelID, + Relayer: relayerAddress, + }) + if err != nil { + return "", err + } + return res.CounterpartyPayee, nil +} + +// QueryBalance returns the balance of a specific denomination for a given account by address. +func (s *E2ETestSuite) QueryBalance(ctx context.Context, chain ibc.Chain, address string, denom string) (math.Int, error) { + queryClient := s.GetChainGRCPClients(chain).BankQueryClient + res, err := queryClient.Balance(ctx, &banktypes.QueryBalanceRequest{ + Address: address, + Denom: denom, + }) + if err != nil { + return math.Int{}, err + } + + return res.Balance.Amount, nil +} + +// QueryProposalV1Beta1 queries the governance proposal on the given chain with the given proposal ID. +func (s *E2ETestSuite) QueryProposalV1Beta1(ctx context.Context, chain ibc.Chain, proposalID uint64) (govtypesv1beta1.Proposal, error) { + queryClient := s.GetChainGRCPClients(chain).GovQueryClient + res, err := queryClient.Proposal(ctx, &govtypesv1beta1.QueryProposalRequest{ + ProposalId: proposalID, + }) + if err != nil { + return govtypesv1beta1.Proposal{}, err + } + + return res.Proposal, nil +} + +func (s *E2ETestSuite) QueryProposalV1(ctx context.Context, chain ibc.Chain, proposalID uint64) (govtypesv1.Proposal, error) { + queryClient := s.GetChainGRCPClients(chain).GovQueryClientV1 + res, err := queryClient.Proposal(ctx, &govtypesv1.QueryProposalRequest{ + ProposalId: proposalID, + }) + if err != nil { + return govtypesv1.Proposal{}, err + } + + return *res.Proposal, nil +} + +// GetBlockHeaderByHeight fetches the block header at a given height. +func (s *E2ETestSuite) GetBlockHeaderByHeight(ctx context.Context, chain ibc.Chain, height uint64) (Header, error) { + consensusService := s.GetChainGRCPClients(chain).ConsensusServiceClient + res, err := consensusService.GetBlockByHeight(ctx, &cmtservice.GetBlockByHeightRequest{ + Height: int64(height), + }) + if err != nil { + return nil, err + } + + // Clean up when v4 is not supported, see: https://github.com/cosmos/ibc-go/issues/3540 + // versions newer than 0.46 SDK use the SdkBlock field while versions older + // than 0.46 SDK, which do not have the SdkBlock field, use the Block field. + if res.SdkBlock != nil { + return &res.SdkBlock.Header, nil + } + return &res.Block.Header, nil // needed for v4 (uses SDK v0.45) +} + +// GetValidatorSetByHeight returns the validators of the given chain at the specified height. The returned validators +// are sorted by address. +func (s *E2ETestSuite) GetValidatorSetByHeight(ctx context.Context, chain ibc.Chain, height uint64) ([]*cmtservice.Validator, error) { + consensusService := s.GetChainGRCPClients(chain).ConsensusServiceClient + res, err := consensusService.GetValidatorSetByHeight(ctx, &cmtservice.GetValidatorSetByHeightRequest{ + Height: int64(height), + }) + if err != nil { + return nil, err + } + + sort.SliceStable(res.Validators, func(i, j int) bool { + return res.Validators[i].Address < res.Validators[j].Address + }) + + return res.Validators, nil +} + +// QueryModuleAccountAddress returns the sdk.AccAddress of a given module name. +func (s *E2ETestSuite) QueryModuleAccountAddress(ctx context.Context, moduleName string, chain ibc.Chain) (sdk.AccAddress, error) { + authClient := s.GetChainGRCPClients(chain).AuthQueryClient + resp, err := authClient.ModuleAccountByName(ctx, &authtypes.QueryModuleAccountByNameRequest{ + Name: moduleName, + }) + if err != nil { + return nil, err + } + + cfg := EncodingConfig() + + var account sdk.AccountI + if err := cfg.InterfaceRegistry.UnpackAny(resp.Account, &account); err != nil { + return nil, err + } + moduleAccount, ok := account.(authtypes.ModuleAccountI) + if !ok { + return nil, fmt.Errorf("failed to cast account: %T as ModuleAccount", moduleAccount) + } + + return moduleAccount.GetAddress(), nil +} + +// QueryGranterGrants returns all GrantAuthorizations for the given granterAddress. +func (s *E2ETestSuite) QueryGranterGrants(ctx context.Context, chain ibc.Chain, granterAddress string) ([]*authz.GrantAuthorization, error) { + authzClient := s.GetChainGRCPClients(chain).AuthZQueryClient + queryRequest := &authz.QueryGranterGrantsRequest{ + Granter: granterAddress, + } + + grants, err := authzClient.GranterGrants(ctx, queryRequest) + if err != nil { + return nil, err + } + + return grants.Grants, nil +} + +// QueryBalances returns all the balances on the given chain for the provided address. +func (s *E2ETestSuite) QueryAllBalances(ctx context.Context, chain ibc.Chain, address string, resolveDenom bool) (sdk.Coins, error) { + queryClient := s.GetChainGRCPClients(chain).BankQueryClient + res, err := queryClient.AllBalances(ctx, &banktypes.QueryAllBalancesRequest{ + Address: address, + ResolveDenom: resolveDenom, + }) + if err != nil { + return sdk.Coins{}, err + } + + return res.Balances, nil +} + +// QueryDenomMetadata queries the metadata for the given denom. +func (s *E2ETestSuite) QueryDenomMetadata(ctx context.Context, chain ibc.Chain, denom string) (banktypes.Metadata, error) { + bankClient := s.GetChainGRCPClients(chain).BankQueryClient + queryRequest := &banktypes.QueryDenomMetadataRequest{ + Denom: denom, + } + res, err := bankClient.DenomMetadata(ctx, queryRequest) + if err != nil { + return banktypes.Metadata{}, err + } + return res.Metadata, nil +} + +// QueryWasmCode queries the code for a wasm contract. +func (s *E2ETestSuite) QueryWasmCode(ctx context.Context, chain ibc.Chain, checksum string) ([]byte, error) { + queryClient := s.GetChainGRCPClients(chain).WasmQueryClient + queryRequest := &wasmtypes.QueryCodeRequest{ + Checksum: checksum, + } + res, err := queryClient.Code(ctx, queryRequest) + if err != nil { + return nil, err + } + return res.Data, nil +} + +// QueryWasmChecksums queries the wasm code checksums stored within the 08-wasm module. +func (s *E2ETestSuite) QueryWasmChecksums(ctx context.Context, chain ibc.Chain) ([]string, error) { + queryClient := s.GetChainGRCPClients(chain).WasmQueryClient + res, err := queryClient.Checksums(ctx, &wasmtypes.QueryChecksumsRequest{}) + if err != nil { + return nil, err + } + + return res.Checksums, nil +} diff --git a/e2e/testsuite/testconfig.go b/e2e/testsuite/testconfig.go new file mode 100644 index 00000000000..c88646fc6d9 --- /dev/null +++ b/e2e/testsuite/testconfig.go @@ -0,0 +1,675 @@ +package testsuite + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "path" + "strings" + "time" + + "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + interchaintestutil "github.com/strangelove-ventures/interchaintest/v8/testutil" + "gopkg.in/yaml.v2" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module/testutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + + cmtjson "github.com/cometbft/cometbft/libs/json" + + "github.com/cosmos/ibc-go/e2e/relayer" + "github.com/cosmos/ibc-go/e2e/semverutil" + "github.com/cosmos/ibc-go/e2e/testvalues" +) + +const ( + // ChainImageEnv specifies the image that the chains will use. If left unspecified, it will + // default to being determined based on the specified binary. E.g. ghcr.io/cosmos/ibc-go-simd + ChainImageEnv = "CHAIN_IMAGE" + // ChainATagEnv specifies the tag that Chain A will use. + ChainATagEnv = "CHAIN_A_TAG" + // ChainBTagEnv specifies the tag that Chain B will use. If unspecified + // the value will default to the same value as Chain A. + ChainBTagEnv = "CHAIN_B_TAG" + // RelayerIDEnv specifies the ID of the relayer to use. + RelayerIDEnv = "RELAYER_ID" + // ChainBinaryEnv binary is the binary that will be used for both chains. + ChainBinaryEnv = "CHAIN_BINARY" + // ChainUpgradeTagEnv specifies the upgrade version tag + ChainUpgradeTagEnv = "CHAIN_UPGRADE_TAG" + // ChainUpgradePlanEnv specifies the upgrade plan name + ChainUpgradePlanEnv = "CHAIN_UPGRADE_PLAN" + // E2EConfigFilePathEnv allows you to specify a custom path for the config file to be used. + E2EConfigFilePathEnv = "E2E_CONFIG_PATH" + + // defaultBinary is the default binary that will be used by the chains. + defaultBinary = "simd" + // defaultRlyTag is the tag that will be used if no relayer tag is specified. + // all images are here https://github.com/cosmos/relayer/pkgs/container/relayer/versions + defaultRlyTag = "latest" + + // TODO: https://github.com/cosmos/ibc-go/issues/4965 + defaultHyperspaceTag = "20231122v39" + // defaultHermesTag is the tag that will be used if no relayer tag is specified for hermes. + defaultHermesTag = "luca_joss-channel-upgrade-authority" + // defaultChainTag is the tag that will be used for the chains if none is specified. + defaultChainTag = "main" + // defaultConfigFileName is the default filename for the config file that can be used to configure + // e2e tests. See sample.config.yaml as an example for what this should look like. + defaultConfigFileName = ".ibc-go-e2e-config.yaml" +) + +func getChainImage(binary string) string { + if binary == "" { + binary = defaultBinary + } + return fmt.Sprintf("ghcr.io/cosmos/ibc-go-%s", binary) +} + +// TestConfig holds configuration used throughout the different e2e tests. +type TestConfig struct { + // ChainConfigs holds configuration values related to the chains used in the tests. + ChainConfigs []ChainConfig `yaml:"chains"` + // RelayerConfig holds all known relayer configurations that can be used in the tests. + RelayerConfigs []relayer.Config `yaml:"relayers"` + // ActiveRelayer specifies the relayer that will be used. It must match the ID of one of the entries in RelayerConfigs. + ActiveRelayer string `yaml:"activeRelayer"` + // UpgradeConfig holds values used only for the upgrade tests. + UpgradeConfig UpgradeConfig `yaml:"upgrade"` + // CometBFTConfig holds values for configuring CometBFT. + CometBFTConfig CometBFTConfig `yaml:"cometbft"` + // DebugConfig holds configuration for miscellaneous options. + DebugConfig DebugConfig `yaml:"debug"` +} + +// Validate validates the test configuration is valid for use within the tests. +// this should be called before using the configuration. +func (tc TestConfig) Validate() error { + if err := tc.validateChains(); err != nil { + return fmt.Errorf("invalid chain configuration: %w", err) + } + + if err := tc.validateRelayers(); err != nil { + return fmt.Errorf("invalid relayer configuration: %w", err) + } + return nil +} + +// validateChains validates the chain configurations. +func (tc TestConfig) validateChains() error { + for _, cfg := range tc.ChainConfigs { + if cfg.Binary == "" { + return fmt.Errorf("chain config missing binary: %+v", cfg) + } + if cfg.Image == "" { + return fmt.Errorf("chain config missing image: %+v", cfg) + } + if cfg.Tag == "" { + return fmt.Errorf("chain config missing tag: %+v", cfg) + } + + // TODO: validate chainID in https://github.com/cosmos/ibc-go/issues/4697 + // these are not passed in the CI at the moment. Defaults are used. + if !IsCI() { + if cfg.ChainID == "" { + return fmt.Errorf("chain config missing chainID: %+v", cfg) + } + } + + // TODO: validate number of nodes in https://github.com/cosmos/ibc-go/issues/4697 + // these are not passed in the CI at the moment. + if !IsCI() { + if cfg.NumValidators == 0 && cfg.NumFullNodes == 0 { + return fmt.Errorf("chain config missing number of validators or full nodes: %+v", cfg) + } + } + } + return nil +} + +// validateRelayers validates relayer configuration. +func (tc TestConfig) validateRelayers() error { + if len(tc.RelayerConfigs) < 1 { + return fmt.Errorf("no relayer configurations specified") + } + + for _, r := range tc.RelayerConfigs { + if r.ID == "" { + return fmt.Errorf("relayer config missing ID: %+v", r) + } + if r.Image == "" { + return fmt.Errorf("relayer config missing image: %+v", r) + } + if r.Tag == "" { + return fmt.Errorf("relayer config missing tag: %+v", r) + } + } + + if tc.GetActiveRelayerConfig() == nil { + return fmt.Errorf("active relayer %s not found in relayer configs: %+v", tc.ActiveRelayer, tc.RelayerConfigs) + } + + return nil +} + +// GetActiveRelayerConfig returns the currently specified relayer config. +func (tc TestConfig) GetActiveRelayerConfig() *relayer.Config { + for _, r := range tc.RelayerConfigs { + if r.ID == tc.ActiveRelayer { + return &r + } + } + return nil +} + +// GetChainNumValidators returns the number of validators for the specific chain index. +// default 1 +func (tc TestConfig) GetChainNumValidators(idx int) int { + if tc.ChainConfigs[idx].NumValidators > 0 { + return tc.ChainConfigs[idx].NumValidators + } + return 1 +} + +// GetChainNumFullNodes returns the number of full nodes for the specific chain index. +// default 0 +func (tc TestConfig) GetChainNumFullNodes(idx int) int { + if tc.ChainConfigs[idx].NumFullNodes > 0 { + return tc.ChainConfigs[idx].NumFullNodes + } + return 0 +} + +// GetChainAID returns the chain-id for chain A. +func (tc TestConfig) GetChainAID() string { + if tc.ChainConfigs[0].ChainID != "" { + return tc.ChainConfigs[0].ChainID + } + return "chainA-1" +} + +// GetChainBID returns the chain-id for chain B. +func (tc TestConfig) GetChainBID() string { + if tc.ChainConfigs[1].ChainID != "" { + return tc.ChainConfigs[1].ChainID + } + return "chainB-1" +} + +// UpgradeConfig holds values relevant to upgrade tests. +type UpgradeConfig struct { + PlanName string `yaml:"planName"` + Tag string `yaml:"tag"` +} + +// ChainConfig holds information about an individual chain used in the tests. +type ChainConfig struct { + ChainID string `yaml:"chainId"` + Image string `yaml:"image"` + Tag string `yaml:"tag"` + Binary string `yaml:"binary"` + NumValidators int `yaml:"numValidators"` + NumFullNodes int `yaml:"numFullNodes"` +} + +type CometBFTConfig struct { + LogLevel string `yaml:"logLevel"` +} + +type DebugConfig struct { + // DumpLogs forces the logs to be collected before removing test containers. + DumpLogs bool `yaml:"dumpLogs"` +} + +// LoadConfig attempts to load a atest configuration from the default file path. +// if any environment variables are specified, they will take precedence over the individual configuration +// options. +func LoadConfig() TestConfig { + tc := getConfig() + if err := tc.Validate(); err != nil { + panic(err) + } + return tc +} + +// getConfig returns the TestConfig with any environment variable overrides. +func getConfig() TestConfig { + fileTc, foundFile := fromFile() + if !foundFile { + return fromEnv() + } + + return applyEnvironmentVariableOverrides(fileTc) +} + +// fromFile returns a TestConfig from a json file and a boolean indicating if the file was found. +func fromFile() (TestConfig, bool) { + var tc TestConfig + bz, err := os.ReadFile(getConfigFilePath()) + if err != nil { + return TestConfig{}, false + } + + if err := yaml.Unmarshal(bz, &tc); err != nil { + panic(err) + } + + return tc, true +} + +// applyEnvironmentVariableOverrides applies all environment variable changes to the config +// loaded from a file. +func applyEnvironmentVariableOverrides(fromFile TestConfig) TestConfig { + envTc := fromEnv() + + if os.Getenv(ChainATagEnv) != "" { + fromFile.ChainConfigs[0].Tag = envTc.ChainConfigs[0].Tag + } + + if os.Getenv(ChainBTagEnv) != "" { + fromFile.ChainConfigs[1].Tag = envTc.ChainConfigs[1].Tag + } + + if os.Getenv(ChainBinaryEnv) != "" { + for i := range fromFile.ChainConfigs { + fromFile.ChainConfigs[i].Binary = envTc.ChainConfigs[i].Binary + } + } + + if os.Getenv(ChainImageEnv) != "" { + for i := range fromFile.ChainConfigs { + fromFile.ChainConfigs[i].Image = envTc.ChainConfigs[i].Image + } + } + + if os.Getenv(RelayerIDEnv) != "" { + fromFile.ActiveRelayer = envTc.ActiveRelayer + } + + if os.Getenv(ChainUpgradePlanEnv) != "" { + fromFile.UpgradeConfig.PlanName = envTc.UpgradeConfig.PlanName + } + + if os.Getenv(ChainUpgradeTagEnv) != "" { + fromFile.UpgradeConfig.Tag = envTc.UpgradeConfig.Tag + } + + return fromFile +} + +// fromEnv returns a TestConfig constructed from environment variables. +func fromEnv() TestConfig { + return TestConfig{ + ChainConfigs: getChainConfigsFromEnv(), + UpgradeConfig: getUpgradePlanConfigFromEnv(), + ActiveRelayer: os.Getenv(RelayerIDEnv), + + // TODO: we can remove this, and specify these values in a config file for the CI + // in https://github.com/cosmos/ibc-go/issues/4697 + RelayerConfigs: []relayer.Config{ + getDefaultRlyRelayerConfig(), + getDefaultHermesRelayerConfig(), + getDefaultHyperspaceRelayerConfig(), + }, + CometBFTConfig: CometBFTConfig{LogLevel: "info"}, + } +} + +// getChainConfigsFromEnv returns the chain configs from environment variables. +func getChainConfigsFromEnv() []ChainConfig { + chainBinary, ok := os.LookupEnv(ChainBinaryEnv) + if !ok { + chainBinary = defaultBinary + } + + chainATag, ok := os.LookupEnv(ChainATagEnv) + if !ok { + chainATag = defaultChainTag + } + + chainBTag, ok := os.LookupEnv(ChainBTagEnv) + if !ok { + chainBTag = chainATag + } + + chainAImage := getChainImage(chainBinary) + specifiedChainImage, ok := os.LookupEnv(ChainImageEnv) + if ok { + chainAImage = specifiedChainImage + } + + numValidators := 4 + numFullNodes := 1 + + chainBImage := chainAImage + return []ChainConfig{ + { + Image: chainAImage, + Tag: chainATag, + Binary: chainBinary, + NumValidators: numValidators, + NumFullNodes: numFullNodes, + }, + { + Image: chainBImage, + Tag: chainBTag, + Binary: chainBinary, + NumValidators: numValidators, + NumFullNodes: numFullNodes, + }, + } +} + +// getConfigFilePath returns the absolute path where the e2e config file should be. +func getConfigFilePath() string { + if absoluteConfigPath := os.Getenv(E2EConfigFilePathEnv); absoluteConfigPath != "" { + return absoluteConfigPath + } + + homeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + return path.Join(homeDir, defaultConfigFileName) +} + +// TODO: remove in https://github.com/cosmos/ibc-go/issues/4697 +// getDefaultHermesRelayerConfig returns the default config for the hermes relayer. +func getDefaultHermesRelayerConfig() relayer.Config { + return relayer.Config{ + Tag: defaultHermesTag, + ID: relayer.Hermes, + Image: relayer.HermesRelayerRepository, + } +} + +// TODO: remove in https://github.com/cosmos/ibc-go/issues/4697 +// getDefaultRlyRelayerConfig returns the default config for the golang relayer. +func getDefaultRlyRelayerConfig() relayer.Config { + return relayer.Config{ + Tag: defaultRlyTag, + ID: relayer.Rly, + Image: relayer.RlyRelayerRepository, + } +} + +// TODO: remove in https://github.com/cosmos/ibc-go/issues/4697 +// getDefaultHyperspaceRelayerConfig returns the default config for the hyperspace relayer. +func getDefaultHyperspaceRelayerConfig() relayer.Config { + return relayer.Config{ + Tag: defaultHyperspaceTag, + ID: relayer.Hyperspace, + Image: relayer.HyperspaceRelayerRepository, + } +} + +// getUpgradePlanConfigFromEnv returns the upgrade config from environment variables. +func getUpgradePlanConfigFromEnv() UpgradeConfig { + upgradeTag, ok := os.LookupEnv(ChainUpgradeTagEnv) + if !ok { + upgradeTag = "" + } + + upgradePlan, ok := os.LookupEnv(ChainUpgradePlanEnv) + if !ok { + upgradePlan = "" + } + return UpgradeConfig{ + PlanName: upgradePlan, + Tag: upgradeTag, + } +} + +func GetChainATag() string { + return LoadConfig().ChainConfigs[0].Tag +} + +func GetChainBTag() string { + if chainBTag := LoadConfig().ChainConfigs[1].Tag; chainBTag != "" { + return chainBTag + } + return GetChainATag() +} + +// IsCI returns true if the tests are running in CI, false is returned +// if the tests are running locally. +// Note: github actions passes a CI env value of true by default to all runners. +func IsCI() bool { + return strings.ToLower(os.Getenv("CI")) == "true" +} + +// IsFork returns true if the tests are running in fork mode, false is returned otherwise. +func IsFork() bool { + return strings.ToLower(os.Getenv("FORK")) == "true" +} + +// ChainOptions stores chain configurations for the chains that will be +// created for the tests. They can be modified by passing ChainOptionConfiguration +// to E2ETestSuite.GetChains. +type ChainOptions struct { + ChainASpec *interchaintest.ChainSpec + ChainBSpec *interchaintest.ChainSpec + SkipPathCreation bool +} + +// ChainOptionConfiguration enables arbitrary configuration of ChainOptions. +type ChainOptionConfiguration func(options *ChainOptions) + +// DefaultChainOptions returns the default configuration for the chains. +// These options can be configured by passing configuration functions to E2ETestSuite.GetChains. +func DefaultChainOptions() ChainOptions { + tc := LoadConfig() + + chainACfg := newDefaultSimappConfig(tc.ChainConfigs[0], "simapp-a", tc.GetChainAID(), "atoma", tc.CometBFTConfig) + chainBCfg := newDefaultSimappConfig(tc.ChainConfigs[1], "simapp-b", tc.GetChainBID(), "atomb", tc.CometBFTConfig) + + chainAVal, chainAFn := getValidatorsAndFullNodes(0) + chainBVal, chainBFn := getValidatorsAndFullNodes(1) + + return ChainOptions{ + ChainASpec: &interchaintest.ChainSpec{ + ChainConfig: chainACfg, + NumFullNodes: &chainAFn, + NumValidators: &chainAVal, + }, + ChainBSpec: &interchaintest.ChainSpec{ + ChainConfig: chainBCfg, + NumFullNodes: &chainBFn, + NumValidators: &chainBVal, + }, + } +} + +// newDefaultSimappConfig creates an ibc configuration for simd. +func newDefaultSimappConfig(cc ChainConfig, name, chainID, denom string, cometCfg CometBFTConfig) ibc.ChainConfig { + configFileOverrides := make(map[string]any) + tmTomlOverrides := make(interchaintestutil.Toml) + + tmTomlOverrides["log_level"] = cometCfg.LogLevel // change to debug in ~/.ibc-go-e2e-config.json to increase cometbft logging. + configFileOverrides["config/config.toml"] = tmTomlOverrides + + return ibc.ChainConfig{ + Type: "cosmos", + Name: name, + ChainID: chainID, + Images: []ibc.DockerImage{ + { + Repository: cc.Image, + Version: cc.Tag, + UidGid: "1000:1000", + }, + }, + Bin: cc.Binary, + Bech32Prefix: "cosmos", + CoinType: fmt.Sprint(sdk.GetConfig().GetCoinType()), + Denom: denom, + EncodingConfig: SDKEncodingConfig(), + GasPrices: fmt.Sprintf("0.00%s", denom), + GasAdjustment: 1.3, + TrustingPeriod: "508h", + NoHostMount: false, + ModifyGenesis: getGenesisModificationFunction(cc), + ConfigFileOverrides: configFileOverrides, + } +} + +// getGenesisModificationFunction returns a genesis modification function that handles the GenesisState type +// correctly depending on if the govv1beta1 gov module is used or if govv1 is being used. +func getGenesisModificationFunction(cc ChainConfig) func(ibc.ChainConfig, []byte) ([]byte, error) { + binary := cc.Binary + version := cc.Tag + + simdSupportsGovV1Genesis := binary == defaultBinary && testvalues.GovGenesisFeatureReleases.IsSupported(version) + + if simdSupportsGovV1Genesis { + return defaultGovv1ModifyGenesis(version) + } + + return defaultGovv1Beta1ModifyGenesis() +} + +// defaultGovv1ModifyGenesis will only modify governance params to ensure the voting period and minimum deposit +// are functional for e2e testing purposes. +func defaultGovv1ModifyGenesis(version string) func(ibc.ChainConfig, []byte) ([]byte, error) { + stdlibJSONMarshalling := semverutil.FeatureReleases{MajorVersion: "v8"} + return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { + appGenesis, err := genutiltypes.AppGenesisFromReader(bytes.NewReader(genbz)) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into genesis doc: %w", err) + } + + var appState genutiltypes.AppMap + if err := json.Unmarshal(appGenesis.AppState, &appState); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into app state: %w", err) + } + + govGenBz, err := modifyGovV1AppState(chainConfig, appState[govtypes.ModuleName]) + if err != nil { + return nil, err + } + + appState[govtypes.ModuleName] = govGenBz + + appGenesis.AppState, err = json.Marshal(appState) + if err != nil { + return nil, err + } + + // in older version < v8, tmjson marshal must be used. + // regular json marshalling must be used for v8 and above as the + // sdk is de-coupled from comet. + marshalIndentFn := cmtjson.MarshalIndent + if stdlibJSONMarshalling.IsSupported(version) { + marshalIndentFn = json.MarshalIndent + } + + bz, err := marshalIndentFn(appGenesis, "", " ") + if err != nil { + return nil, err + } + + return bz, nil + } +} + +// defaultGovv1Beta1ModifyGenesis will only modify governance params to ensure the voting period and minimum deposit +// // are functional for e2e testing purposes. +func defaultGovv1Beta1ModifyGenesis() func(ibc.ChainConfig, []byte) ([]byte, error) { + const appStateKey = "app_state" + return func(chainConfig ibc.ChainConfig, genbz []byte) ([]byte, error) { + genesisDocMap := map[string]interface{}{} + err := json.Unmarshal(genbz, &genesisDocMap) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into genesis doc: %w", err) + } + + appStateMap, ok := genesisDocMap[appStateKey].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("failed to extract to app_state") + } + + govModuleBytes, err := json.Marshal(appStateMap[govtypes.ModuleName]) + if err != nil { + return nil, fmt.Errorf("failed to extract gov genesis bytes: %s", err) + } + + govModuleGenesisBytes, err := modifyGovv1Beta1AppState(chainConfig, govModuleBytes) + if err != nil { + return nil, err + } + + govModuleGenesisMap := map[string]interface{}{} + err = json.Unmarshal(govModuleGenesisBytes, &govModuleGenesisMap) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal gov genesis bytes into map: %w", err) + } + + appStateMap[govtypes.ModuleName] = govModuleGenesisMap + genesisDocMap[appStateKey] = appStateMap + + finalGenesisDocBytes, err := json.MarshalIndent(genesisDocMap, "", " ") + if err != nil { + return nil, err + } + + return finalGenesisDocBytes, nil + } +} + +// modifyGovV1AppState takes the existing gov app state and marshals it to a govv1 GenesisState. +func modifyGovV1AppState(chainConfig ibc.ChainConfig, govAppState []byte) ([]byte, error) { + cfg := testutil.MakeTestEncodingConfig() + + cdc := codec.NewProtoCodec(cfg.InterfaceRegistry) + govv1.RegisterInterfaces(cfg.InterfaceRegistry) + + govGenesisState := &govv1.GenesisState{} + + if err := cdc.UnmarshalJSON(govAppState, govGenesisState); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into gov genesis state: %w", err) + } + + if govGenesisState.Params == nil { + govGenesisState.Params = &govv1.Params{} + } + + govGenesisState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(chainConfig.Denom, govv1beta1.DefaultMinDepositTokens)) + maxDep := time.Second * 10 + govGenesisState.Params.MaxDepositPeriod = &maxDep + vp := testvalues.VotingPeriod + govGenesisState.Params.VotingPeriod = &vp + + govGenBz := MustProtoMarshalJSON(govGenesisState) + + return govGenBz, nil +} + +// modifyGovv1Beta1AppState takes the existing gov app state and marshals it to a govv1beta1 GenesisState. +func modifyGovv1Beta1AppState(chainConfig ibc.ChainConfig, govAppState []byte) ([]byte, error) { + cfg := testutil.MakeTestEncodingConfig() + + cdc := codec.NewProtoCodec(cfg.InterfaceRegistry) + govv1beta1.RegisterInterfaces(cfg.InterfaceRegistry) + + govGenesisState := &govv1beta1.GenesisState{} + if err := cdc.UnmarshalJSON(govAppState, govGenesisState); err != nil { + return nil, fmt.Errorf("failed to unmarshal genesis bytes into govv1beta1 genesis state: %w", err) + } + + govGenesisState.DepositParams.MinDeposit = sdk.NewCoins(sdk.NewCoin(chainConfig.Denom, govv1beta1.DefaultMinDepositTokens)) + govGenesisState.VotingParams.VotingPeriod = testvalues.VotingPeriod + + govGenBz, err := cdc.MarshalJSON(govGenesisState) + if err != nil { + return nil, fmt.Errorf("failed to marshal gov genesis state: %w", err) + } + + return govGenBz, nil +} diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go new file mode 100644 index 00000000000..46e8b73710d --- /dev/null +++ b/e2e/testsuite/testsuite.go @@ -0,0 +1,425 @@ +package testsuite + +import ( + "context" + "errors" + "fmt" + "strings" + + dockerclient "github.com/docker/docker/client" + interchaintest "github.com/strangelove-ventures/interchaintest/v8" + "github.com/strangelove-ventures/interchaintest/v8/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v8/ibc" + "github.com/strangelove-ventures/interchaintest/v8/testreporter" + test "github.com/strangelove-ventures/interchaintest/v8/testutil" + testifysuite "github.com/stretchr/testify/suite" + "go.uber.org/zap" + + sdkmath "cosmossdk.io/math" + + "github.com/cosmos/ibc-go/e2e/relayer" + "github.com/cosmos/ibc-go/e2e/testsuite/diagnostics" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" +) + +const ( + // ChainARelayerName is the name given to the relayer wallet on ChainA + ChainARelayerName = "rlyA" + // ChainBRelayerName is the name given to the relayer wallet on ChainB + ChainBRelayerName = "rlyB" + // DefaultGasValue is the default gas value used to configure tx.Factory + DefaultGasValue = 500_000_0000 +) + +// E2ETestSuite has methods and functionality which can be shared among all test suites. +type E2ETestSuite struct { + testifysuite.Suite + + // proposalIDs keeps track of the active proposal ID for each chain. + proposalIDs map[string]uint64 + grpcClients map[string]GRPCClients + paths map[string]pathPair + relayers relayer.Map + logger *zap.Logger + DockerClient *dockerclient.Client + network string + startRelayerFn func(relayer ibc.Relayer) + + // pathNameIndex is the latest index to be used for generating paths + pathNameIndex int64 +} + +// pathPair is a pairing of two chains which will be used in a test. +type pathPair struct { + chainA, chainB ibc.Chain +} + +// newPath returns a path built from the given chains. +func newPath(chainA, chainB ibc.Chain) pathPair { + return pathPair{ + chainA: chainA, + chainB: chainB, + } +} + +// GetRelayerUsers returns two ibc.Wallet instances which can be used for the relayer users +// on the two chains. +func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...ChainOptionConfiguration) (ibc.Wallet, ibc.Wallet) { + chainA, chainB := s.GetChains(chainOpts...) + chainAAccountBytes, err := chainA.GetAddress(ctx, ChainARelayerName) + s.Require().NoError(err) + + chainBAccountBytes, err := chainB.GetAddress(ctx, ChainBRelayerName) + s.Require().NoError(err) + + chainARelayerUser := cosmos.NewWallet(ChainARelayerName, chainAAccountBytes, "", chainA.Config()) + chainBRelayerUser := cosmos.NewWallet(ChainBRelayerName, chainBAccountBytes, "", chainB.Config()) + + if s.relayers == nil { + s.relayers = make(relayer.Map) + } + s.relayers.AddRelayer(s.T().Name(), chainARelayerUser) + s.relayers.AddRelayer(s.T().Name(), chainBRelayerUser) + + return chainARelayerUser, chainBRelayerUser +} + +// SetupChainsRelayerAndChannel create two chains, a relayer, establishes a connection and creates a channel +// using the given channel options. The relayer returned by this function has not yet started. It should be started +// with E2ETestSuite.StartRelayer if needed. +// This should be called at the start of every test, unless fine grained control is required. +func (s *E2ETestSuite) SetupChainsRelayerAndChannel(ctx context.Context, channelOpts func(*ibc.CreateChannelOptions), chainSpecOpts ...ChainOptionConfiguration) (ibc.Relayer, ibc.ChannelOutput) { + chainA, chainB := s.GetChains(chainSpecOpts...) + r := s.ConfigureRelayer(ctx, chainA, chainB, channelOpts) + s.InitGRPCClients(chainA) + s.InitGRPCClients(chainB) + chainAChannels, err := r.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) + return r, chainAChannels[len(chainAChannels)-1] +} + +func (s *E2ETestSuite) ConfigureRelayer(ctx context.Context, chainA, chainB ibc.Chain, channelOpts func(*ibc.CreateChannelOptions), buildOptions ...func(options *interchaintest.InterchainBuildOptions)) ibc.Relayer { + r := relayer.New(s.T(), *LoadConfig().GetActiveRelayerConfig(), s.logger, s.DockerClient, s.network) + + pathName := s.generatePathName() + + channelOptions := ibc.DefaultChannelOpts() + if channelOpts != nil { + channelOpts(&channelOptions) + } + + ic := interchaintest.NewInterchain(). + AddChain(chainA). + AddChain(chainB). + AddRelayer(r, "r"). + AddLink(interchaintest.InterchainLink{ + Chain1: chainA, + Chain2: chainB, + Relayer: r, + Path: pathName, + CreateChannelOpts: channelOptions, + }) + + buildOpts := interchaintest.InterchainBuildOptions{ + TestName: s.T().Name(), + Client: s.DockerClient, + NetworkID: s.network, + } + + for _, opt := range buildOptions { + opt(&buildOpts) + } + + eRep := s.GetRelayerExecReporter() + s.Require().NoError(ic.Build(ctx, eRep, buildOpts)) + + s.startRelayerFn = func(relayer ibc.Relayer) { + err := relayer.StartRelayer(ctx, eRep, pathName) + s.Require().NoError(err, fmt.Sprintf("failed to start relayer: %s", err)) + // wait for relayer to start. + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") + } + + return r +} + +// SetupSingleChain creates and returns a single CosmosChain for usage in e2e tests. +// This is useful for testing single chain functionality when performing coordinated upgrades as well as testing localhost ibc client functionality. +// TODO: Actually setup a single chain. Seeing panic: runtime error: index out of range [0] with length 0 when using a single chain. +// issue: https://github.com/strangelove-ventures/interchaintest/issues/401 +func (s *E2ETestSuite) SetupSingleChain(ctx context.Context) ibc.Chain { + chainA, chainB := s.GetChains() + + ic := interchaintest.NewInterchain().AddChain(chainA).AddChain(chainB) + + eRep := s.GetRelayerExecReporter() + s.Require().NoError(ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ + TestName: s.T().Name(), + Client: s.DockerClient, + NetworkID: s.network, + SkipPathCreation: true, + })) + + s.InitGRPCClients(chainA) + s.InitGRPCClients(chainB) + + return chainA +} + +// generatePathName generates the path name using the test suites name +func (s *E2ETestSuite) generatePathName() string { + path := s.GetPathName(s.pathNameIndex) + s.pathNameIndex++ + return path +} + +// GetPathName returns the name of a path at a specific index. This can be used in tests +// when the path name is required. +func (s *E2ETestSuite) GetPathName(idx int64) string { + pathName := fmt.Sprintf("%s-path-%d", s.T().Name(), idx) + return strings.ReplaceAll(pathName, "/", "-") +} + +// generatePath generates the path name using the test suites name +func (s *E2ETestSuite) generatePath(ctx context.Context, ibcrelayer ibc.Relayer) string { + chainA, chainB := s.GetChains() + chainAID := chainA.Config().ChainID + chainBID := chainB.Config().ChainID + + pathName := s.generatePathName() + + err := ibcrelayer.GeneratePath(ctx, s.GetRelayerExecReporter(), chainAID, chainBID, pathName) + s.Require().NoError(err) + + return pathName +} + +// SetupClients creates clients on chainA and chainB using the provided create client options +func (s *E2ETestSuite) SetupClients(ctx context.Context, ibcrelayer ibc.Relayer, opts ibc.CreateClientOptions) { + pathName := s.generatePath(ctx, ibcrelayer) + err := ibcrelayer.CreateClients(ctx, s.GetRelayerExecReporter(), pathName, opts) + s.Require().NoError(err) +} + +// UpdateClients updates clients on chainA and chainB +func (s *E2ETestSuite) UpdateClients(ctx context.Context, ibcrelayer ibc.Relayer, pathName string) { + err := ibcrelayer.UpdateClients(ctx, s.GetRelayerExecReporter(), pathName) + s.Require().NoError(err) +} + +// GetChains returns two chains that can be used in a test. The pair returned +// is unique to the current test being run. Note: this function does not create containers. +func (s *E2ETestSuite) GetChains(chainOpts ...ChainOptionConfiguration) (ibc.Chain, ibc.Chain) { + if s.paths == nil { + s.paths = map[string]pathPair{} + } + + path, ok := s.paths[s.T().Name()] + if ok { + return path.chainA, path.chainB + } + + chainOptions := DefaultChainOptions() + for _, opt := range chainOpts { + opt(&chainOptions) + } + + chainA, chainB := s.createChains(chainOptions) + path = newPath(chainA, chainB) + s.paths[s.T().Name()] = path + + if s.proposalIDs == nil { + s.proposalIDs = map[string]uint64{} + } + + s.proposalIDs[chainA.Config().ChainID] = 1 + s.proposalIDs[chainB.Config().ChainID] = 1 + + return path.chainA, path.chainB +} + +// GetRelayerWallets returns the ibcrelayer wallets associated with the chains. +func (s *E2ETestSuite) GetRelayerWallets(ibcrelayer ibc.Relayer) (ibc.Wallet, ibc.Wallet, error) { + chainA, chainB := s.GetChains() + chainARelayerWallet, ok := ibcrelayer.GetWallet(chainA.Config().ChainID) + if !ok { + return nil, nil, fmt.Errorf("unable to find chain A relayer wallet") + } + + chainBRelayerWallet, ok := ibcrelayer.GetWallet(chainB.Config().ChainID) + if !ok { + return nil, nil, fmt.Errorf("unable to find chain B relayer wallet") + } + return chainARelayerWallet, chainBRelayerWallet, nil +} + +// RecoverRelayerWallets adds the corresponding ibcrelayer address to the keychain of the chain. +// This is useful if commands executed on the chains expect the relayer information to present in the keychain. +func (s *E2ETestSuite) RecoverRelayerWallets(ctx context.Context, ibcrelayer ibc.Relayer) error { + chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(ibcrelayer) + if err != nil { + return err + } + + chainA, chainB := s.GetChains() + + if err := chainA.RecoverKey(ctx, ChainARelayerName, chainARelayerWallet.Mnemonic()); err != nil { + return fmt.Errorf("could not recover relayer wallet on chain A: %s", err) + } + if err := chainB.RecoverKey(ctx, ChainBRelayerName, chainBRelayerWallet.Mnemonic()); err != nil { + return fmt.Errorf("could not recover relayer wallet on chain B: %s", err) + } + return nil +} + +// StartRelayer starts the given ibcrelayer. +func (s *E2ETestSuite) StartRelayer(ibcrelayer ibc.Relayer) { + if s.startRelayerFn == nil { + panic(errors.New("cannot start relayer before it is created")) + } + + s.startRelayerFn(ibcrelayer) +} + +// StopRelayer stops the given ibcrelayer. +func (s *E2ETestSuite) StopRelayer(ctx context.Context, ibcrelayer ibc.Relayer) { + err := ibcrelayer.StopRelayer(ctx, s.GetRelayerExecReporter()) + s.Require().NoError(err) +} + +// RestartRelayer restarts the given relayer. +func (s *E2ETestSuite) RestartRelayer(ctx context.Context, ibcrelayer ibc.Relayer) { + s.StopRelayer(ctx, ibcrelayer) + s.StartRelayer(ibcrelayer) +} + +// CreateUserOnChainA creates a user with the given amount of funds on chain A. +func (s *E2ETestSuite) CreateUserOnChainA(ctx context.Context, amount int64) ibc.Wallet { + chainA, _ := s.GetChains() + return interchaintest.GetAndFundTestUsers(s.T(), ctx, strings.ReplaceAll(s.T().Name(), " ", "-"), sdkmath.NewInt(amount), chainA)[0] +} + +// CreateUserOnChainB creates a user with the given amount of funds on chain B. +func (s *E2ETestSuite) CreateUserOnChainB(ctx context.Context, amount int64) ibc.Wallet { + _, chainB := s.GetChains() + return interchaintest.GetAndFundTestUsers(s.T(), ctx, strings.ReplaceAll(s.T().Name(), " ", "-"), sdkmath.NewInt(amount), chainB)[0] +} + +// GetChainANativeBalance gets the balance of a given user on chain A. +func (s *E2ETestSuite) GetChainANativeBalance(ctx context.Context, user ibc.Wallet) (int64, error) { + chainA, _ := s.GetChains() + + balance, err := s.QueryBalance(ctx, chainA, user.FormattedAddress(), chainA.Config().Denom) + if err != nil { + return 0, err + } + return balance.Int64(), nil +} + +// GetChainBNativeBalance gets the balance of a given user on chain B. +func (s *E2ETestSuite) GetChainBNativeBalance(ctx context.Context, user ibc.Wallet) (int64, error) { + _, chainB := s.GetChains() + balance, err := s.QueryBalance(ctx, chainB, user.FormattedAddress(), chainB.Config().Denom) + if err != nil { + return -1, err + } + return balance.Int64(), nil +} + +// GetChainGRCPClients gets the GRPC clients associated with the given chain. +func (s *E2ETestSuite) GetChainGRCPClients(chain ibc.Chain) GRPCClients { + cs, ok := s.grpcClients[chain.Config().ChainID] + s.Require().True(ok, "chain %s does not have GRPC clients", chain.Config().ChainID) + return cs +} + +// AssertPacketRelayed asserts that the packet commitment does not exist on the sending chain. +// The packet commitment will be deleted upon a packet acknowledgement or timeout. +func (s *E2ETestSuite) AssertPacketRelayed(ctx context.Context, chain ibc.Chain, portID, channelID string, sequence uint64) { + commitment, _ := s.QueryPacketCommitment(ctx, chain, portID, channelID, sequence) + s.Require().Empty(commitment) +} + +// AssertHumanReadableDenom asserts that a human readable denom is present for a given chain. +func (s *E2ETestSuite) AssertHumanReadableDenom(ctx context.Context, chain ibc.Chain, counterpartyNativeDenom string, counterpartyChannel ibc.ChannelOutput) { + chainIBCDenom := GetIBCToken(counterpartyNativeDenom, counterpartyChannel.Counterparty.PortID, counterpartyChannel.Counterparty.ChannelID) + + denomMetadata, err := s.QueryDenomMetadata(ctx, chain, chainIBCDenom.IBCDenom()) + s.Require().NoError(err) + + s.Require().Equal(chainIBCDenom.IBCDenom(), denomMetadata.Base, "denom metadata base does not match expected %s: got %s", chainIBCDenom.IBCDenom(), denomMetadata.Base) + expectedName := fmt.Sprintf("%s/%s/%s IBC token", counterpartyChannel.Counterparty.PortID, counterpartyChannel.Counterparty.ChannelID, counterpartyNativeDenom) + s.Require().Equal(expectedName, denomMetadata.Name, "denom metadata name does not match expected %s: got %s", expectedName, denomMetadata.Name) + expectedDisplay := fmt.Sprintf("%s/%s/%s", counterpartyChannel.Counterparty.PortID, counterpartyChannel.Counterparty.ChannelID, counterpartyNativeDenom) + s.Require().Equal(expectedDisplay, denomMetadata.Display, "denom metadata display does not match expected %s: got %s", expectedDisplay, denomMetadata.Display) + s.Require().Equal(strings.ToUpper(counterpartyNativeDenom), denomMetadata.Symbol, "denom metadata symbol does not match expected %s: got %s", strings.ToUpper(counterpartyNativeDenom), denomMetadata.Symbol) +} + +// createChains creates two separate chains in docker containers. +// test and can be retrieved with GetChains. +func (s *E2ETestSuite) createChains(chainOptions ChainOptions) (ibc.Chain, ibc.Chain) { + client, network := interchaintest.DockerSetup(s.T()) + t := s.T() + + s.logger = zap.NewExample() + s.DockerClient = client + s.network = network + + cf := interchaintest.NewBuiltinChainFactory(s.logger, []*interchaintest.ChainSpec{chainOptions.ChainASpec, chainOptions.ChainBSpec}) + + // this is intentionally called after the interchaintest.DockerSetup function. The above function registers a + // cleanup task which deletes all containers. By registering a cleanup function afterwards, it is executed first + // this allows us to process the logs before the containers are removed. + t.Cleanup(func() { + dumpLogs := LoadConfig().DebugConfig.DumpLogs + chains := []string{chainOptions.ChainASpec.ChainConfig.Name, chainOptions.ChainBSpec.ChainConfig.Name} + diagnostics.Collect(t, s.DockerClient, dumpLogs, chains...) + }) + + chains, err := cf.Chains(t.Name()) + s.Require().NoError(err) + + return chains[0], chains[1] +} + +// GetRelayerExecReporter returns a testreporter.RelayerExecReporter instances +// using the current test's testing.T. +func (s *E2ETestSuite) GetRelayerExecReporter() *testreporter.RelayerExecReporter { + rep := testreporter.NewNopReporter() + return rep.RelayerExecReporter(s.T()) +} + +// TransferChannelOptions configures both of the chains to have non-incentivized transfer channels. +func (*E2ETestSuite) TransferChannelOptions() func(options *ibc.CreateChannelOptions) { + return func(opts *ibc.CreateChannelOptions) { + opts.Version = transfertypes.Version + opts.SourcePortName = transfertypes.PortID + opts.DestPortName = transfertypes.PortID + } +} + +// GetTimeoutHeight returns a timeout height of 1000 blocks above the current block height. +// This function should be used when the timeout is never expected to be reached +func (s *E2ETestSuite) GetTimeoutHeight(ctx context.Context, chain ibc.Chain) clienttypes.Height { + height, err := chain.Height(ctx) + s.Require().NoError(err) + return clienttypes.NewHeight(clienttypes.ParseChainID(chain.Config().ChainID), height+1000) +} + +// GetIBCToken returns the denomination of the full token denom sent to the receiving channel +func GetIBCToken(fullTokenDenom string, portID, channelID string) transfertypes.DenomTrace { + return transfertypes.ParseDenomTrace(fmt.Sprintf("%s/%s/%s", portID, channelID, fullTokenDenom)) +} + +// getValidatorsAndFullNodes returns the number of validators and full nodes respectively that should be used for +// the test. If the test is running in CI, more nodes are used, when running locally a single node is used by default to +// use less resources and allow the tests to run faster. +// both the number of validators and full nodes can be overwritten in a config file. +func getValidatorsAndFullNodes(chainIdx int) (int, int) { + if IsCI() { + return 4, 1 + } + tc := LoadConfig() + return tc.GetChainNumValidators(chainIdx), tc.GetChainNumFullNodes(chainIdx) +} 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/apps/transfer/types/authz.pb.go b/modules/apps/transfer/types/authz.pb.go index e05cdc401e7..1f9df8c97d5 100644 --- a/modules/apps/transfer/types/authz.pb.go +++ b/modules/apps/transfer/types/authz.pb.go @@ -36,6 +36,12 @@ type Allocation struct { SpendLimit github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=spend_limit,json=spendLimit,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"spend_limit"` // allow list of receivers, an empty allow list permits any receiver address AllowList []string `protobuf:"bytes,4,rep,name=allow_list,json=allowList,proto3" json:"allow_list,omitempty"` +<<<<<<< HEAD +======= + // allow list of packet data keys, an empty list prohibits all packet data keys; + // a list only with "*" permits any packet data key + AllowedPacketData []string `protobuf:"bytes,5,rep,name=allowed_packet_data,json=allowedPacketData,proto3" json:"allowed_packet_data,omitempty"` +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) } func (m *Allocation) Reset() { *m = Allocation{} } 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..ccb1633f98d 100644 --- a/modules/core/04-channel/keeper/handshake.go +++ b/modules/core/04-channel/keeper/handshake.go @@ -431,6 +431,7 @@ func (k Keeper) ChanCloseConfirm( 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 +461,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..91ddf3baf5f 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() @@ -810,7 +831,7 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { err := suite.chainB.App.GetIBCKeeper().ChannelKeeper.ChanCloseConfirm( 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..d0ec4b36e33 100644 --- a/modules/core/04-channel/keeper/packet_test.go +++ b/modules/core/04-channel/keeper/packet_test.go @@ -3,6 +3,13 @@ package keeper_test import ( "fmt" +<<<<<<< HEAD +======= + "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) 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 +222,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 +342,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 +781,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 +835,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 +1064,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 +1320,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..a0f7f189fa6 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,7 @@ func (k Keeper) TimeoutOnClose( proofClosed []byte, proofHeight exported.Height, nextSequenceRecv uint64, + counterpartyUpgradeSequence uint64, ) error { channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel()) if !found { @@ -243,9 +267,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..27f6def9f85 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.TimeoutOnClose( + 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..153f36cbf49 100644 --- a/modules/core/04-channel/types/codec.go +++ b/modules/core/04-channel/types/codec.go @@ -39,6 +39,14 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { &MsgAcknowledgement{}, &MsgTimeout{}, &MsgTimeoutOnClose{}, + &MsgChannelUpgradeInit{}, + &MsgChannelUpgradeTry{}, + &MsgChannelUpgradeAck{}, + &MsgChannelUpgradeConfirm{}, + &MsgChannelUpgradeOpen{}, + &MsgChannelUpgradeTimeout{}, + &MsgChannelUpgradeCancel{}, + &MsgUpdateParams{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) 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..371b55563fd 100644 --- a/modules/core/04-channel/types/genesis.go +++ b/modules/core/04-channel/types/genesis.go @@ -45,6 +45,7 @@ func (ps PacketSequence) Validate() error { func NewGenesisState( channels []IdentifiedChannel, acks, receipts, commitments []PacketState, sendSeqs, recvSeqs, ackSeqs []PacketSequence, nextChannelSequence uint64, + params Params, ) GenesisState { return GenesisState{ Channels: channels, @@ -54,6 +55,7 @@ func NewGenesisState( RecvSequences: recvSeqs, AckSequences: ackSeqs, NextChannelSequence: nextChannelSequence, + Params: params, } } @@ -68,6 +70,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/genesis_test.go b/modules/core/04-channel/types/genesis_test.go index 973f06b6b0c..957c79725a7 100644 --- a/modules/core/04-channel/types/genesis_test.go +++ b/modules/core/04-channel/types/genesis_test.go @@ -67,6 +67,7 @@ func TestValidateGenesis(t *testing.T) { types.NewPacketSequence(testPort2, testChannel2, 1), }, 2, + types.Params{UpgradeTimeout: types.DefaultTimeout}, ), expPass: true, }, @@ -171,6 +172,7 @@ func TestValidateGenesis(t *testing.T) { types.NewPacketSequence(testPort2, testChannel2, 1), }, 0, + types.Params{UpgradeTimeout: types.DefaultTimeout}, ), expPass: false, }, @@ -208,6 +210,7 @@ func TestValidateGenesis(t *testing.T) { types.NewPacketSequence(testPort2, testChannel2, 1), }, 0, + types.Params{UpgradeTimeout: types.DefaultTimeout}, ), expPass: false, }, 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..5b6b3aa1b44 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" @@ -35,6 +36,10 @@ 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) ) // NewMsgChannelOpenInit creates a new MsgChannelOpenInit. It sets the counterparty channel @@ -265,14 +270,15 @@ func (msg MsgChannelCloseInit) GetSigners() []sdk.AccAddress { // NewMsgChannelCloseConfirm creates a new MsgChannelCloseConfirm instance func NewMsgChannelCloseConfirm( portID, channelID string, proofInit []byte, proofHeight clienttypes.Height, - signer string, + signer string, counterpartyUpgradeSequence uint64, ) *MsgChannelCloseConfirm { return &MsgChannelCloseConfirm{ - PortId: portID, - ChannelId: channelID, - ProofInit: proofInit, - ProofHeight: proofHeight, - Signer: signer, + PortId: portID, + ChannelId: channelID, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer, + CounterpartyUpgradeSequence: counterpartyUpgradeSequence, } } @@ -387,14 +393,16 @@ func NewMsgTimeoutOnClose( 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, + Packet: packet, + NextSequenceRecv: nextSequenceRecv, + ProofUnreceived: proofUnreceived, + ProofClose: proofClose, + ProofHeight: proofHeight, + Signer: signer, + CounterpartyUpgradeSequence: counterpartyUpgradeSequence, } } @@ -456,6 +464,7 @@ func (msg MsgAcknowledgement) ValidateBasic() error { return msg.Packet.ValidateBasic() } +<<<<<<< HEAD // GetSigners implements sdk.Msg func (msg MsgAcknowledgement) GetSigners() []sdk.AccAddress { signer, err := sdk.AccAddressFromBech32(msg.Signer) @@ -463,4 +472,378 @@ func (msg MsgAcknowledgement) GetSigners() []sdk.AccAddress { panic(err) } 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 +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) } diff --git a/modules/core/04-channel/types/msgs_test.go b/modules/core/04-channel/types/msgs_test.go index 8570ad59065..d7531d31a3b 100644 --- a/modules/core/04-channel/types/msgs_test.go +++ b/modules/core/04-channel/types/msgs_test.go @@ -18,15 +18,31 @@ import ( 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" +<<<<<<< HEAD +======= + 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" +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) "github.com/cosmos/ibc-go/v8/testing/simapp" ) const ( +<<<<<<< HEAD // 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 +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) version = "1.0" @@ -144,6 +160,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 +214,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 +259,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 +302,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,20 +344,33 @@ 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}, - {"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}, - {"too short channel id", types.NewMsgChannelCloseConfirm(portid, invalidShortChannel, suite.proof, height, addr), false}, - {"too long channel id", types.NewMsgChannelCloseConfirm(portid, invalidLongChannel, suite.proof, height, addr), false}, - {"channel id contains non-alpha", types.NewMsgChannelCloseConfirm(portid, invalidChannel, suite.proof, height, addr), false}, - {"empty proof", types.NewMsgChannelCloseConfirm(portid, chanid, emptyProof, height, addr), false}, + {"success", types.NewMsgChannelCloseConfirm(portid, chanid, suite.proof, height, addr, 0), true}, + {"success, positive counterparty upgrade sequence", types.NewMsgChannelCloseConfirm(portid, chanid, suite.proof, height, addr, 1), true}, + {"too short port id", types.NewMsgChannelCloseConfirm(invalidShortPort, chanid, suite.proof, height, addr, 0), false}, + {"too long port id", types.NewMsgChannelCloseConfirm(invalidLongPort, chanid, suite.proof, height, addr, 0), false}, + {"port id contains non-alpha", types.NewMsgChannelCloseConfirm(invalidPort, chanid, suite.proof, height, addr, 0), false}, + {"too short channel id", types.NewMsgChannelCloseConfirm(portid, invalidShortChannel, suite.proof, height, addr, 0), false}, + {"too long channel id", types.NewMsgChannelCloseConfirm(portid, invalidLongChannel, suite.proof, height, addr, 0), false}, + {"channel id contains non-alpha", types.NewMsgChannelCloseConfirm(portid, invalidChannel, suite.proof, height, addr, 0), false}, + {"empty proof", types.NewMsgChannelCloseConfirm(portid, chanid, emptyProof, height, addr, 0), false}, } for _, tc := range testCases { @@ -311,6 +388,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, counterpartyUpgradeSequence) + + 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 +428,23 @@ func (suite *TypesTestSuite) TestMsgRecvPacketValidateBasic() { } func (suite *TypesTestSuite) TestMsgRecvPacketGetSigners() { +<<<<<<< HEAD msg := types.NewMsgRecvPacket(packet, suite.proof, height, addr) res := msg.GetSigners() expected := "[7465737461646472313131313131313131313131]" suite.Equal(expected, fmt.Sprintf("%v", res)) +======= + expSigner, err := sdk.AccAddressFromBech32(addr) + suite.Require().NoError(err) + msg := types.NewMsgRecvPacket(packet, 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]) +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) } func (suite *TypesTestSuite) TestMsgTimeoutValidateBasic() { @@ -374,18 +475,31 @@ 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 msg *types.MsgTimeoutOnClose expPass bool }{ - {"success", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, height, addr), 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}, - {"empty proof close", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, emptyProof, height, addr), false}, - {"invalid packet", types.NewMsgTimeoutOnClose(invalidPacket, 1, suite.proof, suite.proof, height, addr), false}, + {"success", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, height, addr, 0), true}, + {"success, positive counterparty upgrade sequence", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, height, addr, 1), true}, + {"seq 0", types.NewMsgTimeoutOnClose(packet, 0, suite.proof, suite.proof, height, addr, 0), false}, + {"signer address is empty", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, suite.proof, height, emptyAddr, 0), false}, + {"empty proof", types.NewMsgTimeoutOnClose(packet, 1, emptyProof, suite.proof, height, addr, 0), false}, + {"empty proof close", types.NewMsgTimeoutOnClose(packet, 1, suite.proof, emptyProof, height, addr, 0), false}, + {"invalid packet", types.NewMsgTimeoutOnClose(invalidPacket, 1, suite.proof, suite.proof, height, addr, 0), false}, } for _, tc := range testCases { @@ -403,6 +517,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, counterpartyUpgradeSequence) + + 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 +556,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/ante/ante_test.go b/modules/core/ante/ante_test.go index 1b9a8c15c64..734d71cc290 100644 --- a/modules/core/ante/ante_test.go +++ b/modules/core/ante/ante_test.go @@ -147,7 +147,7 @@ func (suite *AnteTestSuite) createTimeoutOnCloseMessage(isRedundant bool) sdk.Ms channelKey := host.ChannelKey(packet.GetDestPort(), packet.GetDestChannel()) proofClosed, _ := suite.chainA.QueryProof(channelKey) - return channeltypes.NewMsgTimeoutOnClose(packet, 1, proof, proofClosed, proofHeight, suite.path.EndpointA.Chain.SenderAccount.GetAddress().String()) + return channeltypes.NewMsgTimeoutOnClose(packet, 1, proof, proofClosed, proofHeight, suite.path.EndpointA.Chain.SenderAccount.GetAddress().String(), 0) } func (suite *AnteTestSuite) createUpdateClientMessage() sdk.Msg { diff --git a/modules/core/genesis_test.go b/modules/core/genesis_test.go index 3f6515573c7..be1eb909678 100644 --- a/modules/core/genesis_test.go +++ b/modules/core/genesis_test.go @@ -142,6 +142,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { channeltypes.NewPacketSequence(port2, channel2, 1), }, 0, + channeltypes.Params{UpgradeTimeout: channeltypes.DefaultTimeout}, ), }, expPass: true, @@ -300,6 +301,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { channeltypes.NewPacketSequence(port2, channel2, 1), }, 0, + channeltypes.Params{UpgradeTimeout: channeltypes.DefaultTimeout}, ), }, }, 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..9caa8d482ec 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.ChanCloseConfirm(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.TimeoutOnClose(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..ee8444514e5 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.NewMsgTimeoutOnClose(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..3c73c9c162b 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" @@ -562,11 +564,202 @@ func (endpoint *Endpoint) TimeoutOnClose(packet channeltypes.Packet) error { timeoutOnCloseMsg := channeltypes.NewMsgTimeoutOnClose( 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/solomachine.go b/testing/solomachine.go index 2293f285bec..81eb087f6bc 100644 --- a/testing/solomachine.go +++ b/testing/solomachine.go @@ -358,6 +358,7 @@ func (solo *Solomachine) ChanCloseConfirm(chain *TestChain, portID, channelID st proofInit, clienttypes.ZeroHeight(), chain.SenderAccount.GetAddress().String(), + 0, // use default value for channel that hasn't undergone an upgrade ) res, err := chain.SendMsgs(msgChanCloseConfirm) @@ -449,6 +450,7 @@ func (solo *Solomachine) TimeoutPacketOnClose(chain *TestChain, packet channelty proofClosed, clienttypes.ZeroHeight(), chain.SenderAccount.GetAddress().String(), + 0, // use default value for channel that hasn't undergone an upgrade ) res, err := chain.SendMsgs(msgTimeout) diff --git a/testing/utils.go b/testing/utils.go index a1178929e3f..0af768f9ac9 100644 --- a/testing/utils.go +++ b/testing/utils.go @@ -6,6 +6,13 @@ import ( "github.com/stretchr/testify/require" +<<<<<<< HEAD +======= + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + +>>>>>>> 28f757a5 (feat: channel upgradability (#1613)) abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" ) @@ -25,6 +32,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)