diff --git a/baseapp/abci.go b/baseapp/abci.go index ada95acf1f..d988ead0fc 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -382,6 +382,11 @@ func (app *BaseApp) snapshot(height int64) { func (app *BaseApp) Query(req abci.RequestQuery) abci.ResponseQuery { defer telemetry.MeasureSince(time.Now(), "abci", "query") + // when a client did not provide a query height, manually inject the latest + if req.Height == 0 { + req.Height = app.LastBlockHeight() + } + // handle gRPC routes first rather than calling splitPath because '/' characters // are used as part of gRPC paths if grpcHandler := app.grpcQueryRouter.Route(req.Path); grpcHandler != nil { @@ -742,11 +747,6 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.R req.Path = "/" + strings.Join(path[1:], "/") - // when a client did not provide a query height, manually inject the latest - if req.Height == 0 { - req.Height = app.LastBlockHeight() - } - if req.Height <= 1 && req.Prove { return sdkerrors.QueryResult( sdkerrors.Wrap( diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 0b52dcf194..f251128768 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -15760,6 +15760,396 @@ paths: } tags: - Query + '/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}': + get: + summary: |- + UpgradedConsensusState queries the consensus state that will serve + as a trusted kernel for the next version of this chain. It will only be + stored at the last height of this chain. + UpgradedConsensusState RPC not supported with legacy querier + operationId: UpgradedConsensusState + responses: + '200': + description: A successful response. + schema: + type: object + properties: + upgraded_consensus_state: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at least + + one "/" character. The last segment of the URL's path must + represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in a + canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary all + types that they + + expect it to use in the context of Any. However, for URLs + which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in the + official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message + along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values in + the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default + use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the last + '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an + + additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding a + field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + description: >- + QueryUpgradedConsensusStateResponse is the response type for the + Query/UpgradedConsensusState + + 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 := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by + default use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the + last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with + an + + additional field `@type` which contains the type URL. + Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding + a field + + `value` which holds the custom JSON in addition to the + `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + parameters: + - name: last_height + description: |- + last height of the current chain must be sent in request + as this is the height under which next consensus state is stored + in: path + required: true + type: string + format: int64 + tags: + - Query /ibc/core/channel/v1beta1/channels: get: summary: Channels queries all the IBC channels of a chain. @@ -15882,28 +16272,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryChannelsResponse is the response type for the Query/Channels @@ -16238,28 +16628,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryChannelResponse is the response type for the Query/Channel @@ -16681,28 +17071,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryChannelClientStateResponse is the Response type for the @@ -16909,7 +17299,7 @@ paths: type: string tags: - Query - '/ibc/core/channel/v1beta1/channels/{channel_id}/ports/{port_id}/consensus_state/version/{version_number}/height/{version_height}': + '/ibc/core/channel/v1beta1/channels/{channel_id}/ports/{port_id}/consensus_state/revision/{revision_number}/height/{revision_height}': get: summary: |- ChannelConsensusState queries for the consensus state for the channel @@ -17104,28 +17494,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryChannelClientStateResponse is the Response type for the @@ -17330,14 +17720,14 @@ paths: in: path required: true type: string - - name: version_number - description: version number of the consensus state + - name: revision_number + description: revision number of the consensus state in: path required: true type: string format: uint64 - - name: version_height - description: version height of the consensus state + - name: revision_height + description: revision height of the consensus state in: path required: true type: string @@ -17368,28 +17758,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QuerySequenceResponse is the request type for the @@ -17671,28 +18061,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketAcknowledgemetsResponse is the request type for the @@ -17967,28 +18357,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketAcknowledgementResponse defines the client query @@ -18278,28 +18668,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketCommitmentsResponse is the request type for the @@ -18576,28 +18966,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryUnreceivedAcksResponse is the response type for the @@ -18838,28 +19228,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryUnreceivedPacketsResponse is the response type for the @@ -19098,28 +19488,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketCommitmentResponse defines the client query response @@ -19360,28 +19750,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketReceiptResponse defines the client query response for a @@ -19723,28 +20113,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionChannelsResponse is the Response type for the @@ -20870,28 +21260,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryClientStateResponse is the response type for the @@ -21119,28 +21509,28 @@ paths: title: consensus state height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height - while keeping version + Normally the RevisionHeight is incremented at each + height while keeping RevisionNumber - number the same However some consensus algorithms may - choose to reset the + 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 version number is incremented so + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight + be monitonically increasing even as the RevisionHeight gets reset consensus_state: title: consensus state @@ -21598,7 +21988,7 @@ paths: type: boolean tags: - Query - '/ibc/core/client/v1beta1/consensus_states/{client_id}/version/{version_number}/height/{version_height}': + '/ibc/core/client/v1beta1/consensus_states/{client_id}/revision/{revision_number}/height/{revision_height}': get: summary: >- ConsensusState queries a consensus state associated with a client state @@ -21794,28 +22184,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryConsensusStateResponse is the response type for the @@ -22017,14 +22407,14 @@ paths: in: path required: true type: string - - name: version_number - description: consensus state version number + - name: revision_number + description: consensus state revision number in: path required: true type: string format: uint64 - - name: version_height - description: consensus state version height + - name: revision_height + description: consensus state revision height in: path required: true type: string @@ -22065,28 +22455,28 @@ paths: title: height at which the proof was generated type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryClientConnectionsResponse is the response type for the @@ -22406,28 +22796,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryConnectionsResponse is the response type for the @@ -22764,28 +23154,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryConnectionResponse is the response type for the @@ -23200,28 +23590,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionClientStateResponse is the response type for the @@ -23423,7 +23813,7 @@ paths: type: string tags: - Query - '/ibc/core/connection/v1beta1/connections/{connection_id}/consensus_state/version/{version_number}/height/{version_height}': + '/ibc/core/connection/v1beta1/connections/{connection_id}/consensus_state/revision/{revision_number}/height/{revision_height}': get: summary: |- ConnectionConsensusState queries the consensus state associated with the @@ -23618,28 +24008,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + 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 version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionConsensusStateResponse is the response type for the @@ -23839,12 +24229,12 @@ paths: in: path required: true type: string - - name: version_number + - name: revision_number in: path required: true type: string format: uint64 - - name: version_height + - name: revision_height in: path required: true type: string @@ -31438,6 +31828,173 @@ definitions: RPC method. + cosmos.upgrade.v1beta1.QueryUpgradedConsensusStateResponse: + type: object + properties: + upgraded_consensus_state: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of the + serialized + + protocol buffer message. This string must contain at least + + one "/" character. The last segment of the URL's path must + represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in a + canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary all types + that they + + expect it to use in the context of Any. However, for URLs which + use the + + scheme `http`, `https`, or no scheme, one can optionally set up a + type + + server that maps type URLs to message definitions as follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in the + official + + protobuf release, and it is not used for type URLs beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above specified + type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message along + with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values in the + form + + of utility functions or additional generated methods of the Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default use + + 'type.googleapis.com/full.type.name' as the type URL and the unpack + + methods only use the fully qualified type name after the last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an + + additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom JSON + + representation, that representation will be embedded adding a field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + description: >- + QueryUpgradedConsensusStateResponse is the response type for the + Query/UpgradedConsensusState + + RPC method. ibc.core.channel.v1.Channel: type: object properties: @@ -31803,28 +32360,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryChannelClientStateResponse is the Response type for the Query/QueryChannelClientState RPC method @@ -32002,28 +32558,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryChannelClientStateResponse is the Response type for the Query/QueryChannelClientState RPC method @@ -32107,28 +32662,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryChannelResponse is the response type for the Query/Channel RPC method. @@ -32244,28 +32798,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryChannelsResponse is the response type for the Query/Channels RPC method. @@ -32377,28 +32930,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionChannelsResponse is the Response type for the Query/QueryConnectionChannels RPC method @@ -32417,28 +32969,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QuerySequenceResponse is the request type for the Query/QueryNextSequenceReceiveResponse RPC method @@ -32457,28 +33008,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketAcknowledgementResponse defines the client query response for a packet which also includes a proof and the height from which the @@ -32544,28 +33094,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketAcknowledgemetsResponse is the request type for the Query/QueryPacketAcknowledgements RPC method @@ -32584,28 +33133,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketCommitmentResponse defines the client query response for a packet @@ -32674,28 +33222,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketCommitmentsResponse is the request type for the Query/QueryPacketCommitments RPC method @@ -32713,28 +33260,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketReceiptResponse defines the client query response for a packet receipt @@ -32755,28 +33301,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryUnreceivedAcksResponse is the response type for the Query/UnreceivedAcks RPC method @@ -32793,28 +33338,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryUnreceivedPacketsResponse is the response type for the Query/UnreceivedPacketCommitments RPC method @@ -32841,27 +33385,27 @@ definitions: ibc.core.client.v1.Height: type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while keeping + RevisionNumber - number the same However some consensus algorithms may choose to reset the + 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 version number is incremented so that height continues + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: >- Height is a monotonically increasing data type @@ -33045,28 +33589,27 @@ definitions: title: consensus state height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset consensus_state: title: consensus state type: object @@ -33425,28 +33968,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryClientStateResponse is the response type for the Query/ClientState RPC @@ -33845,28 +34387,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryConsensusStateResponse is the response type for the Query/ConsensusState @@ -33884,28 +34425,29 @@ definitions: title: consensus state height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to - reset the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets + reset consensus_state: title: consensus state type: object @@ -34301,28 +34843,27 @@ definitions: title: height at which the proof was generated type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryClientConnectionsResponse is the response type for the Query/ClientConnections RPC method @@ -34513,28 +35054,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionClientStateResponse is the response type for the Query/ConnectionClientState RPC method @@ -34712,28 +35252,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionConsensusStateResponse is the response type for the Query/ConnectionConsensusState RPC method @@ -34820,28 +35359,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryConnectionResponse is the response type for the Query/Connection RPC @@ -34954,28 +35492,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + 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 version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryConnectionsResponse is the response type for the Query/Connections RPC diff --git a/client/errors.go b/client/errors.go deleted file mode 100644 index d7f7e29664..0000000000 --- a/client/errors.go +++ /dev/null @@ -1,22 +0,0 @@ -package client - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// ErrInvalidAccount returns a standardized error reflecting that a given -// account address does not exist. -func ErrInvalidAccount(addr sdk.AccAddress) error { - return fmt.Errorf(`no account with address %s was found in the state. -Are you sure there has been a transaction involving it?`, addr) -} - -// ErrVerifyCommit returns a common error reflecting that the blockchain commit at a given -// height can't be verified. The reason is that the base checkpoint of the certifier is -// newer than the given height -func ErrVerifyCommit(height int64) error { - return fmt.Errorf(`the height of base truststore in the light client is higher than height %d. -Can't verify blockchain proof at this height. Please set --trust-node to true and try again`, height) -} diff --git a/client/rest/rest.go b/client/rest/rest.go index 9a0f901840..ac05891e04 100644 --- a/client/rest/rest.go +++ b/client/rest/rest.go @@ -6,12 +6,17 @@ import ( "github.com/gorilla/mux" ) +// DeprecationURL is the URL for migrating deprecated REST endpoints to newer ones. +// TODO Switch to `/` (not `/master`) once v0.40 docs are deployed. +// https://github.com/cosmos/cosmos-sdk/issues/8019 +const DeprecationURL = "https://docs.cosmos.network/master/migrations/rest.html" + // addHTTPDeprecationHeaders is a mux middleware function for adding HTTP // Deprecation headers to a http handler func addHTTPDeprecationHeaders(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Deprecation", "true") - w.Header().Set("Link", "; rel=\"deprecation\"") + w.Header().Set("Link", "<"+DeprecationURL+">; rel=\"deprecation\"") w.Header().Set("Warning", "199 - \"this endpoint is deprecated and may not work as before, see deprecation link for more info\"") h.ServeHTTP(w, r) }) diff --git a/client/rpc/block.go b/client/rpc/block.go index a6a42967ce..8bf7f12af8 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -11,7 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec/legacy" "github.com/cosmos/cosmos-sdk/types/rest" ) @@ -68,7 +67,7 @@ func getBlock(clientCtx client.Context, height *int64) ([]byte, error) { return nil, err } - return legacy.Cdc.MarshalJSON(res) + return clientCtx.LegacyAmino.MarshalJSON(res) } // get the current blockchain height diff --git a/client/tx/legacy.go b/client/tx/legacy.go index 62cbf9b7b4..b551ecebb8 100644 --- a/client/tx/legacy.go +++ b/client/tx/legacy.go @@ -61,6 +61,7 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder, ignoreSignatureError bool) builder.SetMemo(tx.GetMemo()) builder.SetFeeAmount(tx.GetFee()) builder.SetGasLimit(tx.GetGas()) + builder.SetTimeoutHeight(tx.GetTimeoutHeight()) return nil } diff --git a/client/tx/legacy_test.go b/client/tx/legacy_test.go index 59a7b95d7f..b10c51e344 100644 --- a/client/tx/legacy_test.go +++ b/client/tx/legacy_test.go @@ -21,8 +21,9 @@ import ( ) const ( - memo = "waboom" - gas = uint64(10000) + memo = "waboom" + gas = uint64(10000) + timeoutHeight = 5 ) var ( @@ -47,6 +48,7 @@ func buildTestTx(t *testing.T, builder client.TxBuilder) { require.NoError(t, err) err = builder.SetSignatures(sig) require.NoError(t, err) + builder.SetTimeoutHeight(timeoutHeight) } type TestSuite struct { @@ -105,6 +107,7 @@ func (s *TestSuite) TestConvertTxToStdTx() { s.Require().Equal(gas, stdTx.Fee.Gas) s.Require().Equal(fee, stdTx.Fee.Amount) s.Require().Equal(msg, stdTx.Msgs[0]) + s.Require().Equal(timeoutHeight, stdTx.TimeoutHeight) s.Require().Equal(sig.PubKey, stdTx.Signatures[0].PubKey) s.Require().Equal(sig.Data.(*signing2.SingleSignatureData).Signature, stdTx.Signatures[0].Signature) @@ -123,6 +126,7 @@ func (s *TestSuite) TestConvertTxToStdTx() { s.Require().Equal(gas, stdTx.Fee.Gas) s.Require().Equal(fee, stdTx.Fee.Amount) s.Require().Equal(msg, stdTx.Msgs[0]) + s.Require().Equal(timeoutHeight, stdTx.TimeoutHeight) s.Require().Empty(stdTx.Signatures) // std tx diff --git a/docs/building-modules/msg-services.md b/docs/building-modules/msg-services.md index 0cde42b195..0df12fa911 100644 --- a/docs/building-modules/msg-services.md +++ b/docs/building-modules/msg-services.md @@ -16,6 +16,10 @@ All `Msg` processing is done by a [`Msg`](messages-and-queries.md#msg-services) As further described in [ADR 031](../architecture/adr-031-msg-service.md), this approach has the advantage of clearly specifying return types and generating server and client code. +Based on the definition of the `Msg` service, Protobuf generates a `MsgServer` interface. It is the role of the module developer to implement this interface, by implementing the state transition logic that should happen upon receival of each `Msg`. As an example, here is the generated `MsgServer` interface for `x/bank`, which exposes two `Msg`s: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/bank/types/tx.pb.go#L285-L291 + When possible, the existing module's [`Keeper`](keeper.md) should implement `MsgServer`, otherwise a `msgServer` struct that embeds the `Keeper` can be created, typically in `./keeper/msg_server.go`: +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/bank/keeper/msg_server.go#L14-L16 diff --git a/docs/core/README.md b/docs/core/README.md index 9cb69b4c71..20b344d3a0 100644 --- a/docs/core/README.md +++ b/docs/core/README.md @@ -8,7 +8,7 @@ parent: This repository contains reference documentation on the core concepts of the Cosmos SDK. -1. [`Baseapp`](./baseapp.md) +1. [`BaseApp`](./baseapp.md) 2. [Transaction](./transactions.md) 3. [Context](./context.md) 4. [Node Client](./node.md) diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 0b9417cfe6..421ed74c93 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -2,7 +2,7 @@ order: 1 --> -# Baseapp +# BaseApp This document describes `BaseApp`, the abstraction that implements the core functionalities of an SDK application. {synopsis} @@ -15,11 +15,9 @@ This document describes `BaseApp`, the abstraction that implements the core func `BaseApp` is a base type that implements the core of an SDK application, namely: -- The [Application Blockchain Interface](#abci), for the state-machine to communicate with the -underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route messages and queries to the appropriate module. -- Different [states](#states), as the state-machine can have different volatile -states updated based on the ABCI message received. +- The [Application Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- [Service Routers](#service-routers), to route messages and queries to the appropriate module. +- Different [states](#states), as the state-machine can have different volatile states updated based on the ABCI message received. The goal of `BaseApp` is to provide the fundamental layer of an SDK application that developers can easily extend to build their own custom application. Usually, @@ -40,67 +38,67 @@ type App struct { Extending the application with `BaseApp` gives the former access to all of `BaseApp`'s methods. This allows developers to compose their custom application with the modules they want, while not -having to concern themselves with the hard work of implementing the ABCI, the routing and state +having to concern themselves with the hard work of implementing the ABCI, the service routers and state management logic. ## Type Definition The `BaseApp` type holds many important parameters for any Cosmos SDK based application. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L54-L108 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/baseapp.go#L46-L131 Let us go through the most important components. -> __Note__: Not all parameters are described, only the most important ones. Refer to the -type definition for the full list. +> **Note**: Not all parameters are described, only the most important ones. Refer to the +> type definition for the full list. First, the important parameters that are initialized during the bootstrapping of the application: - [`CommitMultiStore`](./store.md#commitmultistore): This is the main store of the application, -which holds the canonical state that is committed at the [end of each block](#commit). This store -is **not** cached, meaning it is not used to update the application's volatile (un-committed) states. -The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application -uses one or multiple `KVStores` in the multi-store to persist their subset of the state. + which holds the canonical state that is committed at the [end of each block](#commit). This store + is **not** cached, meaning it is not used to update the application's volatile (un-committed) states. + The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application + uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - Database: The `db` is used by the `CommitMultiStore` to handle data persistence. -- [Router](#message-routing): The `router` facilitates the routing of `messages` to the appropriate -module for it to be processed. Here a `message` refers to the transaction components that need to be -processed by the application in order to update the state, and not to ABCI messages which implement -the interface between the application and the underlying consensus engine. -- [Query Router](#query-routing): The `query router` facilitates the routing of queries to the -appropriate module for it to be processed. These `queries` are not ABCI messages themselves, but they -are relayed to the application from the underlying consensus engine via the ABCI message [`Query`](#query). +- [`Msg` Service Router](#msg-service-router): The `msgServiceRouter` facilitates the routing of service `Msg`s to the appropriate + module for it to be processed. Here a service `Msg` refers to the transaction components that need to be + processed by the application in order to update the state, and not to ABCI messages which implement + the interface between the application and the underlying consensus engine. +- [gRPC Query Router](#grpc-query-router): The `grpcQueryRouter` facilitates the routing of gRPC queries to the + appropriate module for it to be processed. These queries are not ABCI messages themselves, but they + are relayed to the relevant module's gRPC `Query` service. - [`TxDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder): It is used to decode -raw transaction bytes relayed by the underlying Tendermint engine. + raw transaction bytes relayed by the underlying Tendermint engine. - [`ParamStore`](#paramstore): The parameter store used to get and set application consensus parameters. - [`AnteHandler`](#antehandler): This handler is used to handle signature verification, fee payment, -and other pre-message execution checks when a transaction is received. It's executed during -[`CheckTx/RecheckTx`](#checktx) and [`DeliverTx`](#delivertx). + and other pre-message execution checks when a transaction is received. It's executed during + [`CheckTx/RecheckTx`](#checktx) and [`DeliverTx`](#delivertx). - [`InitChainer`](../basics/app-anatomy.md#initchainer), -[`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker): These are -the functions executed when the application receives the `InitChain`, `BeginBlock` and `EndBlock` -ABCI messages from the underlying Tendermint engine. + [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker): These are + the functions executed when the application receives the `InitChain`, `BeginBlock` and `EndBlock` + ABCI messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): - `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). - `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and set to `nil` on -[`Commit`](#commit) and gets re-initialized on BeginBlock. + [`Commit`](#commit) and gets re-initialized on BeginBlock. Finally, a few more important parameterd: - `voteInfos`: This parameter carries the list of validators whose precommit is missing, either -because they did not vote or because the proposer did not include their vote. This information is -carried by the [Context](#context) and can be used by the application for various things like -punishing absent validators. + because they did not vote or because the proposer did not include their vote. This information is + carried by the [Context](#context) and can be used by the application for various things like + punishing absent validators. - `minGasPrices`: This parameter defines the minimum gas prices accepted by the node. This is a -**local** parameter, meaning each full-node can set a different `minGasPrices`. It is used in the -`AnteHandler` during [`CheckTx`](#checktx), mainly as a spam protection mechanism. The transaction -enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) -only if the gas prices of the transaction are greater than one of the minimum gas price in -`minGasPrices` (e.g. if `minGasPrices == 1uatom,1photon`, the `gas-price` of the transaction must be -greater than `1uatom` OR `1photon`). + **local** parameter, meaning each full-node can set a different `minGasPrices`. It is used in the + `AnteHandler` during [`CheckTx`](#checktx), mainly as a spam protection mechanism. The transaction + enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) + only if the gas prices of the transaction are greater than one of the minimum gas price in + `minGasPrices` (e.g. if `minGasPrices == 1uatom,1photon`, the `gas-price` of the transaction must be + greater than `1uatom` OR `1photon`). - `appVersion`: Version of the application. It is set in the -[application's constructor function](../basics/app-anatomy.md#constructor-function). + [application's constructor function](../basics/app-anatomy.md#constructor-function). ## Constructor @@ -114,7 +112,7 @@ func NewBaseApp( ``` The `BaseApp` constructor function is pretty straightforward. The only thing worth noting is the -possibility to provide additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/options.go) +possibility to provide additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/options.go) to the `BaseApp`, which will execute them in order. The `options` are generally `setter` functions for important parameters, like `SetPruning()` to set pruning options or `SetMinGasPrices()` to set the node's `min-gas-prices`. @@ -143,7 +141,7 @@ the root `CommitMultiStore`. Any subsequent reads and writes happen on cached ve ### CheckTx State Updates During `CheckTx`, the `checkState`, which is based off of the last committed state from the root -store, is used for any reads and writes. Here we only execute the `AnteHandler` and verify a router +store, is used for any reads and writes. Here we only execute the `AnteHandler` and verify a service router exists for every message in the transaction. Note, when we execute the `AnteHandler`, we cache-wrap the already cache-wrapped `checkState`. This has the side effect that if the `AnteHandler` fails, the state transitions won't be reflected in the `checkState` -- i.e. `checkState` is only updated on @@ -186,23 +184,23 @@ parameters are non-nil, they are set in the BaseApp's `ParamStore`. Behind the s is actually managed by an `x/params` module `Subspace`. This allows the parameters to be tweaked via on-chain governance. -## Routing +## Service Routers -When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. +When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `BaseApp`, which holds a `msgServiceRouter` for messages, and a `grpcQueryRouter` for queries. -### Message Routing +### `Msg` Service Router -[Messages](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `BaseApp` holds a router which maps string paths to the appropriate module [handler](../building-modules/msg-services.md#handler-type) using the `.Route(ctx sdk.Context, path string)` function. Usually, the `path` is the name of the module. +[`Msg`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `BaseApp` holds a `msgServiceRouter` which maps fully-qualified service methods (`string`, defined in each module's `Msg` Protobuf service) to the appropriate module's `Msg` server implementation. -The [default router included in baseapp](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) is stateless. However, some applications may want to make use of more stateful routing mechanisms such as allowing governance to disable certain routes or point them to new modules for upgrade purposes. For this reason, the `sdk.Context` is also passed into the `Route` function of the [Router interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/router.go#L12). For a stateless router that doesn't want to make use of this, can just ignore the ctx. +The [default `msgServiceRouter` included in `BaseApp`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/msg_service_router.go) is stateless. However, some applications may want to make use of more stateful routing mechanisms such as allowing governance to disable certain routes or point them to new modules for upgrade purposes. For this reason, the `sdk.Context` is also passed into each [route handler inside `msgServiceRouter`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/msg_service_router.go#L31-L32). For a stateless router that doesn't want to make use of this, you can just ignore the `ctx`. -The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md#manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `msgServiceRouter` is initialized with all the routes using the application's [module manager](../building-modules/module-manager.md#manager) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). -### Query Routing +### gRPC Query Router -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/query-services.md). To do so, `baseapp` holds a `query router`, which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query). +Similar to `Msg`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [`Query` service](../building-modules/query-services.md). To do so, `BaseApp` holds a `grpcQueryRouter`, which maps modules' fully-qualified service methods (`string`, defined in their Protobuf `Query` gRPC) to their `Query` server implementation. The `grpcQueryRouter` is called during the initial stages of query processing, which can be either by directly sending a gRPC query to the gRPC endpoint, or via the [`Query` ABCI message](#query) on the Tendermint RPC endpoint. -Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +Just like the `msgServiceRouter`, the `grpcQueryRouter` is initialized with all the query routes using the application's [module manager](../building-modules/module-manager.md) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages @@ -211,11 +209,11 @@ The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) ( The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. -Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) +Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `BaseApp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `BaseApp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ### CheckTx @@ -228,18 +226,18 @@ Unconfirmed transactions are relayed to peers only if they pass `CheckTx`. make them lightweight. In the Cosmos SDK, after [decoding transactions](./encoding.md), `CheckTx()` is implemented to do the following checks: -1. Extract the `message`s from the transaction. -2. Perform _stateless_ checks by calling `ValidateBasic()` on each of the `messages`. This is done +1. Extract the `Msg`s from the transaction. +2. Perform _stateless_ checks by calling `ValidateBasic()` on each of the `Msg`s. This is done first, as _stateless_ checks are less computationally expensive than _stateful_ checks. If `ValidateBasic()` fail, `CheckTx` returns before running _stateful_ checks, which saves resources. 3. Perform non-module related _stateful_ checks on the [account](../basics/accounts.md). This step is mainly about checking - that the `message` signatures are valid, that enough fees are provided and that the sending account + that the `Msg` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](../basics/gas-fees.md) counting occurs here, - as `message`s are not processed. Usually, the [`AnteHandler`](../basics/gas-fees.md#antehandler) will check that the `gas` provided + as `Msg`s are not processed. Usually, the [`AnteHandler`](../basics/gas-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually - process `message`s. `Message`s only need to be processed when the canonical state need to be updated, +4. Ensure that each `Msg`'s fully-qualified service method matches on of the routes inside the `msgServiceRouter`, but do **not** actually + process `Msg`s. `Msg`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. Steps 2. and 3. are performed by the [`AnteHandler`](../basics/gas-fees.md#antehandler) in the [`RunTx()`](#runtx-antehandler-and-runmsgs) @@ -257,11 +255,11 @@ is actually included in a block, because `checkState` never gets committed to th `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. - `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction. Next is an example: +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/ante/basic.go#L104 - `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. @@ -280,27 +278,27 @@ This allows certain checks like signature verification can be skipped during `Ch When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: 1. The `AnteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -2. For each message in the transaction, route to the appropriate module's [`handler`](../building-modules/msg-services.md#handler-type). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +2. For each `Msg` in the transaction, route to the appropriate module's [`Msg` service](../building-modules/msg-services.md). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `Msg` service returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L142-L150 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L153-L162 -At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseDeliverTx`](https://tendermint.com/docs/spec/abci/abci.html#delivertx). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction, and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction, and by adding gas each time a read/write to the store occurs. - `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. @@ -308,41 +306,41 @@ At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0 ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](../basics/gas-fees.md) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](../basics/gas-fees.md) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx()` calls `ValidateBasic()` on each `message`in the `Tx`, which runs preliminary _stateless_ validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. +After that, `RunTx()` calls `ValidateBasic()` on each `Msg`in the `Tx`, which runs preliminary _stateless_ validity checks. If any `Msg` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L587 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/baseapp.go#L623-L630 -This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. -Finally, the [`RunMsgs()`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. +Finally, the [`RunMsgs()`](#runmsgs) function is called to process the `Msg`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. ### AnteHandler -The `AnteHandler` is a special handler that implements the `anteHandler` interface and is used to authenticate the transaction before the transaction's internal messages are processed. +The `AnteHandler` is a special handler that implements the `AnteHandler` interface and is used to authenticate the transaction before the transaction's internal messages are processed. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/handler.go#L8 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/handler.go#L6-L8 The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./transactions.md#transaction-generation) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./transactions.md#transaction-generation) checking. +- Perform preliminary _stateful_ validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. -`baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/ante.go). +`BaseApp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/ante.go). -Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. +Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `Msg`s. -First, it retreives the message's `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/msg-services.md#handler-type) function for the message is executed, before `RunMsgs` returns. +First, it retrieves the `Msg`'s fully-qualified service method name, by checking the `type_url` of the Protobuf `Any` representing the service `Msg`. Then, using the application's [`msgServiceRouter`](#msg-service-router), it checks for the existence of this fully-qualified service method. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`Msg` server](../building-modules/msg-services.md) implementation for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages @@ -350,49 +348,49 @@ First, it retreives the message's `route` using the `Msg.Route()` method. Then, The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/gas-fees.md#block-gas-meter), with infinite gas to process genesis transactions. +- The [block gas meter](../basics/gas-fees.md#block-gas-meter), with infinite gas to process genesis transactions. -Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the `genesis file` and, if defined, call the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. +Finally, the `InitChain(req abci.RequestInitChain)` method of `BaseApp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the `genesis file` and, if defined, call the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. ### BeginBlock The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the `setDeliverState` function. +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the `setDeliverState` function. +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L387-L397 -This function also resets the [main gas meter](../basics/gas-fees.md#main-gas-meter). -- Initialize the [block gas meter](../basics/gas-fees.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. + This function also resets the [main gas meter](../basics/gas-fees.md#main-gas-meter). +- Initialize the [block gas meter](../basics/gas-fees.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`beginBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. -- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. +- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose _precommit_ for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transaction in the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`EndBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`EndBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transaction in the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`EndBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`EndBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received _precommits_ from 2/3+ of validators (weighted by voting power). On the `BaseApp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `BaseApp` will return the application's name, version and the hash of the last commit of `app.cms`. ### Query -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It used to be the main entrypoint to build interfaces with the application, but with the introduction of [gRPC queries](../building-modules/query-services.md) in Cosmos SDK v0.40, its usage is more limited. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). -Each `query` comes with a `path`, which contains multiple `string`s. By convention, the first element of the `path` (`path[0]`) contains the category of `query` (`app`, `p2p`, `store` or `custom`). The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving these 4 main categories of queries: +Each Tendermint `query` comes with a `path`, which is a `string` which denotes what to query. If the `path` matches a gRPC fully-qualified service method, then `BaseApp` will defer the query to the `grpcQueryRouter` and let it handle it like explained [above](#grpc-query-router). Otherwise, the `path` represents a query that is not (yet) handled by the gRPC router. `BaseApp` splits the `path` string with the `/` delimiter. By convention, the first element of the splitted string (`splitted[0]`) contains the category of `query` (`app`, `p2p`, `store` or `custom` ). The `BaseApp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving these 4 main categories of queries: - Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. - Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. -- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's `querier`. +- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `BaseApp`'s [constructor](#constructor). +- Custom queries, which encompass legacy queries (before the introduction of gRPC queries), are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from `app.queryRouter` to map the query to the appropriate module's [legacy `querier`](../building-modules/query-services.md#legacy-queriers). ## Next {hide} diff --git a/docs/core/context.md b/docs/core/context.md index e7c42bd339..cc0628b5eb 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -15,25 +15,9 @@ The `context` is a data structure intended to be passed from function to functio The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) as its base, and has many additional types within its definition that are specific to the Cosmos SDK. he `Context` is integral to transaction processing in that it allows modules to easily access their respective [store](./store.md#base-layer-kvstores) in the [`multistore`](./store.md#multistore) and retrieve transactional context such as the block header and gas meter. -```go -type Context struct { - ctx context.Context - ms MultiStore - header tmproto.Header - chainID string - txBytes []byte - logger log.Logger - voteInfo []abci.VoteInfo - gasMeter GasMeter - blockGasMeter GasMeter - checkTx bool - minGasPrice DecCoins - consParams *abci.ConsensusParams - eventManager *EventManager -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L16-L39 -- **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below. +- **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below. - **Multistore:** Every application's `BaseApp` contains a [`CommitMultiStore`](./store.md#multistore) which is provided when a `Context` is created. Calling the `KVStore()` and `TransientStore()` methods allows modules to fetch their respective [`KVStore`](./store.md#base-layer-kvstores) using their unique `StoreKey`. - **ABCI Header:** The [header](https://tendermint.com/docs/spec/abci/abci.html#header) is an ABCI type. It carries important information about the state of the blockchain, such as block height and proposer of the current block. - **Chain ID:** The unique identification number of the blockchain a block pertains to. @@ -42,10 +26,10 @@ type Context struct { - **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block. - **Gas Meters:** Specifically, a [`gasMeter`](../basics/gas-fees.md#main-gas-meter) for the transaction currently being processed using the context and a [`blockGasMeter`](../basics/gas-fees.md#block-gas-meter) for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/gas-fees.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. - **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode. -- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually, and should therefore **not be used in any functions used in sequences leading to state-transitions**. +- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually, and should therefore **not be used in any functions used in sequences leading to state-transitions**. - **Consensus Params:** The ABCI type [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters), which specify certain limits for the blockchain, such as maximum gas for a block. - **Event Manager:** The event manager allows any caller with access to a `Context` to emit [`Events`](./events.md). Modules may define module specific -`Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, and `EndBlock` and are returned to Tendermint for indexing. For example: + `Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, and `EndBlock` and are returned to Tendermint for indexing. For example: ```go ctx.EventManager().EmitEvent(sdk.NewEvent( @@ -63,7 +47,7 @@ are also designed to enable concurrency and to be used in goroutines. Contexts are intended to be **immutable**; they should never be edited. Instead, the convention is to create a child context from its parent using a `With` function. For example: -``` go +```go childCtx = parentCtx.WithBlockHeader(header) ``` @@ -79,12 +63,12 @@ goes wrong. The pattern of usage for a Context is as follows: 1. A process receives a Context `ctx` from its parent process, which provides information needed to perform the process. -2. The `ctx.ms` is **cache wrapped**, i.e. a cached copy of the [multistore](./store.md#multistore) is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms`. This is useful to protect the underlying multistore in case the changes need to be reverted at some point in the execution. +2. The `ctx.ms` is **cache wrapped**, i.e. a cached copy of the [multistore](./store.md#multistore) is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms`. This is useful to protect the underlying multistore in case the changes need to be reverted at some point in the execution. 3. The process may read and write from `ctx` as it is executing. It may call a subprocess and pass -`ctx` to it as needed. + `ctx` to it as needed. 4. When a subprocess returns, it checks if the result is a success or failure. If a failure, nothing -needs to be done - the cache wrapped `ctx` is simply discarded. If successful, the changes made to -the cache-wrapped `MultiStore` can be committed to the original `ctx.ms` via `Write()`. + needs to be done - the cache wrapped `ctx` is simply discarded. If successful, the changes made to + the cache-wrapped `MultiStore` can be committed to the original `ctx.ms` via `Write()`. For example, here is a snippet from the [`runTx`](./baseapp.md#runtx-and-runmsgs) function in [`baseapp`](./baseapp.md): @@ -106,12 +90,12 @@ if result.IsOK() { Here is the process: 1. Prior to calling `runMsgs` on the message(s) in the transaction, it uses `app.cacheTxContext()` -to cache-wrap the context and multistore. + to cache-wrap the context and multistore. 2. The cache-wrapped context, `runMsgCtx`, is used in `runMsgs` to return a result. 3. If the process is running in [`checkTxMode`](./baseapp.md#checktx), there is no need to write the -changes - the result is returned immediately. + changes - the result is returned immediately. 4. If the process is running in [`deliverTxMode`](./baseapp.md#delivertx) and the result indicates -a successful run over all the messages, the cached multistore is written back to the original. + a successful run over all the messages, the cached multistore is written back to the original. ## Next {hide} diff --git a/docs/core/node.md b/docs/core/node.md index 54ae46e753..825344040d 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -12,60 +12,65 @@ The main endpoint of an SDK application is the daemon client, otherwise known as ## `main` function -The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `./cmd/appd/main.go` file. Running this function creates an executable `.appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node. +The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `./appd/cmd/main.go` file. Running this function creates an executable `appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node. In general, developers will implement the `main.go` function with the following structure: -- First, a [`codec`](./encoding.md) is instanciated for the application. +- First, an [`appCodec`](./encoding.md) is instanciated for the application. - Then, the `config` is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys). - +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/config.go#L10-L21 -- Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. -- Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). + +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/config.go#L13-L24 +- Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. +- Add default server commands to `rootCmd` using the `server.AddCommands()` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). - Prepare and execute the `executor`. - +++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/cli/setup.go#L75-L78 + +++ https://github.com/tendermint/tendermint/blob/v0.34.0-rc6/libs/cli/setup.go#L74-L78 -See an example of `main` function from the [`gaia`](https://github.com/cosmos/gaia) application: +See an example of `main` function from the `simapp` application, the SDK's application for demo purposes: -+++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/cmd/gaiad/main.go ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/simd/main.go ## `start` command The `start` command is defined in the `/server` folder of the Cosmos SDK. It is added to the root command of the full-node client in the [`main` function](#main-function) and called by the end-user to start their node: -```go -// For an example app named "app", the following command starts the full-node - +```bash +# For an example app named "app", the following command starts the full-node. appd start + +# Using the SDK's own simapp, the following commands start the simapp node. +simd start ``` -As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine (Tendermint Core by default), while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node. +As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine (Tendermint Core by default), while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node. -The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db` (a [`leveldb`](https://github.com/syndtr/goleveldb) instance by default). This `db` contains the latest known state of the application (empty if the application is started from the first time. +The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db` (a [`leveldb`](https://github.com/syndtr/goleveldb) instance by default). This `db` contains the latest known state of the application (empty if the application is started from the first time. With the `db`, the `start` command creates a new instance of the application using an `appCreator` function: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/start.go#L144 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L227 -Note that an `appCreator` is a function that fulfills the `AppCreator` signature. In practice, the [constructor the application](../basics/app-anatomy.md#constructor-function) is passed as the `appCreator`. +Note that an `appCreator` is a function that fulfills the `AppCreator` signature: ++++https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/types/app.go#L48-L50 -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/constructors.go#L17-L25 +In practice, the [constructor of the application](../basics/app-anatomy.md#constructor-function) is passed as the `appCreator`. + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/simd/cmd/root.go#L170-L215 Then, the instance of `app` is used to instanciate a new Tendermint node: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/start.go#L153-L163 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L235-L244 -The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file. +The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/v0.34.0/abci/types/application.go#L7-L32) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file. Once the Tendermint node is instanciated and in sync with the application, the node can be started: -```go -if err := tmNode.Start(); err != nil { - return nil, err -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L250-L252 -Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress. +Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress. + +## Other commands + +To discover how to concretely run a node and interact with it, please refer to our [Running a Node](../run-node/README.md) guide. ## Next {hide} -Learn about the [store](./store.md) {hide} \ No newline at end of file +Learn about the [store](./store.md) {hide} diff --git a/docs/core/store.md b/docs/core/store.md index 1be9c505ee..b9e97163ba 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -58,11 +58,11 @@ The Cosmos SDK comes with a large set of stores to persist the state of applicat At its very core, a Cosmos SDK `store` is an object that holds a `CacheWrapper` and implements a `GetStoreType()` method: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L12-L15 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L15-L18 The `GetStoreType` is a simple method that returns the type of store, whereas a `CacheWrapper` is a simple interface that specifies cache-wrapping and `Write` methods: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L217-L238 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L240-L264 Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A cache-wrapper creates a light snapshot of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. If a state-transition sequence is performed without issue, the cached store can be committed to the underlying store at the end of the sequence. @@ -70,11 +70,11 @@ Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be impleme A commit store is a store that has the ability to commit changes made to the underlying tree or db. The Cosmos SDK differentiates simple stores from commit stores by extending the basic store interfaces with a `Committer`: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L24-L28 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L29-L33 The `Committer` is an interface that defines methods to persist changes to disk: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L17-L22 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L20-L27 The `CommitID` is a deterministic commit of the state tree. Its hash is returned to the underlying consensus engine and stored in the block header. Note that commit store interfaces exist for various purposes, one of which is to make sure not every object can commit the store. As part of the [object-capabilities model](./ocap.md) of the Cosmos SDK, only `baseapp` should have the ability to commit stores. For example, this is the reason why the `ctx.KVStore()` method by which modules typically access stores returns a `KVStore` and not a `CommitKVStore`. @@ -86,27 +86,27 @@ The Cosmos SDK comes with many types of stores, the most used being [`CommitMult Each Cosmos SDK application holds a multistore at its root to persist its state. The multistore is a store of `KVStores` that follows the `Multistore` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L83-L112 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L104-L133 -If tracing is enabled, then cache-wrapping the multistore will wrap all the underlying `KVStore` in [`TraceKv.Store`](#tracekv-store) before caching them. +If tracing is enabled, then cache-wrapping the multistore will wrap all the underlying `KVStore` in [`TraceKv.Store`](#tracekv-store) before caching them. ### CommitMultiStore The main type of `Multistore` used in the Cosmos SDK is `CommitMultiStore`, which is an extension of the `Multistore` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L120-L158 ++++https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L141-L184 -As for concrete implementation, the [`rootMulti.Store`] is the go-to implementation of the `CommitMultiStore` interface. +As for concrete implementation, the [`rootMulti.Store`] is the go-to implementation of the `CommitMultiStore` interface. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/rootmulti/store.go#L27-L43 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/rootmulti/store.go#L43-L61 The `rootMulti.Store` is a base-layer multistore built around a `db` on top of which multiple `KVStores` can be mounted, and is the default multistore store used in [`baseapp`](./baseapp.md). ### CacheMultiStore -Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used. +Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/cachemulti/store.go#L17-L28 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/cachemulti/store.go#L17-L28 `cachemulti.Store` cache wraps all substores in its constructor and hold them in `Store.stores`. `Store.GetKVStore()` returns the store from `Store.stores`, and `Store.Write()` recursively calls `CacheWrap.Write()` on all the substores. @@ -114,50 +114,37 @@ Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store` ### `KVStore` and `CommitKVStore` Interfaces -A `KVStore` is a simple key-value store used to store and retrieve data. A `CommitKVStore` is a `KVStore` that also implements a `Committer`. By default, stores mounted in `baseapp`'s main `CommitMultiStore` are `CommitKVStore`s. The `KVStore` interface is primarily used to restrict modules from accessing the committer. +A `KVStore` is a simple key-value store used to store and retrieve data. A `CommitKVStore` is a `KVStore` that also implements a `Committer`. By default, stores mounted in `baseapp`'s main `CommitMultiStore` are `CommitKVStore`s. The `KVStore` interface is primarily used to restrict modules from accessing the committer. Individual `KVStore`s are used by modules to manage a subset of the global state. `KVStores` can be accessed by objects that hold a specific key. This `key` should only be exposed to the [`keeper`](../building-modules/keeper.md) of the module that defines the store. -`CommitKVStore`s are declared by proxy of their respective `key` and mounted on the application's [multistore](#multistore) in the [main application file](../basics/app-anatomy.md#core-application-file). In the same file, the `key` is also passed to the module's `keeper` that is responsible for managing the store. +`CommitKVStore`s are declared by proxy of their respective `key` and mounted on the application's [multistore](#multistore) in the [main application file](../basics/app-anatomy.md#core-application-file). In the same file, the `key` is also passed to the module's `keeper` that is responsible for managing the store. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L163-L193 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L189-L219 -Apart from the traditional `Get` and `Set` methods, a `KVStore` is expected to implement an `Iterator()` method which returns an `Iterator` object. The `Iterator()` method is used to iterate over a domain of keys, typically keys that share a common prefix. Here is a common pattern of using an `Iterator` that might be found in a module's `keeper`: +Apart from the traditional `Get` and `Set` methods, a `KVStore` must provide an `Iterator(start, end)` method which returns an `Iterator` object. It is used to iterate over a range of keys, typically keys that share a common prefix. Below is an example from the bank's module keeper, used to iterate over all account balances: -```go -store := ctx.KVStore(keeper.storeKey) -iterator := sdk.KVStorePrefixIterator(store, prefix) // proxy for store.Iterator - -defer iterator.Close() -for ; iterator.Valid(); iterator.Next() { - var object types.Object - keeper.cdc.MustUnmarshalBinaryBare(iterator.Value(), &object) - - if cb(object) { - break - } -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/bank/keeper/view.go#L115-L134 ### `IAVL` Store The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is the `iavl.Store`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/iavl/store.go#L32-L47 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/iavl/store.go#L37-L40 - `iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that: +`iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that: - `Get` and `Set` operations are O(log n), where n is the number of elements in the tree. - Iteration efficiently returns the sorted elements within the range. -- Each tree version is immutable and can be retrieved even after a commit (depending on the pruning settings). +- Each tree version is immutable and can be retrieved even after a commit (depending on the pruning settings). -The documentation on the IAVL Tree is located [here](https://github.com/tendermint/iavl/blob/f9d4b446a226948ed19286354f0d433a887cc4a3/docs/overview.md). +The documentation on the IAVL Tree is located [here](https://github.com/cosmos/iavl/blob/v0.15.0-rc5/docs/overview.md). ### `DbAdapter` Store `dbadapter.Store` is a adapter for `dbm.DB` making it fulfilling the `KVStore` interface. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/dbadapter/store.go#L13-L16 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/dbadapter/store.go#L13-L16 `dbadapter.Store` embeds `dbm.DB`, meaning most of the `KVStore` interface functions are implemented. The other functions (mostly miscellaneous) are manually implemented. This store is primarily used within [Transient Stores](#transient-stores) @@ -165,17 +152,17 @@ The documentation on the IAVL Tree is located [here](https://github.com/tendermi `Transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/transient/store.go#L14-L17 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/transient/store.go#L13-L16 `Transient.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, a new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected. -This type of store is useful to persist information that is only relevant per-block. One example would be to store parameter changes (i.e. a bool set to `true` if a parameter changed in a block). +This type of store is useful to persist information that is only relevant per-block. One example would be to store parameter changes (i.e. a bool set to `true` if a parameter changed in a block). -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/params/subspace/subspace.go#L24-L32 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/params/types/subspace.go#L20-L30 Transient stores are typically accessed via the [`context`](./context.md) via the `TransientStore()` method: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/context.go#L215-L218 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L232-L235 ## KVStore Wrappers @@ -183,9 +170,9 @@ Transient stores are typically accessed via the [`context`](./context.md) via th `cachekv.Store` is a wrapper `KVStore` which provides buffered writing / cached reading functionalities over the underlying `KVStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/cachekv/store.go#L26-L33 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/cachekv/store.go#L27-L34 -This is the type used whenever an IAVL Store needs to be cache-wrapped (typically when setting value that might be reverted later). +This is the type used whenever an IAVL Store needs to be cache-wrapped (typically when setting value that might be reverted later). #### `Get` @@ -201,27 +188,27 @@ This is the type used whenever an IAVL Store needs to be cache-wrapped (typicall ### `GasKv` Store -Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. +Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/gaskv/store.go#L11-L17 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/gaskv/store.go#L13-L19 When methods of the parent `KVStore` are called, `GasKv.Store` automatically consumes appropriate amount of gas depending on the `Store.gasConfig`: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L141-L150 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L153-L162 By default, all `KVStores` are wrapped in `GasKv.Stores` when retrieved. This is done in the `KVStore()` method of the [`context`](./context.md): -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/context.go#L210-L213 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L227-L230 In this case, the default gas configuration is used: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L152-L163 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L164-L175 ### `TraceKv` Store -`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. It is applied automatically by the Cosmos SDK on all `KVStore` if tracing is enabled on the parent `MultiStore`. +`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. It is applied automatically by the Cosmos SDK on all `KVStore` if tracing is enabled on the parent `MultiStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/tracekv/store.go#L20-L43 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/tracekv/store.go#L20-L43 When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. `traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`. @@ -229,7 +216,7 @@ When each `KVStore` methods are called, `tracekv.Store` automatically logs `trac `prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/prefix/store.go#L17-L20 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/prefix/store.go#L15-L21 When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`. diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 8bd5ae17f4..a2ccbfdb70 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -8,84 +8,146 @@ order: 2 ## Pre-requisite Readings -* [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} +- [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} ## Transactions -Transactions are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [`Msg` service](../building-modules/msg-services.md). +Transactions are comprised of metadata held in [contexts](./context.md) and [`Msg`s](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [`Msg` service](../building-modules/msg-services.md). -When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's `message`s must be signed using the private key associated with the appropriate account(s), before the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's `Msg`s must be signed using the private key associated with the appropriate account(s), before the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Type Definition Transaction objects are SDK types that implement the `Tx` interface -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L34-L41 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/tx_msg.go#L49-L57 It contains the following methods: -* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./baseapp.md#checktx) and [`DeliverTx`](./baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is to be distinct from the `ValidateBasic` functions for *`messages`*, which perform basic validity checks on messages only. For example, when [`runTx`](./baseapp.md#runtx) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. -* **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. +- **GetMsgs:** unwraps the transaction and returns a list of its `Msg`s - one transaction may have one or multiple [`Msg`s](../building-modules/messages-and-queries.md#messages), which are defined by module developers. +- **ValidateBasic:** includes lightweight, [_stateless_](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./baseapp.md#checktx) and [`DeliverTx`](./baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is to be distinct from the `ValidateBasic` functions for `Msg`s, which perform basic validity checks on messages only. For example, when [`runTx`](./baseapp.md#runtx) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -The most used implementation of the `Tx` interface is [`StdTx` from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go). As a developer, using `StdTx` as your transaction format is as simple as importing the `auth` module in your application (which can be done in the [constructor of the application](../basics/app-anatomy.md#constructor-function)) +As a developer, you should rarely manipulate `Tx` directly, as `Tx` is really an intermediate type used for transaction generation. Instead, developers should prefer the `TxBuilder` interface, which you can learn more about [below](#transaction-generation). + +### Signing Transactions + +Every message in a transaction must be signed by the addresses specified by its `GetSigners`. The SDK currently allows signing transactions in two different ways. + +#### `SIGN_MODE_DIRECT` (preferred) + +The most used implementation of the `Tx` interface is the Protobuf `Tx` message, which is used in `SIGN_MODE_DIRECT`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/tx/v1beta1/tx.proto#L12-L25 + +Because Protobuf serialization is not deterministic, the SDK uses an additional `TxRaw` type to denote the pinned bytes over which a transaction is signed. Any user can generate a valid `body` and `auth_info` for a transaction, and serialize these two messages using Protobuf. `TxRaw` then pins the user's exact binary representation of `body` and `auth_info`, called respectively `body_bytes` and `auth_info_bytes`. The document that is signed by all signers of the transaction is `SignDoc` (deterministically serialized using [ADR-027](../architecture/adr-027-deterministic-protobuf-serialization.md)): + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/tx/v1beta1/tx.proto#L47-L64 + +Once signed by all signers, the `body_bytes`, `auth_info_bytes` and `signatures` are gathered into `TxRaw`, whose serialized bytes are broadcasted over the network. + +#### `SIGN_MODE_LEGACY_AMINO_JSON` + +The legacy implemention of the `Tx` interface is the `StdTx` struct from `x/auth`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/auth/legacy/legacytx/stdtx.go#L120-L130 + +The document signed by all signers is `StdSignDoc`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/auth/legacy/legacytx/stdsign.go#L20-L33 + +which is encoded into bytes using Amino JSON. Once all signatures are gathered into `StdTx`, `StdTx` is serialized using Amino JSON, and these bytes are broadcasted over the network. + +#### Other Sign Modes + +Other sign modes, most notably `SIGN_MODE_TEXTUAL`, are being discussed. If you wish to learn more about them, please refer to [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md). ## Transaction Process -A transaction is created by an end-user through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. +The process of an end-user sending a transaction is: -### CLI and REST Interfaces +- decide on the messages to put into the transaction, +- generate the transaction using the SDK's `TxBuilder`, +- broadcast the transaction using one of the available interfaces. -Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) and/or [REST interface](../interfaces/rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. - -For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/module-interfaces.md#legacy-rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. - -When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. +The next paragraphs will describe each of these components, in this order. ### Messages -**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/msg-services.md#handler-type) to process them. +::: tip +Module `Msg`s are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. +::: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L8-L29 +**Messages** (or `Msg`s) are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by adding methods to the Protobuf [`Msg` service](../building-modules/msg-services.md), and also implement the corresponding `MsgServer`. -`Message`s in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's `message`s is defined in a `handler.go` file. +`Msg`s in a module are defined as methods in the [`Msg` service] inside each module's `tx.proto` file. Since `Msg`s are module-specific, each module needs a to process all of its message types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To achieve this, Protobuf generates a `MsgServer` interface for each module, and the module developer needs to implement this interface. The methods on the `MsgServer` interface corresponds on how to handle each of the different `Msg`. -Note: module `messages` are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. - -To learn more about `message`s, click [here](../building-modules/messages-and-queries.md#messages). +To learn more about `Msg` services and how to implement `MsgServer`, click [here](../building-modules/msg-services.md). While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `Context`. ### Transaction Generation -Transactions are first created by end-users through an `appcli tx` command through the command-line or a POST request to an HTTPS server. For details about transaction creation, click [here](../basics/tx-lifecycle.md#transaction-creation). +The `TxBuilder` interface contains data closely related with the generation of transactions, which an end-user can freely set to generate the desired transaction: -[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction through the `auth` module (though it is not mandatory to create transactions this way), two contexts are created: the [`Context`](../interfaces/query-lifecycle.md#context) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/client/tx_config.go#L32-L45 -The `TxBuilder` contains data closely related with the processing of transactions. +- `Msg`s, the array of [messages](#messages) included in the transaction. +- `GasLimit`, option chosen by the users for how to calculate how much gas they will need to pay. +- `Memo`, to send with the transaction. +- `FeeAmount`, the maximum amount the user is willing to pay in fees. +- `TimeoutHeight`, block height until which the transaction is valid. +- `Signatures`, the array of signatures from all signers of the transaction. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/txbuilder.go#L18-L31 +As there are currently two sign modes for signing transactions, there are also two implementations of `TxBuilder`: -* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. -* `Keybase` that manages the user's keys and is used to perform signing operations. -* `AccountNumber` from which this transaction originated. -* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. -* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. -* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. -* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. -* `ChainID` representing which blockchain this transaction pertains to. -* `Memo` to send with the transaction. -* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. -* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. +- [wrapper](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/auth/tx/builder.go#L19-L33) for creating transactions for `SIGN_MODE_DIRECT`, +- [StdTxBuilder](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/auth/legacy/legacytx/stdtx_builder.go#L14-L20) for `SIGN_MODE_LEGACY_AMINO_JSON`. -The `Context` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `Context` [here](../interfaces/query-lifecycle.md#context). +However, the two implementation of `TxBuilder` should be hidden away from end-users, as they should prefer using the overarching `TxConfig` interface: -Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `Context` is used to broadcast transactions. ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/client/tx_config.go#L21-L30 -### Handlers +`TxConfig` is an app-wide configuration for managing transactions. Most importantly, it holds the information about whether to sign each transaction with `SIGN_MODE_DIRECT` or `SIGN_MODE_LEGACY_AMINO_JSON`. By calling `txBuilder := txConfig.NewTxBuilder()`, a new `TxBuilder` will be created with the appropriate sign mode. -Since messages are module-specific types, each module needs a [`handler`](../building-modules/msg-services.md#handler-type) to process all of its message types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about `handler`s, click [here](../building-modules/msg-services.md#handler-type). +Once `TxBuilder` is correctly populated with the setters exposed above, `TxConfig` will also take care of correctly encoding the bytes (again, either using `SIGN_MODE_DIRECT` or `SIGN_MODE_LEGACY_AMINO_JSON`). Here's a pseudo-code snippet of how to generate and encode a transaction, using the `TxEncoder()` method: + +```go +txBuilder := txConfig.NewTxBuilder() +txBuilder.SetMsgs(...) // and other setters on txBuilder + +bz, err := txConfig.TxEncoder()(txBuilder.GetTx()) +// bz are bytes to be broadcasted over the network +``` + +### Broadcasting the Transaction + +Once the transaction bytes are generated, there are currently three ways of broadcasting it. + +#### CLI + +Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) and/or [REST interface](../interfaces/rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line. + +For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. CLI commands actually bundle all the steps of transaction processing into one simple command: creating messages, generating transactions and broadcasting. For concrete examples, see the [Interacting with a Node](../run-node/interact-node.md) section. An example transaction made using CLI looks like: + +```bash +simd tx send $MY_VALIDATOR_ADDRESS $RECIPIENT 1000stake +``` + +#### gRPC + +[gRPC](https://grpc.io) is introduced in Cosmos SDK 0.40 as the main component for the SDK's RPC layer. The principal usage of gRPC is in the context of modules' [`Query` services](../building-modules). However, the SDK also exposes a few other module-agnostic gRPC services, one of them being the `Tx` service: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/tx/v1beta1/service.proto + +The `Tx` service exposes a handful of utility functions, such as simulating a transaction or querying a transaction, and also one method to broadcast transactions. + +An example of broadcasting a transaction is shown in [TODO](https://github.com/cosmos/cosmos-sdk/issues/7657). Please note that the `BroadcastTx` endpoint takes `TxRaw`, not bytes. + +#### REST + +Each gRPC method has its corresponding REST endpoint, generated using [gRPC-gateway](https://github.com/grpc-ecosystem/grpc-gateway). Therefore, instead of using gRPC, you can also use HTTP to broadcast the same transaction, on the `POST /cosmos/tx/v1beta1/broadcast_tx` endpoint. + +An example can be seen [here TODO](https://github.com/cosmos/cosmos-sdk/issues/7657) ## Next {hide} diff --git a/docs/migrations/rest.md b/docs/migrations/rest.md new file mode 100644 index 0000000000..4de2946faa --- /dev/null +++ b/docs/migrations/rest.md @@ -0,0 +1,89 @@ +# REST Endpoints Migration + +Migrate your REST endpoints to the Stargate ones. {synopsis} + +## Deprecation of Legacy REST Endpoints + +The Cosmos SDK versions v0.39 and earlier provided REST endpoints to query the state and broadcast transactions. These endpoints are kept in Cosmos SDK v0.40 (Stargate), but they are marked as deprecated, and will be removed in v0.41. We therefore call these endpoints legacy REST endpoints. + +Some important information concerning all legacy REST endpoints: + +- Most of these endpoints are backwards-comptatible. All breaking changes are described in the next section. +- In particular, these endpoints still output Amino JSON. Cosmos v0.40 introduced Protobuf as the default encoding library throughout the codebase, but legacy REST endpoints are one of the few places where the encoding is hardcoded to Amino. For more information about Protobuf and Amino, please read our [encoding guide](../core/encoding.md). +- All legacy REST endpoints include a [HTTP deprecation header](https://tools.ietf.org/id/draft-dalal-deprecation-header-01.html) which links to this document. + +## Breaking Changes in Legacy REST Endpoints + +| Legacy REST Endpoint | Description | Breaking Change | +| ------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `GET /txs/{hash}` | Query tx by hash | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)1. | +| `GET /txs` | Query tx by events | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)1. | +| `GET /staking/validators` | Get all validators | BondStatus is now a protobuf enum instead of an int32, and JSON serialized using its protobuf name, so expect query parameters like `?status=BOND_STATUS_{BONDED,UNBONDED,UNBONDING}` as opposed to `?status={bonded,unbonded,unbonding}`. | + +1: Transactions that don't support Amino serialization are the ones that contain one or more `Msg`s that are not registered with the Amino codec. Currently in the SDK, only IBC `Msg`s fall into this case. + +## Migrating to New REST Endpoints + +Thanks to the Protocol Buffers migration in v0.40 we are able to take advantage of a vast number of gRPC tools and solutions. For most of the legacy REST endpoints, Cosmos SDK v0.40 provides new REST endpoints generated from [gRPC `Query` services](../building-modules/query-services.md) using [grpc-gateway](https://grpc-ecosystem.github.io/grpc-gateway/). We usually call them _gGPC-gateway REST endpoints_. + +Some modules expose legacy `POST` endpoints to generate unsigned transactions for their `Msg`s. These `POST` endpoints have been removed. We recommend to use [service `Msg`s](../building-modules/msg-services.md) directly, and use Protobuf to do client-side transaction generation. A guide can be found [here (TODO)](https://github.com/cosmos/cosmos-sdk/issues/7657). + +| Legacy REST Endpoint | Description | New gGPC-gateway REST Endpoint | +| ------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `GET /txs/{hash}` | Query tx by hash | `GET /cosmos/tx/v1beta1/tx/{hash}` | +| `GET /txs` | Query tx by events | `GET /cosmos/tx/v1beta1/txs` | +| `POST /txs` | Broadcast tx | `POST /cosmos/tx/v1beta1/txs` | +| `POST /txs/encode` | Encodes an Amino JSON tx to an Amino binary tx | N/A, use Protobuf directly | +| `POST /txs/decode` | Decodes an Amino binary tx into an Amino JSON tx | N/A, use Protobuf directly | +| `POST /bank/*` | Create unsigned `Msg`s for bank tx | N/A, use Protobuf directly | +| `GET /bank/balances/{address}` | Get the balance of an address | `GET /cosmos/bank/v1beta1/balances/{address}/{denom}` | +| `GET /bank/total` | Get the total supply of all coins | `GET /cosmos/bank/v1beta1/supply` | +| `GET /bank/total/{denom}` | Get the total supply of one coin | `GET /cosmos/bank/v1beta1/supply/{denom}` | +| `POST /distribution/delegators/{delegatorAddr}/rewards` | Withdraw all delegator rewards | N/A, use Protobuf directly | +| `POST /distribution/*` | Create unsigned `Msg`s for distribution | N/A, use Protobuf directly | +| `GET /distribution/delegators/{delegatorAddr}/rewards` | Get the total rewards balance from all delegations | `GET /cosmos/distribution/v1beta1/v1beta1/delegators/{delegator_address}/rewards` | +| `GET /distribution/delegators/{delegatorAddr}/rewards/{validatorAddr}` | Query a delegation reward | `GET /cosmos/distribution/v1beta1/delegators/{delegatorAddr}/rewards/{validatorAddr}` | +| `GET /distribution/delegators/{delegatorAddr}/withdraw_address` | Get the rewards withdrawal address | `GET /cosmos/distribution/v1beta1/delegators/{delegatorAddr}/withdraw_address` | +| `GET /distribution/validators/{validatorAddr}` | Validator distribution information | `GET /cosmos/distribution/v1beta1/validators/{validatorAddr}` | +| `GET /distribution/validators/{validatorAddr}/rewards` | Commission and self-delegation rewards of a single a validator | `GET /cosmos/distribution/v1beta1/validators/{validatorAddr}/rewards` | +| `GET /distribution/validators/{validatorAddr}/outstanding_rewards` | Outstanding rewards of a single validator | `GET /cosmos/distribution/v1beta1/validators/{validatorAddr}/outstanding_rewards` | +| `GET /distribution/parameters` | Get the current distribution parameter values | `GET /cosmos/distribution/v1beta1/params` | +| `GET /distribution/community_pool` | Get the amount held in the community pool | `GET /cosmos/distribution/v1beta1/community_pool` | +| `GET /evidence/{evidence-hash}` | Get evidence by hash | `GET /cosmos/evidence/v1beta1/evidence/{evidence_hash}` | +| `GET /evidence` | Get all evidence | `GET /cosmos/evidence/v1beta1/evidence` | +| `POST /gov/*` | Create unsigned `Msg`s for gov | N/A, use Protobuf directly | +| `GET /gov/parameters/{type}` | Get government parameters | `GET /cosmos/gov/v1beta1/params/{type}` | +| `GET /gov/proposals` | Get all proposals | `GET /cosmos/gov/v1beta1/proposals` | +| `GET /gov/proposals/{proposal-id}` | Get proposal by id | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}` | +| `GET /gov/proposals/{proposal-id}/proposer` | Get proposer of a proposal | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}` (Get proposer from `Proposal` struct) | +| `GET /gov/proposals/{proposal-id}/deposits` | Get deposits of a proposal | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/deposits` | +| `GET /gov/proposals/{proposal-id}/deposits/{depositor}` | Get depositor a of deposit | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/deposits/{depositor}` | +| `GET /gov/proposals/{proposal-id}/tally` | Get tally of a proposal | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/tally` | +| `GET /gov/proposals/{proposal-id}/votes` | Get votes of a proposal | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/votes` | +| `GET /gov/proposals/{proposal-id}/votes/{vote}` | Get a particular vote | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/votes/{vote}` | +| `GET /minting/parameters` | Get parameters for minting | `GET /cosmos/minting/v1beta1/params` | +| `GET /minting/inflation` | Get minting inflation | `GET /cosmos/minting/v1beta1/inflation` | +| `GET /minting/annual-provisions` | Get minting annual provisions | `GET /cosmos/minting/v1beta1/annual_provisions` | +| `POST /slashing/*` | Create unsigned `Msg`s for slashing | N/A, use Protobuf directly | +| `GET /slashing/validators/{validatorPubKey}/signing_info` | Get validator signing info | `GET /cosmos/slashing/v1beta1/signing_infos/{cons_address}` (Use consensus address instead of pubkey) | +| `GET /slashing/signing_infos` | Get all signing infos | `GET /cosmos/slashing/v1beta1/signing_infos` | +| `GET /slashing/parameters` | Get slashing parameters | `GET /cosmos/slashing/v1beta1/params` | +| `POST /staking/*` | Create unsigned `Msg`s for staking | N/A, use Protobuf directly | +| `GET /staking/delegators/{delegatorAddr}/delegations` | Get all delegations from a delegator | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/delegations` | +| `GET /staking/delegators/{delegatorAddr}/unbonding_delegations` | Get all unbonding delegations from a delegator | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/unbonding_delegations` | +| `GET /staking/delegators/{delegatorAddr}/txs` | Get all staking txs (i.e msgs) from a delegator | Removed | +| `GET /staking/delegators/{delegatorAddr}/validators` | Query all validators that a delegator is bonded to | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/validators` | +| `GET /staking/delegators/{delegatorAddr}/validators/{validatorAddr}` | Query a validator that a delegator is bonded to | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/validators/{validatorAddr}` | +| `GET /staking/delegators/{delegatorAddr}/delegations/{validatorAddr}` | Query a delegation between a delegator and a validator | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/delegations/{validatorAddr}` | +| `GET /staking/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}` | Query all unbonding delegations between a delegator and a validator | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}` | +| `GET /staking/redelegations` | Query redelegations | `GET /cosmos/staking/v1beta1/v1beta1/delegators/{delegator_addr}/redelegations` | +| `GET /staking/validators` | Get all validators | `GET /cosmos/staking/v1beta1/validators` | +| `GET /staking/validators/{validatorAddr}` | Get a single validator info | `GET /cosmos/staking/v1beta1/validators/{validatorAddr}` | +| `GET /staking/validators/{validatorAddr}/delegations` | Get all delegations to a validator | `GET /cosmos/staking/v1beta1/validators/{validatorAddr}/delegations` | +| `GET /staking/validators/{validatorAddr}/unbonding_delegations` | Get all unbonding delegations from a validator | `GET /cosmos/staking/v1beta1/validators/{validatorAddr}/unbonding_delegations` | +| `GET /staking/historical_info/{height}` | Get HistoricalInfo at a given height | `GET /cosmos/staking/v1beta1/historical_info/{height}` | +| `GET /staking/pool` | Get the current state of the staking pool | `GET /cosmos/staking/v1beta1/pool` | +| `GET /staking/parameters` | Get the current staking parameter values | `GET /cosmos/staking/v1beta1/params` | +| `POST /upgrade/*` | Create unsigned `Msg`s for upgrade | N/A, use Protobuf directly | +| `GET /upgrade/current` | Get the current plan | `GET /cosmos/upgrade/v1beta1/current_plan` | +| `GET /upgrade/applied_plan/{name}` | Get a previously applied plan | `GET /cosmos/upgrade/v1beta1/applied/{name}` | diff --git a/docs/run-node/keyring.md b/docs/run-node/keyring.md index 9725007c9f..a0bc0254f7 100644 --- a/docs/run-node/keyring.md +++ b/docs/run-node/keyring.md @@ -101,7 +101,7 @@ information. Make sure you can build your own binary, and replace `simd` with the name of your binary in the snippets. ::: -Applications developed using the Cosmos SDK come with the `keys` subcommand. For the purpose of this tutorial, we're running the `simd` CLI, which is an application built using the Cosmos SDK for testing and educational purposes. For more information, see [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp). +Applications developed using the Cosmos SDK come with the `keys` subcommand. For the purpose of this tutorial, we're running the `simd` CLI, which is an application built using the Cosmos SDK for testing and educational purposes. For more information, see [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc3/simapp). You can use `simd keys` for help about the keys command and `simd keys [command] --help` for more information about a particular subcommand. diff --git a/docs/run-node/run-node.md b/docs/run-node/run-node.md index 05708e63d4..768726d602 100644 --- a/docs/run-node/run-node.md +++ b/docs/run-node/run-node.md @@ -4,7 +4,7 @@ order: 2 # Running a Node -Now that the application is ready and the keyring populated, it's time to see how to run the blockchain node. In this section, the application we are running is called [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp), and its corresponding CLI binary `simd`. {synopsis} +Now that the application is ready and the keyring populated, it's time to see how to run the blockchain node. In this section, the application we are running is called [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc3/simapp), and its corresponding CLI binary `simd`. {synopsis} ## Pre-requisite Readings @@ -47,7 +47,7 @@ Now that you have created a local account, go ahead and grant it some `stake` to simd add-genesis-account $MY_VALIDATOR_ADDRESS 100000000stake ``` -Recall that `$MY_VALIDATOR_ADDRESS` is a variable that holds the address of the `my_validator` key in the [keyring](./keyring.md#adding-keys-to-the-keyring). Also note that the tokens in the SDK have the `{amount}{denom}` format: `amount` is is a 18-digit-precision decimal number, and `denom` is the unique token identifier with its denomination key (e.g. `atom` or `uatom`). Here, we are granting `stake` tokens, as `stake` is the token identifier used for staking in [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp). For your own chain with its own staking denom, that token identifier should be used instead. +Recall that `$MY_VALIDATOR_ADDRESS` is a variable that holds the address of the `my_validator` key in the [keyring](./keyring.md#adding-keys-to-the-keyring). Also note that the tokens in the SDK have the `{amount}{denom}` format: `amount` is is a 18-digit-precision decimal number, and `denom` is the unique token identifier with its denomination key (e.g. `atom` or `uatom`). Here, we are granting `stake` tokens, as `stake` is the token identifier used for staking in [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc3/simapp). For your own chain with its own staking denom, that token identifier should be used instead. Now that your account has some tokens, you need to add a validator to your chain. Validators are special full-nodes that participate in the consensus process (implemented in the [underlying consensus engine](../intro/sdk-app-architecture.md#tendermint)) in order to add new blocks to the chain. Any account can declare its intention to become a validator operator, but only those with sufficient delegation get to enter the active set (for example, only the top 125 validator candidates with the most delegation get to be validators in the Cosmos Hub). For this guide, you will add your local node (created via the `init` command above) as a validator of your chain. Validators can be declared before a chain is first started via a special transaction included in the genesis file called a `gentx`: @@ -83,7 +83,7 @@ You should see blocks come in. The previous command allow you to run a single node. This is enough for the next section on interacting with this node, but you may wish to run multiple nodes at the same time, and see how consensus happens between them. -The naive way would be to run the same commands again in separate terminal windows. This is possible, however in the SDK, we leverage the power of [Docker Compose](https://docs.docker.com/compose/) to run a localnet. If you need inspiration on how to set up your own localnet with Docker Compose, you can have a look at the SDK's [`docker-compose.yml`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc2/docker-compose.yml). +The naive way would be to run the same commands again in separate terminal windows. This is possible, however in the SDK, we leverage the power of [Docker Compose](https://docs.docker.com/compose/) to run a localnet. If you need inspiration on how to set up your own localnet with Docker Compose, you can have a look at the SDK's [`docker-compose.yml`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/docker-compose.yml). ## Next {hide} diff --git a/proto/cosmos/upgrade/v1beta1/query.proto b/proto/cosmos/upgrade/v1beta1/query.proto index d5c6bd7b2b..9eab27e76b 100644 --- a/proto/cosmos/upgrade/v1beta1/query.proto +++ b/proto/cosmos/upgrade/v1beta1/query.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package cosmos.upgrade.v1beta1; +import "google/protobuf/any.proto"; import "google/api/annotations.proto"; import "cosmos/upgrade/v1beta1/upgrade.proto"; @@ -17,6 +18,14 @@ service Query { rpc AppliedPlan(QueryAppliedPlanRequest) returns (QueryAppliedPlanResponse) { option (google.api.http).get = "/cosmos/upgrade/v1beta1/applied_plan/{name}"; } + + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}"; + } } // QueryCurrentPlanRequest is the request type for the Query/CurrentPlan RPC @@ -43,3 +52,17 @@ message QueryAppliedPlanResponse { // height is the block height at which the plan was applied. int64 height = 1; } + +// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateRequest { + // last height of the current chain must be sent in request + // as this is the height under which next consensus state is stored + int64 last_height = 1; +} + +// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateResponse { + google.protobuf.Any upgraded_consensus_state = 1; +} diff --git a/proto/ibc/core/channel/v1/genesis.proto b/proto/ibc/core/channel/v1/genesis.proto index a89e69c7dd..d3b2c0424e 100644 --- a/proto/ibc/core/channel/v1/genesis.proto +++ b/proto/ibc/core/channel/v1/genesis.proto @@ -18,6 +18,8 @@ message GenesisState { [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"recv_sequences\""]; repeated PacketSequence ack_sequences = 7 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"ack_sequences\""]; + // the sequence for the next generated channel identifier + uint64 next_channel_sequence = 8 [(gogoproto.moretags) = "yaml:\"next_channel_sequence\""]; } // 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 4121096240..d9e3ceb8a6 100644 --- a/proto/ibc/core/channel/v1/query.proto +++ b/proto/ibc/core/channel/v1/query.proto @@ -38,8 +38,8 @@ service Query { // associated with the provided channel identifiers. rpc ChannelConsensusState(QueryChannelConsensusStateRequest) returns (QueryChannelConsensusStateResponse) { option (google.api.http).get = - "/ibc/core/channel/v1beta1/channels/{channel_id}/ports/{port_id}/consensus_state/version/" - "{version_number}/height/{version_height}"; + "/ibc/core/channel/v1beta1/channels/{channel_id}/ports/{port_id}/consensus_state/revision/" + "{revision_number}/height/{revision_height}"; } // PacketCommitment queries a stored packet commitment hash. @@ -176,10 +176,10 @@ message QueryChannelConsensusStateRequest { string port_id = 1; // channel unique identifier string channel_id = 2; - // version number of the consensus state - uint64 version_number = 3; - // version height of the consensus state - uint64 version_height = 4; + // revision number of the consensus state + uint64 revision_number = 3; + // revision height of the consensus state + uint64 revision_height = 4; } // QueryChannelClientStateResponse is the Response type for the diff --git a/proto/ibc/core/channel/v1/tx.proto b/proto/ibc/core/channel/v1/tx.proto index c60ecc4363..5f84264124 100644 --- a/proto/ibc/core/channel/v1/tx.proto +++ b/proto/ibc/core/channel/v1/tx.proto @@ -46,10 +46,9 @@ message MsgChannelOpenInit { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - Channel channel = 3 [(gogoproto.nullable) = false]; - string signer = 4; + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + Channel channel = 2 [(gogoproto.nullable) = false]; + string signer = 3; } // MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. @@ -61,15 +60,16 @@ message MsgChannelOpenTry { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string desired_channel_id = 2 [(gogoproto.moretags) = "yaml:\"desired_channel_id\""]; - string counterparty_chosen_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_channel_id\""]; - Channel channel = 4 [(gogoproto.nullable) = false]; - string counterparty_version = 5 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; - bytes proof_init = 6 [(gogoproto.moretags) = "yaml:\"proof_init\""]; - ibc.core.client.v1.Height proof_height = 7 + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // in the case of crossing hello's, when both chains call OpenInit, we need the channel identifier + // of the previous channel in state INIT + string previous_channel_id = 2 [(gogoproto.moretags) = "yaml:\"previous_channel_id\""]; + Channel channel = 3 [(gogoproto.nullable) = false]; + string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; + bytes proof_init = 5 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 8; + string signer = 7; } // MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. @@ -147,9 +147,9 @@ message MsgRecvPacket { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; - ibc.core.client.v1.Height proof_height = 3 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; string signer = 4; } @@ -162,9 +162,9 @@ message MsgTimeout { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - ibc.core.client.v1.Height proof_height = 3 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; string signer = 5; @@ -178,10 +178,10 @@ message MsgTimeoutOnClose { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; - ibc.core.client.v1.Height proof_height = 4 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; string signer = 6; @@ -197,7 +197,7 @@ message MsgAcknowledgement { Packet packet = 1 [(gogoproto.nullable) = false]; bytes acknowledgement = 2; - bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; + bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; ibc.core.client.v1.Height proof_height = 4 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; string signer = 5; diff --git a/proto/ibc/core/client/v1/client.proto b/proto/ibc/core/client/v1/client.proto index a5d2b0f19e..11d2195aaf 100644 --- a/proto/ibc/core/client/v1/client.proto +++ b/proto/ibc/core/client/v1/client.proto @@ -52,19 +52,19 @@ message ClientUpdateProposal { // that can be compared against another Height for the purposes of updating and // freezing clients // -// Normally the VersionHeight is incremented at each height while keeping version -// number the same However some consensus algorithms may choose to reset the +// 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 version number is incremented so that height continues to -// be monitonically increasing even as the VersionHeight gets reset +// In these cases, the RevisionNumber is incremented so that height continues to +// be monitonically increasing even as the RevisionHeight gets reset message Height { option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = false; - // the version that the client is currently on - uint64 version_number = 1 [(gogoproto.moretags) = "yaml:\"version_number\""]; - // the height within the given version - uint64 version_height = 2 [(gogoproto.moretags) = "yaml:\"version_height\""]; + // the revision that the client is currently on + uint64 revision_number = 1 [(gogoproto.moretags) = "yaml:\"revision_number\""]; + // the height within the given revision + uint64 revision_height = 2 [(gogoproto.moretags) = "yaml:\"revision_height\""]; } // Params defines the set of IBC light client parameters. diff --git a/proto/ibc/core/client/v1/query.proto b/proto/ibc/core/client/v1/query.proto index 7a1bf50538..97f3acd627 100644 --- a/proto/ibc/core/client/v1/query.proto +++ b/proto/ibc/core/client/v1/query.proto @@ -24,8 +24,8 @@ service Query { // ConsensusState queries a consensus state associated with a client state at // a given height. rpc ConsensusState(QueryConsensusStateRequest) returns (QueryConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1beta1/consensus_states/{client_id}/version/{version_number}/" - "height/{version_height}"; + option (google.api.http).get = "/ibc/core/client/v1beta1/consensus_states/{client_id}/revision/{revision_number}/" + "height/{revision_height}"; } // ConsensusStates queries all the consensus state associated with a given @@ -82,10 +82,10 @@ message QueryClientStatesResponse { message QueryConsensusStateRequest { // client identifier string client_id = 1; - // consensus state version number - uint64 version_number = 2; - // consensus state version height - uint64 version_height = 3; + // consensus state revision number + uint64 revision_number = 2; + // consensus state revision height + uint64 revision_height = 3; // latest_height overrrides the height field and queries the latest stored // ConsensusState bool latest_height = 4; diff --git a/proto/ibc/core/client/v1/tx.proto b/proto/ibc/core/client/v1/tx.proto index fd54a92108..1019e15a03 100644 --- a/proto/ibc/core/client/v1/tx.proto +++ b/proto/ibc/core/client/v1/tx.proto @@ -60,16 +60,21 @@ message MsgUpdateClientResponse {} // MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state message MsgUpgradeClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + // client unique identifier string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; // upgraded client state google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; - // height at which old chain halts and upgrades (i.e last block executed) - Height upgrade_height = 3 [(gogoproto.moretags) = "yaml:\"upgrade_height\""]; + // upgraded consensus state, only contains enough information to serve as a basis of trust in update logic + google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; // proof that old chain committed to new client - bytes proof_upgrade = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade\""]; + bytes proof_upgrade_client = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade_client\""]; + // proof that old chain committed to new consensus state + bytes proof_upgrade_consensus_state = 5 [(gogoproto.moretags) = "yaml:\"proof_upgrade_consensus_state\""]; // signer address - string signer = 5; + string signer = 6; } // MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. diff --git a/proto/ibc/core/connection/v1/genesis.proto b/proto/ibc/core/connection/v1/genesis.proto index 4cc2ab7a5e..11df4ba180 100644 --- a/proto/ibc/core/connection/v1/genesis.proto +++ b/proto/ibc/core/connection/v1/genesis.proto @@ -11,4 +11,6 @@ message GenesisState { repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; repeated ConnectionPaths client_connection_paths = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_connection_paths\""]; + // the sequence for the next generated connection identifier + uint64 next_connection_sequence = 3 [(gogoproto.moretags) = "yaml:\"next_connection_sequence\""]; } diff --git a/proto/ibc/core/connection/v1/query.proto b/proto/ibc/core/connection/v1/query.proto index 9e5b068804..c5085a131f 100644 --- a/proto/ibc/core/connection/v1/query.proto +++ b/proto/ibc/core/connection/v1/query.proto @@ -38,7 +38,7 @@ service Query { // connection. rpc ConnectionConsensusState(QueryConnectionConsensusStateRequest) returns (QueryConnectionConsensusStateResponse) { option (google.api.http).get = "/ibc/core/connection/v1beta1/connections/{connection_id}/consensus_state/" - "version/{version_number}/height/{version_height}"; + "revision/{revision_number}/height/{revision_height}"; } } @@ -118,9 +118,9 @@ message QueryConnectionClientStateResponse { // Query/ConnectionConsensusState RPC method message QueryConnectionConsensusStateRequest { // connection identifier - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - uint64 version_number = 2; - uint64 version_height = 3; + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + uint64 revision_number = 2; + uint64 revision_height = 3; } // QueryConnectionConsensusStateResponse is the response type for the diff --git a/proto/ibc/core/connection/v1/tx.proto b/proto/ibc/core/connection/v1/tx.proto index 02a12b0e31..21c283545d 100644 --- a/proto/ibc/core/connection/v1/tx.proto +++ b/proto/ibc/core/connection/v1/tx.proto @@ -29,11 +29,10 @@ message MsgConnectionOpenInit { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - Counterparty counterparty = 3 [(gogoproto.nullable) = false]; - Version version = 4; - string signer = 5; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + Counterparty counterparty = 2 [(gogoproto.nullable) = false]; + Version version = 3; + string signer = 4; } // MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response type. @@ -45,24 +44,25 @@ message MsgConnectionOpenTry { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - string desired_connection_id = 2 [(gogoproto.moretags) = "yaml:\"desired_connection_id\""]; - string counterparty_chosen_connection_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_connection_id\""]; - google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""]; - Counterparty counterparty = 5 [(gogoproto.nullable) = false]; - repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; - ibc.core.client.v1.Height proof_height = 7 + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // in the case of crossing hello's, when both chains call OpenInit, we need the connection identifier + // of the previous connection in state INIT + string previous_connection_id = 2 [(gogoproto.moretags) = "yaml:\"previous_connection_id\""]; + google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""]; + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + repeated Version counterparty_versions = 5 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; // proof of the initialization the connection on Chain A: `UNITIALIZED -> // INIT` - bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + bytes proof_init = 7 [(gogoproto.moretags) = "yaml:\"proof_init\""]; // proof of client state included in message - bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + bytes proof_client = 8 [(gogoproto.moretags) = "yaml:\"proof_client\""]; // proof of client consensus state - bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; - ibc.core.client.v1.Height consensus_height = 11 + bytes proof_consensus = 9 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; + ibc.core.client.v1.Height consensus_height = 10 [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; - string signer = 12; + string signer = 11; } // MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. diff --git a/proto/ibc/lightclients/solomachine/v1/solomachine.proto b/proto/ibc/lightclients/solomachine/v1/solomachine.proto index 738217fa6c..89686f3b7f 100644 --- a/proto/ibc/lightclients/solomachine/v1/solomachine.proto +++ b/proto/ibc/lightclients/solomachine/v1/solomachine.proto @@ -48,11 +48,11 @@ message Header { // Misbehaviour defines misbehaviour for a solo machine which consists // of a sequence and two signatures over different messages at that sequence. message Misbehaviour { - option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - uint64 sequence = 2; - SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; - SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; + option (gogoproto.goproto_getters) = false; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + uint64 sequence = 2; + SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; + SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; } // SignatureAndData contains a signature and the data signed over to create that diff --git a/proto/ibc/lightclients/tendermint/v1/tendermint.proto b/proto/ibc/lightclients/tendermint/v1/tendermint.proto index 6f9285c057..a6882bf432 100644 --- a/proto/ibc/lightclients/tendermint/v1/tendermint.proto +++ b/proto/ibc/lightclients/tendermint/v1/tendermint.proto @@ -42,8 +42,12 @@ message ClientState { // Proof specifications used in verifying counterparty state repeated ics23.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; - // Path at which next upgraded client will be committed - string upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""]; + // Path at which next upgraded client will be committed. + // Each element corresponds to the key for a single CommitmentProof in the chained proof. + // NOTE: ClientState must stored under `{upgradePath}/{upgradeHeight}/clientState` + // ConsensusState must be stored under `{upgradepath}/{upgradeHeight}/consensusState` + // For SDK chains using the default upgrade module, upgrade_path should be []string{"upgrade", "upgradedIBCState"}` + repeated string upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""]; // This flag, when set to true, will allow governance to recover a client // which has expired @@ -71,7 +75,7 @@ message ConsensusState { // Misbehaviour is a wrapper over two conflicting Headers // that implements Misbehaviour interface expected by ICS-02 message Misbehaviour { - option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_getters) = false; string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; Header header_1 = 2 [(gogoproto.customname) = "Header1", (gogoproto.moretags) = "yaml:\"header_1\""]; diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 6fa3325c79..dd6132095c 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -167,6 +167,7 @@ func txCommand() *cobra.Command { return cmd } +// newApp is an AppCreator func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application { var cache sdk.MultiStorePersistentCache diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index d60028abc5..674e24a008 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -9,6 +9,7 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client" + clientrest "github.com/cosmos/cosmos-sdk/client/rest" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" @@ -19,7 +20,7 @@ import ( const unRegisteredConcreteTypeErr = "unregistered concrete type" -// query accountREST Handler +// QueryAccountRequestHandlerFn is the query accountREST Handler. func QueryAccountRequestHandlerFn(storeName string, clientCtx client.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -206,7 +207,8 @@ func checkSignModeError(w http.ResponseWriter, ctx client.Context, resp interfac rest.WriteErrorResponse(w, http.StatusInternalServerError, "This transaction was created with the new SIGN_MODE_DIRECT signing method, and therefore cannot be displayed"+ " via legacy REST handlers, please use CLI or directly query the Tendermint RPC endpoint to query"+ - " this transaction. gRPC gateway endpoint is "+grpcEndPoint) + " this transaction. gRPC gateway endpoint is "+grpcEndPoint+". Please also see the REST endpoints migration"+ + " guide at "+clientrest.DeprecationURL+".") return err } diff --git a/x/auth/client/rest/rest_test.go b/x/auth/client/rest/rest_test.go index b03b615b6a..889067d852 100644 --- a/x/auth/client/rest/rest_test.go +++ b/x/auth/client/rest/rest_test.go @@ -307,8 +307,8 @@ func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { val := s.network.Validators[0] args := []string{ - "121", // dummy port-id - "21212121212", // dummy channel-id + "121", // dummy port-id + "channel-0", // dummy channel-id fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), diff --git a/x/bank/client/rest/query_test.go b/x/bank/client/rest/query_test.go index bbd803ba75..5ca3a15be5 100644 --- a/x/bank/client/rest/query_test.go +++ b/x/bank/client/rest/query_test.go @@ -29,7 +29,7 @@ func (s *IntegrationTestSuite) SetupSuite() { s.cfg = cfg s.network = network.New(s.T(), cfg) - _, err := s.network.WaitForHeight(1) + _, err := s.network.WaitForHeight(2) s.Require().NoError(err) } @@ -43,14 +43,26 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() { baseURL := val.APIAddress testCases := []struct { - name string - url string - respType fmt.Stringer - expected fmt.Stringer + name string + url string + expHeight int64 + respType fmt.Stringer + expected fmt.Stringer }{ { "total account balance", + fmt.Sprintf("%s/bank/balances/%s", baseURL, val.Address), + -1, + &sdk.Coins{}, + sdk.NewCoins( + sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens), + sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Sub(s.cfg.BondedTokens)), + ), + }, + { + "total account balance with height", fmt.Sprintf("%s/bank/balances/%s?height=1", baseURL, val.Address), + 1, &sdk.Coins{}, sdk.NewCoins( sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens), @@ -59,13 +71,15 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() { }, { "total account balance of a specific denom", - fmt.Sprintf("%s/bank/balances/%s?height=1&denom=%s", baseURL, val.Address, s.cfg.BondDenom), + fmt.Sprintf("%s/bank/balances/%s?denom=%s", baseURL, val.Address, s.cfg.BondDenom), + -1, &sdk.Coin{}, sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Sub(s.cfg.BondedTokens)), }, { "total account balance of a bogus denom", - fmt.Sprintf("%s/bank/balances/%s?height=1&denom=foobar", baseURL, val.Address), + fmt.Sprintf("%s/bank/balances/%s?denom=foobar", baseURL, val.Address), + -1, &sdk.Coin{}, sdk.NewCoin("foobar", sdk.ZeroInt()), }, @@ -74,12 +88,23 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + respJSON, err := rest.GetRequest(tc.url) s.Require().NoError(err) - bz, err := rest.ParseResponseWithHeight(val.ClientCtx.LegacyAmino, resp) + var resp = rest.ResponseWithHeight{} + err = val.ClientCtx.LegacyAmino.UnmarshalJSON(respJSON, &resp) s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(bz, tc.respType)) + + // Check height. + if tc.expHeight >= 0 { + s.Require().Equal(resp.Height, tc.expHeight) + } else { + // To avoid flakiness, just test that height is positive. + s.Require().Greater(resp.Height, int64(0)) + } + + // Check result. + s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(resp.Result, tc.respType)) s.Require().Equal(tc.expected.String(), tc.respType.String()) }) } diff --git a/x/ibc/applications/transfer/client/cli/tx.go b/x/ibc/applications/transfer/client/cli/tx.go index 7f43c97777..1c4fa4e613 100644 --- a/x/ibc/applications/transfer/client/cli/tx.go +++ b/x/ibc/applications/transfer/client/cli/tx.go @@ -29,7 +29,7 @@ func NewTransferTxCmd() *cobra.Command { Short: "Transfer a fungible token through IBC", Long: strings.TrimSpace(`Transfer a fungible token through IBC. Timeouts can be specified as absolute or relative using the "absolute-timeouts" flag. Timeout height can be set by passing in the height string -in the form {version}-{height} using the "packet-timeout-height" flag. Relative timeouts are added to +in the form {revision}-{height} using the "packet-timeout-height" flag. Relative timeouts are added to the block height and block timestamp queried from the latest consensus state corresponding to the counterparty channel. Any timeout set to 0 is disabled.`), Example: fmt.Sprintf("%s tx ibc-transfer transfer [src-port] [src-channel] [receiver] [amount]", version.AppName), @@ -85,8 +85,8 @@ to the counterparty channel. Any timeout set to 0 is disabled.`), if !timeoutHeight.IsZero() { absoluteHeight := height - absoluteHeight.VersionNumber += timeoutHeight.VersionNumber - absoluteHeight.VersionHeight += timeoutHeight.VersionHeight + absoluteHeight.RevisionNumber += timeoutHeight.RevisionNumber + absoluteHeight.RevisionHeight += timeoutHeight.RevisionHeight timeoutHeight = absoluteHeight } diff --git a/x/ibc/applications/transfer/keeper/relay_test.go b/x/ibc/applications/transfer/keeper/relay_test.go index 7878c59357..9f30317517 100644 --- a/x/ibc/applications/transfer/keeper/relay_test.go +++ b/x/ibc/applications/transfer/keeper/relay_test.go @@ -51,8 +51,8 @@ func (suite *KeeperTestSuite) TestSendTransfer() { {"next seq send not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA = connA.NextTestChannel(ibctesting.TransferPort) - channelB = connB.NextTestChannel(ibctesting.TransferPort) + channelA = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB = suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // manually create channel so next seq send is never set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainA.GetContext(), diff --git a/x/ibc/applications/transfer/module_test.go b/x/ibc/applications/transfer/module_test.go index b0d0fd10e4..b6ce1077c6 100644 --- a/x/ibc/applications/transfer/module_test.go +++ b/x/ibc/applications/transfer/module_test.go @@ -33,7 +33,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() { }, { "invalid port ID", func() { - testChannel = connA.NextTestChannel(ibctesting.MockPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.MockPort) }, false, }, { @@ -56,7 +56,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterparty := channeltypes.NewCounterparty(testChannel.PortID, testChannel.ID) channel = &channeltypes.Channel{ State: channeltypes.INIT, @@ -122,7 +122,7 @@ func (suite *TransferTestSuite) TestOnChanOpenTry() { }, { "invalid port ID", func() { - testChannel = connA.NextTestChannel(ibctesting.MockPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.MockPort) }, false, }, { @@ -144,7 +144,7 @@ func (suite *TransferTestSuite) TestOnChanOpenTry() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterparty := channeltypes.NewCounterparty(testChannel.PortID, testChannel.ID) channel = &channeltypes.Channel{ State: channeltypes.TRYOPEN, @@ -210,7 +210,7 @@ func (suite *TransferTestSuite) TestOnChanOpenAck() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterpartyVersion = types.Version module, _, err := suite.chainA.App.IBCKeeper.PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.TransferPort) diff --git a/x/ibc/applications/transfer/types/msgs_test.go b/x/ibc/applications/transfer/types/msgs_test.go index 4c9eb80acd..89bd39524a 100644 --- a/x/ibc/applications/transfer/types/msgs_test.go +++ b/x/ibc/applications/transfer/types/msgs_test.go @@ -19,7 +19,7 @@ const ( validChannel = "testchannel" invalidChannel = "(invalidchannel1)" - invalidShortChannel = "invalidch" + invalidShortChannel = "invalid" invalidLongChannel = "invalidlongchannelinvalidlongchannelinvalidlongchannelinvalidlongchannel" ) diff --git a/x/ibc/core/02-client/abci_test.go b/x/ibc/core/02-client/abci_test.go index fe9016750f..3a296618b3 100644 --- a/x/ibc/core/02-client/abci_test.go +++ b/x/ibc/core/02-client/abci_test.go @@ -28,9 +28,9 @@ func (suite *ClientTestSuite) SetupTest() { suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1)) // set localhost client - version := types.ParseChainID(suite.chainA.GetContext().ChainID()) + revision := types.ParseChainID(suite.chainA.GetContext().ChainID()) localHostClient := localhosttypes.NewClientState( - suite.chainA.GetContext().ChainID(), types.NewHeight(version, uint64(suite.chainA.GetContext().BlockHeight())), + suite.chainA.GetContext().ChainID(), types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())), ) suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), exported.Localhost, localHostClient) } diff --git a/x/ibc/core/02-client/client/utils/utils.go b/x/ibc/core/02-client/client/utils/utils.go index 200f6423fd..1a7bc003bc 100644 --- a/x/ibc/core/02-client/client/utils/utils.go +++ b/x/ibc/core/02-client/client/utils/utils.go @@ -77,10 +77,10 @@ func QueryConsensusState( queryClient := types.NewQueryClient(clientCtx) req := &types.QueryConsensusStateRequest{ - ClientId: clientID, - VersionNumber: height.GetVersionNumber(), - VersionHeight: height.GetVersionHeight(), - LatestHeight: latestHeight, + ClientId: clientID, + RevisionNumber: height.GetRevisionNumber(), + RevisionHeight: height.GetRevisionHeight(), + LatestHeight: latestHeight, } return queryClient.ConsensusState(context.Background(), req) diff --git a/x/ibc/core/02-client/genesis.go b/x/ibc/core/02-client/genesis.go index 988e297c18..ef00930f0b 100644 --- a/x/ibc/core/02-client/genesis.go +++ b/x/ibc/core/02-client/genesis.go @@ -50,9 +50,9 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { } // client id is always "localhost" - version := types.ParseChainID(ctx.ChainID()) + revision := types.ParseChainID(ctx.ChainID()) clientState := localhosttypes.NewClientState( - ctx.ChainID(), types.NewHeight(version, uint64(ctx.BlockHeight())), + ctx.ChainID(), types.NewHeight(revision, uint64(ctx.BlockHeight())), ) if err := clientState.Validate(); err != nil { diff --git a/x/ibc/core/02-client/keeper/client.go b/x/ibc/core/02-client/keeper/client.go index 5a6bb78d24..ddb742563c 100644 --- a/x/ibc/core/02-client/keeper/client.go +++ b/x/ibc/core/02-client/keeper/client.go @@ -107,7 +107,8 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H // UpgradeClient upgrades the client to a new client state if this new client was committed to // by the old client at the specified upgrade height -func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient exported.ClientState, upgradeHeight exported.Height, proofUpgrade []byte) error { +func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient exported.ClientState, upgradedConsState exported.ConsensusState, + proofUpgradeClient, proofUpgradeConsState []byte) error { clientState, found := k.GetClientState(ctx, clientID) if !found { return sdkerrors.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID) @@ -118,13 +119,14 @@ func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient e return sdkerrors.Wrapf(types.ErrClientFrozen, "cannot update client with ID %s", clientID) } - updatedClientState, updatedConsensusState, err := clientState.VerifyUpgradeAndUpdateState(ctx, k.cdc, k.ClientStore(ctx, clientID), upgradedClient, upgradeHeight, proofUpgrade) + updatedClientState, updatedConsState, err := clientState.VerifyUpgradeAndUpdateState(ctx, k.cdc, k.ClientStore(ctx, clientID), + upgradedClient, upgradedConsState, proofUpgradeClient, proofUpgradeConsState) if err != nil { return sdkerrors.Wrapf(err, "cannot upgrade client with ID %s", clientID) } k.SetClientState(ctx, clientID, updatedClientState) - k.SetClientConsensusState(ctx, clientID, updatedClientState.GetLatestHeight(), updatedConsensusState) + k.SetClientConsensusState(ctx, clientID, updatedClientState.GetLatestHeight(), updatedConsState) k.Logger(ctx).Info("client state upgraded", "client-id", clientID, "height", updatedClientState.GetLatestHeight().String()) diff --git a/x/ibc/core/02-client/keeper/client_test.go b/x/ibc/core/02-client/keeper/client_test.go index c2f5c8144a..736a34d1e4 100644 --- a/x/ibc/core/02-client/keeper/client_test.go +++ b/x/ibc/core/02-client/keeper/client_test.go @@ -56,17 +56,17 @@ func (suite *KeeperTestSuite) TestCreateClient() { func (suite *KeeperTestSuite) TestUpdateClientTendermint() { // Must create header creation functions since suite.header gets recreated on each test case createFutureUpdateFn := func(s *KeeperTestSuite) *ibctmtypes.Header { - heightPlus3 := clienttypes.NewHeight(suite.header.GetHeight().GetVersionNumber(), suite.header.GetHeight().GetVersionHeight()+3) + heightPlus3 := clienttypes.NewHeight(suite.header.GetHeight().GetRevisionNumber(), suite.header.GetHeight().GetRevisionHeight()+3) height := suite.header.GetHeight().(clienttypes.Height) - return suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus3.VersionHeight), height, suite.header.Header.Time.Add(time.Hour), + return suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus3.RevisionHeight), height, suite.header.Header.Time.Add(time.Hour), suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } createPastUpdateFn := func(s *KeeperTestSuite) *ibctmtypes.Header { - heightMinus2 := clienttypes.NewHeight(suite.header.GetHeight().GetVersionNumber(), suite.header.GetHeight().GetVersionHeight()-2) - heightMinus4 := clienttypes.NewHeight(suite.header.GetHeight().GetVersionNumber(), suite.header.GetHeight().GetVersionHeight()-4) + heightMinus2 := clienttypes.NewHeight(suite.header.GetHeight().GetRevisionNumber(), suite.header.GetHeight().GetRevisionHeight()-2) + heightMinus4 := clienttypes.NewHeight(suite.header.GetHeight().GetRevisionNumber(), suite.header.GetHeight().GetRevisionHeight()-4) - return suite.chainA.CreateTMClientHeader(testChainID, int64(heightMinus2.VersionHeight), heightMinus4, suite.header.Header.Time, + return suite.chainA.CreateTMClientHeader(testChainID, int64(heightMinus2.RevisionHeight), heightMinus4, suite.header.Header.Time, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } var ( @@ -146,7 +146,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { }, false}, {"valid past update before client was frozen", func() error { clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientState.FrozenHeight = types.NewHeight(0, testClientHeight.VersionHeight-1) + clientState.FrozenHeight = types.NewHeight(0, testClientHeight.RevisionHeight-1) err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState) suite.Require().NoError(err) @@ -221,8 +221,8 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { } func (suite *KeeperTestSuite) TestUpdateClientLocalhost() { - version := types.ParseChainID(suite.chainA.ChainID) - var localhostClient exported.ClientState = localhosttypes.NewClientState(suite.chainA.ChainID, types.NewHeight(version, uint64(suite.chainA.GetContext().BlockHeight()))) + revision := types.ParseChainID(suite.chainA.ChainID) + var localhostClient exported.ClientState = localhosttypes.NewClientState(suite.chainA.ChainID, types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight()))) ctx := suite.chainA.GetContext().WithBlockHeight(suite.chainA.GetContext().BlockHeight() + 1) err := suite.chainA.App.IBCKeeper.ClientKeeper.UpdateClient(ctx, exported.Localhost, nil) @@ -235,10 +235,11 @@ func (suite *KeeperTestSuite) TestUpdateClientLocalhost() { func (suite *KeeperTestSuite) TestUpgradeClient() { var ( - upgradedClient exported.ClientState - upgradeHeight exported.Height - clientA string - proofUpgrade []byte + upgradedClient exported.ClientState + upgradedConsState exported.ConsensusState + lastHeight exported.Height + clientA string + proofUpgradedClient, proofUpgradedConsState []byte ) testCases := []struct { @@ -251,12 +252,16 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { setup: func() { upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -267,7 +272,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: true, }, @@ -276,12 +282,16 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { setup: func() { upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -292,7 +302,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) clientA = "wrongclientid" }, @@ -303,12 +314,16 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { setup: func() { upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -319,7 +334,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) // set frozen client in store tmClient, ok := cs.(*ibctmtypes.ClientState) @@ -334,12 +350,16 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { setup: func() { upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // change upgradedClient client-specified parameters upgradedClient = ibctmtypes.NewClientState("wrongchainID", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, true, true) @@ -351,7 +371,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -363,7 +384,10 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { tc.setup() - err := suite.chainA.App.IBCKeeper.ClientKeeper.UpgradeClient(suite.chainA.GetContext(), clientA, upgradedClient, upgradeHeight, proofUpgrade) + // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient + upgradedClient = upgradedClient.ZeroCustomFields() + + err := suite.chainA.App.IBCKeeper.ClientKeeper.UpgradeClient(suite.chainA.GetContext(), clientA, upgradedClient, upgradedConsState, proofUpgradedClient, proofUpgradedConsState) if tc.expPass { suite.Require().NoError(err, "verify upgrade failed on valid case: %s", tc.name) @@ -411,8 +435,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusting period misbehavior should pass", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ClientId: testClientID, }, func() error { @@ -427,8 +451,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehavior at later height should pass", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), ClientId: testClientID, }, func() error { @@ -453,8 +477,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehavior at later height with different trusted heights should pass", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ClientId: testClientID, }, func() error { @@ -479,8 +503,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusted ConsensusState1 not found", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), heightPlus3, altTime, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, altTime, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), ClientId: testClientID, }, func() error { @@ -495,8 +519,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusted ConsensusState2 not found", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ClientId: testClientID, }, func() error { @@ -517,8 +541,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "client already frozen at earlier height", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ClientId: testClientID, }, func() error { @@ -536,8 +560,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehaviour check failed", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners), ClientId: testClientID, }, func() error { diff --git a/x/ibc/core/02-client/keeper/grpc_query.go b/x/ibc/core/02-client/keeper/grpc_query.go index 9f4bb6c808..f14507d8ce 100644 --- a/x/ibc/core/02-client/keeper/grpc_query.go +++ b/x/ibc/core/02-client/keeper/grpc_query.go @@ -112,11 +112,11 @@ func (q Keeper) ConsensusState(c context.Context, req *types.QueryConsensusState found bool ) - height := types.NewHeight(req.VersionNumber, req.VersionHeight) + height := types.NewHeight(req.RevisionNumber, req.RevisionHeight) if req.LatestHeight { consensusState, found = q.GetLatestClientConsensusState(ctx, req.ClientId) } else { - if req.VersionHeight == 0 { + if req.RevisionHeight == 0 { return nil, status.Error(codes.InvalidArgument, "consensus state height cannot be 0") } diff --git a/x/ibc/core/02-client/keeper/grpc_query_test.go b/x/ibc/core/02-client/keeper/grpc_query_test.go index a252005fc9..d8125198e2 100644 --- a/x/ibc/core/02-client/keeper/grpc_query_test.go +++ b/x/ibc/core/02-client/keeper/grpc_query_test.go @@ -184,8 +184,8 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() { func() { req = &types.QueryConsensusStateRequest{ ClientId: testClientID, - VersionNumber: 0, - VersionHeight: 0, + RevisionNumber: 0, + RevisionHeight: 0, LatestHeight: false, } }, @@ -236,8 +236,8 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() { req = &types.QueryConsensusStateRequest{ ClientId: testClientID, - VersionNumber: 0, - VersionHeight: height, + RevisionNumber: 0, + RevisionHeight: height, } }, true, diff --git a/x/ibc/core/02-client/keeper/keeper.go b/x/ibc/core/02-client/keeper/keeper.go index 7ebfa33555..accf48bb14 100644 --- a/x/ibc/core/02-client/keeper/keeper.go +++ b/x/ibc/core/02-client/keeper/keeper.go @@ -2,7 +2,6 @@ package keeper import ( "fmt" - "net/url" "reflect" "strings" @@ -168,18 +167,18 @@ func (k Keeper) GetLatestClientConsensusState(ctx sdk.Context, clientID string) // GetSelfConsensusState introspects the (self) past historical info at a given height // and returns the expected consensus state at that height. -// For now, can only retrieve self consensus states for the current version +// For now, can only retrieve self consensus states for the current revision func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height exported.Height) (exported.ConsensusState, bool) { selfHeight, ok := height.(types.Height) if !ok { return nil, false } - // check that height version matches chainID version - version := types.ParseChainID(ctx.ChainID()) - if version != height.GetVersionNumber() { + // check that height revision matches chainID revision + revision := types.ParseChainID(ctx.ChainID()) + if revision != height.GetRevisionNumber() { return nil, false } - histInfo, found := k.stakingKeeper.GetHistoricalInfo(ctx, int64(selfHeight.VersionHeight)) + histInfo, found := k.stakingKeeper.GetHistoricalInfo(ctx, int64(selfHeight.RevisionHeight)) if !found { return nil, false } @@ -194,7 +193,7 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height exported.Height) ( // ValidateSelfClient validates the client parameters for a client of the running chain // This function is only used to validate the client state the counterparty stores for this chain -// Client must be in same version as the executing chain +// Client must be in same revision as the executing chain func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error { tmClient, ok := clientState.(*ibctmtypes.ClientState) if !ok { @@ -211,15 +210,15 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS ctx.ChainID(), tmClient.ChainId) } - version := types.ParseChainID(ctx.ChainID()) + revision := types.ParseChainID(ctx.ChainID()) - // client must be in the same version as executing chain - if tmClient.LatestHeight.VersionNumber != version { - return sdkerrors.Wrapf(types.ErrInvalidClient, "client is not in the same version as the chain. expected version: %d, got: %d", - tmClient.LatestHeight.VersionNumber, version) + // client must be in the same revision as executing chain + if tmClient.LatestHeight.RevisionNumber != revision { + return sdkerrors.Wrapf(types.ErrInvalidClient, "client is not in the same revision as the chain. expected revision: %d, got: %d", + tmClient.LatestHeight.RevisionNumber, revision) } - selfHeight := types.NewHeight(version, uint64(ctx.BlockHeight())) + selfHeight := types.NewHeight(revision, uint64(ctx.BlockHeight())) if tmClient.LatestHeight.GTE(selfHeight) { return sdkerrors.Wrapf(types.ErrInvalidClient, "client has LatestHeight %d greater than or equal to chain height %d", tmClient.LatestHeight, selfHeight) @@ -246,13 +245,11 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS tmClient.UnbondingPeriod, tmClient.TrustingPeriod) } - if tmClient.UpgradePath != "" { + if len(tmClient.UpgradePath) != 0 { // For now, SDK IBC implementation assumes that upgrade path (if defined) is defined by SDK upgrade module - // Must escape any merkle key before adding it to upgrade path - upgradeKey := url.PathEscape(upgradetypes.KeyUpgradedClient) - expectedUpgradePath := fmt.Sprintf("%s/%s", upgradetypes.StoreKey, upgradeKey) - if tmClient.UpgradePath != expectedUpgradePath { - return sdkerrors.Wrapf(types.ErrInvalidClient, "upgrade path must be the upgrade path defined by upgrade module. expected %s, got %s", + expectedUpgradePath := []string{upgradetypes.StoreKey, upgradetypes.KeyUpgradedIBCState} + if !reflect.DeepEqual(expectedUpgradePath, tmClient.UpgradePath) { + return sdkerrors.Wrapf(types.ErrInvalidClient, "upgrade path must be the upgrade path defined by upgrade module. expected %v, got %v", expectedUpgradePath, tmClient.UpgradePath) } } diff --git a/x/ibc/core/02-client/keeper/keeper_test.go b/x/ibc/core/02-client/keeper/keeper_test.go index c031ac37c9..45ff4f674e 100644 --- a/x/ibc/core/02-client/keeper/keeper_test.go +++ b/x/ibc/core/02-client/keeper/keeper_test.go @@ -27,8 +27,8 @@ import ( ) const ( - testChainID = "gaiahub-0" - testChainIDVersion1 = "gaiahub-1" + testChainID = "gaiahub-0" + testChainIDRevision1 = "gaiahub-1" testClientID = "gaiachain" testClientID2 = "ethbridge" @@ -42,9 +42,9 @@ const ( ) var ( - testClientHeight = types.NewHeight(0, 5) - testClientHeightVersion1 = types.NewHeight(1, 5) - newClientHeight = types.NewHeight(1, 1) + testClientHeight = types.NewHeight(0, 5) + testClientHeightRevision1 = types.NewHeight(1, 5) + newClientHeight = types.NewHeight(1, 1) ) type KeeperTestSuite struct { @@ -94,7 +94,7 @@ func (suite *KeeperTestSuite) SetupTest() { validator := tmtypes.NewValidator(pubKey, 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) suite.valSetHash = suite.valSet.Hash() - suite.header = suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeightMinus1, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeightMinus1, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.consensusState = ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("hash")), suite.valSetHash) var validators stakingtypes.Validators @@ -116,9 +116,9 @@ func (suite *KeeperTestSuite) SetupTest() { } // add localhost client - version := types.ParseChainID(suite.chainA.ChainID) + revision := types.ParseChainID(suite.chainA.ChainID) localHostClient := localhosttypes.NewClientState( - suite.chainA.ChainID, types.NewHeight(version, uint64(suite.chainA.GetContext().BlockHeight())), + suite.chainA.ChainID, types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())), ) suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), exported.Localhost, localHostClient) @@ -166,7 +166,7 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { }, { "success with nil UpgradePath", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), "", false, false), + ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), nil, false, false), true, }, { @@ -190,8 +190,8 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { false, }, { - "invalid client version", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightVersion1, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + "invalid client revision", + ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightRevision1, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), false, }, { @@ -216,7 +216,7 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { }, { "invalid upgrade path", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), "bad/upgrade/path", false, false), + ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), []string{"bad", "upgrade", "path"}, false, false), false, }, } @@ -295,7 +295,7 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() { testClientHeightPlus5 := types.NewHeight(0, height+5) - header := suite.chainA.CreateTMClientHeader(testClientID, int64(testClientHeightPlus5.VersionHeight), testClientHeight, suite.header.Header.Time.Add(time.Minute), + header := suite.chainA.CreateTMClientHeader(testClientID, int64(testClientHeightPlus5.RevisionHeight), testClientHeight, suite.header.Header.Time.Add(time.Minute), suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) // mock update functionality diff --git a/x/ibc/core/02-client/types/client.pb.go b/x/ibc/core/02-client/types/client.pb.go index 95fc58c339..f6233435ca 100644 --- a/x/ibc/core/02-client/types/client.pb.go +++ b/x/ibc/core/02-client/types/client.pb.go @@ -242,16 +242,16 @@ var xxx_messageInfo_ClientUpdateProposal proto.InternalMessageInfo // that can be compared against another Height for the purposes of updating and // freezing clients // -// Normally the VersionHeight is incremented at each height while keeping version -// number the same However some consensus algorithms may choose to reset the +// 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 version number is incremented so that height continues to -// be monitonically increasing even as the VersionHeight gets reset +// In these cases, the RevisionNumber is incremented so that height continues to +// be monitonically increasing even as the RevisionHeight gets reset type Height struct { - // the version that the client is currently on - VersionNumber uint64 `protobuf:"varint,1,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty" yaml:"version_number"` - // the height within the given version - VersionHeight uint64 `protobuf:"varint,2,opt,name=version_height,json=versionHeight,proto3" json:"version_height,omitempty" yaml:"version_height"` + // the revision that the client is currently on + RevisionNumber uint64 `protobuf:"varint,1,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty" yaml:"revision_number"` + // the height within the given revision + RevisionHeight uint64 `protobuf:"varint,2,opt,name=revision_height,json=revisionHeight,proto3" json:"revision_height,omitempty" yaml:"revision_height"` } func (m *Height) Reset() { *m = Height{} } @@ -344,44 +344,43 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/client.proto", fileDescriptor_b6bc4c8185546947) } var fileDescriptor_b6bc4c8185546947 = []byte{ - // 579 bytes of a gzipped FileDescriptorProto + // 574 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xbd, 0x8e, 0xd3, 0x4c, - 0x14, 0xcd, 0x6c, 0xf2, 0x45, 0x9b, 0xc9, 0x47, 0xb2, 0x32, 0x09, 0xeb, 0x4d, 0x61, 0x47, 0x53, - 0xa5, 0xd8, 0xb5, 0x49, 0x28, 0x40, 0xa9, 0xc0, 0x69, 0xd8, 0x02, 0x14, 0x8c, 0x10, 0x88, 0x26, - 0xf2, 0xcf, 0xac, 0x33, 0xc2, 0xf1, 0x44, 0x9e, 0x49, 0xd8, 0xbc, 0x01, 0x25, 0x15, 0xa2, 0xa0, - 0xe0, 0x09, 0xe8, 0x78, 0x03, 0x8a, 0x2d, 0xb7, 0xa4, 0xb2, 0x50, 0xf2, 0x06, 0x79, 0x02, 0x64, - 0xcf, 0xec, 0x66, 0x1d, 0x88, 0xb4, 0xa2, 0xf2, 0x9d, 0x7b, 0xaf, 0xcf, 0x3d, 0xe7, 0xdc, 0xd1, - 0x40, 0x9d, 0xb8, 0x9e, 0xe9, 0xd1, 0x18, 0x9b, 0x5e, 0x48, 0x70, 0xc4, 0xcd, 0x79, 0x57, 0x46, - 0xc6, 0x34, 0xa6, 0x9c, 0x2a, 0x0a, 0x71, 0x3d, 0x23, 0x6d, 0x30, 0x64, 0x7a, 0xde, 0x6d, 0x35, - 0x02, 0x1a, 0xd0, 0xac, 0x6c, 0xa6, 0x91, 0xe8, 0x6c, 0x1d, 0x05, 0x94, 0x06, 0x21, 0x36, 0xb3, - 0x93, 0x3b, 0x3b, 0x33, 0x9d, 0x68, 0x21, 0x4a, 0xe8, 0x0b, 0x80, 0xcd, 0x53, 0x1f, 0x47, 0x9c, - 0x9c, 0x11, 0xec, 0x0f, 0x32, 0xa0, 0x97, 0xdc, 0xe1, 0x58, 0xe9, 0xc2, 0x8a, 0xc0, 0x1d, 0x11, - 0x5f, 0x05, 0x6d, 0xd0, 0xa9, 0x58, 0x8d, 0x75, 0xa2, 0x1f, 0x2c, 0x9c, 0x49, 0xd8, 0x47, 0xd7, - 0x25, 0x64, 0xef, 0x8b, 0xf8, 0xd4, 0x57, 0x86, 0xf0, 0x7f, 0x99, 0x67, 0x29, 0x84, 0xba, 0xd7, - 0x06, 0x9d, 0x6a, 0xaf, 0x61, 0x88, 0xf1, 0xc6, 0xd5, 0x78, 0xe3, 0x49, 0xb4, 0xb0, 0x0e, 0xd7, - 0x89, 0x7e, 0x37, 0x87, 0x95, 0xfd, 0x83, 0xec, 0xaa, 0xb7, 0x21, 0x81, 0xbe, 0x01, 0xa8, 0x0e, - 0x68, 0xc4, 0x70, 0xc4, 0x66, 0x2c, 0x4b, 0xbd, 0x26, 0x7c, 0xfc, 0x14, 0x93, 0x60, 0xcc, 0x95, - 0x47, 0xb0, 0x3c, 0xce, 0xa2, 0x8c, 0x5e, 0xb5, 0xd7, 0x32, 0xfe, 0x74, 0xc4, 0x10, 0xbd, 0x56, - 0xe9, 0x22, 0xd1, 0x0b, 0xb6, 0xec, 0x57, 0xde, 0xc0, 0xba, 0x77, 0x85, 0x7a, 0x0b, 0xae, 0x47, - 0xeb, 0x44, 0x6f, 0xa6, 0x5c, 0xd1, 0xd6, 0x5f, 0xc8, 0xae, 0x79, 0x39, 0x76, 0xe8, 0x07, 0x80, - 0x4d, 0xe1, 0x62, 0x9e, 0x36, 0xfb, 0x17, 0x3f, 0xcf, 0xe1, 0xc1, 0xd6, 0x40, 0xa6, 0xee, 0xb5, - 0x8b, 0x9d, 0x6a, 0xef, 0xf8, 0x6f, 0x52, 0x77, 0x19, 0x65, 0xe9, 0xa9, 0xf8, 0x75, 0xa2, 0x1f, - 0xca, 0x59, 0x5b, 0x98, 0xc8, 0xae, 0xe7, 0x55, 0x30, 0xf4, 0x1d, 0xc0, 0x86, 0x90, 0xf1, 0x6a, - 0xea, 0x3b, 0x1c, 0x0f, 0x63, 0x3a, 0xa5, 0xcc, 0x09, 0x95, 0x06, 0xfc, 0x8f, 0x13, 0x1e, 0x62, - 0xa1, 0xc0, 0x16, 0x07, 0xa5, 0x0d, 0xab, 0x3e, 0x66, 0x5e, 0x4c, 0xa6, 0x9c, 0xd0, 0x28, 0xf3, - 0xb2, 0x62, 0xdf, 0x4c, 0xe5, 0xd5, 0x17, 0x6f, 0xa5, 0xfe, 0x38, 0x5d, 0xaf, 0xe3, 0xe3, 0x58, - 0x2d, 0xed, 0xde, 0x8d, 0x2d, 0x7b, 0xfa, 0xa5, 0x0f, 0x5f, 0xf5, 0x02, 0xfa, 0x04, 0x60, 0x59, - 0xde, 0x8e, 0xc7, 0xb0, 0x36, 0xc7, 0x31, 0x23, 0x34, 0x1a, 0x45, 0xb3, 0x89, 0x8b, 0xe3, 0x8c, - 0x72, 0x69, 0xb3, 0xcc, 0x3e, 0xca, 0xd7, 0x91, 0x7d, 0x47, 0x26, 0x9e, 0x67, 0xe7, 0x9b, 0x08, - 0xf2, 0x9e, 0xed, 0xed, 0x42, 0x10, 0xf5, 0x0d, 0x82, 0xe0, 0xd0, 0xdf, 0x4f, 0x49, 0x7d, 0x4e, - 0x89, 0x3d, 0x83, 0xe5, 0xa1, 0x13, 0x3b, 0x13, 0xa6, 0x0c, 0x60, 0xdd, 0x09, 0x43, 0xfa, 0x1e, - 0xfb, 0x23, 0x21, 0x95, 0xa9, 0xa0, 0x5d, 0xec, 0x54, 0xac, 0xd6, 0x3a, 0xd1, 0xef, 0x09, 0xd8, - 0xad, 0x06, 0x64, 0xd7, 0x64, 0x46, 0xec, 0x84, 0x59, 0x2f, 0x2e, 0x96, 0x1a, 0xb8, 0x5c, 0x6a, - 0xe0, 0xd7, 0x52, 0x03, 0x1f, 0x57, 0x5a, 0xe1, 0x72, 0xa5, 0x15, 0x7e, 0xae, 0xb4, 0xc2, 0xdb, - 0x87, 0x01, 0xe1, 0xe3, 0x99, 0x6b, 0x78, 0x74, 0x62, 0x7a, 0x94, 0x4d, 0x28, 0x93, 0x9f, 0x13, - 0xe6, 0xbf, 0x33, 0xcf, 0xcd, 0xeb, 0x57, 0xe5, 0x7e, 0xef, 0x44, 0x3e, 0x2c, 0x7c, 0x31, 0xc5, - 0xcc, 0x2d, 0x67, 0xb6, 0x3e, 0xf8, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x91, 0xd2, 0x2f, 0x3f, 0x78, - 0x04, 0x00, 0x00, + 0x14, 0x8d, 0x93, 0x7c, 0xd1, 0x66, 0xf2, 0x29, 0x59, 0x99, 0x84, 0xf5, 0xa6, 0xb0, 0xa3, 0xa9, + 0x52, 0xec, 0xda, 0x24, 0x14, 0xa0, 0x74, 0x38, 0x0d, 0x5b, 0x80, 0x82, 0x11, 0x02, 0xd1, 0x44, + 0xfe, 0x99, 0x75, 0x46, 0x38, 0x9e, 0xc8, 0x33, 0x09, 0x9b, 0x37, 0xa0, 0xa4, 0xa4, 0xa0, 0xe0, + 0x09, 0xe8, 0x78, 0x03, 0x8a, 0x2d, 0xb7, 0xa4, 0xb2, 0x50, 0xf2, 0x06, 0x79, 0x02, 0xe4, 0x99, + 0xc9, 0x12, 0x07, 0x22, 0xad, 0xa8, 0x7c, 0x7d, 0xe6, 0xcc, 0xb9, 0xe7, 0xdc, 0x19, 0x0d, 0x30, + 0xb0, 0xe7, 0x5b, 0x3e, 0x49, 0x90, 0xe5, 0x47, 0x18, 0xc5, 0xcc, 0x5a, 0xf4, 0x64, 0x65, 0xce, + 0x12, 0xc2, 0x88, 0xaa, 0x62, 0xcf, 0x37, 0x33, 0x82, 0x29, 0xe1, 0x45, 0xaf, 0xdd, 0x0c, 0x49, + 0x48, 0xf8, 0xb2, 0x95, 0x55, 0x82, 0xd9, 0x3e, 0x0d, 0x09, 0x09, 0x23, 0x64, 0xf1, 0x3f, 0x6f, + 0x7e, 0x69, 0xb9, 0xf1, 0x52, 0x2c, 0xc1, 0xcf, 0x0a, 0x68, 0x5d, 0x04, 0x28, 0x66, 0xf8, 0x12, + 0xa3, 0x60, 0xc8, 0x85, 0x5e, 0x32, 0x97, 0x21, 0xb5, 0x07, 0xaa, 0x42, 0x77, 0x8c, 0x03, 0x4d, + 0xe9, 0x28, 0xdd, 0xaa, 0xdd, 0xdc, 0xa4, 0xc6, 0xf1, 0xd2, 0x9d, 0x46, 0x03, 0x78, 0xbb, 0x04, + 0x9d, 0x23, 0x51, 0x5f, 0x04, 0xea, 0x08, 0xfc, 0x2f, 0x71, 0x9a, 0x49, 0x68, 0xc5, 0x8e, 0xd2, + 0xad, 0xf5, 0x9b, 0xa6, 0x68, 0x6f, 0x6e, 0xdb, 0x9b, 0x4f, 0xe2, 0xa5, 0x7d, 0xb2, 0x49, 0x8d, + 0x7b, 0x39, 0x2d, 0xbe, 0x07, 0x3a, 0x35, 0xff, 0xb7, 0x09, 0xf8, 0x55, 0x01, 0xda, 0x90, 0xc4, + 0x14, 0xc5, 0x74, 0x4e, 0x39, 0xf4, 0x1a, 0xb3, 0xc9, 0x53, 0x84, 0xc3, 0x09, 0x53, 0x1f, 0x83, + 0xca, 0x84, 0x57, 0xdc, 0x5e, 0xad, 0xdf, 0x36, 0xff, 0x9c, 0x88, 0x29, 0xb8, 0x76, 0xf9, 0x3a, + 0x35, 0x0a, 0x8e, 0xe4, 0xab, 0x6f, 0x40, 0xc3, 0xdf, 0xaa, 0xde, 0xc1, 0xeb, 0xe9, 0x26, 0x35, + 0x5a, 0x99, 0x57, 0xb8, 0xb7, 0x0b, 0x3a, 0x75, 0x3f, 0xe7, 0x0e, 0x7e, 0x57, 0x40, 0x4b, 0x4c, + 0x31, 0x6f, 0x9b, 0xfe, 0xcb, 0x3c, 0xaf, 0xc0, 0xf1, 0x5e, 0x43, 0xaa, 0x15, 0x3b, 0xa5, 0x6e, + 0xad, 0x7f, 0xf6, 0xb7, 0xa8, 0x87, 0x06, 0x65, 0x1b, 0x59, 0xf8, 0x4d, 0x6a, 0x9c, 0xc8, 0x5e, + 0x7b, 0x9a, 0xd0, 0x69, 0xe4, 0x53, 0x50, 0xf8, 0x4d, 0x01, 0x4d, 0x11, 0xe3, 0xd5, 0x2c, 0x70, + 0x19, 0x1a, 0x25, 0x64, 0x46, 0xa8, 0x1b, 0xa9, 0x4d, 0xf0, 0x1f, 0xc3, 0x2c, 0x42, 0x22, 0x81, + 0x23, 0x7e, 0xd4, 0x0e, 0xa8, 0x05, 0x88, 0xfa, 0x09, 0x9e, 0x31, 0x4c, 0x62, 0x3e, 0xcb, 0xaa, + 0xb3, 0x0b, 0xe5, 0xd3, 0x97, 0xee, 0x94, 0xfe, 0x2c, 0x3b, 0x5e, 0x37, 0x40, 0x89, 0x56, 0x3e, + 0x7c, 0x36, 0x8e, 0xe4, 0x0c, 0xca, 0x1f, 0xbe, 0x18, 0x85, 0xec, 0x3a, 0x57, 0xe4, 0xed, 0x18, + 0x82, 0x46, 0x82, 0x16, 0x98, 0x62, 0x12, 0x8f, 0xe3, 0xf9, 0xd4, 0x43, 0x09, 0xf7, 0x5c, 0xb6, + 0xdb, 0x9b, 0xd4, 0xb8, 0x2f, 0xfa, 0xee, 0x11, 0xa0, 0x53, 0xdf, 0x22, 0xcf, 0x39, 0x90, 0x13, + 0x91, 0x77, 0xad, 0x78, 0x50, 0x44, 0x10, 0x76, 0x44, 0x84, 0x93, 0xc1, 0x51, 0x66, 0xed, 0x53, + 0x66, 0xef, 0x19, 0xa8, 0x8c, 0xdc, 0xc4, 0x9d, 0xd2, 0x4c, 0xd8, 0x8d, 0x22, 0xf2, 0x1e, 0x05, + 0x63, 0x11, 0x98, 0x6a, 0x4a, 0xa7, 0xd4, 0xad, 0xee, 0x0a, 0xef, 0x11, 0xa0, 0x53, 0x97, 0x88, + 0x38, 0x19, 0x6a, 0xbf, 0xb8, 0x5e, 0xe9, 0xca, 0xcd, 0x4a, 0x57, 0x7e, 0xae, 0x74, 0xe5, 0xe3, + 0x5a, 0x2f, 0xdc, 0xac, 0xf5, 0xc2, 0x8f, 0xb5, 0x5e, 0x78, 0xfb, 0x28, 0xc4, 0x6c, 0x32, 0xf7, + 0x4c, 0x9f, 0x4c, 0x2d, 0x9f, 0xd0, 0x29, 0xa1, 0xf2, 0x73, 0x4e, 0x83, 0x77, 0xd6, 0x95, 0x75, + 0xfb, 0xb6, 0x3c, 0xe8, 0x9f, 0xcb, 0xe7, 0x85, 0x2d, 0x67, 0x88, 0x7a, 0x15, 0x3e, 0xdc, 0x87, + 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x39, 0xbe, 0xfd, 0x04, 0x7e, 0x04, 0x00, 0x00, } func (m *IdentifiedClientState) Marshal() (dAtA []byte, err error) { @@ -591,13 +590,13 @@ func (m *Height) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.VersionHeight != 0 { - i = encodeVarintClient(dAtA, i, uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + i = encodeVarintClient(dAtA, i, uint64(m.RevisionHeight)) i-- dAtA[i] = 0x10 } - if m.VersionNumber != 0 { - i = encodeVarintClient(dAtA, i, uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + i = encodeVarintClient(dAtA, i, uint64(m.RevisionNumber)) i-- dAtA[i] = 0x8 } @@ -729,11 +728,11 @@ func (m *Height) Size() (n int) { } var l int _ = l - if m.VersionNumber != 0 { - n += 1 + sovClient(uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + n += 1 + sovClient(uint64(m.RevisionNumber)) } - if m.VersionHeight != 0 { - n += 1 + sovClient(uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + n += 1 + sovClient(uint64(m.RevisionHeight)) } return n } @@ -1337,9 +1336,9 @@ func (m *Height) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionNumber", wireType) } - m.VersionNumber = 0 + m.RevisionNumber = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowClient @@ -1349,16 +1348,16 @@ func (m *Height) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionNumber |= uint64(b&0x7F) << shift + m.RevisionNumber |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHeight", wireType) } - m.VersionHeight = 0 + m.RevisionHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowClient @@ -1368,7 +1367,7 @@ func (m *Height) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionHeight |= uint64(b&0x7F) << shift + m.RevisionHeight |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ibc/core/02-client/types/codec.go b/x/ibc/core/02-client/types/codec.go index 64b2a3a4f1..8d79dcdaa4 100644 --- a/x/ibc/core/02-client/types/codec.go +++ b/x/ibc/core/02-client/types/codec.go @@ -37,6 +37,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { (*sdk.Msg)(nil), &MsgCreateClient{}, &MsgUpdateClient{}, + &MsgUpgradeClient{}, &MsgSubmitMisbehaviour{}, ) diff --git a/x/ibc/core/02-client/types/genesis.go b/x/ibc/core/02-client/types/genesis.go index fc3ba12d19..4da2f5e920 100644 --- a/x/ibc/core/02-client/types/genesis.go +++ b/x/ibc/core/02-client/types/genesis.go @@ -101,6 +101,12 @@ func (gs GenesisState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { // Validate performs basic genesis state validation returning an error upon any // failure. func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + + validClients := make(map[string]bool) + for i, client := range gs.Clients { if err := host.ClientIdentifierValidator(client.ClientId); err != nil { return fmt.Errorf("invalid client consensus state identifier %s index %d: %w", client.ClientId, i, err) @@ -110,14 +116,22 @@ func (gs GenesisState) Validate() error { if !ok { return fmt.Errorf("invalid client state with ID %s", client.ClientId) } + + if !gs.Params.IsAllowedClient(clientState.ClientType()) { + return fmt.Errorf("client type %s not allowed by genesis params", clientState.ClientType()) + } if err := clientState.Validate(); err != nil { return fmt.Errorf("invalid client %v index %d: %w", client, i, err) } + + // add client id to validClients map + validClients[client.ClientId] = true } for i, cc := range gs.ClientsConsensus { - if err := host.ClientIdentifierValidator(cc.ClientId); err != nil { - return fmt.Errorf("invalid client consensus state identifier %s index %d: %w", cc.ClientId, i, err) + // check that consensus state is for a client in the genesis clients list + if !validClients[cc.ClientId] { + return fmt.Errorf("consensus state in genesis has a client id %s that does not map to a genesis client", cc.ClientId) } for _, consensusState := range cc.ConsensusStates { @@ -136,10 +150,6 @@ func (gs GenesisState) Validate() error { } } - if err := gs.Params.Validate(); err != nil { - return err - } - if gs.CreateLocalhost && !gs.Params.IsAllowedClient(exported.Localhost) { return fmt.Errorf("localhost client is not registered on the allowlist") } diff --git a/x/ibc/core/02-client/types/genesis_test.go b/x/ibc/core/02-client/types/genesis_test.go index d6caca0e68..7d131bae61 100644 --- a/x/ibc/core/02-client/types/genesis_test.go +++ b/x/ibc/core/02-client/types/genesis_test.go @@ -52,7 +52,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) heightMinus1 := types.NewHeight(0, height-1) - header := suite.chainA.CreateTMClientHeader(chainID, int64(clientHeight.VersionHeight), heightMinus1, now, valSet, valSet, []tmtypes.PrivValidator{privVal}) + header := suite.chainA.CreateTMClientHeader(chainID, int64(clientHeight.RevisionHeight), heightMinus1, now, valSet, valSet, []tmtypes.PrivValidator{privVal}) testCases := []struct { name string @@ -88,7 +88,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, ), }, - types.NewParams(exported.Tendermint), + types.NewParams(exported.Tendermint, exported.Localhost), false, ), expPass: true, @@ -106,7 +106,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, []types.ClientConsensusStates{ types.NewClientConsensusStates( - clientID, + "/~@$*", []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), @@ -138,7 +138,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { expPass: false, }, { - name: "invalid consensus state client id", + name: "consensus state client id does not match client id in genesis clients", genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( @@ -150,7 +150,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, []types.ClientConsensusStates{ types.NewClientConsensusStates( - "(CLIENTID2)", + "wrongclientid", []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( types.ZeroHeight(), @@ -224,6 +224,35 @@ func (suite *TypesTestSuite) TestValidateGenesis() { ), expPass: false, }, + { + name: "client in genesis clients is disallowed by params", + genState: types.NewGenesisState( + []types.IdentifiedClientState{ + types.NewIdentifiedClientState( + clientID, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ), + types.NewIdentifiedClientState( + exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight), + ), + }, + []types.ClientConsensusStates{ + types.NewClientConsensusStates( + clientID, + []types.ConsensusStateWithHeight{ + types.NewConsensusStateWithHeight( + header.GetHeight().(types.Height), + ibctmtypes.NewConsensusState( + header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, + ), + ), + }, + ), + }, + types.NewParams(exported.Solomachine), + false, + ), + expPass: false, + }, { name: "invalid params", genState: types.NewGenesisState( diff --git a/x/ibc/core/02-client/types/height.go b/x/ibc/core/02-client/types/height.go index ab156e80de..d507ddea8c 100644 --- a/x/ibc/core/02-client/types/height.go +++ b/x/ibc/core/02-client/types/height.go @@ -14,10 +14,10 @@ import ( var _ exported.Height = (*Height)(nil) -// IsVersionFormat checks if a chainID is in the format required for parsing versions -// The chainID must be in the form: `{chainID}-{version} +// IsRevisionFormat checks if a chainID is in the format required for parsing revisions +// The chainID must be in the form: `{chainID}-{revision} // 24-host may enforce stricter checks on chainID -var IsVersionFormat = regexp.MustCompile(`^.+[^-]-{1}[1-9][0-9]*$`).MatchString +var IsRevisionFormat = regexp.MustCompile(`^.+[^-]-{1}[1-9][0-9]*$`).MatchString // ZeroHeight is a helper function which returns an uninitialized height. func ZeroHeight() Height { @@ -25,21 +25,21 @@ func ZeroHeight() Height { } // NewHeight is a constructor for the IBC height type -func NewHeight(versionNumber, versionHeight uint64) Height { +func NewHeight(revisionNumber, revisionHeight uint64) Height { return Height{ - VersionNumber: versionNumber, - VersionHeight: versionHeight, + RevisionNumber: revisionNumber, + RevisionHeight: revisionHeight, } } -// GetVersionNumber returns the version-number of the height -func (h Height) GetVersionNumber() uint64 { - return h.VersionNumber +// GetRevisionNumber returns the revision-number of the height +func (h Height) GetRevisionNumber() uint64 { + return h.RevisionNumber } -// GetVersionHeight returns the version-height of the height -func (h Height) GetVersionHeight() uint64 { - return h.VersionHeight +// GetRevisionHeight returns the revision-height of the height +func (h Height) GetRevisionHeight() uint64 { + return h.RevisionHeight } // Compare implements a method to compare two heights. When comparing two heights a, b @@ -48,20 +48,20 @@ func (h Height) GetVersionHeight() uint64 { // 0 if a = b // 1 if a > b // -// It first compares based on version numbers, whichever has the higher version number is the higher height -// If version number is the same, then the version height is compared +// It first compares based on revision numbers, whichever has the higher revision number is the higher height +// If revision number is the same, then the revision height is compared func (h Height) Compare(other exported.Height) int64 { height, ok := other.(Height) if !ok { panic(fmt.Sprintf("cannot compare against invalid height type: %T. expected height type: %T", other, h)) } var a, b big.Int - if h.VersionNumber != height.VersionNumber { - a.SetUint64(h.VersionNumber) - b.SetUint64(height.VersionNumber) + if h.RevisionNumber != height.RevisionNumber { + a.SetUint64(h.RevisionNumber) + b.SetUint64(height.RevisionNumber) } else { - a.SetUint64(h.VersionHeight) - b.SetUint64(height.VersionHeight) + a.SetUint64(h.RevisionHeight) + b.SetUint64(height.RevisionHeight) } return int64(a.Cmp(&b)) } @@ -95,27 +95,27 @@ func (h Height) EQ(other exported.Height) bool { // String returns a string representation of Height func (h Height) String() string { - return fmt.Sprintf("%d-%d", h.VersionNumber, h.VersionHeight) + return fmt.Sprintf("%d-%d", h.RevisionNumber, h.RevisionHeight) } -// Decrement will return a new height with the VersionHeight decremented -// If the VersionHeight is already at lowest value (1), then false success flag is returend +// Decrement will return a new height with the RevisionHeight decremented +// If the RevisionHeight is already at lowest value (1), then false success flag is returend func (h Height) Decrement() (decremented exported.Height, success bool) { - if h.VersionHeight == 0 { + if h.RevisionHeight == 0 { return Height{}, false } - return NewHeight(h.VersionNumber, h.VersionHeight-1), true + return NewHeight(h.RevisionNumber, h.RevisionHeight-1), true } -// Increment will return a height with the same version number but an -// incremented version height +// Increment will return a height with the same revision number but an +// incremented revision height func (h Height) Increment() Height { - return NewHeight(h.VersionNumber, h.VersionHeight+1) + return NewHeight(h.RevisionNumber, h.RevisionHeight+1) } -// IsZero returns true if height version and version-height are both 0 +// IsZero returns true if height revision and revision-height are both 0 func (h Height) IsZero() bool { - return h.VersionNumber == 0 && h.VersionHeight == 0 + return h.RevisionNumber == 0 && h.RevisionHeight == 0 } // MustParseHeight will attempt to parse a string representation of a height and panic if @@ -134,55 +134,55 @@ func MustParseHeight(heightStr string) Height { func ParseHeight(heightStr string) (Height, error) { splitStr := strings.Split(heightStr, "-") if len(splitStr) != 2 { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "expected height string format: {version}-{height}. Got: %s", heightStr) + return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "expected height string format: {revision}-{height}. Got: %s", heightStr) } - versionNumber, err := strconv.ParseUint(splitStr[0], 10, 64) + revisionNumber, err := strconv.ParseUint(splitStr[0], 10, 64) if err != nil { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid version number. parse err: %s", err) + return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid revision number. parse err: %s", err) } - versionHeight, err := strconv.ParseUint(splitStr[1], 10, 64) + revisionHeight, err := strconv.ParseUint(splitStr[1], 10, 64) if err != nil { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid version height. parse err: %s", err) + return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid revision height. parse err: %s", err) } - return NewHeight(versionNumber, versionHeight), nil + return NewHeight(revisionNumber, revisionHeight), nil } -// SetVersionNumber takes a chainID in valid version format and swaps the version number -// in the chainID with the given version number. -func SetVersionNumber(chainID string, version uint64) (string, error) { - if !IsVersionFormat(chainID) { +// SetRevisionNumber takes a chainID in valid revision format and swaps the revision number +// in the chainID with the given revision number. +func SetRevisionNumber(chainID string, revision uint64) (string, error) { + if !IsRevisionFormat(chainID) { return "", sdkerrors.Wrapf( - sdkerrors.ErrInvalidChainID, "chainID is not in version format: %s", chainID, + sdkerrors.ErrInvalidChainID, "chainID is not in revision format: %s", chainID, ) } splitStr := strings.Split(chainID, "-") - // swap out version number with given version - splitStr[len(splitStr)-1] = strconv.Itoa(int(version)) + // swap out revision number with given revision + splitStr[len(splitStr)-1] = strconv.Itoa(int(revision)) return strings.Join(splitStr, "-"), nil } -// ParseChainID is a utility function that returns an version number from the given ChainID. -// ParseChainID attempts to parse a chain id in the format: `{chainID}-{version}` -// and return the versionnumber as a uint64. -// If the chainID is not in the expected format, a default version value of 0 is returned. +// ParseChainID is a utility function that returns an revision number from the given ChainID. +// ParseChainID attempts to parse a chain id in the format: `{chainID}-{revision}` +// and return the revisionnumber as a uint64. +// If the chainID is not in the expected format, a default revision value of 0 is returned. func ParseChainID(chainID string) uint64 { - if !IsVersionFormat(chainID) { - // chainID is not in version format, return 0 as default + if !IsRevisionFormat(chainID) { + // chainID is not in revision format, return 0 as default return 0 } splitStr := strings.Split(chainID, "-") - version, err := strconv.ParseUint(splitStr[len(splitStr)-1], 10, 64) + revision, err := strconv.ParseUint(splitStr[len(splitStr)-1], 10, 64) // sanity check: error should always be nil since regex only allows numbers in last element if err != nil { panic(fmt.Sprintf("regex allowed non-number value as last split element for chainID: %s", chainID)) } - return version + return revision } // GetSelfHeight is a utility function that returns self height given context -// Version number is retrieved from ctx.ChainID() +// Revision number is retrieved from ctx.ChainID() func GetSelfHeight(ctx sdk.Context) Height { - version := ParseChainID(ctx.ChainID()) - return NewHeight(version, uint64(ctx.BlockHeight())) + revision := ParseChainID(ctx.ChainID()) + return NewHeight(revision, uint64(ctx.BlockHeight())) } diff --git a/x/ibc/core/02-client/types/height_test.go b/x/ibc/core/02-client/types/height_test.go index 0bd8f0848f..f2615c8c1d 100644 --- a/x/ibc/core/02-client/types/height_test.go +++ b/x/ibc/core/02-client/types/height_test.go @@ -20,12 +20,12 @@ func TestCompareHeights(t *testing.T) { height2 types.Height compareSign int64 }{ - {"version number 1 is lesser", types.NewHeight(1, 3), types.NewHeight(3, 4), -1}, - {"version number 1 is greater", types.NewHeight(7, 5), types.NewHeight(4, 5), 1}, - {"version height 1 is lesser", types.NewHeight(3, 4), types.NewHeight(3, 9), -1}, - {"version height 1 is greater", types.NewHeight(3, 8), types.NewHeight(3, 3), 1}, - {"version number is MaxUint64", types.NewHeight(math.MaxUint64, 1), types.NewHeight(0, 1), 1}, - {"version height is MaxUint64", types.NewHeight(1, math.MaxUint64), types.NewHeight(1, 0), 1}, + {"revision number 1 is lesser", types.NewHeight(1, 3), types.NewHeight(3, 4), -1}, + {"revision number 1 is greater", types.NewHeight(7, 5), types.NewHeight(4, 5), 1}, + {"revision height 1 is lesser", types.NewHeight(3, 4), types.NewHeight(3, 9), -1}, + {"revision height 1 is greater", types.NewHeight(3, 8), types.NewHeight(3, 3), 1}, + {"revision number is MaxUint64", types.NewHeight(math.MaxUint64, 1), types.NewHeight(0, 1), 1}, + {"revision height is MaxUint64", types.NewHeight(1, math.MaxUint64), types.NewHeight(1, 0), 1}, {"height is equal", types.NewHeight(4, 4), types.NewHeight(4, 4), 0}, } @@ -66,11 +66,11 @@ func TestString(t *testing.T) { _, err := types.ParseHeight("height") require.Error(t, err, "invalid height string passed") - _, err = types.ParseHeight("version-10") - require.Error(t, err, "invalid version string passed") + _, err = types.ParseHeight("revision-10") + require.Error(t, err, "invalid revision string passed") _, err = types.ParseHeight("3-height") - require.Error(t, err, "invalid version-height string passed") + require.Error(t, err, "invalid revision-height string passed") height := types.NewHeight(3, 4) recovered, err := types.ParseHeight(height.String()) @@ -100,7 +100,7 @@ func (suite *TypesTestSuite) TestMustParseHeight() { func TestParseChainID(t *testing.T) { cases := []struct { chainID string - version uint64 + revision uint64 formatted bool }{ {"gaiamainnet-3", 3, true}, @@ -114,36 +114,36 @@ func TestParseChainID(t *testing.T) { } for i, tc := range cases { - require.Equal(t, tc.formatted, types.IsVersionFormat(tc.chainID), "case %d does not match expected format", i) + require.Equal(t, tc.formatted, types.IsRevisionFormat(tc.chainID), "case %d does not match expected format", i) - version := types.ParseChainID(tc.chainID) - require.Equal(t, tc.version, version, "case %d returns incorrect version", i) + revision := types.ParseChainID(tc.chainID) + require.Equal(t, tc.revision, revision, "case %d returns incorrect revision", i) } } -func TestSetVersionNumber(t *testing.T) { - // Test SetVersionNumber - chainID, err := types.SetVersionNumber("gaiamainnet", 3) - require.Error(t, err, "invalid version format passed SetVersionNumber") - require.Equal(t, "", chainID, "invalid version format returned non-empty string on SetVersionNumber") +func TestSetRevisionNumber(t *testing.T) { + // Test SetRevisionNumber + chainID, err := types.SetRevisionNumber("gaiamainnet", 3) + require.Error(t, err, "invalid revision format passed SetRevisionNumber") + require.Equal(t, "", chainID, "invalid revision format returned non-empty string on SetRevisionNumber") chainID = "gaiamainnet-3" - chainID, err = types.SetVersionNumber(chainID, 4) - require.NoError(t, err, "valid version format failed SetVersionNumber") - require.Equal(t, "gaiamainnet-4", chainID, "valid version format returned incorrect string on SetVersionNumber") + chainID, err = types.SetRevisionNumber(chainID, 4) + require.NoError(t, err, "valid revision format failed SetRevisionNumber") + require.Equal(t, "gaiamainnet-4", chainID, "valid revision format returned incorrect string on SetRevisionNumber") } func (suite *TypesTestSuite) TestSelfHeight() { ctx := suite.chainA.GetContext() - // Test default version + // Test default revision ctx = ctx.WithChainID("gaiamainnet") ctx = ctx.WithBlockHeight(10) height := types.GetSelfHeight(ctx) suite.Require().Equal(types.NewHeight(0, 10), height, "default self height failed") - // Test successful version format + // Test successful revision format ctx = ctx.WithChainID("gaiamainnet-3") ctx = ctx.WithBlockHeight(18) height = types.GetSelfHeight(ctx) diff --git a/x/ibc/core/02-client/types/msgs.go b/x/ibc/core/02-client/types/msgs.go index 04b351eb26..d1d084ddad 100644 --- a/x/ibc/core/02-client/types/msgs.go +++ b/x/ibc/core/02-client/types/msgs.go @@ -182,23 +182,24 @@ func (msg MsgUpdateClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) err // NewMsgUpgradeClient creates a new MsgUpgradeClient instance // nolint: interfacer -func NewMsgUpgradeClient(clientID string, clientState exported.ClientState, upgradeHeight exported.Height, proofUpgrade []byte, signer sdk.AccAddress) (*MsgUpgradeClient, error) { +func NewMsgUpgradeClient(clientID string, clientState exported.ClientState, consState exported.ConsensusState, + proofUpgradeClient, proofUpgradeConsState []byte, signer sdk.AccAddress) (*MsgUpgradeClient, error) { anyClient, err := PackClientState(clientState) if err != nil { return nil, err } - - height, ok := upgradeHeight.(Height) - if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid height type. expected: %T, got: %T", &Height{}, upgradeHeight) + anyConsState, err := PackConsensusState(consState) + if err != nil { + return nil, err } return &MsgUpgradeClient{ - ClientId: clientID, - ClientState: anyClient, - ProofUpgrade: proofUpgrade, - UpgradeHeight: &height, - Signer: signer.String(), + ClientId: clientID, + ClientState: anyClient, + ConsensusState: anyConsState, + ProofUpgradeClient: proofUpgradeClient, + ProofUpgradeConsensusState: proofUpgradeConsState, + Signer: signer.String(), }, nil } @@ -214,21 +215,28 @@ func (msg MsgUpgradeClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgUpgradeClient) ValidateBasic() error { + // will not validate client state as committed client may not form a valid client state. + // client implementations are responsible for ensuring final upgraded client is valid. clientState, err := UnpackClientState(msg.ClientState) if err != nil { return err } - if err := clientState.Validate(); err != nil { + // will not validate consensus state here since the trusted kernel may not form a valid consenus state. + // client implementations are responsible for ensuring client can submit new headers against this consensus state. + consensusState, err := UnpackConsensusState(msg.ConsensusState) + if err != nil { return err } - if len(msg.ProofUpgrade) == 0 { - return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade cannot be empty") + + if clientState.ClientType() != consensusState.ClientType() { + return sdkerrors.Wrapf(ErrInvalidUpgradeClient, "consensus state's client-type does not match client. expected: %s, got: %s", + clientState.ClientType(), consensusState.ClientType()) } - if msg.UpgradeHeight == nil { - return sdkerrors.Wrap(ErrInvalidUpgradeClient, "upgrade height cannot be nil") + if len(msg.ProofUpgradeClient) == 0 { + return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade client cannot be empty") } - if msg.UpgradeHeight.IsZero() { - return sdkerrors.Wrap(ErrInvalidUpgradeClient, "upgrade height cannot be zero") + if len(msg.ProofUpgradeConsensusState) == 0 { + return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade consensus state cannot be empty") } _, err = sdk.AccAddressFromBech32(msg.Signer) if err != nil { @@ -254,8 +262,14 @@ func (msg MsgUpgradeClient) GetSigners() []sdk.AccAddress { // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (msg MsgUpgradeClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - var clientState exported.ClientState - return unpacker.UnpackAny(msg.ClientState, &clientState) + var ( + clientState exported.ClientState + consState exported.ConsensusState + ) + if err := unpacker.UnpackAny(msg.ClientState, &clientState); err != nil { + return err + } + return unpacker.UnpackAny(msg.ConsensusState, &consState) } // NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance. diff --git a/x/ibc/core/02-client/types/msgs_test.go b/x/ibc/core/02-client/types/msgs_test.go index 7373205cc5..7d2da65d2c 100644 --- a/x/ibc/core/02-client/types/msgs_test.go +++ b/x/ibc/core/02-client/types/msgs_test.go @@ -339,8 +339,6 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { err error ) - newClientHeight := types.NewHeight(1, 1) - testCases := []struct { name string malleate func() @@ -349,7 +347,8 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { "client upgrades to new tendermint client", func() { tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - msg, err = types.NewMsgUpgradeClient("clientid", tendermintClient, newClientHeight, []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress()) + tendermintConsState := &ibctmtypes.ConsensusState{NextValidatorsHash: []byte("nextValsHash")} + msg, err = types.NewMsgUpgradeClient("clientid", tendermintClient, tendermintConsState, []byte("proofUpgradeClient"), []byte("proofUpgradeConsState"), suite.chainA.SenderAccount.GetAddress()) suite.Require().NoError(err) }, }, @@ -357,7 +356,7 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { "client upgrades to new solomachine client", func() { soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 1) - msg, err = types.NewMsgUpgradeClient("clientid", soloMachine.ClientState(), newClientHeight, []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress()) + msg, err = types.NewMsgUpgradeClient("clientid", soloMachine.ClientState(), soloMachine.ConsensusState(), []byte("proofUpgradeClient"), []byte("proofUpgradeConsState"), suite.chainA.SenderAccount.GetAddress()) suite.Require().NoError(err) }, }, @@ -381,8 +380,6 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { newMsg := &types.MsgUpgradeClient{} err = cdc.UnmarshalJSON(bz, newMsg) suite.Require().NoError(err) - - suite.Require().True(proto.Equal(msg, newMsg)) }) } } @@ -412,20 +409,6 @@ func (suite *TypesTestSuite) TestMsgUpgradeClient_ValidateBasic() { }, expPass: false, }, - { - name: "upgrade height is nil", - malleate: func(msg *types.MsgUpgradeClient) { - msg.UpgradeHeight = nil - }, - expPass: false, - }, - { - name: "upgrade height is zero", - malleate: func(msg *types.MsgUpgradeClient) { - msg.UpgradeHeight = &types.Height{} - }, - expPass: false, - }, { name: "unpacking clientstate fails", malleate: func(msg *types.MsgUpgradeClient) { @@ -434,19 +417,33 @@ func (suite *TypesTestSuite) TestMsgUpgradeClient_ValidateBasic() { expPass: false, }, { - name: "invalid client state", + name: "unpacking consensus state fails", malleate: func(msg *types.MsgUpgradeClient) { - cs := &ibctmtypes.ClientState{} - var err error - msg.ClientState, err = types.PackClientState(cs) - suite.Require().NoError(err) + msg.ConsensusState = nil }, expPass: false, }, { - name: "empty proof", + name: "client and consensus type does not match", malleate: func(msg *types.MsgUpgradeClient) { - msg.ProofUpgrade = nil + soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2) + soloConsensus, err := types.PackConsensusState(soloMachine.ConsensusState()) + suite.Require().NoError(err) + msg.ConsensusState = soloConsensus + }, + expPass: false, + }, + { + name: "empty client proof", + malleate: func(msg *types.MsgUpgradeClient) { + msg.ProofUpgradeClient = nil + }, + expPass: false, + }, + { + name: "empty consensus state proof", + malleate: func(msg *types.MsgUpgradeClient) { + msg.ProofUpgradeConsensusState = nil }, expPass: false, }, @@ -463,18 +460,18 @@ func (suite *TypesTestSuite) TestMsgUpgradeClient_ValidateBasic() { tc := tc clientState := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - newClientHeight := types.NewHeight(1, 1) - msg, _ := types.NewMsgUpgradeClient("testclientid", clientState, newClientHeight, []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress()) + consState := &ibctmtypes.ConsensusState{NextValidatorsHash: []byte("nextValsHash")} + msg, err := types.NewMsgUpgradeClient("testclientid", clientState, consState, []byte("proofUpgradeClient"), []byte("proofUpgradeConsState"), suite.chainA.SenderAccount.GetAddress()) + suite.Require().NoError(err) tc.malleate(msg) - err := msg.ValidateBasic() + err = msg.ValidateBasic() if tc.expPass { suite.Require().NoError(err, "valid case %s failed", tc.name) } else { suite.Require().Error(err, "invalid case %s passed", tc.name) } } - } // tests that different misbehaviours within MsgSubmitMisbehaviour can be marshaled @@ -500,8 +497,8 @@ func (suite *TypesTestSuite) TestMarshalMsgSubmitMisbehaviour() { "tendermint client", func() { height := types.NewHeight(0, uint64(suite.chainA.CurrentHeader.Height)) heightMinus1 := types.NewHeight(0, uint64(suite.chainA.CurrentHeader.Height)-1) - header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.VersionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) - header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.VersionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) + header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) + header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) misbehaviour := ibctmtypes.NewMisbehaviour("tendermint", header1, header2) msg, err = types.NewMsgSubmitMisbehaviour("tendermint", misbehaviour, suite.chainA.SenderAccount.GetAddress()) @@ -558,8 +555,8 @@ func (suite *TypesTestSuite) TestMsgSubmitMisbehaviour_ValidateBasic() { func() { height := types.NewHeight(0, uint64(suite.chainA.CurrentHeader.Height)) heightMinus1 := types.NewHeight(0, uint64(suite.chainA.CurrentHeader.Height)-1) - header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.VersionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) - header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.VersionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) + header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) + header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) misbehaviour := ibctmtypes.NewMisbehaviour("tendermint", header1, header2) msg, err = types.NewMsgSubmitMisbehaviour("tendermint", misbehaviour, suite.chainA.SenderAccount.GetAddress()) diff --git a/x/ibc/core/02-client/types/query.pb.go b/x/ibc/core/02-client/types/query.pb.go index 755d401802..afe6670d4b 100644 --- a/x/ibc/core/02-client/types/query.pb.go +++ b/x/ibc/core/02-client/types/query.pb.go @@ -253,10 +253,10 @@ func (m *QueryClientStatesResponse) GetPagination() *query.PageResponse { type QueryConsensusStateRequest struct { // client identifier ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` - // consensus state version number - VersionNumber uint64 `protobuf:"varint,2,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty"` - // consensus state version height - VersionHeight uint64 `protobuf:"varint,3,opt,name=version_height,json=versionHeight,proto3" json:"version_height,omitempty"` + // consensus state revision number + RevisionNumber uint64 `protobuf:"varint,2,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty"` + // consensus state revision height + RevisionHeight uint64 `protobuf:"varint,3,opt,name=revision_height,json=revisionHeight,proto3" json:"revision_height,omitempty"` // latest_height overrrides the height field and queries the latest stored // ConsensusState LatestHeight bool `protobuf:"varint,4,opt,name=latest_height,json=latestHeight,proto3" json:"latest_height,omitempty"` @@ -302,16 +302,16 @@ func (m *QueryConsensusStateRequest) GetClientId() string { return "" } -func (m *QueryConsensusStateRequest) GetVersionNumber() uint64 { +func (m *QueryConsensusStateRequest) GetRevisionNumber() uint64 { if m != nil { - return m.VersionNumber + return m.RevisionNumber } return 0 } -func (m *QueryConsensusStateRequest) GetVersionHeight() uint64 { +func (m *QueryConsensusStateRequest) GetRevisionHeight() uint64 { if m != nil { - return m.VersionHeight + return m.RevisionHeight } return 0 } @@ -599,59 +599,59 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/query.proto", fileDescriptor_dc42cdfd1d52d76e) } var fileDescriptor_dc42cdfd1d52d76e = []byte{ - // 823 bytes of a gzipped FileDescriptorProto + // 824 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4d, 0x4f, 0xdb, 0x48, - 0x18, 0xce, 0xf0, 0x25, 0x98, 0x04, 0x58, 0x8d, 0xd0, 0x6e, 0x30, 0xc8, 0x44, 0x5e, 0x2d, 0x9b, - 0xdd, 0x85, 0x19, 0x92, 0xdd, 0x2d, 0x52, 0x25, 0x0e, 0x05, 0x89, 0x96, 0x4b, 0x0b, 0xee, 0xa1, - 0x52, 0xa5, 0x0a, 0xd9, 0xce, 0xc4, 0xb1, 0x4a, 0x3c, 0x21, 0xe3, 0x44, 0x45, 0x88, 0x0b, 0x7f, - 0xa0, 0x95, 0x7a, 0xec, 0xb5, 0xa7, 0xaa, 0xea, 0xa5, 0x87, 0xfe, 0x83, 0x8a, 0x23, 0x52, 0x7b, - 0xe8, 0xa9, 0x1f, 0xd0, 0x1f, 0xd1, 0x63, 0xe5, 0x99, 0x31, 0xb1, 0x89, 0x11, 0x16, 0x6a, 0x4f, - 0xb1, 0xdf, 0xaf, 0x79, 0x9e, 0xe7, 0x7d, 0xdf, 0x71, 0xa0, 0xee, 0xd9, 0x0e, 0x71, 0x58, 0x9b, - 0x12, 0x67, 0xc7, 0xa3, 0x7e, 0x40, 0xba, 0x15, 0xb2, 0xdb, 0xa1, 0xed, 0x3d, 0xdc, 0x6a, 0xb3, - 0x80, 0x21, 0xe4, 0xd9, 0x0e, 0x0e, 0xfd, 0x58, 0xfa, 0x71, 0xb7, 0xa2, 0xfd, 0xed, 0x30, 0xde, - 0x64, 0x9c, 0xd8, 0x16, 0xa7, 0x32, 0x98, 0x74, 0x2b, 0x36, 0x0d, 0xac, 0x0a, 0x69, 0x59, 0xae, - 0xe7, 0x5b, 0x81, 0xc7, 0x7c, 0x99, 0xaf, 0xcd, 0xa5, 0xd4, 0x57, 0x95, 0x64, 0xc0, 0xb4, 0xcb, - 0x98, 0xbb, 0x43, 0x89, 0x78, 0xb3, 0x3b, 0x75, 0x62, 0xf9, 0xea, 0x6c, 0x6d, 0x56, 0xb9, 0xac, - 0x96, 0x47, 0x2c, 0xdf, 0x67, 0x81, 0x28, 0xcc, 0x95, 0x77, 0xca, 0x65, 0x2e, 0x13, 0x8f, 0x24, - 0x7c, 0x92, 0x56, 0xe3, 0x1a, 0xfc, 0x6d, 0x2b, 0x44, 0xb4, 0x26, 0xce, 0xb8, 0x1b, 0x58, 0x01, - 0x35, 0xe9, 0x6e, 0x87, 0xf2, 0x00, 0xcd, 0xc0, 0x31, 0x79, 0xf2, 0xb6, 0x57, 0x2b, 0x82, 0x12, - 0x28, 0x8f, 0x99, 0xa3, 0xd2, 0xb0, 0x51, 0x33, 0x5e, 0x01, 0x58, 0xec, 0x4f, 0xe4, 0x2d, 0xe6, - 0x73, 0x8a, 0x96, 0x61, 0x41, 0x65, 0xf2, 0xd0, 0x2e, 0x92, 0xf3, 0xd5, 0x29, 0x2c, 0xf1, 0xe1, - 0x08, 0x3a, 0xbe, 0xe1, 0xef, 0x99, 0x79, 0xa7, 0x57, 0x00, 0x4d, 0xc1, 0xe1, 0x56, 0x9b, 0xb1, - 0x7a, 0x71, 0xa0, 0x04, 0xca, 0x05, 0x53, 0xbe, 0xa0, 0x35, 0x58, 0x10, 0x0f, 0xdb, 0x0d, 0xea, - 0xb9, 0x8d, 0xa0, 0x38, 0x28, 0xca, 0x69, 0xb8, 0x5f, 0x6a, 0x7c, 0x4b, 0x44, 0xac, 0x0e, 0x1d, - 0x7d, 0x9c, 0xcb, 0x99, 0x79, 0x91, 0x25, 0x4d, 0x86, 0xdd, 0x8f, 0x97, 0x47, 0x4c, 0xd7, 0x21, - 0xec, 0x35, 0x42, 0xa1, 0x9d, 0xc7, 0xb2, 0x6b, 0x38, 0xec, 0x1a, 0x96, 0x2d, 0x56, 0x5d, 0xc3, - 0x9b, 0x96, 0x1b, 0xa9, 0x64, 0xc6, 0x32, 0x8d, 0xf7, 0x00, 0x4e, 0xa7, 0x1c, 0xa2, 0x54, 0xf1, - 0xe1, 0x78, 0x5c, 0x15, 0x5e, 0x04, 0xa5, 0xc1, 0x72, 0xbe, 0xfa, 0x57, 0x1a, 0x8f, 0x8d, 0x1a, - 0xf5, 0x03, 0xaf, 0xee, 0xd1, 0x5a, 0xac, 0xd4, 0xaa, 0x1e, 0xd2, 0x7a, 0xf1, 0x69, 0xee, 0xd7, - 0x54, 0x37, 0x37, 0x0b, 0x31, 0x2d, 0x39, 0xba, 0x99, 0x60, 0x35, 0x20, 0x58, 0xfd, 0x79, 0x29, - 0x2b, 0x09, 0x36, 0x41, 0xeb, 0x25, 0x80, 0x9a, 0xa4, 0x15, 0xba, 0x7c, 0xde, 0xe1, 0x99, 0xe7, - 0x04, 0xfd, 0x01, 0x27, 0xba, 0xb4, 0xcd, 0x3d, 0xe6, 0x6f, 0xfb, 0x9d, 0xa6, 0x4d, 0xdb, 0x02, - 0xc8, 0x90, 0x39, 0xae, 0xac, 0xb7, 0x85, 0x31, 0x1e, 0x16, 0x6b, 0x72, 0x2f, 0x4c, 0x36, 0x11, - 0xfd, 0x0e, 0xc7, 0x77, 0x42, 0x6e, 0x41, 0x14, 0x35, 0x54, 0x02, 0xe5, 0x51, 0xb3, 0x20, 0x8d, - 0xaa, 0xd3, 0x6f, 0x00, 0x9c, 0x49, 0x85, 0xab, 0xfa, 0xb0, 0x02, 0x27, 0x9d, 0xc8, 0x93, 0x61, - 0x40, 0x27, 0x9c, 0x44, 0x99, 0x9f, 0x39, 0xa3, 0x87, 0xe9, 0xc8, 0x79, 0x26, 0xa5, 0xd7, 0x53, - 0xda, 0x7d, 0x95, 0x21, 0x7e, 0x0b, 0xe0, 0x6c, 0x3a, 0x08, 0xa5, 0xdf, 0x03, 0xf8, 0xcb, 0x39, - 0xfd, 0xa2, 0x51, 0x5e, 0x48, 0xa3, 0x9b, 0x2c, 0x73, 0xcf, 0x0b, 0x1a, 0x09, 0x01, 0x26, 0x93, - 0xf2, 0xfe, 0xc0, 0xb1, 0xd5, 0x12, 0x1b, 0xbf, 0x69, 0xb5, 0xad, 0x66, 0xa4, 0xa4, 0x71, 0x27, - 0xb1, 0xa8, 0x91, 0x4f, 0x11, 0xac, 0xc2, 0x91, 0x96, 0xb0, 0xa8, 0xb9, 0x48, 0xed, 0xa2, 0xca, - 0x51, 0x91, 0xd5, 0x6f, 0x23, 0x70, 0x58, 0x54, 0x44, 0xcf, 0x01, 0xcc, 0xc7, 0xb6, 0x12, 0xfd, - 0x93, 0x96, 0x7d, 0xc1, 0x9d, 0xab, 0x2d, 0x64, 0x0b, 0x96, 0x40, 0x8d, 0xeb, 0x87, 0xef, 0xbe, - 0x3e, 0x1d, 0xf8, 0x0f, 0x55, 0x49, 0xff, 0x57, 0x43, 0x7e, 0x5f, 0x12, 0x17, 0x0e, 0xd9, 0x3f, - 0x9b, 0x9e, 0x03, 0xf4, 0x0c, 0xc0, 0x42, 0xfc, 0xf2, 0x40, 0x99, 0x8e, 0x8e, 0x04, 0xd4, 0x16, - 0x33, 0x46, 0x2b, 0xa4, 0x58, 0x20, 0x2d, 0xa3, 0xf9, 0x6c, 0x48, 0xd1, 0x17, 0x00, 0x27, 0x92, - 0x83, 0x83, 0xf0, 0xc5, 0x27, 0xa6, 0x5d, 0x4b, 0x1a, 0xc9, 0x1c, 0xaf, 0x30, 0xfa, 0x02, 0x63, - 0x03, 0xd5, 0x2f, 0xc6, 0x78, 0x6e, 0xec, 0xe3, 0x82, 0x12, 0x75, 0x53, 0x91, 0xfd, 0xe4, 0x7d, - 0x77, 0x40, 0xe4, 0x8d, 0xd0, 0xb3, 0xcb, 0xf7, 0x03, 0xf4, 0x1a, 0xc0, 0xc9, 0x73, 0x3b, 0x86, - 0xb2, 0x82, 0x3e, 0xeb, 0xc3, 0x52, 0xf6, 0x04, 0x45, 0x73, 0x45, 0xd0, 0x5c, 0x46, 0xff, 0x5f, - 0x89, 0x26, 0x7a, 0x7c, 0x36, 0x37, 0x72, 0x03, 0x2e, 0x9d, 0x9b, 0xc4, 0xe2, 0x5d, 0x3a, 0x37, - 0xc9, 0x55, 0x34, 0x0c, 0x01, 0x76, 0x16, 0x69, 0x12, 0x6c, 0x12, 0xa7, 0x5c, 0xbd, 0xd5, 0xad, - 0xa3, 0x13, 0x1d, 0x1c, 0x9f, 0xe8, 0xe0, 0xf3, 0x89, 0x0e, 0x9e, 0x9c, 0xea, 0xb9, 0xe3, 0x53, - 0x3d, 0xf7, 0xe1, 0x54, 0xcf, 0xdd, 0x5f, 0x76, 0xbd, 0xa0, 0xd1, 0xb1, 0xb1, 0xc3, 0x9a, 0x44, - 0xfd, 0x07, 0x93, 0x3f, 0x8b, 0xbc, 0xf6, 0x90, 0x3c, 0xea, 0x09, 0xb0, 0x54, 0x5d, 0x54, 0xb5, - 0x83, 0xbd, 0x16, 0xe5, 0xf6, 0x88, 0xf8, 0x02, 0xfc, 0xfb, 0x3d, 0x00, 0x00, 0xff, 0xff, 0xca, - 0xdc, 0xd5, 0x38, 0xee, 0x09, 0x00, 0x00, + 0x18, 0xce, 0xf0, 0x25, 0x98, 0x04, 0xb2, 0x1a, 0xa1, 0xdd, 0x60, 0x90, 0x89, 0xbc, 0x12, 0x64, + 0x77, 0x61, 0x86, 0x64, 0x3f, 0x90, 0x56, 0xe2, 0xb0, 0x20, 0xb1, 0xe5, 0xd2, 0x82, 0x7b, 0xa8, + 0x54, 0xa9, 0x42, 0xb6, 0x33, 0x38, 0x16, 0xc4, 0x13, 0x32, 0x4e, 0x54, 0x84, 0xb8, 0xf0, 0x07, + 0x5a, 0xa9, 0xc7, 0x5e, 0x7b, 0xea, 0xa1, 0xaa, 0xd4, 0x43, 0xff, 0x41, 0xc5, 0x11, 0xa9, 0x3d, + 0xf4, 0xd4, 0x56, 0xc0, 0xbf, 0xe8, 0xa5, 0xf2, 0xcc, 0x18, 0xec, 0xc4, 0x08, 0x0b, 0xb5, 0xa7, + 0xd8, 0xef, 0xd7, 0x3c, 0xcf, 0xf3, 0xbe, 0xef, 0x38, 0x50, 0xf7, 0x6c, 0x87, 0x38, 0xac, 0x4d, + 0x89, 0xb3, 0xe7, 0x51, 0x3f, 0x20, 0xdd, 0x2a, 0xd9, 0xef, 0xd0, 0xf6, 0x01, 0x6e, 0xb5, 0x59, + 0xc0, 0x10, 0xf2, 0x6c, 0x07, 0x87, 0x7e, 0x2c, 0xfd, 0xb8, 0x5b, 0xd5, 0x7e, 0x77, 0x18, 0x6f, + 0x32, 0x4e, 0x6c, 0x8b, 0x53, 0x19, 0x4c, 0xba, 0x55, 0x9b, 0x06, 0x56, 0x95, 0xb4, 0x2c, 0xd7, + 0xf3, 0xad, 0xc0, 0x63, 0xbe, 0xcc, 0xd7, 0x66, 0x53, 0xea, 0xab, 0x4a, 0x32, 0x60, 0xca, 0x65, + 0xcc, 0xdd, 0xa3, 0x44, 0xbc, 0xd9, 0x9d, 0x1d, 0x62, 0xf9, 0xea, 0x6c, 0x6d, 0x46, 0xb9, 0xac, + 0x96, 0x47, 0x2c, 0xdf, 0x67, 0x81, 0x28, 0xcc, 0x95, 0x77, 0xd2, 0x65, 0x2e, 0x13, 0x8f, 0x24, + 0x7c, 0x92, 0x56, 0xe3, 0x1f, 0xf8, 0xcb, 0x56, 0x88, 0x68, 0x4d, 0x9c, 0x71, 0x3f, 0xb0, 0x02, + 0x6a, 0xd2, 0xfd, 0x0e, 0xe5, 0x01, 0x9a, 0x86, 0x63, 0xf2, 0xe4, 0x6d, 0xaf, 0x5e, 0x02, 0x65, + 0x50, 0x19, 0x33, 0x47, 0xa5, 0x61, 0xa3, 0x6e, 0xbc, 0x02, 0xb0, 0xd4, 0x9f, 0xc8, 0x5b, 0xcc, + 0xe7, 0x14, 0x2d, 0xc3, 0x82, 0xca, 0xe4, 0xa1, 0x5d, 0x24, 0xe7, 0x6b, 0x93, 0x58, 0xe2, 0xc3, + 0x11, 0x74, 0xfc, 0x9f, 0x7f, 0x60, 0xe6, 0x9d, 0xab, 0x02, 0x68, 0x12, 0x0e, 0xb7, 0xda, 0x8c, + 0xed, 0x94, 0x06, 0xca, 0xa0, 0x52, 0x30, 0xe5, 0x0b, 0x5a, 0x83, 0x05, 0xf1, 0xb0, 0xdd, 0xa0, + 0x9e, 0xdb, 0x08, 0x4a, 0x83, 0xa2, 0x9c, 0x86, 0xfb, 0xa5, 0xc6, 0x77, 0x44, 0xc4, 0xea, 0xd0, + 0xc9, 0xa7, 0xd9, 0x9c, 0x99, 0x17, 0x59, 0xd2, 0x64, 0xd8, 0xfd, 0x78, 0x79, 0xc4, 0x74, 0x1d, + 0xc2, 0xab, 0x46, 0x28, 0xb4, 0x73, 0x58, 0x76, 0x0d, 0x87, 0x5d, 0xc3, 0xb2, 0xc5, 0xaa, 0x6b, + 0x78, 0xd3, 0x72, 0x23, 0x95, 0xcc, 0x58, 0xa6, 0xf1, 0x01, 0xc0, 0xa9, 0x94, 0x43, 0x94, 0x2a, + 0x3e, 0x1c, 0x8f, 0xab, 0xc2, 0x4b, 0xa0, 0x3c, 0x58, 0xc9, 0xd7, 0x7e, 0x4b, 0xe3, 0xb1, 0x51, + 0xa7, 0x7e, 0xe0, 0xed, 0x78, 0xb4, 0x1e, 0x2b, 0xb5, 0xaa, 0x87, 0xb4, 0x5e, 0x7e, 0x9e, 0xfd, + 0x39, 0xd5, 0xcd, 0xcd, 0x42, 0x4c, 0x4b, 0x8e, 0xfe, 0x4f, 0xb0, 0x1a, 0x10, 0xac, 0xe6, 0x6f, + 0x64, 0x25, 0xc1, 0x26, 0x68, 0xbd, 0x06, 0x50, 0x93, 0xb4, 0x42, 0x97, 0xcf, 0x3b, 0x3c, 0xf3, + 0x9c, 0xa0, 0x79, 0x58, 0x6c, 0xd3, 0xae, 0xc7, 0x3d, 0xe6, 0x6f, 0xfb, 0x9d, 0xa6, 0x4d, 0xdb, + 0x02, 0xc9, 0x90, 0x39, 0x11, 0x99, 0xef, 0x0a, 0x6b, 0x22, 0x30, 0xd6, 0xe7, 0x58, 0xa0, 0x6c, + 0x24, 0xfa, 0x15, 0x8e, 0xef, 0x85, 0xfc, 0x82, 0x28, 0x6c, 0xa8, 0x0c, 0x2a, 0xa3, 0x66, 0x41, + 0x1a, 0x55, 0xb7, 0xdf, 0x02, 0x38, 0x9d, 0x0a, 0x59, 0xf5, 0x62, 0x05, 0x16, 0x9d, 0xc8, 0x93, + 0x61, 0x48, 0x27, 0x9c, 0x44, 0x99, 0x1f, 0x39, 0xa7, 0xc7, 0xe9, 0xc8, 0x79, 0x26, 0xb5, 0xd7, + 0x53, 0x5a, 0x7e, 0x9b, 0x41, 0x7e, 0x07, 0xe0, 0x4c, 0x3a, 0x08, 0xa5, 0xdf, 0x23, 0xf8, 0x53, + 0x8f, 0x7e, 0xd1, 0x38, 0x2f, 0xa4, 0xd1, 0x4d, 0x96, 0x79, 0xe0, 0x05, 0x8d, 0x84, 0x00, 0xc5, + 0xa4, 0xbc, 0xdf, 0x71, 0x74, 0xb5, 0xc4, 0xd6, 0x6f, 0x5a, 0x6d, 0xab, 0x19, 0x29, 0x69, 0xdc, + 0x4b, 0x2c, 0x6b, 0xe4, 0x53, 0x04, 0x6b, 0x70, 0xa4, 0x25, 0x2c, 0x6a, 0x2e, 0x52, 0xbb, 0xa8, + 0x72, 0x54, 0x64, 0xed, 0xeb, 0x08, 0x1c, 0x16, 0x15, 0xd1, 0x0b, 0x00, 0xf3, 0xb1, 0xcd, 0x44, + 0x7f, 0xa4, 0x65, 0x5f, 0x73, 0xef, 0x6a, 0x0b, 0xd9, 0x82, 0x25, 0x50, 0xe3, 0xdf, 0xe3, 0xf7, + 0x17, 0xcf, 0x06, 0xfe, 0x42, 0x35, 0xd2, 0xff, 0xe5, 0x90, 0xdf, 0x98, 0xc4, 0xa5, 0x43, 0x0e, + 0x2f, 0xa7, 0xe7, 0x08, 0x3d, 0x07, 0xb0, 0x10, 0xbf, 0x40, 0x50, 0xa6, 0xa3, 0x23, 0x01, 0xb5, + 0xc5, 0x8c, 0xd1, 0x0a, 0x29, 0x16, 0x48, 0x2b, 0x68, 0x2e, 0x1b, 0x52, 0x74, 0x01, 0xe0, 0x44, + 0x72, 0x70, 0x10, 0xbe, 0xfe, 0xc4, 0xb4, 0xab, 0x49, 0x23, 0x99, 0xe3, 0x15, 0xc6, 0x7d, 0x81, + 0x71, 0x17, 0x79, 0xd7, 0x63, 0xec, 0x19, 0xfb, 0xb8, 0xa0, 0x24, 0xba, 0xaa, 0xc8, 0x61, 0xcf, + 0xa5, 0x77, 0x44, 0xe4, 0x9d, 0x10, 0x73, 0x48, 0xc3, 0x11, 0x7a, 0x03, 0x60, 0xb1, 0x67, 0xcd, + 0x50, 0x56, 0xdc, 0x97, 0xad, 0x58, 0xca, 0x9e, 0xa0, 0x98, 0xae, 0x08, 0xa6, 0xcb, 0xe8, 0xef, + 0x5b, 0x31, 0x45, 0x4f, 0x2e, 0x47, 0x47, 0x2e, 0xc1, 0x8d, 0xa3, 0x93, 0xd8, 0xbd, 0x1b, 0x47, + 0x27, 0xb9, 0x8d, 0x86, 0x21, 0xc0, 0xce, 0x20, 0x4d, 0x82, 0x4d, 0xe2, 0x94, 0xdb, 0xb7, 0xba, + 0x75, 0x72, 0xa6, 0x83, 0xd3, 0x33, 0x1d, 0x7c, 0x39, 0xd3, 0xc1, 0xd3, 0x73, 0x3d, 0x77, 0x7a, + 0xae, 0xe7, 0x3e, 0x9e, 0xeb, 0xb9, 0x87, 0xcb, 0xae, 0x17, 0x34, 0x3a, 0x36, 0x76, 0x58, 0x93, + 0xa8, 0xbf, 0x62, 0xf2, 0x67, 0x91, 0xd7, 0x77, 0xc9, 0xe3, 0x2b, 0x01, 0x96, 0x6a, 0x8b, 0xaa, + 0x76, 0x70, 0xd0, 0xa2, 0xdc, 0x1e, 0x11, 0x1f, 0x81, 0x3f, 0xbf, 0x05, 0x00, 0x00, 0xff, 0xff, + 0xa7, 0x0d, 0x7c, 0x62, 0xf5, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1088,13 +1088,13 @@ func (m *QueryConsensusStateRequest) MarshalToSizedBuffer(dAtA []byte) (int, err i-- dAtA[i] = 0x20 } - if m.VersionHeight != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionHeight)) i-- dAtA[i] = 0x18 } - if m.VersionNumber != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionNumber)) i-- dAtA[i] = 0x10 } @@ -1394,11 +1394,11 @@ func (m *QueryConsensusStateRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - if m.VersionNumber != 0 { - n += 1 + sovQuery(uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + n += 1 + sovQuery(uint64(m.RevisionNumber)) } - if m.VersionHeight != 0 { - n += 1 + sovQuery(uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + n += 1 + sovQuery(uint64(m.RevisionHeight)) } if m.LatestHeight { n += 2 @@ -2005,9 +2005,9 @@ func (m *QueryConsensusStateRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionNumber", wireType) } - m.VersionNumber = 0 + m.RevisionNumber = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2017,16 +2017,16 @@ func (m *QueryConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionNumber |= uint64(b&0x7F) << shift + m.RevisionNumber |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHeight", wireType) } - m.VersionHeight = 0 + m.RevisionHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2036,7 +2036,7 @@ func (m *QueryConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionHeight |= uint64(b&0x7F) << shift + m.RevisionHeight |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ibc/core/02-client/types/query.pb.gw.go b/x/ibc/core/02-client/types/query.pb.gw.go index 77b3df69a8..d4414d5ea3 100644 --- a/x/ibc/core/02-client/types/query.pb.gw.go +++ b/x/ibc/core/02-client/types/query.pb.gw.go @@ -122,7 +122,7 @@ func local_request_Query_ClientStates_0(ctx context.Context, marshaler runtime.M } var ( - filter_Query_ConsensusState_0 = &utilities.DoubleArray{Encoding: map[string]int{"client_id": 0, "version_number": 1, "version_height": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} + filter_Query_ConsensusState_0 = &utilities.DoubleArray{Encoding: map[string]int{"client_id": 0, "revision_number": 1, "revision_height": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} ) func request_Query_ConsensusState_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -147,26 +147,26 @@ func request_Query_ConsensusState_0(ctx context.Context, marshaler runtime.Marsh return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } if err := req.ParseForm(); err != nil { @@ -203,26 +203,26 @@ func local_request_Query_ConsensusState_0(ctx context.Context, marshaler runtime return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } if err := req.ParseForm(); err != nil { @@ -582,7 +582,7 @@ var ( pattern_Query_ClientStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1beta1", "client_states"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_ConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "client", "v1beta1", "consensus_states", "client_id", "version", "version_number", "height", "version_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "client", "v1beta1", "consensus_states", "client_id", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_ConsensusStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1beta1", "consensus_states", "client_id"}, "", runtime.AssumeColonVerbOpt(true))) diff --git a/x/ibc/core/02-client/types/tx.pb.go b/x/ibc/core/02-client/types/tx.pb.go index 4b637e5ba6..2a1a6b8885 100644 --- a/x/ibc/core/02-client/types/tx.pb.go +++ b/x/ibc/core/02-client/types/tx.pb.go @@ -199,12 +199,14 @@ type MsgUpgradeClient struct { ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` // upgraded client state ClientState *types.Any `protobuf:"bytes,2,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` - // height at which old chain halts and upgrades (i.e last block executed) - UpgradeHeight *Height `protobuf:"bytes,3,opt,name=upgrade_height,json=upgradeHeight,proto3" json:"upgrade_height,omitempty" yaml:"upgrade_height"` + // upgraded consensus state, only contains enough information to serve as a basis of trust in update logic + ConsensusState *types.Any `protobuf:"bytes,3,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty" yaml:"consensus_state"` // proof that old chain committed to new client - ProofUpgrade []byte `protobuf:"bytes,4,opt,name=proof_upgrade,json=proofUpgrade,proto3" json:"proof_upgrade,omitempty" yaml:"proof_upgrade"` + ProofUpgradeClient []byte `protobuf:"bytes,4,opt,name=proof_upgrade_client,json=proofUpgradeClient,proto3" json:"proof_upgrade_client,omitempty" yaml:"proof_upgrade_client"` + // proof that old chain committed to new consensus state + ProofUpgradeConsensusState []byte `protobuf:"bytes,5,opt,name=proof_upgrade_consensus_state,json=proofUpgradeConsensusState,proto3" json:"proof_upgrade_consensus_state,omitempty" yaml:"proof_upgrade_consensus_state"` // signer address - Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty"` + Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgUpgradeClient) Reset() { *m = MsgUpgradeClient{} } @@ -240,41 +242,6 @@ func (m *MsgUpgradeClient) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpgradeClient proto.InternalMessageInfo -func (m *MsgUpgradeClient) GetClientId() string { - if m != nil { - return m.ClientId - } - return "" -} - -func (m *MsgUpgradeClient) GetClientState() *types.Any { - if m != nil { - return m.ClientState - } - return nil -} - -func (m *MsgUpgradeClient) GetUpgradeHeight() *Height { - if m != nil { - return m.UpgradeHeight - } - return nil -} - -func (m *MsgUpgradeClient) GetProofUpgrade() []byte { - if m != nil { - return m.ProofUpgrade - } - return nil -} - -func (m *MsgUpgradeClient) GetSigner() string { - if m != nil { - return m.Signer - } - return "" -} - // MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. type MsgUpgradeClientResponse struct { } @@ -407,45 +374,45 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/tx.proto", fileDescriptor_cb5dc4651eb49a04) } var fileDescriptor_cb5dc4651eb49a04 = []byte{ - // 608 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0x3f, 0x6f, 0xd3, 0x40, - 0x14, 0x8f, 0x1b, 0x88, 0xda, 0x6b, 0xd2, 0x56, 0x26, 0x6d, 0x13, 0x23, 0xec, 0xca, 0x30, 0x14, - 0xd1, 0xda, 0x24, 0x0c, 0xa0, 0x4a, 0x0c, 0xa4, 0x0b, 0x0c, 0x91, 0xc0, 0x15, 0x03, 0x08, 0x29, - 0xf8, 0xcf, 0xf5, 0x62, 0x91, 0xf8, 0x22, 0xdf, 0x39, 0x6a, 0xbe, 0x01, 0x23, 0x12, 0x7c, 0x80, - 0x8a, 0x81, 0xcf, 0xc2, 0xc0, 0xd0, 0x91, 0x29, 0x42, 0xc9, 0xc2, 0x9c, 0x4f, 0x80, 0x7c, 0x77, - 0xb1, 0xec, 0x34, 0x89, 0x22, 0x58, 0x98, 0xe2, 0x77, 0xef, 0xf7, 0x7e, 0xef, 0xe7, 0xdf, 0x7b, - 0x17, 0x83, 0xdb, 0xbe, 0xe3, 0x9a, 0x2e, 0x0e, 0xa1, 0xe9, 0x76, 0x7c, 0x18, 0x50, 0xb3, 0x5f, - 0x33, 0xe9, 0x85, 0xd1, 0x0b, 0x31, 0xc5, 0xb2, 0xec, 0x3b, 0xae, 0x11, 0x27, 0x0d, 0x9e, 0x34, - 0xfa, 0x35, 0xa5, 0x8c, 0x30, 0xc2, 0x2c, 0x6d, 0xc6, 0x4f, 0x1c, 0xa9, 0x54, 0x11, 0xc6, 0xa8, - 0x03, 0x4d, 0x16, 0x39, 0xd1, 0xb9, 0x69, 0x07, 0x03, 0x91, 0xd2, 0xe6, 0x74, 0x10, 0x74, 0x0c, - 0xa0, 0x7f, 0x5e, 0x03, 0xdb, 0x4d, 0x82, 0x4e, 0x43, 0x68, 0x53, 0x78, 0xca, 0x32, 0x72, 0x0d, - 0x6c, 0x70, 0x4c, 0xcb, 0xf7, 0x2a, 0xd2, 0x81, 0x74, 0xb8, 0xd1, 0x28, 0x4f, 0x86, 0xda, 0xce, - 0xc0, 0xee, 0x76, 0x4e, 0xf4, 0x24, 0xa5, 0x5b, 0xeb, 0xfc, 0xf9, 0x85, 0x27, 0xbf, 0x04, 0x45, - 0x71, 0x4e, 0xa8, 0x4d, 0x61, 0x65, 0xed, 0x40, 0x3a, 0xdc, 0xac, 0x97, 0x0d, 0xae, 0xcc, 0x98, - 0x2a, 0x33, 0x9e, 0x05, 0x83, 0xc6, 0xfe, 0x64, 0xa8, 0xdd, 0xca, 0x70, 0xb1, 0x1a, 0xdd, 0xda, - 0xe4, 0xe1, 0x59, 0x1c, 0xc9, 0x6f, 0xc0, 0xb6, 0x8b, 0x03, 0x02, 0x03, 0x12, 0x11, 0x41, 0x9a, - 0x5f, 0x42, 0xaa, 0x4c, 0x86, 0xda, 0x9e, 0x20, 0xcd, 0x96, 0xe9, 0xd6, 0x56, 0x72, 0xc2, 0xa9, - 0xf7, 0x40, 0x81, 0xf8, 0x28, 0x80, 0x61, 0xe5, 0x46, 0xfc, 0x72, 0x96, 0x88, 0x4e, 0xd6, 0x3f, - 0x5e, 0x6a, 0xb9, 0xdf, 0x97, 0x5a, 0x4e, 0xaf, 0x82, 0xfd, 0x19, 0x53, 0x2c, 0x48, 0x7a, 0x31, - 0x8b, 0xfe, 0x45, 0x62, 0x86, 0xbd, 0xee, 0x79, 0xff, 0x64, 0xd8, 0x11, 0x28, 0xb4, 0xa1, 0xed, - 0xc1, 0x70, 0x99, 0x55, 0x96, 0xc0, 0xa4, 0x14, 0xe7, 0x97, 0x2a, 0x4e, 0xab, 0x4a, 0x14, 0xff, - 0x58, 0x03, 0x3b, 0x2c, 0x87, 0x42, 0xdb, 0xfb, 0xaf, 0x66, 0xfc, 0x0e, 0x6c, 0x45, 0x5c, 0x55, - 0xab, 0x0d, 0x7d, 0xd4, 0xa6, 0x62, 0xc4, 0x8a, 0x71, 0x7d, 0xf7, 0x8d, 0xe7, 0x0c, 0xd1, 0xa8, - 0x4e, 0x86, 0xda, 0x2e, 0x67, 0xce, 0xd6, 0xea, 0x56, 0x49, 0x1c, 0x70, 0xa4, 0xfc, 0x14, 0x94, - 0x7a, 0x21, 0xc6, 0xe7, 0x2d, 0x71, 0xcc, 0xa6, 0x5d, 0x6c, 0x54, 0x26, 0x43, 0xad, 0xcc, 0x09, - 0x32, 0x69, 0xdd, 0x2a, 0xb2, 0x58, 0xf8, 0x94, 0xf2, 0xfc, 0x66, 0xda, 0x73, 0x5d, 0x01, 0x95, - 0x59, 0x37, 0x13, 0xab, 0xbf, 0x49, 0x60, 0xb7, 0x49, 0xd0, 0x59, 0xe4, 0x74, 0x7d, 0xda, 0xf4, - 0x89, 0x03, 0xdb, 0x76, 0xdf, 0xc7, 0x51, 0xf8, 0x37, 0x7e, 0x3f, 0x01, 0xc5, 0x6e, 0x8a, 0x62, - 0xe9, 0xa2, 0x64, 0x90, 0x2b, 0xac, 0x8b, 0x06, 0xee, 0xcc, 0xd5, 0x39, 0x7d, 0x93, 0xfa, 0xd7, - 0x3c, 0xc8, 0x37, 0x09, 0x92, 0xdf, 0x83, 0x62, 0xe6, 0xbf, 0xe1, 0xee, 0xbc, 0xd1, 0xcc, 0xdc, - 0x15, 0xe5, 0xc1, 0x0a, 0xa0, 0x69, 0xa7, 0xb8, 0x43, 0xe6, 0x32, 0x2d, 0xea, 0x90, 0x06, 0x2d, - 0xec, 0x30, 0xef, 0x02, 0xc8, 0x2e, 0x28, 0x65, 0x97, 0xff, 0xde, 0xc2, 0xea, 0x14, 0x4a, 0x39, - 0x5a, 0x05, 0x95, 0x34, 0x09, 0x81, 0x3c, 0x67, 0xec, 0xf7, 0x17, 0x70, 0x5c, 0x87, 0x2a, 0xb5, - 0x95, 0xa1, 0xd3, 0x9e, 0x8d, 0x57, 0xdf, 0x47, 0xaa, 0x74, 0x35, 0x52, 0xa5, 0x5f, 0x23, 0x55, - 0xfa, 0x34, 0x56, 0x73, 0x57, 0x63, 0x35, 0xf7, 0x73, 0xac, 0xe6, 0xde, 0x3e, 0x46, 0x3e, 0x6d, - 0x47, 0x8e, 0xe1, 0xe2, 0xae, 0xe9, 0x62, 0xd2, 0xc5, 0x44, 0xfc, 0x1c, 0x13, 0xef, 0x83, 0x79, - 0x61, 0x26, 0x9f, 0x85, 0x87, 0xf5, 0x63, 0xf1, 0x65, 0xa0, 0x83, 0x1e, 0x24, 0x4e, 0x81, 0xad, - 0xd5, 0xa3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb1, 0x03, 0x55, 0x1e, 0x9b, 0x06, 0x00, 0x00, + // 598 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x55, 0x3f, 0x6f, 0xd3, 0x4e, + 0x18, 0x8e, 0x9b, 0xdf, 0x2f, 0x6a, 0xaf, 0x81, 0x56, 0x26, 0xb4, 0xa9, 0xab, 0xda, 0x95, 0xe9, + 0x10, 0x44, 0xeb, 0x23, 0x61, 0x00, 0x75, 0x23, 0x9d, 0x18, 0x22, 0x51, 0x57, 0x0c, 0xb0, 0x04, + 0xff, 0xb9, 0x5e, 0xac, 0x26, 0xbe, 0xc8, 0x67, 0x47, 0xcd, 0x37, 0x60, 0x44, 0x82, 0x0f, 0x50, + 0x31, 0xf0, 0x59, 0x18, 0x3b, 0x30, 0x30, 0x45, 0x28, 0x59, 0x98, 0xf3, 0x09, 0x90, 0xef, 0x1c, + 0xcb, 0x76, 0xed, 0x28, 0x82, 0x91, 0xc9, 0x7e, 0xef, 0x7d, 0xee, 0x79, 0x9e, 0x7b, 0xdf, 0xf7, + 0x6c, 0xb0, 0xef, 0x98, 0x16, 0xb4, 0x88, 0x87, 0xa0, 0xd5, 0x77, 0x90, 0xeb, 0xc3, 0x51, 0x13, + 0xfa, 0xd7, 0xda, 0xd0, 0x23, 0x3e, 0x11, 0x45, 0xc7, 0xb4, 0xb4, 0x30, 0xa9, 0xf1, 0xa4, 0x36, + 0x6a, 0x4a, 0x35, 0x4c, 0x30, 0x61, 0x69, 0x18, 0xbe, 0x71, 0xa4, 0xb4, 0x87, 0x09, 0xc1, 0x7d, + 0x04, 0x59, 0x64, 0x06, 0x97, 0xd0, 0x70, 0xc7, 0x51, 0x4a, 0xc9, 0x51, 0x88, 0xe8, 0x18, 0x40, + 0xfd, 0xb4, 0x06, 0xb6, 0x3a, 0x14, 0x9f, 0x79, 0xc8, 0xf0, 0xd1, 0x19, 0xcb, 0x88, 0x4d, 0xb0, + 0xc1, 0x31, 0x5d, 0xc7, 0xae, 0x0b, 0x87, 0x42, 0x63, 0xa3, 0x5d, 0x9b, 0x4f, 0x94, 0xed, 0xb1, + 0x31, 0xe8, 0x9f, 0xaa, 0x71, 0x4a, 0xd5, 0xd7, 0xf9, 0xfb, 0x2b, 0x5b, 0x7c, 0x0d, 0xaa, 0xd1, + 0x3a, 0xf5, 0x0d, 0x1f, 0xd5, 0xd7, 0x0e, 0x85, 0xc6, 0x66, 0xab, 0xa6, 0x71, 0x67, 0xda, 0xc2, + 0x99, 0xf6, 0xd2, 0x1d, 0xb7, 0x77, 0xe7, 0x13, 0xe5, 0x41, 0x8a, 0x8b, 0xed, 0x51, 0xf5, 0x4d, + 0x1e, 0x5e, 0x84, 0x91, 0xf8, 0x16, 0x6c, 0x59, 0xc4, 0xa5, 0xc8, 0xa5, 0x01, 0x8d, 0x48, 0xcb, + 0x4b, 0x48, 0xa5, 0xf9, 0x44, 0xd9, 0x89, 0x48, 0xd3, 0xdb, 0x54, 0xfd, 0x7e, 0xbc, 0xc2, 0xa9, + 0x77, 0x40, 0x85, 0x3a, 0xd8, 0x45, 0x5e, 0xfd, 0xbf, 0xf0, 0x70, 0x7a, 0x14, 0x9d, 0xae, 0x7f, + 0xb8, 0x51, 0x4a, 0xbf, 0x6e, 0x94, 0x92, 0xba, 0x07, 0x76, 0x33, 0x45, 0xd1, 0x11, 0x1d, 0x86, + 0x2c, 0xea, 0x67, 0x81, 0x15, 0xec, 0xcd, 0xd0, 0xfe, 0xab, 0x82, 0x1d, 0x83, 0x4a, 0x0f, 0x19, + 0x36, 0xf2, 0x96, 0x95, 0x4a, 0x8f, 0x30, 0x09, 0xc7, 0xe5, 0xa5, 0x8e, 0x93, 0xae, 0x62, 0xc7, + 0xdf, 0xcb, 0x60, 0x9b, 0xe5, 0xb0, 0x67, 0xd8, 0xff, 0x4a, 0x8f, 0xcf, 0x41, 0x6d, 0xe8, 0x11, + 0x72, 0xd9, 0x0d, 0xf8, 0xb1, 0xbb, 0x5c, 0x97, 0x75, 0xbc, 0xda, 0x56, 0xe6, 0x13, 0x65, 0x9f, + 0x33, 0xe5, 0xa1, 0x54, 0x5d, 0x64, 0xcb, 0xe9, 0x92, 0x5d, 0x81, 0x83, 0x0c, 0x38, 0xe3, 0xfd, + 0x7f, 0xc6, 0xdd, 0x98, 0x4f, 0x94, 0xa3, 0x5c, 0xee, 0xac, 0x67, 0x29, 0x25, 0x52, 0x34, 0xa3, + 0x95, 0x82, 0x8e, 0x4b, 0xa0, 0x9e, 0xed, 0x6a, 0xdc, 0xf2, 0xaf, 0x02, 0x78, 0xd8, 0xa1, 0xf8, + 0x22, 0x30, 0x07, 0x8e, 0xdf, 0x71, 0xa8, 0x89, 0x7a, 0xc6, 0xc8, 0x21, 0x81, 0xf7, 0x27, 0x7d, + 0x7f, 0x01, 0xaa, 0x83, 0x04, 0xc5, 0xd2, 0x81, 0x4d, 0x21, 0x57, 0x18, 0x5b, 0x05, 0x1c, 0xe4, + 0xfa, 0x5c, 0x9c, 0xa4, 0xf5, 0xa5, 0x0c, 0xca, 0x1d, 0x8a, 0xc5, 0xf7, 0xa0, 0x9a, 0xfa, 0x46, + 0x3d, 0xd2, 0xee, 0x7e, 0x1e, 0xb5, 0xcc, 0x9d, 0x95, 0x9e, 0xac, 0x00, 0x5a, 0x28, 0x85, 0x0a, + 0xa9, 0x4b, 0x5d, 0xa4, 0x90, 0x04, 0x15, 0x2a, 0xe4, 0x5d, 0x44, 0xd1, 0x02, 0xf7, 0xd2, 0x13, + 0x75, 0x54, 0xb8, 0x3b, 0x81, 0x92, 0x8e, 0x57, 0x41, 0xc5, 0x22, 0x1e, 0x10, 0x73, 0xda, 0xfe, + 0xb8, 0x80, 0xe3, 0x2e, 0x54, 0x6a, 0xae, 0x0c, 0x5d, 0x68, 0xb6, 0xcf, 0xbf, 0x4d, 0x65, 0xe1, + 0x76, 0x2a, 0x0b, 0x3f, 0xa7, 0xb2, 0xf0, 0x71, 0x26, 0x97, 0x6e, 0x67, 0x72, 0xe9, 0xc7, 0x4c, + 0x2e, 0xbd, 0x7b, 0x8e, 0x1d, 0xbf, 0x17, 0x98, 0x9a, 0x45, 0x06, 0xd0, 0x22, 0x74, 0x40, 0x68, + 0xf4, 0x38, 0xa1, 0xf6, 0x15, 0xbc, 0x86, 0xf1, 0xef, 0xe9, 0x69, 0xeb, 0x24, 0xfa, 0x43, 0xf9, + 0xe3, 0x21, 0xa2, 0x66, 0x85, 0x8d, 0xd5, 0xb3, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd2, 0x19, + 0x59, 0x52, 0x23, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -825,18 +792,25 @@ func (m *MsgUpgradeClient) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- + dAtA[i] = 0x32 + } + if len(m.ProofUpgradeConsensusState) > 0 { + i -= len(m.ProofUpgradeConsensusState) + copy(dAtA[i:], m.ProofUpgradeConsensusState) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgradeConsensusState))) + i-- dAtA[i] = 0x2a } - if len(m.ProofUpgrade) > 0 { - i -= len(m.ProofUpgrade) - copy(dAtA[i:], m.ProofUpgrade) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgrade))) + if len(m.ProofUpgradeClient) > 0 { + i -= len(m.ProofUpgradeClient) + copy(dAtA[i:], m.ProofUpgradeClient) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgradeClient))) i-- dAtA[i] = 0x22 } - if m.UpgradeHeight != nil { + if m.ConsensusState != nil { { - size, err := m.UpgradeHeight.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ConsensusState.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1052,11 +1026,15 @@ func (m *MsgUpgradeClient) Size() (n int) { l = m.ClientState.Size() n += 1 + l + sovTx(uint64(l)) } - if m.UpgradeHeight != nil { - l = m.UpgradeHeight.Size() + if m.ConsensusState != nil { + l = m.ConsensusState.Size() n += 1 + l + sovTx(uint64(l)) } - l = len(m.ProofUpgrade) + l = len(m.ProofUpgradeClient) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofUpgradeConsensusState) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -1659,7 +1637,7 @@ func (m *MsgUpgradeClient) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpgradeHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsensusState", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1686,16 +1664,16 @@ func (m *MsgUpgradeClient) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.UpgradeHeight == nil { - m.UpgradeHeight = &Height{} + if m.ConsensusState == nil { + m.ConsensusState = &types.Any{} } - if err := m.UpgradeHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgrade", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgradeClient", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1722,12 +1700,46 @@ func (m *MsgUpgradeClient) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofUpgrade = append(m.ProofUpgrade[:0], dAtA[iNdEx:postIndex]...) - if m.ProofUpgrade == nil { - m.ProofUpgrade = []byte{} + m.ProofUpgradeClient = append(m.ProofUpgradeClient[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUpgradeClient == nil { + m.ProofUpgradeClient = []byte{} } iNdEx = postIndex case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgradeConsensusState", 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.ProofUpgradeConsensusState = append(m.ProofUpgradeConsensusState[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUpgradeConsensusState == nil { + m.ProofUpgradeConsensusState = []byte{} + } + iNdEx = postIndex + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } diff --git a/x/ibc/core/03-connection/client/cli/query.go b/x/ibc/core/03-connection/client/cli/query.go index 0beddb2f42..0c22dbdc82 100644 --- a/x/ibc/core/03-connection/client/cli/query.go +++ b/x/ibc/core/03-connection/client/cli/query.go @@ -79,7 +79,7 @@ func GetCmdQueryConnection() *cobra.Command { return err } - clientCtx = clientCtx.WithHeight(int64(connRes.ProofHeight.VersionHeight)) + clientCtx = clientCtx.WithHeight(int64(connRes.ProofHeight.RevisionHeight)) return clientCtx.PrintOutput(connRes) }, } @@ -113,7 +113,7 @@ func GetCmdQueryClientConnections() *cobra.Command { return err } - clientCtx = clientCtx.WithHeight(int64(connPathsRes.ProofHeight.VersionHeight)) + clientCtx = clientCtx.WithHeight(int64(connPathsRes.ProofHeight.RevisionHeight)) return clientCtx.PrintOutput(connPathsRes) }, } diff --git a/x/ibc/core/03-connection/client/cli/tx.go b/x/ibc/core/03-connection/client/cli/tx.go index 9526c5f8c0..bff4c5da94 100644 --- a/x/ibc/core/03-connection/client/cli/tx.go +++ b/x/ibc/core/03-connection/client/cli/tx.go @@ -22,23 +22,22 @@ import ( const ( flagVersionIdentifier = "version-identifier" flagVersionFeatures = "version-features" - flagProvedID = "proved-id" ) // NewConnectionOpenInitCmd defines the command to initialize a connection on // chain A with a given counterparty chain B func NewConnectionOpenInitCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-init [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json]", + Use: "open-init [client-id] [counterparty-client-id] [path/to/counterparty_prefix.json]", Short: "Initialize connection on chain A", Long: `Initialize a connection on chain A with a given counterparty chain B. - 'version-identifier' flag can be a single pre-selected version identifier to be used in the handshake. - 'version-features' flag can be a list of features separated by commas to accompany the version identifier.`, Example: fmt.Sprintf( - "%s tx %s %s open-init [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] --version-identifier=\"1.0\" --version-features=\"ORDER_UNORDERED\"", + "%s tx %s %s open-init [client-id] [counterparty-client-id] [path/to/counterparty_prefix.json] --version-identifier=\"1.0\" --version-features=\"ORDER_UNORDERED\"", version.AppName, host.ModuleName, types.SubModuleName, ), - Args: cobra.ExactArgs(5), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -46,12 +45,10 @@ func NewConnectionOpenInitCmd() *cobra.Command { return err } - connectionID := args[0] - clientID := args[1] - counterpartyConnectionID := args[2] - counterpartyClientID := args[3] + clientID := args[0] + counterpartyClientID := args[1] - counterpartyPrefix, err := utils.ParsePrefix(clientCtx.LegacyAmino, args[4]) + counterpartyPrefix, err := utils.ParsePrefix(clientCtx.LegacyAmino, args[2]) if err != nil { return err } @@ -71,7 +68,7 @@ func NewConnectionOpenInitCmd() *cobra.Command { } msg := types.NewMsgConnectionOpenInit( - connectionID, clientID, counterpartyConnectionID, counterpartyClientID, + clientID, counterpartyClientID, counterpartyPrefix, version, clientCtx.GetFromAddress(), ) @@ -116,7 +113,6 @@ func NewConnectionOpenTryCmd() *cobra.Command { } connectionID := args[0] - provedID, _ := cmd.Flags().GetString(flagProvedID) clientID := args[1] counterpartyConnectionID := args[2] counterpartyClientID := args[3] @@ -179,7 +175,7 @@ func NewConnectionOpenTryCmd() *cobra.Command { } msg := types.NewMsgConnectionOpenTry( - connectionID, provedID, clientID, counterpartyConnectionID, counterpartyClientID, + connectionID, clientID, counterpartyConnectionID, counterpartyClientID, counterpartyClient, counterpartyPrefix, counterpartyVersions, proofInit, proofClient, proofConsensus, proofHeight, consensusHeight, clientCtx.GetFromAddress(), @@ -193,7 +189,6 @@ func NewConnectionOpenTryCmd() *cobra.Command { }, } - cmd.Flags().String(flagProvedID, "", "identifier set by the counterparty chain") flags.AddTxFlagsToCmd(cmd) return cmd diff --git a/x/ibc/core/03-connection/client/utils/utils.go b/x/ibc/core/03-connection/client/utils/utils.go index 44283aef82..e1eb1ce00c 100644 --- a/x/ibc/core/03-connection/client/utils/utils.go +++ b/x/ibc/core/03-connection/client/utils/utils.go @@ -143,9 +143,9 @@ func QueryConnectionConsensusState( queryClient := types.NewQueryClient(clientCtx) req := &types.QueryConnectionConsensusStateRequest{ - ConnectionId: connectionID, - VersionNumber: height.VersionNumber, - VersionHeight: height.VersionHeight, + ConnectionId: connectionID, + RevisionNumber: height.RevisionNumber, + RevisionHeight: height.RevisionHeight, } res, err := queryClient.ConnectionConsensusState(context.Background(), req) diff --git a/x/ibc/core/03-connection/genesis.go b/x/ibc/core/03-connection/genesis.go index da8ffcd50d..4f97ed37ba 100644 --- a/x/ibc/core/03-connection/genesis.go +++ b/x/ibc/core/03-connection/genesis.go @@ -16,6 +16,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { for _, connPaths := range gs.ClientConnectionPaths { k.SetClientConnectionPaths(ctx, connPaths.ClientId, connPaths.Paths) } + k.SetNextConnectionSequence(ctx, gs.NextConnectionSequence) } // ExportGenesis returns the ibc connection submodule's exported genesis. diff --git a/x/ibc/core/03-connection/keeper/grpc_query.go b/x/ibc/core/03-connection/keeper/grpc_query.go index 5b34d1e4ef..62b1c00a34 100644 --- a/x/ibc/core/03-connection/keeper/grpc_query.go +++ b/x/ibc/core/03-connection/keeper/grpc_query.go @@ -160,7 +160,7 @@ func (q Keeper) ConnectionConsensusState(c context.Context, req *types.QueryConn ) } - height := clienttypes.NewHeight(req.VersionNumber, req.VersionHeight) + height := clienttypes.NewHeight(req.RevisionNumber, req.RevisionHeight) consensusState, found := q.clientKeeper.GetClientConsensusState(ctx, connection.ClientId, height) if !found { return nil, status.Error( diff --git a/x/ibc/core/03-connection/keeper/grpc_query_test.go b/x/ibc/core/03-connection/keeper/grpc_query_test.go index 7e27b5af10..553033810d 100644 --- a/x/ibc/core/03-connection/keeper/grpc_query_test.go +++ b/x/ibc/core/03-connection/keeper/grpc_query_test.go @@ -112,18 +112,18 @@ func (suite *KeeperTestSuite) TestQueryConnections() { "success", func() { clientA, clientB, connA0, connB0 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - connA1, connB1, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) + clientA1, clientB1, connA1, connB1 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) + connA2, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) - clientA1, clientB1, connA2, connB2 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - counterparty1 := types.NewCounterparty(clientB, connB0.ID, suite.chainB.GetPrefix()) - counterparty2 := types.NewCounterparty(clientB, connB1.ID, suite.chainB.GetPrefix()) - counterparty3 := types.NewCounterparty(clientB1, connB2.ID, suite.chainB.GetPrefix()) + counterparty2 := types.NewCounterparty(clientB1, connB1.ID, suite.chainB.GetPrefix()) + // counterparty connection id is blank after open init + counterparty3 := types.NewCounterparty(clientB, "", suite.chainB.GetPrefix()) conn1 := types.NewConnectionEnd(types.OPEN, clientA, counterparty1, types.ExportedVersionsToProto(types.GetCompatibleVersions())) - conn2 := types.NewConnectionEnd(types.INIT, clientA, counterparty2, types.ExportedVersionsToProto(types.GetCompatibleVersions())) - conn3 := types.NewConnectionEnd(types.OPEN, clientA1, counterparty3, types.ExportedVersionsToProto(types.GetCompatibleVersions())) + conn2 := types.NewConnectionEnd(types.OPEN, clientA1, counterparty2, types.ExportedVersionsToProto(types.GetCompatibleVersions())) + conn3 := types.NewConnectionEnd(types.INIT, clientA, counterparty3, types.ExportedVersionsToProto(types.GetCompatibleVersions())) iconn1 := types.NewIdentifiedConnection(connA0.ID, conn1) iconn2 := types.NewIdentifiedConnection(connA1.ID, conn2) @@ -339,8 +339,8 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { func() { req = &types.QueryConnectionConsensusStateRequest{ ConnectionId: "", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -350,8 +350,8 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { func() { req = &types.QueryConnectionConsensusStateRequest{ ConnectionId: "test-connection-id", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -363,8 +363,8 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { req = &types.QueryConnectionConsensusStateRequest{ ConnectionId: connA.ID, - VersionNumber: 0, - VersionHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height + RevisionNumber: 0, + RevisionHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height } }, false, }, @@ -380,8 +380,8 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { req = &types.QueryConnectionConsensusStateRequest{ ConnectionId: connA.ID, - VersionNumber: clientState.GetLatestHeight().GetVersionNumber(), - VersionHeight: clientState.GetLatestHeight().GetVersionHeight(), + RevisionNumber: clientState.GetLatestHeight().GetRevisionNumber(), + RevisionHeight: clientState.GetLatestHeight().GetRevisionHeight(), } }, true, diff --git a/x/ibc/core/03-connection/keeper/handshake.go b/x/ibc/core/03-connection/keeper/handshake.go index 0fce7d9006..7a7d700570 100644 --- a/x/ibc/core/03-connection/keeper/handshake.go +++ b/x/ibc/core/03-connection/keeper/handshake.go @@ -14,36 +14,33 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" ) -// ConnOpenInit initialises a connection attempt on chain A. +// ConnOpenInit initialises a connection attempt on chain A. The generated connection identifier +// is returned. // -// NOTE: Identifiers are checked on msg validation. +// NOTE: Msg validation verifies the supplied identifiers and ensures that the counterparty +// connection identifier is empty. func (k Keeper) ConnOpenInit( ctx sdk.Context, - connectionID, // identifier clientID string, - counterparty types.Counterparty, // desiredCounterpartyConnectionIdentifier, counterpartyPrefix, counterpartyClientIdentifier + counterparty types.Counterparty, // counterpartyPrefix, counterpartyClientIdentifier version *types.Version, -) error { - _, found := k.GetConnection(ctx, connectionID) - if found { - return sdkerrors.Wrap(types.ErrConnectionExists, connectionID) - } - +) (string, error) { versions := types.GetCompatibleVersions() if version != nil { if !types.IsSupportedVersion(version) { - return sdkerrors.Wrap(types.ErrInvalidVersion, "version is not supported") + return "", sdkerrors.Wrap(types.ErrInvalidVersion, "version is not supported") } versions = []exported.Version{version} } // connection defines chain A's ConnectionEnd + connectionID := k.GenerateConnectionIdentifier(ctx) connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.ExportedVersionsToProto(versions)) k.SetConnection(ctx, connectionID, connection) if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { - return err + return "", err } k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", "NONE", "new-state", "INIT") @@ -52,7 +49,7 @@ func (k Keeper) ConnOpenInit( telemetry.IncrCounter(1, "ibc", "connection", "open-init") }() - return nil + return connectionID, nil } // ConnOpenTry relays notice of a connection attempt on chain A to chain B (this @@ -63,8 +60,7 @@ func (k Keeper) ConnOpenInit( // - Identifiers are checked on msg validation func (k Keeper) ConnOpenTry( ctx sdk.Context, - desiredConnectionID, // desiredIdentifier - counterpartyChosenConnectionID string, // counterparty used this identifier in proof + previousConnectionID string, // previousIdentifier counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier clientID string, // clientID of chainA clientState exported.ClientState, // clientState that chainA has for chainB @@ -74,10 +70,47 @@ func (k Keeper) ConnOpenTry( proofConsensus []byte, // proof that chainA stored chainB's consensus state at consensus height proofHeight exported.Height, // height at which relayer constructs proof of A storing connectionEnd in state consensusHeight exported.Height, // latest height of chain B which chain A has stored in its chain B client -) error { +) (string, error) { + var ( + connectionID string + previousConnection types.ConnectionEnd + found bool + ) + + // empty connection identifier indicates continuing a previous connection handshake + if previousConnectionID != "" { + // ensure that the previous connection exists + previousConnection, found = k.GetConnection(ctx, previousConnectionID) + if !found { + return "", sdkerrors.Wrapf(types.ErrConnectionNotFound, "previous connection does not exist for supplied previous connectionID %s", previousConnectionID) + } + + // ensure that the existing connection's + // counterparty is chainA and connection is on INIT stage. + // Check that existing connection versions for initialized connection is equal to compatible + // versions for this chain. + if !(previousConnection.Counterparty.ConnectionId == "" && + bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) && + previousConnection.ClientId == clientID && + previousConnection.Counterparty.ClientId == counterparty.ClientId) { + return "", sdkerrors.Wrap(types.ErrInvalidConnection, "connection fields mismatch previous connection fields") + } + + if !(previousConnection.State == types.INIT) { + return "", sdkerrors.Wrapf(types.ErrInvalidConnectionState, "previous connection state is in state %s, expected INIT", previousConnection.State) + } + + // continue with previous connection + connectionID = previousConnectionID + + } else { + // generate a new connection + connectionID = k.GenerateConnectionIdentifier(ctx) + } + selfHeight := clienttypes.GetSelfHeight(ctx) if consensusHeight.GTE(selfHeight) { - return sdkerrors.Wrapf( + return "", sdkerrors.Wrapf( sdkerrors.ErrInvalidHeight, "consensus height is greater than or equal to the current block height (%s >= %s)", consensusHeight, selfHeight, ) @@ -85,43 +118,20 @@ func (k Keeper) ConnOpenTry( // validate client parameters of a chainB client stored on chainA if err := k.clientKeeper.ValidateSelfClient(ctx, clientState); err != nil { - return err + return "", err } expectedConsensusState, found := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if !found { - return sdkerrors.Wrap(clienttypes.ErrSelfConsensusStateNotFound, consensusHeight.String()) - } - - // If the connection id chosen for this connection end by the counterparty is empty then - // flexible connection identifier selection is allowed by using the desired connection id. - // Otherwise the desiredConnectionID must match the counterpartyChosenConnectionID. - if counterpartyChosenConnectionID != "" && counterpartyChosenConnectionID != desiredConnectionID { - return sdkerrors.Wrapf( - types.ErrInvalidConnectionIdentifier, - "counterparty chosen connection ID (%s) must be empty or equal to the desired connection ID (%s)", counterpartyChosenConnectionID, desiredConnectionID, - ) + return "", sdkerrors.Wrap(clienttypes.ErrSelfConsensusStateNotFound, consensusHeight.String()) } // expectedConnection defines Chain A's ConnectionEnd // NOTE: chain A's counterparty is chain B (i.e where this code is executed) prefix := k.GetCommitmentPrefix() - expectedCounterparty := types.NewCounterparty(clientID, counterpartyChosenConnectionID, commitmenttypes.NewMerklePrefix(prefix.Bytes())) + expectedCounterparty := types.NewCounterparty(clientID, "", commitmenttypes.NewMerklePrefix(prefix.Bytes())) expectedConnection := types.NewConnectionEnd(types.INIT, counterparty.ClientId, expectedCounterparty, types.ExportedVersionsToProto(counterpartyVersions)) - // If connection already exists for desiredConnectionID, ensure that the existing connection's - // counterparty is chainA and connection is on INIT stage. - // Check that existing connection versions for initialized connection is equal to compatible - // versions for this chain. - previousConnection, found := k.GetConnection(ctx, desiredConnectionID) - if found && !(previousConnection.State == types.INIT && - previousConnection.Counterparty.ConnectionId == counterparty.ConnectionId && - bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) && - previousConnection.ClientId == clientID && - previousConnection.Counterparty.ClientId == counterparty.ClientId) { - return sdkerrors.Wrap(types.ErrInvalidConnection, "cannot relay connection attempt") - } - supportedVersions := types.GetCompatibleVersions() if len(previousConnection.Versions) != 0 { supportedVersions = previousConnection.GetVersions() @@ -132,7 +142,7 @@ func (k Keeper) ConnOpenTry( // of the supported versions and the counterparty versions. version, err := types.PickVersion(supportedVersions, counterpartyVersions) if err != nil { - return err + return "", err } // connection defines chain B's ConnectionEnd @@ -143,34 +153,34 @@ func (k Keeper) ConnOpenTry( ctx, connection, proofHeight, proofInit, counterparty.ConnectionId, expectedConnection, ); err != nil { - return err + return "", err } // Check that ChainA stored the clientState provided in the msg if err := k.VerifyClientState(ctx, connection, proofHeight, proofClient, clientState); err != nil { - return err + return "", err } // Check that ChainA stored the correct ConsensusState of chainB at the given consensusHeight if err := k.VerifyClientConsensusState( ctx, connection, proofHeight, consensusHeight, proofConsensus, expectedConsensusState, ); err != nil { - return err + return "", err } // store connection in chainB state - if err := k.addConnectionToClient(ctx, clientID, desiredConnectionID); err != nil { - return sdkerrors.Wrapf(err, "failed to add connection with ID %s to client with ID %s", desiredConnectionID, clientID) + if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { + return "", sdkerrors.Wrapf(err, "failed to add connection with ID %s to client with ID %s", connectionID, clientID) } - k.SetConnection(ctx, desiredConnectionID, connection) - k.Logger(ctx).Info("connection state updated", "connection-id", desiredConnectionID, "previous-state", previousConnection.State.String(), "new-state", "TRYOPEN") + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", previousConnection.State.String(), "new-state", "TRYOPEN") defer func() { telemetry.IncrCounter(1, "ibc", "connection", "open-try") }() - return nil + return connectionID, nil } // ConnOpenAck relays acceptance of a connection open attempt from chain B back @@ -204,16 +214,6 @@ func (k Keeper) ConnOpenAck( return sdkerrors.Wrap(types.ErrConnectionNotFound, connectionID) } - // If the previously set connection end allowed for the counterparty to select its own - // connection identifier then we use the counterpartyConnectionID. Otherwise the - // counterpartyConnectionID must match the previously set counterparty connection ID. - if connection.Counterparty.ConnectionId != "" && counterpartyConnectionID != connection.Counterparty.ConnectionId { - return sdkerrors.Wrapf( - types.ErrInvalidConnectionIdentifier, - "counterparty connection identifier (%s) must be equal to stored connection ID for counterparty (%s)", counterpartyConnectionID, connection.Counterparty.ConnectionId, - ) - } - // Verify the provided version against the previously set connection state switch { // connection on ChainA must be in INIT or TRYOPEN diff --git a/x/ibc/core/03-connection/keeper/handshake_test.go b/x/ibc/core/03-connection/keeper/handshake_test.go index 2ece130ebb..eb9ca5c401 100644 --- a/x/ibc/core/03-connection/keeper/handshake_test.go +++ b/x/ibc/core/03-connection/keeper/handshake_test.go @@ -36,9 +36,6 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] }, true}, - {"connection already exists", func() { - clientA, clientB, _, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - }, false}, {"invalid version", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) version = &types.Version{} @@ -58,19 +55,20 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { tc.malleate() - connA := suite.chainA.GetFirstTestConnection(clientA, clientB) connB := suite.chainB.GetFirstTestConnection(clientB, clientA) if emptyConnBID { connB.ID = "" } counterparty := types.NewCounterparty(clientB, connB.ID, suite.chainB.GetPrefix()) - err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), connA.ID, clientA, counterparty, version) + connectionID, err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), clientA, counterparty, version) if tc.expPass { suite.Require().NoError(err) + suite.Require().Equal(types.FormatConnectionIdentifier(0), connectionID) } else { suite.Require().Error(err) + suite.Require().Equal("", connectionID) } }) } @@ -80,11 +78,12 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { // connection on chainA is INIT func (suite *KeeperTestSuite) TestConnOpenTry() { var ( - clientA string - clientB string - versions []exported.Version - consensusHeight exported.Height - counterpartyClient exported.ClientState + clientA string + clientB string + previousConnectionID string + versions []exported.Version + consensusHeight exported.Height + counterpartyClient exported.ClientState ) testCases := []struct { @@ -100,50 +99,16 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) }, true}, - {"success with empty counterpartyChosenConnectionID", func() { + {"success with crossing hellos", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to empty string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - - connection.Counterparty.ConnectionId = "" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) + _, connB, err := suite.coordinator.ConnOpenInitOnBothChains(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) + + previousConnectionID = connB.ID }, true}, - {"counterpartyChosenConnectionID does not match desiredConnectionID", func() { - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to invalid identifier - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - - connection.Counterparty.ConnectionId = "badidentifier" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - // retrieve client state of chainA to pass as counterpartyClient - counterpartyClient = suite.chainA.GetClientState(clientA) - }, false}, {"invalid counterparty client", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) _, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) @@ -255,6 +220,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) + + previousConnectionID = connB.ID }, false}, {"invalid previous connection has invalid versions", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) @@ -281,6 +248,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) + + previousConnectionID = connB.ID }, false}, } @@ -291,20 +260,13 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.SetupTest() // reset consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate versions = types.GetCompatibleVersions() // must be explicitly changed in malleate + previousConnectionID = "" tc.malleate() connA := suite.chainA.GetFirstTestConnection(clientA, clientB) - connB := suite.chainB.GetFirstTestConnection(clientB, clientA) counterparty := types.NewCounterparty(clientA, connA.ID, suite.chainA.GetPrefix()) - // get counterpartyChosenConnectionID - var counterpartyChosenConnectionID string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - if found { - counterpartyChosenConnectionID = connection.Counterparty.ConnectionId - } - connectionKey := host.ConnectionKey(connA.ID) proofInit, proofHeight := suite.chainA.QueryProof(connectionKey) @@ -319,16 +281,18 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { clientKey := host.FullClientStateKey(clientA) proofClient, _ := suite.chainA.QueryProof(clientKey) - err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( - suite.chainB.GetContext(), connB.ID, counterpartyChosenConnectionID, counterparty, clientB, counterpartyClient, + connectionID, err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( + suite.chainB.GetContext(), previousConnectionID, counterparty, clientB, counterpartyClient, versions, proofInit, proofClient, proofConsensus, proofHeight, consensusHeight, ) if tc.expPass { suite.Require().NoError(err) + suite.Require().Equal(types.FormatConnectionIdentifier(0), connectionID) } else { suite.Require().Error(err) + suite.Require().Equal("", connectionID) } }) } @@ -338,12 +302,11 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // the initialization (TRYINIT) of the connection on Chain B (ID #2). func (suite *KeeperTestSuite) TestConnOpenAck() { var ( - clientA string - clientB string - counterpartyConnectionID string - consensusHeight exported.Height - version *types.Version - counterpartyClient exported.ClientState + clientA string + clientB string + consensusHeight exported.Height + version *types.Version + counterpartyClient exported.ClientState ) testCases := []struct { @@ -362,33 +325,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // retrieve client state of chainB to pass as counterpartyClient counterpartyClient = suite.chainB.GetClientState(clientB) }, true}, - {"success with empty stored counterparty connection ID", func() { - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - err = suite.coordinator.ConnOpenTry(suite.chainB, suite.chainA, connB, connA) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to empty string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - - connection.Counterparty.ConnectionId = "" - // use some other identifier - counterpartyConnectionID = connB.ID - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - // retrieve client state of chainB to pass as counterpartyClient - counterpartyClient = suite.chainB.GetClientState(clientB) - }, true}, {"success from tryopen", func() { // chainA is in TRYOPEN, chainB is in TRYOPEN clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) @@ -401,6 +337,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // set chainB to TRYOPEN connection := suite.chainB.GetConnection(connB) connection.State = types.TRYOPEN + connection.Counterparty.ConnectionId = connA.ID suite.chainB.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainB.GetContext(), connB.ID, connection) // update clientB so state change is committed suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) @@ -410,37 +347,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // retrieve client state of chainB to pass as counterpartyClient counterpartyClient = suite.chainB.GetClientState(clientB) }, true}, - {"success from tryopen with empty stored connection id", func() { - // chainA is in TRYOPEN, chainB is in TRYOPEN - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connB, connA, err := suite.coordinator.ConnOpenInit(suite.chainB, suite.chainA, clientB, clientA) - suite.Require().NoError(err) - - err = suite.coordinator.ConnOpenTry(suite.chainA, suite.chainB, connA, connB) - suite.Require().NoError(err) - - // set chainB to TRYOPEN - connection := suite.chainB.GetConnection(connB) - connection.State = types.TRYOPEN - - suite.chainB.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainB.GetContext(), connB.ID, connection) - - // set connA to use empty string - connection = suite.chainA.GetConnection(connA) - - // set counterparty connection identifier to empty string - connection.Counterparty.ConnectionId = "" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - // update clientB so state change is committed - suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - - suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - - // retrieve client state of chainB to pass as counterpartyClient - counterpartyClient = suite.chainB.GetClientState(clientB) - }, true}, {"invalid counterparty client", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) @@ -663,17 +569,12 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.SetupTest() // reset version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] // must be explicitly changed in malleate consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate - counterpartyConnectionID = "" // must be explicitly changed in malleate tc.malleate() connA := suite.chainA.GetFirstTestConnection(clientA, clientB) connB := suite.chainB.GetFirstTestConnection(clientB, clientA) - if counterpartyConnectionID == "" { - counterpartyConnectionID = connB.ID - } - connectionKey := host.ConnectionKey(connB.ID) proofTry, proofHeight := suite.chainB.QueryProof(connectionKey) @@ -690,7 +591,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { proofClient, _ := suite.chainB.QueryProof(clientKey) err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenAck( - suite.chainA.GetContext(), connA.ID, counterpartyClient, version, counterpartyConnectionID, + suite.chainA.GetContext(), connA.ID, counterpartyClient, version, connB.ID, proofTry, proofClient, proofConsensus, proofHeight, consensusHeight, ) diff --git a/x/ibc/core/03-connection/keeper/keeper.go b/x/ibc/core/03-connection/keeper/keeper.go index dda5295877..05d110fec8 100644 --- a/x/ibc/core/03-connection/keeper/keeper.go +++ b/x/ibc/core/03-connection/keeper/keeper.go @@ -45,6 +45,16 @@ func (k Keeper) GetCommitmentPrefix() exported.Prefix { return commitmenttypes.NewMerklePrefix([]byte(k.storeKey.Name())) } +// GenerateConnectionIdentifier returns the next connection identifier. +func (k Keeper) GenerateConnectionIdentifier(ctx sdk.Context) string { + nextConnSeq := k.GetNextConnectionSequence(ctx) + connectionID := types.FormatConnectionIdentifier(nextConnSeq) + + nextConnSeq++ + k.SetNextConnectionSequence(ctx, nextConnSeq) + return connectionID +} + // GetConnection returns a connection with a particular identifier func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { store := ctx.KVStore(k.storeKey) @@ -105,6 +115,24 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths store.Set(host.ClientConnectionsKey(clientID), bz) } +// GetNextConnectionSequence gets the next connection sequence from the store. +func (k Keeper) GetNextConnectionSequence(ctx sdk.Context) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get([]byte(types.KeyNextConnectionSequence)) + if bz == nil { + panic("next connection sequence is nil") + } + + return sdk.BigEndianToUint64(bz) +} + +// SetNextConnectionSequence sets the next connection sequence to the store. +func (k Keeper) SetNextConnectionSequence(ctx sdk.Context, sequence uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set([]byte(types.KeyNextConnectionSequence), bz) +} + // GetAllClientConnectionPaths returns all stored clients connection id paths. It // will ignore the clients that haven't initialized a connection handshake since // no paths are stored. diff --git a/x/ibc/core/03-connection/keeper/verify_test.go b/x/ibc/core/03-connection/keeper/verify_test.go index 3b047e741a..4bf1bfb9da 100644 --- a/x/ibc/core/03-connection/keeper/verify_test.go +++ b/x/ibc/core/03-connection/keeper/verify_test.go @@ -478,5 +478,5 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { } func malleateHeight(height exported.Height, diff uint64) exported.Height { - return clienttypes.NewHeight(height.GetVersionNumber(), height.GetVersionHeight()+diff) + return clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+diff) } diff --git a/x/ibc/core/03-connection/types/connection_test.go b/x/ibc/core/03-connection/types/connection_test.go index 93891cbea1..133bb1e5c6 100644 --- a/x/ibc/core/03-connection/types/connection_test.go +++ b/x/ibc/core/03-connection/types/connection_test.go @@ -13,7 +13,7 @@ import ( var ( chainID = "gaiamainnet" - connectionID = "connectionidone" + connectionID = "connection-0" clientID = "clientidone" connectionID2 = "connectionidtwo" clientID2 = "clientidtwo" diff --git a/x/ibc/core/03-connection/types/genesis.go b/x/ibc/core/03-connection/types/genesis.go index 58b21678c2..f5af9b8486 100644 --- a/x/ibc/core/03-connection/types/genesis.go +++ b/x/ibc/core/03-connection/types/genesis.go @@ -17,18 +17,21 @@ func NewConnectionPaths(id string, paths []string) ConnectionPaths { // NewGenesisState creates a GenesisState instance. func NewGenesisState( connections []IdentifiedConnection, connPaths []ConnectionPaths, + nextConnectionSequence uint64, ) GenesisState { return GenesisState{ - Connections: connections, - ClientConnectionPaths: connPaths, + Connections: connections, + ClientConnectionPaths: connPaths, + NextConnectionSequence: nextConnectionSequence, } } // DefaultGenesisState returns the ibc connection submodule's default genesis state. func DefaultGenesisState() GenesisState { return GenesisState{ - Connections: []IdentifiedConnection{}, - ClientConnectionPaths: []ConnectionPaths{}, + Connections: []IdentifiedConnection{}, + ClientConnectionPaths: []ConnectionPaths{}, + NextConnectionSequence: 0, } } diff --git a/x/ibc/core/03-connection/types/genesis.pb.go b/x/ibc/core/03-connection/types/genesis.pb.go index ba8b3bcd5b..19c4e6aeb8 100644 --- a/x/ibc/core/03-connection/types/genesis.pb.go +++ b/x/ibc/core/03-connection/types/genesis.pb.go @@ -27,6 +27,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { Connections []IdentifiedConnection `protobuf:"bytes,1,rep,name=connections,proto3" json:"connections"` ClientConnectionPaths []ConnectionPaths `protobuf:"bytes,2,rep,name=client_connection_paths,json=clientConnectionPaths,proto3" json:"client_connection_paths" yaml:"client_connection_paths"` + // the sequence for the next generated connection identifier + NextConnectionSequence uint64 `protobuf:"varint,3,opt,name=next_connection_sequence,json=nextConnectionSequence,proto3" json:"next_connection_sequence,omitempty" yaml:"next_connection_sequence"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -76,6 +78,13 @@ func (m *GenesisState) GetClientConnectionPaths() []ConnectionPaths { return nil } +func (m *GenesisState) GetNextConnectionSequence() uint64 { + if m != nil { + return m.NextConnectionSequence + } + return 0 +} + func init() { proto.RegisterType((*GenesisState)(nil), "ibc.core.connection.v1.GenesisState") } @@ -85,25 +94,28 @@ func init() { } var fileDescriptor_1879d34bc6ac3cd7 = []byte{ - // 281 bytes of a gzipped FileDescriptorProto + // 326 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc9, 0x4c, 0x4a, 0xd6, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcb, 0x4b, 0x4d, 0x2e, 0xc9, 0xcc, 0xcf, 0xd3, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xcb, 0x4c, 0x4a, 0xd6, 0x03, 0xa9, 0xd2, 0x43, 0xa8, 0xd2, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0xa5, 0xd4, 0x71, 0x98, 0x89, - 0xa4, 0x17, 0xac, 0x50, 0xe9, 0x1d, 0x23, 0x17, 0x8f, 0x3b, 0xc4, 0xa2, 0xe0, 0x92, 0xc4, 0x92, + 0xa4, 0x17, 0xac, 0x50, 0xe9, 0x2c, 0x13, 0x17, 0x8f, 0x3b, 0xc4, 0xa2, 0xe0, 0x92, 0xc4, 0x92, 0x54, 0xa1, 0x10, 0x2e, 0x6e, 0x84, 0xa2, 0x62, 0x09, 0x46, 0x05, 0x66, 0x0d, 0x6e, 0x23, 0x1d, 0x3d, 0xec, 0xb6, 0xeb, 0x79, 0xa6, 0xa4, 0xe6, 0x95, 0x64, 0xa6, 0x65, 0xa6, 0xa6, 0x38, 0xc3, 0xc5, 0x9d, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x42, 0x36, 0x46, 0xa8, 0x9d, 0x91, 0x4b, 0x3c, 0x39, 0x27, 0x33, 0x35, 0xaf, 0x24, 0x1e, 0x21, 0x1c, 0x5f, 0x90, 0x58, 0x92, 0x51, 0x2c, 0xc1, 0x04, 0xb6, 0x42, 0x1d, 0x97, 0x15, 0x08, 0x83, 0x03, 0x40, 0xca, 0x9d, 0xd4, 0x40, 0xa6, 0x7f, 0xba, 0x27, 0x2f, 0x57, 0x99, 0x98, 0x9b, 0x63, 0xa5, 0x84, 0xc3, 0x54, 0xa5, 0x20, 0x51, 0x88, - 0x0c, 0xba, 0xf6, 0xd0, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, - 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x4e, - 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, - 0x86, 0x52, 0xba, 0xc5, 0x29, 0xd9, 0xfa, 0x15, 0xfa, 0xf0, 0x20, 0x35, 0x30, 0xd6, 0x45, 0x0a, - 0xd5, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0x70, 0x70, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, - 0xff, 0xae, 0x12, 0xc8, 0x83, 0xcd, 0x01, 0x00, 0x00, + 0x0c, 0x9a, 0x76, 0xa1, 0x58, 0x2e, 0x89, 0xbc, 0xd4, 0x0a, 0x14, 0x0d, 0xc5, 0xa9, 0x85, 0xa5, + 0xa9, 0x79, 0xc9, 0xa9, 0x12, 0xcc, 0x0a, 0x8c, 0x1a, 0x2c, 0x4e, 0xca, 0x9f, 0xee, 0xc9, 0xcb, + 0x43, 0x0c, 0xc7, 0xa5, 0x52, 0x29, 0x48, 0x0c, 0x24, 0x85, 0x30, 0x3b, 0x18, 0x2a, 0xe1, 0x14, + 0x7a, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, + 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xd6, 0xe9, 0x99, 0x25, 0x19, + 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0x50, 0x4a, 0xb7, + 0x38, 0x25, 0x5b, 0xbf, 0x42, 0x1f, 0x1e, 0x63, 0x06, 0xc6, 0xba, 0x48, 0x91, 0x56, 0x52, 0x59, + 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x8e, 0x2d, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xad, + 0x14, 0x09, 0x2c, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -126,6 +138,11 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NextConnectionSequence != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.NextConnectionSequence)) + i-- + dAtA[i] = 0x18 + } if len(m.ClientConnectionPaths) > 0 { for iNdEx := len(m.ClientConnectionPaths) - 1; iNdEx >= 0; iNdEx-- { { @@ -186,6 +203,9 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if m.NextConnectionSequence != 0 { + n += 1 + sovGenesis(uint64(m.NextConnectionSequence)) + } return n } @@ -292,6 +312,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextConnectionSequence", wireType) + } + m.NextConnectionSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextConnectionSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/ibc/core/03-connection/types/genesis_test.go b/x/ibc/core/03-connection/types/genesis_test.go index 6290a98a9f..343d69b08e 100644 --- a/x/ibc/core/03-connection/types/genesis_test.go +++ b/x/ibc/core/03-connection/types/genesis_test.go @@ -31,6 +31,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{connectionID}}, }, + 0, ), expPass: true, }, @@ -43,6 +44,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{connectionID}}, }, + 0, ), expPass: false, }, @@ -55,6 +57,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {"(CLIENTIDONE)", []string{connectionID}}, }, + 0, ), expPass: false, }, @@ -67,6 +70,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{invalidConnectionID}}, }, + 0, ), expPass: false, }, diff --git a/x/ibc/core/03-connection/types/keys.go b/x/ibc/core/03-connection/types/keys.go index 23478ec759..c44602203e 100644 --- a/x/ibc/core/03-connection/types/keys.go +++ b/x/ibc/core/03-connection/types/keys.go @@ -1,5 +1,13 @@ package types +import ( + "fmt" + "strconv" + "strings" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + const ( // SubModuleName defines the IBC connection name SubModuleName = "connection" @@ -12,4 +20,40 @@ const ( // QuerierRoute is the querier route for IBC connections QuerierRoute = SubModuleName + + // KeyNextConnectionSequence is the key used to store the next connection sequence in + // the keeper. + KeyNextConnectionSequence = "nextConnectionSequence" + + // ConnectionPrefix is the prefix used when creating a connection identifier + ConnectionPrefix = "connection-" ) + +// FormatConnectionIdentifier returns the connection identifier with the sequence appended. +func FormatConnectionIdentifier(sequence uint64) string { + return fmt.Sprintf("%s%d", ConnectionPrefix, sequence) +} + +// IsValidConnectionID return true if the connection identifier is valid. +func IsValidConnectionID(connectionID string) bool { + _, err := ParseConnectionSequence(connectionID) + return err == nil +} + +// ParseConnectionSequence parses the connection sequence from the connection identifier. +func ParseConnectionSequence(connectionID string) (uint64, error) { + if !strings.HasPrefix(connectionID, ConnectionPrefix) { + return 0, sdkerrors.Wrapf(ErrInvalidConnectionIdentifier, "doesn't contain prefix `%s`", ConnectionPrefix) + } + + splitStr := strings.Split(connectionID, ConnectionPrefix) + if len(splitStr) != 2 { + return 0, sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "connection identifier must be in format: `connection-{N}`") + } + + sequence, err := strconv.ParseUint(splitStr[1], 10, 64) + if err != nil { + return 0, sdkerrors.Wrap(err, "failed to parse connection identifier sequence") + } + return sequence, nil +} diff --git a/x/ibc/core/03-connection/types/keys_test.go b/x/ibc/core/03-connection/types/keys_test.go new file mode 100644 index 0000000000..261bd2895f --- /dev/null +++ b/x/ibc/core/03-connection/types/keys_test.go @@ -0,0 +1,44 @@ +package types_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types" + "github.com/stretchr/testify/require" +) + +// tests ParseConnectionSequence and IsValidConnectionID +func TestParseConnectionSequence(t *testing.T) { + testCases := []struct { + name string + connectionID string + expSeq uint64 + expPass bool + }{ + {"valid 0", "connection-0", 0, true}, + {"valid 1", "connection-1", 1, true}, + {"valid large sequence", "connection-234568219356718293", 234568219356718293, true}, + // uint64 == 20 characters + {"invalid large sequence", "connection-2345682193567182931243", 0, false}, + {"capital prefix", "Connection-0", 0, false}, + {"missing dash", "connection0", 0, false}, + {"blank id", " ", 0, false}, + {"empty id", "", 0, false}, + {"negative sequence", "connection--1", 0, false}, + } + + for _, tc := range testCases { + + seq, err := types.ParseConnectionSequence(tc.connectionID) + valid := types.IsValidConnectionID(tc.connectionID) + require.Equal(t, tc.expSeq, seq) + + if tc.expPass { + require.NoError(t, err, tc.name) + require.True(t, valid) + } else { + require.Error(t, err, tc.name) + require.False(t, valid) + } + } +} diff --git a/x/ibc/core/03-connection/types/msgs.go b/x/ibc/core/03-connection/types/msgs.go index a162fb589b..a734f98608 100644 --- a/x/ibc/core/03-connection/types/msgs.go +++ b/x/ibc/core/03-connection/types/msgs.go @@ -12,16 +12,16 @@ import ( var _ sdk.Msg = &MsgConnectionOpenInit{} -// NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance +// NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance. It sets the +// counterparty connection identifier to be empty. //nolint:interfacer func NewMsgConnectionOpenInit( - connectionID, clientID, counterpartyConnectionID, - counterpartyClientID string, counterpartyPrefix commitmenttypes.MerklePrefix, + clientID, counterpartyClientID string, + counterpartyPrefix commitmenttypes.MerklePrefix, version *Version, signer sdk.AccAddress, ) *MsgConnectionOpenInit { - counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) + counterparty := NewCounterparty(counterpartyClientID, "", counterpartyPrefix) return &MsgConnectionOpenInit{ - ConnectionId: connectionID, ClientId: clientID, Counterparty: counterparty, Version: version, @@ -41,12 +41,13 @@ func (msg MsgConnectionOpenInit) Type() string { // ValidateBasic implements sdk.Msg. func (msg MsgConnectionOpenInit) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") - } if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { return sdkerrors.Wrap(err, "invalid client ID") } + if msg.Counterparty.ConnectionId != "" { + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty connection identifier must be empty") + } + // NOTE: Version can be nil on MsgConnectionOpenInit if msg.Version != nil { if err := ValidateVersion(msg.Version); err != nil { @@ -80,7 +81,7 @@ var _ sdk.Msg = &MsgConnectionOpenTry{} // NewMsgConnectionOpenTry creates a new MsgConnectionOpenTry instance //nolint:interfacer func NewMsgConnectionOpenTry( - desiredConnectionID, counterpartyChosenConnectionID, clientID, counterpartyConnectionID, + previousConnectionID, clientID, counterpartyConnectionID, counterpartyClientID string, counterpartyClient exported.ClientState, counterpartyPrefix commitmenttypes.MerklePrefix, counterpartyVersions []*Version, proofInit, proofClient, proofConsensus []byte, @@ -89,18 +90,17 @@ func NewMsgConnectionOpenTry( counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) csAny, _ := clienttypes.PackClientState(counterpartyClient) return &MsgConnectionOpenTry{ - DesiredConnectionId: desiredConnectionID, - CounterpartyChosenConnectionId: counterpartyChosenConnectionID, - ClientId: clientID, - ClientState: csAny, - Counterparty: counterparty, - CounterpartyVersions: counterpartyVersions, - ProofInit: proofInit, - ProofClient: proofClient, - ProofConsensus: proofConsensus, - ProofHeight: proofHeight, - ConsensusHeight: consensusHeight, - Signer: signer.String(), + PreviousConnectionId: previousConnectionID, + ClientId: clientID, + ClientState: csAny, + Counterparty: counterparty, + CounterpartyVersions: counterpartyVersions, + ProofInit: proofInit, + ProofClient: proofClient, + ProofConsensus: proofConsensus, + ProofHeight: proofHeight, + ConsensusHeight: consensusHeight, + Signer: signer.String(), } } @@ -116,15 +116,19 @@ func (msg MsgConnectionOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenTry) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.DesiredConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid desired connection ID") - } - if msg.CounterpartyChosenConnectionId != "" && msg.CounterpartyChosenConnectionId != msg.DesiredConnectionId { - return sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "counterparty chosen connection identifier must be empty or equal to desired connection identifier") + // an empty connection identifier indicates that a connection identifier should be generated + if msg.PreviousConnectionId != "" { + if !IsValidConnectionID(msg.PreviousConnectionId) { + return sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "invalid previous connection ID") + } } if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { return sdkerrors.Wrap(err, "invalid client ID") } + // counterparty validate basic allows empty counterparty connection identifiers + if err := host.ConnectionIdentifierValidator(msg.Counterparty.ConnectionId); err != nil { + return sdkerrors.Wrap(err, "invalid counterparty connection ID") + } if msg.ClientState == nil { return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "counterparty client is nil") } @@ -234,8 +238,8 @@ func (msg MsgConnectionOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenAck) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") + if !IsValidConnectionID(msg.ConnectionId) { + return ErrInvalidConnectionIdentifier } if err := host.ConnectionIdentifierValidator(msg.CounterpartyConnectionId); err != nil { return sdkerrors.Wrap(err, "invalid counterparty connection ID") @@ -318,8 +322,8 @@ func (msg MsgConnectionOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenConfirm) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") + if !IsValidConnectionID(msg.ConnectionId) { + return ErrInvalidConnectionIdentifier } if len(msg.ProofAck) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") diff --git a/x/ibc/core/03-connection/types/msgs_test.go b/x/ibc/core/03-connection/types/msgs_test.go index 675de99347..9c09ec1f7b 100644 --- a/x/ibc/core/03-connection/types/msgs_test.go +++ b/x/ibc/core/03-connection/types/msgs_test.go @@ -87,14 +87,13 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() { msg *types.MsgConnectionOpenInit expPass bool }{ - {"invalid connection ID", types.NewMsgConnectionOpenInit("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, version, signer), false}, - {"invalid client ID", types.NewMsgConnectionOpenInit("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, version, signer), false}, - {"invalid counterparty client ID", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "test/conn1", "clienttotest", prefix, version, signer), false}, - {"invalid counterparty connection ID", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "test/conn1", prefix, version, signer), false}, - {"empty counterparty prefix", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", emptyPrefix, version, signer), false}, - {"supplied version fails basic validation", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, &types.Version{}, signer), false}, - {"empty singer", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, version, nil), false}, - {"success", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, version, signer), true}, + {"invalid client ID", types.NewMsgConnectionOpenInit("test/iris", "clienttotest", prefix, version, signer), false}, + {"invalid counterparty client ID", types.NewMsgConnectionOpenInit("clienttotest", "(clienttotest)", prefix, version, signer), false}, + {"invalid counterparty connection ID", &types.MsgConnectionOpenInit{connectionID, types.NewCounterparty("clienttotest", "connectiontotest", prefix), version, signer.String()}, false}, + {"empty counterparty prefix", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", emptyPrefix, version, signer), false}, + {"supplied version fails basic validation", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, &types.Version{}, signer), false}, + {"empty singer", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, nil), false}, + {"success", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, signer), true}, } for _, tc := range testCases { @@ -112,7 +111,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") clientState := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) // Pack consensus state into any to test unpacking error @@ -124,33 +123,32 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { // invalidClientState fails validateBasic invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) - provedID := "" var testCases = []struct { name string msg *types.MsgConnectionOpenTry expPass bool }{ - {"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid connection ID", types.NewMsgConnectionOpenTry("ibcconntest", "test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid client ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid counterparty client ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid nil counterparty client", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid client unpacking", &types.MsgConnectionOpenTry{"ibcconntest", provedID, "clienttotesta", invalidAny, counterparty, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer.String()}, false}, - {"counterparty failed Validate", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty counterparty prefix", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty counterpartyVersions", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofInit", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofClient", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofConsensus", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, - {"invalid proofHeight", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false}, - {"invalid consensusHeight", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, - {"empty singer", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, nil), false}, - {"success", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, - {"invalid version", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid connection ID", types.NewMsgConnectionOpenTry("(invalidconnection)", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid client ID", types.NewMsgConnectionOpenTry(connectionID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid counterparty client ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid nil counterparty client", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid client unpacking", &types.MsgConnectionOpenTry{connectionID, "clienttotesta", invalidAny, counterparty, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer.String()}, false}, + {"counterparty failed Validate", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty counterparty prefix", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty counterpartyVersions", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofInit", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofClient", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofConsensus", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, + {"invalid proofHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false}, + {"invalid consensusHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, + {"empty singer", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, nil), false}, + {"success", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, + {"invalid version", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, } for _, tc := range testCases { @@ -166,7 +164,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") clientState := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) // Pack consensus state into any to test unpacking error @@ -177,9 +175,9 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { // invalidClientState fails validateBasic invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) - connectionID := "ibcconntest" + connectionID := "connection-0" var testCases = []struct { name string @@ -216,10 +214,10 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { testMsgs := []*types.MsgConnectionOpenConfirm{ types.NewMsgConnectionOpenConfirm("test/conn1", suite.proof, clientHeight, signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", emptyProof, clientHeight, signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clienttypes.ZeroHeight(), signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clientHeight, nil), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clientHeight, signer), + types.NewMsgConnectionOpenConfirm(connectionID, emptyProof, clientHeight, signer), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clienttypes.ZeroHeight(), signer), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clientHeight, nil), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clientHeight, signer), } var testCases = []struct { diff --git a/x/ibc/core/03-connection/types/query.pb.go b/x/ibc/core/03-connection/types/query.pb.go index 5c3a2bcb26..2861c8a5fb 100644 --- a/x/ibc/core/03-connection/types/query.pb.go +++ b/x/ibc/core/03-connection/types/query.pb.go @@ -484,9 +484,9 @@ func (m *QueryConnectionClientStateResponse) GetProofHeight() types.Height { // Query/ConnectionConsensusState RPC method type QueryConnectionConsensusStateRequest struct { // connection identifier - ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` - VersionNumber uint64 `protobuf:"varint,2,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty"` - VersionHeight uint64 `protobuf:"varint,3,opt,name=version_height,json=versionHeight,proto3" json:"version_height,omitempty"` + ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` + RevisionNumber uint64 `protobuf:"varint,2,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty"` + RevisionHeight uint64 `protobuf:"varint,3,opt,name=revision_height,json=revisionHeight,proto3" json:"revision_height,omitempty"` } func (m *QueryConnectionConsensusStateRequest) Reset() { *m = QueryConnectionConsensusStateRequest{} } @@ -529,16 +529,16 @@ func (m *QueryConnectionConsensusStateRequest) GetConnectionId() string { return "" } -func (m *QueryConnectionConsensusStateRequest) GetVersionNumber() uint64 { +func (m *QueryConnectionConsensusStateRequest) GetRevisionNumber() uint64 { if m != nil { - return m.VersionNumber + return m.RevisionNumber } return 0 } -func (m *QueryConnectionConsensusStateRequest) GetVersionHeight() uint64 { +func (m *QueryConnectionConsensusStateRequest) GetRevisionHeight() uint64 { if m != nil { - return m.VersionHeight + return m.RevisionHeight } return 0 } @@ -635,63 +635,63 @@ func init() { } var fileDescriptor_cd8d529f8c7cd06b = []byte{ - // 887 bytes of a gzipped FileDescriptorProto + // 892 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x41, 0x4f, 0x33, 0x45, - 0x18, 0xee, 0x14, 0xbe, 0x2f, 0x1f, 0x53, 0x40, 0x9d, 0x14, 0xa8, 0xab, 0x16, 0x5c, 0x45, 0x0a, - 0x91, 0x19, 0x0a, 0xd1, 0x20, 0xd0, 0x44, 0x21, 0x88, 0x1c, 0x24, 0xb8, 0xc6, 0x8b, 0x17, 0xb2, - 0xbb, 0x1d, 0xb6, 0x1b, 0xe9, 0x4e, 0xe9, 0x6e, 0x1b, 0x1b, 0xd2, 0x83, 0xfe, 0x02, 0x13, 0x8f, - 0xde, 0x3c, 0x70, 0xf5, 0xe0, 0xd1, 0x1f, 0x20, 0x47, 0x12, 0x2f, 0x5e, 0x24, 0xa6, 0x78, 0xf5, - 0xe2, 0x2f, 0x30, 0x3b, 0x33, 0x65, 0x67, 0xe9, 0xb6, 0x94, 0xe6, 0xe3, 0xd4, 0xdd, 0x77, 0xde, - 0x77, 0xe6, 0x79, 0x9e, 0xf7, 0x9d, 0x67, 0x0b, 0x75, 0xd7, 0xb2, 0x89, 0xcd, 0xea, 0x94, 0xd8, - 0xcc, 0xf3, 0xa8, 0x1d, 0xb8, 0xcc, 0x23, 0xcd, 0x22, 0x39, 0x6f, 0xd0, 0x7a, 0x0b, 0xd7, 0xea, - 0x2c, 0x60, 0x68, 0xd6, 0xb5, 0x6c, 0x1c, 0xe6, 0xe0, 0x28, 0x07, 0x37, 0x8b, 0x5a, 0xd6, 0x61, - 0x0e, 0xe3, 0x29, 0x24, 0x7c, 0x12, 0xd9, 0xda, 0x8a, 0xcd, 0xfc, 0x2a, 0xf3, 0x89, 0x65, 0xfa, - 0x54, 0x6c, 0x43, 0x9a, 0x45, 0x8b, 0x06, 0x66, 0x91, 0xd4, 0x4c, 0xc7, 0xf5, 0x4c, 0x5e, 0x2e, - 0x72, 0xe7, 0xa3, 0xd3, 0xcf, 0x5c, 0xea, 0x05, 0xe1, 0xc9, 0xe2, 0x49, 0x26, 0x2c, 0xf5, 0x81, - 0xa7, 0x00, 0x11, 0x89, 0x6f, 0x3a, 0x8c, 0x39, 0x67, 0x94, 0x98, 0x35, 0x97, 0x98, 0x9e, 0xc7, - 0x02, 0x7e, 0x8c, 0x2f, 0x57, 0x5f, 0x97, 0xab, 0xfc, 0xcd, 0x6a, 0x9c, 0x12, 0xd3, 0x93, 0xe4, - 0xf4, 0x12, 0x9c, 0xfd, 0x22, 0x04, 0xb9, 0x77, 0xb7, 0xa3, 0x41, 0xcf, 0x1b, 0xd4, 0x0f, 0xd0, - 0x3b, 0x70, 0x2a, 0x3a, 0xe6, 0xc4, 0x2d, 0xe7, 0xc0, 0x02, 0x28, 0x4c, 0x18, 0x93, 0x51, 0xf0, - 0xb0, 0xac, 0xff, 0x06, 0xe0, 0x5c, 0x4f, 0xbd, 0x5f, 0x63, 0x9e, 0x4f, 0xd1, 0x3e, 0x84, 0x51, - 0x2e, 0xaf, 0xce, 0xac, 0x2f, 0xe2, 0x64, 0x31, 0x71, 0x54, 0xbf, 0xef, 0x95, 0x0d, 0xa5, 0x10, - 0x65, 0xe1, 0xb3, 0x5a, 0x9d, 0xb1, 0xd3, 0x5c, 0x7a, 0x01, 0x14, 0x26, 0x0d, 0xf1, 0x82, 0xf6, - 0xe0, 0x24, 0x7f, 0x38, 0xa9, 0x50, 0xd7, 0xa9, 0x04, 0xb9, 0x31, 0xbe, 0xbd, 0xa6, 0x6c, 0x2f, - 0x74, 0x6c, 0x16, 0xf1, 0x67, 0x3c, 0x63, 0x77, 0xfc, 0xea, 0x66, 0x3e, 0x65, 0x64, 0x78, 0x95, - 0x08, 0xe9, 0x66, 0x0f, 0x78, 0xbf, 0xcb, 0xfe, 0x53, 0x08, 0xa3, 0x76, 0x49, 0xf0, 0xef, 0x61, - 0xd1, 0x5b, 0x1c, 0xf6, 0x16, 0x8b, 0x11, 0x91, 0xbd, 0xc5, 0xc7, 0xa6, 0x43, 0x65, 0xad, 0xa1, - 0x54, 0xea, 0xff, 0x02, 0x98, 0xeb, 0x3d, 0x43, 0x2a, 0x74, 0x04, 0x33, 0x11, 0x51, 0x3f, 0x07, - 0x16, 0xc6, 0x0a, 0x99, 0xf5, 0xf7, 0xfb, 0x49, 0x74, 0x58, 0xa6, 0x5e, 0xe0, 0x9e, 0xba, 0xb4, - 0xac, 0x88, 0xad, 0x6e, 0x80, 0x0e, 0x62, 0xa0, 0xd3, 0x1c, 0xf4, 0xd2, 0x83, 0xa0, 0x05, 0x18, - 0x15, 0x35, 0xda, 0x84, 0xcf, 0x1f, 0xa9, 0xab, 0xcc, 0xd7, 0x77, 0xe0, 0x5b, 0x82, 0x2e, 0x4f, - 0x4b, 0x10, 0xf6, 0x0d, 0x38, 0x21, 0xb6, 0x88, 0x46, 0xea, 0x85, 0x08, 0x1c, 0x96, 0xf5, 0x4b, - 0x00, 0xf3, 0xfd, 0xca, 0xa5, 0x66, 0xcb, 0xf0, 0x55, 0x65, 0x2c, 0x6b, 0x66, 0x50, 0x11, 0xc2, - 0x4d, 0x18, 0xaf, 0x44, 0xf1, 0xe3, 0x30, 0xfc, 0x94, 0x93, 0x63, 0xc1, 0xb7, 0xef, 0x75, 0x55, - 0x20, 0xfe, 0x32, 0x30, 0x83, 0xee, 0x1c, 0xa0, 0x52, 0xe2, 0x0d, 0xda, 0xcd, 0xfd, 0x77, 0x33, - 0x9f, 0x6d, 0x99, 0xd5, 0xb3, 0x2d, 0x3d, 0xb6, 0xac, 0xdf, 0xbb, 0x5b, 0x1d, 0x00, 0xf5, 0x41, - 0x87, 0x48, 0x41, 0x4c, 0x38, 0xe7, 0xde, 0x4d, 0xc6, 0x89, 0xd4, 0xd6, 0x0f, 0x53, 0xe4, 0xd8, - 0x2e, 0x27, 0x51, 0x53, 0x86, 0x49, 0xd9, 0x73, 0xc6, 0x4d, 0x0a, 0x3f, 0xa5, 0x90, 0xbf, 0x02, - 0xf8, 0xee, 0x7d, 0x92, 0x21, 0x2d, 0xcf, 0x6f, 0xf8, 0x2f, 0x51, 0x4c, 0xb4, 0x08, 0xa7, 0x9b, - 0xb4, 0xee, 0x87, 0x8b, 0x5e, 0xa3, 0x6a, 0xd1, 0x3a, 0xe7, 0x32, 0x6e, 0x4c, 0xc9, 0xe8, 0x11, - 0x0f, 0xaa, 0x69, 0x0a, 0xab, 0x28, 0x4d, 0xa2, 0xbe, 0x01, 0x70, 0xf1, 0x01, 0xd4, 0xb2, 0x3b, - 0x25, 0x18, 0x8e, 0xa5, 0x58, 0x89, 0x75, 0x25, 0x8b, 0x85, 0x29, 0xe3, 0xae, 0x29, 0xe3, 0x4f, - 0xbc, 0x96, 0x31, 0x6d, 0xc7, 0xb6, 0x89, 0xdf, 0x96, 0x74, 0xfc, 0xb6, 0x44, 0x6d, 0x19, 0x1b, - 0xd4, 0x96, 0xf1, 0x11, 0xda, 0xb2, 0x7e, 0xf9, 0x02, 0x3e, 0xe3, 0x04, 0xd1, 0x2f, 0x00, 0xc2, - 0x88, 0x25, 0xc2, 0xfd, 0xdc, 0x29, 0xf9, 0x2b, 0xa2, 0x91, 0xa1, 0xf3, 0x85, 0x60, 0xfa, 0xc7, - 0xdf, 0xff, 0xf1, 0xcf, 0x8f, 0xe9, 0x2d, 0xb4, 0x49, 0x92, 0xbf, 0x7d, 0xe2, 0x53, 0xaa, 0xb8, - 0x1e, 0xb9, 0x88, 0x35, 0xbe, 0x8d, 0x7e, 0x06, 0x30, 0xa3, 0x38, 0x07, 0x1a, 0x16, 0x42, 0xd7, - 0xa2, 0xb4, 0xb5, 0xe1, 0x0b, 0x24, 0xe8, 0x35, 0x0e, 0x7a, 0x05, 0x15, 0x86, 0x05, 0x8d, 0x7e, - 0x07, 0xf0, 0xb5, 0x1e, 0x93, 0x43, 0x1f, 0x0c, 0x3e, 0xb9, 0x8f, 0xa7, 0x6a, 0x1f, 0x3e, 0xb6, - 0x4c, 0xc2, 0xde, 0xe3, 0xb0, 0x4b, 0x68, 0x7b, 0x30, 0x6c, 0x31, 0x80, 0x71, 0xc9, 0xbb, 0x43, - 0xd9, 0x46, 0x7f, 0x01, 0x38, 0x93, 0xe8, 0x50, 0xe8, 0xa3, 0x21, 0x75, 0xec, 0xb5, 0x4e, 0x6d, - 0x6b, 0x94, 0x52, 0xc9, 0xea, 0x73, 0xce, 0xea, 0x00, 0xed, 0x8f, 0x3a, 0x41, 0x44, 0x35, 0x51, - 0xf4, 0x53, 0x1a, 0xe6, 0xfa, 0x5d, 0x73, 0xb4, 0x33, 0x2c, 0xce, 0x24, 0x4f, 0xd3, 0x4a, 0x23, - 0x56, 0x4b, 0xa2, 0xdf, 0x01, 0xce, 0xf4, 0x02, 0xb5, 0x46, 0x67, 0x1a, 0xf7, 0x26, 0x22, 0x6d, - 0x8e, 0x5c, 0xc4, 0xcd, 0xb2, 0x4d, 0x84, 0x99, 0x44, 0x71, 0xf1, 0xde, 0xde, 0xfd, 0xea, 0xaa, - 0x93, 0x07, 0xd7, 0x9d, 0x3c, 0xf8, 0xbb, 0x93, 0x07, 0x3f, 0xdc, 0xe6, 0x53, 0xd7, 0xb7, 0xf9, - 0xd4, 0x9f, 0xb7, 0xf9, 0xd4, 0xd7, 0xdb, 0x8e, 0x1b, 0x54, 0x1a, 0x16, 0xb6, 0x59, 0x95, 0xc8, - 0xff, 0xc4, 0xe2, 0x67, 0xd5, 0x2f, 0x7f, 0x43, 0xbe, 0x8d, 0x20, 0xaf, 0x6d, 0xac, 0x2a, 0xa8, - 0x83, 0x56, 0x8d, 0xfa, 0xd6, 0x73, 0xee, 0x8a, 0x1b, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x91, - 0x3b, 0x2c, 0x79, 0xa0, 0x0b, 0x00, 0x00, + 0x18, 0xee, 0x14, 0xbe, 0x2f, 0x1f, 0x53, 0xfc, 0x3e, 0x9d, 0x14, 0xa8, 0xab, 0x16, 0x5c, 0x45, + 0x0a, 0x91, 0x19, 0x0a, 0xd1, 0x20, 0xd0, 0x44, 0x21, 0x88, 0x1c, 0x24, 0xb8, 0xc6, 0x8b, 0x17, + 0xb2, 0xbb, 0x1d, 0xb6, 0x1b, 0xe9, 0x4e, 0xe9, 0x6e, 0x1b, 0x1b, 0xac, 0x07, 0xe3, 0x0f, 0x30, + 0xf1, 0xee, 0xc1, 0x83, 0x89, 0x27, 0x8f, 0x1e, 0xfc, 0x01, 0x72, 0x24, 0xf1, 0xe2, 0x45, 0x62, + 0x8a, 0x57, 0x2f, 0xfe, 0x02, 0xb3, 0x33, 0x53, 0x76, 0xb6, 0xdd, 0x96, 0xd2, 0x7c, 0x9c, 0xba, + 0xfb, 0xce, 0xfb, 0xce, 0x3c, 0xcf, 0xf3, 0xbe, 0xf3, 0x6c, 0xa1, 0xee, 0x5a, 0x36, 0xb1, 0x59, + 0x9d, 0x12, 0x9b, 0x79, 0x1e, 0xb5, 0x03, 0x97, 0x79, 0xa4, 0x59, 0x24, 0xe7, 0x0d, 0x5a, 0x6f, + 0xe1, 0x5a, 0x9d, 0x05, 0x0c, 0xcd, 0xba, 0x96, 0x8d, 0xc3, 0x1c, 0x1c, 0xe5, 0xe0, 0x66, 0x51, + 0xcb, 0x3a, 0xcc, 0x61, 0x3c, 0x85, 0x84, 0x4f, 0x22, 0x5b, 0x5b, 0xb1, 0x99, 0x5f, 0x65, 0x3e, + 0xb1, 0x4c, 0x9f, 0x8a, 0x6d, 0x48, 0xb3, 0x68, 0xd1, 0xc0, 0x2c, 0x92, 0x9a, 0xe9, 0xb8, 0x9e, + 0xc9, 0xcb, 0x45, 0xee, 0x7c, 0x74, 0xfa, 0x99, 0x4b, 0xbd, 0x20, 0x3c, 0x59, 0x3c, 0xc9, 0x84, + 0xa5, 0x01, 0xf0, 0x14, 0x20, 0x22, 0xf1, 0x55, 0x87, 0x31, 0xe7, 0x8c, 0x12, 0xb3, 0xe6, 0x12, + 0xd3, 0xf3, 0x58, 0xc0, 0x8f, 0xf1, 0xe5, 0xea, 0xcb, 0x72, 0x95, 0xbf, 0x59, 0x8d, 0x53, 0x62, + 0x7a, 0x92, 0x9c, 0x5e, 0x82, 0xb3, 0x9f, 0x84, 0x20, 0xf7, 0x6e, 0x77, 0x34, 0xe8, 0x79, 0x83, + 0xfa, 0x01, 0x7a, 0x03, 0xbe, 0x10, 0x1d, 0x73, 0xe2, 0x96, 0x73, 0x60, 0x01, 0x14, 0xa6, 0x8c, + 0xe9, 0x28, 0x78, 0x58, 0xd6, 0x7f, 0x03, 0x70, 0xae, 0xaf, 0xde, 0xaf, 0x31, 0xcf, 0xa7, 0x68, + 0x1f, 0xc2, 0x28, 0x97, 0x57, 0x67, 0xd6, 0x17, 0x71, 0xb2, 0x98, 0x38, 0xaa, 0xdf, 0xf7, 0xca, + 0x86, 0x52, 0x88, 0xb2, 0xf0, 0x51, 0xad, 0xce, 0xd8, 0x69, 0x2e, 0xbd, 0x00, 0x0a, 0xd3, 0x86, + 0x78, 0x41, 0x7b, 0x70, 0x9a, 0x3f, 0x9c, 0x54, 0xa8, 0xeb, 0x54, 0x82, 0xdc, 0x04, 0xdf, 0x5e, + 0x53, 0xb6, 0x17, 0x3a, 0x36, 0x8b, 0xf8, 0x23, 0x9e, 0xb1, 0x3b, 0x79, 0x79, 0x3d, 0x9f, 0x32, + 0x32, 0xbc, 0x4a, 0x84, 0x74, 0xb3, 0x0f, 0xbc, 0xdf, 0x65, 0xff, 0x21, 0x84, 0x51, 0xbb, 0x24, + 0xf8, 0xb7, 0xb0, 0xe8, 0x2d, 0x0e, 0x7b, 0x8b, 0xc5, 0x88, 0xc8, 0xde, 0xe2, 0x63, 0xd3, 0xa1, + 0xb2, 0xd6, 0x50, 0x2a, 0xf5, 0x7f, 0x01, 0xcc, 0xf5, 0x9f, 0x21, 0x15, 0x3a, 0x82, 0x99, 0x88, + 0xa8, 0x9f, 0x03, 0x0b, 0x13, 0x85, 0xcc, 0xfa, 0xdb, 0x83, 0x24, 0x3a, 0x2c, 0x53, 0x2f, 0x70, + 0x4f, 0x5d, 0x5a, 0x56, 0xc4, 0x56, 0x37, 0x40, 0x07, 0x31, 0xd0, 0x69, 0x0e, 0x7a, 0xe9, 0x4e, + 0xd0, 0x02, 0x8c, 0x8a, 0x1a, 0x6d, 0xc2, 0xc7, 0xf7, 0xd4, 0x55, 0xe6, 0xeb, 0x3b, 0xf0, 0x35, + 0x41, 0x97, 0xa7, 0x25, 0x08, 0xfb, 0x0a, 0x9c, 0x12, 0x5b, 0x44, 0x23, 0xf5, 0x44, 0x04, 0x0e, + 0xcb, 0xfa, 0x4f, 0x00, 0xe6, 0x07, 0x95, 0x4b, 0xcd, 0x96, 0xe1, 0x8b, 0xca, 0x58, 0xd6, 0xcc, + 0xa0, 0x22, 0x84, 0x9b, 0x32, 0x9e, 0x45, 0xf1, 0xe3, 0x30, 0xfc, 0x90, 0x93, 0x63, 0xc1, 0xd7, + 0x7b, 0xba, 0x2a, 0x10, 0x7f, 0x1a, 0x98, 0x41, 0x77, 0x0e, 0x50, 0x29, 0xf1, 0x06, 0xed, 0xe6, + 0xfe, 0xbb, 0x9e, 0xcf, 0xb6, 0xcc, 0xea, 0xd9, 0x96, 0x1e, 0x5b, 0xd6, 0x7b, 0xee, 0x56, 0x07, + 0x40, 0x7d, 0xd8, 0x21, 0x52, 0x10, 0x13, 0xce, 0xb9, 0xb7, 0x93, 0x71, 0x22, 0xb5, 0xf5, 0xc3, + 0x14, 0x39, 0xb6, 0xcb, 0x49, 0xd4, 0x94, 0x61, 0x52, 0xf6, 0x9c, 0x71, 0x93, 0xc2, 0x0f, 0x29, + 0xe4, 0xaf, 0x00, 0xbe, 0xd9, 0x4b, 0x32, 0xa4, 0xe5, 0xf9, 0x0d, 0xff, 0x39, 0x8a, 0x89, 0x96, + 0xe0, 0xb3, 0x3a, 0x6d, 0xba, 0x7e, 0xb8, 0xea, 0x35, 0xaa, 0x16, 0xad, 0x73, 0x32, 0x93, 0xc6, + 0xd3, 0x6e, 0xf8, 0x88, 0x47, 0x63, 0x89, 0x0a, 0x31, 0x25, 0x51, 0x22, 0xbf, 0x06, 0x70, 0xf1, + 0x0e, 0xe4, 0xb2, 0x43, 0x25, 0x18, 0x8e, 0xa6, 0x58, 0x89, 0x75, 0x26, 0x8b, 0x85, 0x31, 0xe3, + 0xae, 0x31, 0xe3, 0x0f, 0xbc, 0x96, 0xf1, 0xd4, 0x8e, 0x6d, 0x13, 0xbf, 0x31, 0xe9, 0xf8, 0x8d, + 0x89, 0x5a, 0x33, 0x31, 0xac, 0x35, 0x93, 0x63, 0xb4, 0x66, 0xfd, 0xe7, 0x27, 0xf0, 0x11, 0x27, + 0x88, 0x7e, 0x01, 0x10, 0x46, 0x2c, 0x11, 0x1e, 0xe4, 0x50, 0xc9, 0x5f, 0x12, 0x8d, 0x8c, 0x9c, + 0x2f, 0x04, 0xd3, 0xdf, 0xff, 0xe6, 0x8f, 0x7f, 0xbe, 0x4f, 0x6f, 0xa1, 0x4d, 0x92, 0xfc, 0xfd, + 0x13, 0x9f, 0x53, 0xc5, 0xf9, 0xc8, 0x45, 0xac, 0xf9, 0x6d, 0xf4, 0x23, 0x80, 0x19, 0xc5, 0x3d, + 0xd0, 0xa8, 0x10, 0xba, 0x36, 0xa5, 0xad, 0x8d, 0x5e, 0x20, 0x41, 0xaf, 0x71, 0xd0, 0x2b, 0xa8, + 0x30, 0x2a, 0x68, 0xf4, 0x3b, 0x80, 0x2f, 0xf5, 0x19, 0x1d, 0x7a, 0x67, 0xf8, 0xc9, 0x03, 0x7c, + 0x55, 0x7b, 0xf7, 0xbe, 0x65, 0x12, 0xf6, 0x1e, 0x87, 0x5d, 0x42, 0xdb, 0xc3, 0x61, 0x8b, 0x01, + 0x8c, 0x4b, 0xde, 0x1d, 0xca, 0x36, 0xfa, 0x0b, 0xc0, 0x99, 0x44, 0x97, 0x42, 0xef, 0x8d, 0xa8, + 0x63, 0xbf, 0x7d, 0x6a, 0x5b, 0xe3, 0x94, 0x4a, 0x56, 0x1f, 0x73, 0x56, 0x07, 0x68, 0x7f, 0xdc, + 0x09, 0x22, 0xaa, 0x91, 0xa2, 0x1f, 0xd2, 0x30, 0x37, 0xe8, 0x9a, 0xa3, 0x9d, 0x51, 0x71, 0x26, + 0xf9, 0x9a, 0x56, 0x1a, 0xb3, 0x5a, 0x12, 0xfd, 0x16, 0x70, 0xa6, 0x5f, 0xa3, 0xaf, 0xc6, 0x67, + 0x1a, 0xf7, 0x26, 0xd2, 0xf5, 0x39, 0x72, 0xd1, 0xe3, 0x98, 0x6d, 0x22, 0xec, 0x44, 0x59, 0x10, + 0x81, 0xf6, 0xee, 0x67, 0x97, 0x9d, 0x3c, 0xb8, 0xea, 0xe4, 0xc1, 0xdf, 0x9d, 0x3c, 0xf8, 0xee, + 0x26, 0x9f, 0xba, 0xba, 0xc9, 0xa7, 0xfe, 0xbc, 0xc9, 0xa7, 0x3e, 0xdf, 0x76, 0xdc, 0xa0, 0xd2, + 0xb0, 0xb0, 0xcd, 0xaa, 0x44, 0xfe, 0x35, 0x16, 0x3f, 0xab, 0x7e, 0xf9, 0x0b, 0xf2, 0x65, 0x84, + 0x7a, 0x6d, 0x63, 0x55, 0x01, 0x1e, 0xb4, 0x6a, 0xd4, 0xb7, 0x1e, 0x73, 0x63, 0xdc, 0xf8, 0x3f, + 0x00, 0x00, 0xff, 0xff, 0x7c, 0x35, 0x91, 0xa4, 0xa7, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1291,13 +1291,13 @@ func (m *QueryConnectionConsensusStateRequest) MarshalToSizedBuffer(dAtA []byte) _ = i var l int _ = l - if m.VersionHeight != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionHeight)) i-- dAtA[i] = 0x18 } - if m.VersionNumber != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionNumber)) i-- dAtA[i] = 0x10 } @@ -1523,11 +1523,11 @@ func (m *QueryConnectionConsensusStateRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - if m.VersionNumber != 0 { - n += 1 + sovQuery(uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + n += 1 + sovQuery(uint64(m.RevisionNumber)) } - if m.VersionHeight != 0 { - n += 1 + sovQuery(uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + n += 1 + sovQuery(uint64(m.RevisionHeight)) } return n } @@ -2588,9 +2588,9 @@ func (m *QueryConnectionConsensusStateRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionNumber", wireType) } - m.VersionNumber = 0 + m.RevisionNumber = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2600,16 +2600,16 @@ func (m *QueryConnectionConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionNumber |= uint64(b&0x7F) << shift + m.RevisionNumber |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHeight", wireType) } - m.VersionHeight = 0 + m.RevisionHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2619,7 +2619,7 @@ func (m *QueryConnectionConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionHeight |= uint64(b&0x7F) << shift + m.RevisionHeight |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ibc/core/03-connection/types/query.pb.gw.go b/x/ibc/core/03-connection/types/query.pb.gw.go index 1d7151ad5b..3e6de4e064 100644 --- a/x/ibc/core/03-connection/types/query.pb.gw.go +++ b/x/ibc/core/03-connection/types/query.pb.gw.go @@ -251,26 +251,26 @@ func request_Query_ConnectionConsensusState_0(ctx context.Context, marshaler run return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "connection_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } msg, err := client.ConnectionConsensusState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -300,26 +300,26 @@ func local_request_Query_ConnectionConsensusState_0(ctx context.Context, marshal return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "connection_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } msg, err := server.ConnectionConsensusState(ctx, &protoReq) @@ -586,7 +586,7 @@ var ( pattern_Query_ConnectionClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"ibc", "core", "connection", "v1beta1", "connections", "connection_id", "client_state"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_ConnectionConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 2, 7, 1, 0, 4, 1, 5, 8, 2, 9, 1, 0, 4, 1, 5, 10}, []string{"ibc", "core", "connection", "v1beta1", "connections", "connection_id", "consensus_state", "version", "version_number", "height", "version_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConnectionConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 2, 7, 1, 0, 4, 1, 5, 8, 2, 9, 1, 0, 4, 1, 5, 10}, []string{"ibc", "core", "connection", "v1beta1", "connections", "connection_id", "consensus_state", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( diff --git a/x/ibc/core/03-connection/types/tx.pb.go b/x/ibc/core/03-connection/types/tx.pb.go index be78639db0..05e60cf3e1 100644 --- a/x/ibc/core/03-connection/types/tx.pb.go +++ b/x/ibc/core/03-connection/types/tx.pb.go @@ -34,10 +34,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // initialize a connection with Chain B. type MsgConnectionOpenInit struct { ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` - ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` - Counterparty Counterparty `protobuf:"bytes,3,opt,name=counterparty,proto3" json:"counterparty"` - Version *Version `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` - Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty"` + Counterparty Counterparty `protobuf:"bytes,2,opt,name=counterparty,proto3" json:"counterparty"` + Version *Version `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgConnectionOpenInit) Reset() { *m = MsgConnectionOpenInit{} } @@ -113,22 +112,23 @@ var xxx_messageInfo_MsgConnectionOpenInitResponse proto.InternalMessageInfo // MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a // connection on Chain B. type MsgConnectionOpenTry struct { - ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` - DesiredConnectionId string `protobuf:"bytes,2,opt,name=desired_connection_id,json=desiredConnectionId,proto3" json:"desired_connection_id,omitempty" yaml:"desired_connection_id"` - CounterpartyChosenConnectionId string `protobuf:"bytes,3,opt,name=counterparty_chosen_connection_id,json=counterpartyChosenConnectionId,proto3" json:"counterparty_chosen_connection_id,omitempty" yaml:"counterparty_chosen_connection_id"` - ClientState *types.Any `protobuf:"bytes,4,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` - Counterparty Counterparty `protobuf:"bytes,5,opt,name=counterparty,proto3" json:"counterparty"` - CounterpartyVersions []*Version `protobuf:"bytes,6,rep,name=counterparty_versions,json=counterpartyVersions,proto3" json:"counterparty_versions,omitempty" yaml:"counterparty_versions"` - ProofHeight types1.Height `protobuf:"bytes,7,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` + // in the case of crossing hello's, when both chains call OpenInit, we need the connection identifier + // of the previous connection in state INIT + PreviousConnectionId string `protobuf:"bytes,2,opt,name=previous_connection_id,json=previousConnectionId,proto3" json:"previous_connection_id,omitempty" yaml:"previous_connection_id"` + ClientState *types.Any `protobuf:"bytes,3,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` + Counterparty Counterparty `protobuf:"bytes,4,opt,name=counterparty,proto3" json:"counterparty"` + CounterpartyVersions []*Version `protobuf:"bytes,5,rep,name=counterparty_versions,json=counterpartyVersions,proto3" json:"counterparty_versions,omitempty" yaml:"counterparty_versions"` + ProofHeight types1.Height `protobuf:"bytes,6,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` // proof of the initialization the connection on Chain A: `UNITIALIZED -> // INIT` - ProofInit []byte `protobuf:"bytes,8,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` + ProofInit []byte `protobuf:"bytes,7,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` // proof of client state included in message - ProofClient []byte `protobuf:"bytes,9,opt,name=proof_client,json=proofClient,proto3" json:"proof_client,omitempty" yaml:"proof_client"` + ProofClient []byte `protobuf:"bytes,8,opt,name=proof_client,json=proofClient,proto3" json:"proof_client,omitempty" yaml:"proof_client"` // proof of client consensus state - ProofConsensus []byte `protobuf:"bytes,10,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` - ConsensusHeight types1.Height `protobuf:"bytes,11,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` - Signer string `protobuf:"bytes,12,opt,name=signer,proto3" json:"signer,omitempty"` + ProofConsensus []byte `protobuf:"bytes,9,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` + ConsensusHeight types1.Height `protobuf:"bytes,10,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` + Signer string `protobuf:"bytes,11,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgConnectionOpenTry) Reset() { *m = MsgConnectionOpenTry{} } @@ -384,65 +384,62 @@ func init() { func init() { proto.RegisterFile("ibc/core/connection/v1/tx.proto", fileDescriptor_5d00fde5fc97399e) } var fileDescriptor_5d00fde5fc97399e = []byte{ - // 917 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x3f, 0x93, 0xdb, 0x44, - 0x14, 0xb7, 0xce, 0xf7, 0xc7, 0xde, 0x33, 0x24, 0x51, 0xec, 0x3b, 0x21, 0x82, 0xe4, 0xec, 0xc0, - 0x70, 0x45, 0x4e, 0x8a, 0x93, 0x30, 0x03, 0xc7, 0x50, 0xd8, 0x6e, 0xb8, 0x22, 0xc0, 0x88, 0x83, - 0x22, 0x8d, 0xc7, 0x96, 0xd7, 0xb2, 0xc6, 0xe7, 0x5d, 0x8f, 0x56, 0x76, 0x22, 0x5a, 0x1a, 0x86, - 0x8a, 0x8f, 0x90, 0x4f, 0xc1, 0x67, 0x48, 0x47, 0x4a, 0x2a, 0x0d, 0xdc, 0x35, 0xd4, 0xea, 0xe8, - 0x18, 0xad, 0xfe, 0x78, 0x65, 0xcb, 0x73, 0x36, 0xe7, 0x54, 0xd2, 0xdb, 0xf7, 0x7b, 0xef, 0xed, - 0xfe, 0xf6, 0xfd, 0xde, 0x2c, 0x50, 0xed, 0x9e, 0xa9, 0x9b, 0xc4, 0x41, 0xba, 0x49, 0x30, 0x46, - 0xa6, 0x6b, 0x13, 0xac, 0xcf, 0x1a, 0xba, 0xfb, 0x4a, 0x9b, 0x38, 0xc4, 0x25, 0xe2, 0x91, 0xdd, - 0x33, 0xb5, 0x10, 0xa0, 0xcd, 0x01, 0xda, 0xac, 0x21, 0x57, 0x2d, 0x62, 0x11, 0x06, 0xd1, 0xc3, - 0xbf, 0x08, 0x2d, 0x7f, 0x60, 0x11, 0x62, 0x5d, 0x22, 0x9d, 0x59, 0xbd, 0xe9, 0x40, 0xef, 0x62, - 0x2f, 0x76, 0x71, 0x95, 0x2e, 0x6d, 0x84, 0xdd, 0xb0, 0x4a, 0xf4, 0x17, 0x03, 0x3e, 0x5d, 0xb1, - 0x15, 0xae, 0x2e, 0x03, 0xc2, 0xdf, 0x77, 0x40, 0xed, 0x39, 0xb5, 0xda, 0xe9, 0xfa, 0xb7, 0x13, - 0x84, 0xcf, 0xb1, 0xed, 0x8a, 0x0d, 0x50, 0x8e, 0x52, 0x76, 0xec, 0xbe, 0x24, 0xd4, 0x85, 0x93, - 0x72, 0xab, 0x1a, 0xf8, 0xea, 0x5d, 0xaf, 0x3b, 0xbe, 0x3c, 0x83, 0xa9, 0x0b, 0x1a, 0xa5, 0xe8, - 0xff, 0xbc, 0x2f, 0x7e, 0x05, 0xde, 0x9b, 0x17, 0x08, 0xc3, 0x76, 0x58, 0x98, 0x14, 0xf8, 0x6a, - 0x35, 0x0e, 0xe3, 0xdd, 0xd0, 0xa8, 0xcc, 0xed, 0xf3, 0xbe, 0xf8, 0x0d, 0xa8, 0x98, 0x64, 0x8a, - 0x5d, 0xe4, 0x4c, 0xba, 0x8e, 0xeb, 0x49, 0xc5, 0xba, 0x70, 0x72, 0xf8, 0xe4, 0x63, 0x2d, 0x9f, - 0x35, 0xad, 0xcd, 0x61, 0x5b, 0xbb, 0x6f, 0x7c, 0xb5, 0x60, 0x64, 0xe2, 0xc5, 0x2f, 0xc0, 0xc1, - 0x0c, 0x39, 0xd4, 0x26, 0x58, 0xda, 0x65, 0xa9, 0xd4, 0x55, 0xa9, 0x7e, 0x8c, 0x60, 0x46, 0x82, - 0x17, 0x8f, 0xc0, 0x3e, 0xb5, 0x2d, 0x8c, 0x1c, 0x69, 0x2f, 0x3c, 0x82, 0x11, 0x5b, 0x67, 0xa5, - 0x5f, 0x5e, 0xab, 0x85, 0x7f, 0x5e, 0xab, 0x05, 0xa8, 0x82, 0x8f, 0x72, 0x79, 0x33, 0x10, 0x9d, - 0x10, 0x4c, 0x11, 0xfc, 0xe3, 0x00, 0x54, 0x97, 0x10, 0x17, 0x8e, 0xf7, 0x7f, 0x88, 0xbd, 0x00, - 0xb5, 0x3e, 0xa2, 0xb6, 0x83, 0xfa, 0x9d, 0x3c, 0x82, 0xeb, 0x81, 0xaf, 0x3e, 0x88, 0xc2, 0x73, - 0x61, 0xd0, 0xb8, 0x1f, 0xaf, 0xb7, 0x79, 0xbe, 0x5f, 0x82, 0x87, 0x3c, 0x5f, 0x1d, 0x73, 0x48, - 0x28, 0xc2, 0x0b, 0x15, 0x8a, 0xac, 0xc2, 0xa3, 0xc0, 0x57, 0x4f, 0x92, 0x2b, 0xbc, 0x21, 0x04, - 0x1a, 0x0a, 0x8f, 0x69, 0x33, 0x48, 0xa6, 0xf0, 0x77, 0xa0, 0x12, 0x1f, 0x93, 0xba, 0x5d, 0x17, - 0xc5, 0xb7, 0x53, 0xd5, 0xa2, 0x86, 0xd7, 0x92, 0x86, 0xd7, 0x9a, 0xd8, 0x6b, 0x1d, 0x07, 0xbe, - 0x7a, 0x3f, 0x43, 0x0d, 0x8b, 0x81, 0xc6, 0x61, 0x64, 0x7e, 0x1f, 0x5a, 0x4b, 0xad, 0xb3, 0x77, - 0xcb, 0xd6, 0x99, 0x81, 0x5a, 0xe6, 0x9c, 0x71, 0x5f, 0x50, 0x69, 0xbf, 0x5e, 0x5c, 0xa3, 0x91, - 0xf8, 0x1b, 0xc9, 0xcd, 0x03, 0x8d, 0x2a, 0xbf, 0x1e, 0x87, 0x51, 0xf1, 0x05, 0xa8, 0x4c, 0x1c, - 0x42, 0x06, 0x9d, 0x21, 0xb2, 0xad, 0xa1, 0x2b, 0x1d, 0xb0, 0x73, 0xc8, 0x5c, 0xb9, 0x48, 0xe5, - 0xb3, 0x86, 0xf6, 0x35, 0x43, 0xb4, 0x3e, 0x0c, 0x77, 0x3f, 0xe7, 0x88, 0x8f, 0x86, 0xc6, 0x21, - 0x33, 0x23, 0xa4, 0xf8, 0x0c, 0x80, 0xc8, 0x6b, 0x63, 0xdb, 0x95, 0x4a, 0x75, 0xe1, 0xa4, 0xd2, - 0xaa, 0x05, 0xbe, 0x7a, 0x8f, 0x8f, 0x0c, 0x7d, 0xd0, 0x28, 0x33, 0x83, 0x8d, 0x81, 0xb3, 0x64, - 0x47, 0x51, 0x65, 0xa9, 0xcc, 0xe2, 0x8e, 0x17, 0x2b, 0x46, 0xde, 0xa4, 0x62, 0x9b, 0x59, 0x62, - 0x1b, 0xdc, 0x89, 0xbd, 0xa1, 0x22, 0x30, 0x9d, 0x52, 0x09, 0xb0, 0x70, 0x39, 0xf0, 0xd5, 0xa3, - 0x4c, 0x78, 0x02, 0x80, 0xc6, 0xfb, 0x51, 0x86, 0x64, 0x41, 0x1c, 0x80, 0xbb, 0xa9, 0x37, 0xa1, - 0xe5, 0xf0, 0x46, 0x5a, 0xd4, 0x98, 0x96, 0xe3, 0x74, 0xee, 0x64, 0x32, 0x40, 0xe3, 0x4e, 0xba, - 0x14, 0xd3, 0x33, 0x97, 0x7c, 0x65, 0x85, 0xe4, 0x15, 0xf0, 0x20, 0x4f, 0xd0, 0xa9, 0xe2, 0xff, - 0xde, 0xcb, 0x51, 0x7c, 0xd3, 0x1c, 0x2d, 0xcf, 0x45, 0x61, 0xa3, 0xb9, 0x68, 0x02, 0x39, 0x2b, - 0xba, 0x9c, 0x11, 0xf0, 0x49, 0xe0, 0xab, 0x0f, 0xf3, 0x04, 0x9a, 0x4d, 0x2c, 0x65, 0x94, 0xc9, - 0x17, 0xe1, 0x86, 0x65, 0x71, 0xc3, 0x61, 0xb9, 0x7d, 0x39, 0x2f, 0xca, 0x60, 0x6f, 0x8b, 0x32, - 0x68, 0x80, 0xa8, 0xbb, 0x3b, 0xae, 0xe3, 0x49, 0xfb, 0xac, 0x1d, 0xb9, 0xf1, 0x9b, 0xba, 0xa0, - 0x51, 0x62, 0xff, 0xe1, 0xc4, 0x5e, 0xd4, 0xc0, 0xc1, 0xed, 0x34, 0x50, 0xda, 0x8a, 0x06, 0xca, - 0xef, 0x54, 0x03, 0x60, 0x03, 0x0d, 0x34, 0xcd, 0x51, 0xaa, 0x81, 0x5f, 0x77, 0x80, 0xb4, 0x04, - 0x68, 0x13, 0x3c, 0xb0, 0x9d, 0xf1, 0x6d, 0x75, 0x90, 0xde, 0x5c, 0xd7, 0x1c, 0xb1, 0xb6, 0xcf, - 0xb9, 0xb9, 0xae, 0x39, 0x4a, 0x6e, 0x2e, 0x54, 0xde, 0x62, 0x23, 0x15, 0xb7, 0xd8, 0x48, 0x73, - 0xb2, 0x76, 0x57, 0x90, 0x05, 0x41, 0x7d, 0x15, 0x17, 0x09, 0x61, 0x4f, 0xfe, 0x2d, 0x82, 0xe2, - 0x73, 0x6a, 0x89, 0x3f, 0x01, 0x31, 0xe7, 0x11, 0x76, 0xba, 0x4a, 0x84, 0xb9, 0x6f, 0x0f, 0xf9, - 0xb3, 0x8d, 0xe0, 0xc9, 0x1e, 0xc4, 0x97, 0xe0, 0xde, 0xf2, 0x33, 0xe5, 0xd1, 0xda, 0xb9, 0x2e, - 0x1c, 0x4f, 0x7e, 0xb6, 0x09, 0x7a, 0x75, 0xe1, 0xf0, 0xce, 0xd6, 0x2f, 0xdc, 0x34, 0x47, 0x1b, - 0x14, 0xe6, 0xda, 0x54, 0xfc, 0x59, 0x00, 0xb5, 0xfc, 0x1e, 0x7d, 0xbc, 0x76, 0xbe, 0x38, 0x42, - 0xfe, 0x7c, 0xd3, 0x88, 0x64, 0x17, 0xad, 0x1f, 0xde, 0x5c, 0x29, 0xc2, 0xdb, 0x2b, 0x45, 0xf8, - 0xeb, 0x4a, 0x11, 0x7e, 0xbb, 0x56, 0x0a, 0x6f, 0xaf, 0x95, 0xc2, 0x9f, 0xd7, 0x4a, 0xe1, 0xc5, - 0x97, 0x96, 0xed, 0x0e, 0xa7, 0x3d, 0xcd, 0x24, 0x63, 0xdd, 0x24, 0x74, 0x4c, 0x68, 0xfc, 0x39, - 0xa5, 0xfd, 0x91, 0xfe, 0x4a, 0x4f, 0x9f, 0xf7, 0x8f, 0x9f, 0x9e, 0x72, 0x2f, 0x7c, 0xd7, 0x9b, - 0x20, 0xda, 0xdb, 0x67, 0x13, 0xf7, 0xe9, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x86, 0xcf, 0x23, - 0x2c, 0x90, 0x0c, 0x00, 0x00, + // 880 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x31, 0x73, 0xda, 0x58, + 0x10, 0x46, 0x06, 0x63, 0x78, 0x70, 0x67, 0x5b, 0x07, 0x58, 0xa7, 0xb3, 0x11, 0xd6, 0xdc, 0xcd, + 0xb9, 0x38, 0x4b, 0xc6, 0xf6, 0xcd, 0xdc, 0xf9, 0xe6, 0x0a, 0xa0, 0x39, 0x17, 0xbe, 0x64, 0x14, + 0x27, 0x99, 0x71, 0xc3, 0x80, 0x10, 0xb2, 0x06, 0xa3, 0xc7, 0xe8, 0x09, 0x62, 0xa5, 0x4d, 0x93, + 0x49, 0x95, 0x9f, 0xe0, 0x9f, 0xe3, 0xd2, 0x65, 0xd2, 0x68, 0x12, 0xbb, 0x49, 0xad, 0x26, 0x93, + 0x2e, 0xa3, 0xf7, 0x24, 0x21, 0x40, 0x8c, 0x21, 0x38, 0x15, 0x5a, 0xed, 0xf7, 0xed, 0xae, 0x76, + 0xf7, 0x7b, 0x3c, 0xc0, 0x69, 0x4d, 0x59, 0x94, 0xa1, 0xa1, 0x88, 0x32, 0xd4, 0x75, 0x45, 0x36, + 0x35, 0xa8, 0x8b, 0x83, 0xb2, 0x68, 0x5e, 0x0a, 0x3d, 0x03, 0x9a, 0x90, 0x2e, 0x68, 0x4d, 0x59, + 0x70, 0x01, 0xc2, 0x10, 0x20, 0x0c, 0xca, 0x6c, 0x4e, 0x85, 0x2a, 0xc4, 0x10, 0xd1, 0x7d, 0x22, + 0x68, 0xf6, 0x67, 0x15, 0x42, 0xf5, 0x42, 0x11, 0xb1, 0xd5, 0xec, 0xb7, 0xc5, 0x86, 0x6e, 0x79, + 0xae, 0x50, 0xa6, 0x0b, 0x4d, 0xd1, 0x4d, 0x37, 0x0b, 0x79, 0xf2, 0x00, 0xbf, 0x4f, 0x29, 0x25, + 0x94, 0x17, 0x03, 0xf9, 0xcf, 0x14, 0xc8, 0x9f, 0x20, 0xb5, 0x16, 0xbc, 0x7f, 0xd4, 0x53, 0xf4, + 0x63, 0x5d, 0x33, 0xe9, 0x32, 0x48, 0x93, 0x90, 0x75, 0xad, 0xc5, 0x50, 0x25, 0x6a, 0x27, 0x5d, + 0xcd, 0x39, 0x36, 0xb7, 0x66, 0x35, 0xba, 0x17, 0x47, 0x7c, 0xe0, 0xe2, 0xa5, 0x14, 0x79, 0x3e, + 0x6e, 0xd1, 0xff, 0x83, 0xac, 0x0c, 0xfb, 0xba, 0xa9, 0x18, 0xbd, 0x86, 0x61, 0x5a, 0xcc, 0x52, + 0x89, 0xda, 0xc9, 0xec, 0xff, 0x2a, 0x44, 0x7f, 0xb6, 0x50, 0x0b, 0x61, 0xab, 0x89, 0x6b, 0x9b, + 0x8b, 0x49, 0x23, 0x7c, 0xfa, 0x6f, 0xb0, 0x32, 0x50, 0x0c, 0xa4, 0x41, 0x9d, 0x89, 0xe3, 0x50, + 0xdc, 0xb4, 0x50, 0xcf, 0x08, 0x4c, 0xf2, 0xf1, 0x74, 0x01, 0x24, 0x91, 0xa6, 0xea, 0x8a, 0xc1, + 0x24, 0xdc, 0xd2, 0x25, 0xcf, 0x3a, 0x4a, 0xbd, 0xbe, 0xe2, 0x62, 0x9f, 0xae, 0xb8, 0x18, 0xcf, + 0x81, 0xad, 0xc8, 0x0f, 0x97, 0x14, 0xd4, 0x83, 0x3a, 0x52, 0xf8, 0xf7, 0x49, 0x90, 0x9b, 0x40, + 0x9c, 0x1a, 0xd6, 0xb7, 0x74, 0xe6, 0x39, 0x28, 0xf4, 0x0c, 0x65, 0xa0, 0xc1, 0x3e, 0xaa, 0x0f, + 0x2b, 0x77, 0xf9, 0x4b, 0x98, 0xbf, 0xed, 0xd8, 0xdc, 0x16, 0xe1, 0x47, 0xe3, 0x78, 0x29, 0xe7, + 0x3b, 0x86, 0x05, 0x1d, 0xb7, 0xe8, 0xc7, 0x20, 0xeb, 0x25, 0x44, 0x66, 0xc3, 0x54, 0xbc, 0x3e, + 0xe5, 0x04, 0xb2, 0x3b, 0x82, 0xbf, 0x3b, 0x42, 0x45, 0xb7, 0xaa, 0x1b, 0x8e, 0xcd, 0xfd, 0x34, + 0x52, 0x24, 0xe6, 0xf0, 0x52, 0x86, 0x98, 0x4f, 0x5c, 0x6b, 0x62, 0x88, 0x89, 0x05, 0x87, 0x38, + 0x00, 0xf9, 0xb0, 0x5d, 0xf7, 0x26, 0x84, 0x98, 0xe5, 0x52, 0x7c, 0x86, 0x91, 0x56, 0x4b, 0x8e, + 0xcd, 0x6d, 0x7a, 0x55, 0x47, 0xc5, 0xe1, 0xa5, 0x5c, 0xf8, 0xbd, 0x47, 0x43, 0xf4, 0x19, 0xc8, + 0xf6, 0x0c, 0x08, 0xdb, 0xf5, 0x73, 0x45, 0x53, 0xcf, 0x4d, 0x26, 0x89, 0xbf, 0x83, 0x0d, 0xa5, + 0x23, 0x82, 0x19, 0x94, 0x85, 0xff, 0x30, 0xa2, 0xfa, 0x8b, 0x5b, 0xfd, 0xb0, 0x47, 0x61, 0x36, + 0x2f, 0x65, 0xb0, 0x49, 0x90, 0xf4, 0x21, 0x00, 0xc4, 0xab, 0xe9, 0x9a, 0xc9, 0xac, 0x94, 0xa8, + 0x9d, 0x6c, 0x35, 0xef, 0xd8, 0xdc, 0x7a, 0x98, 0xe9, 0xfa, 0x78, 0x29, 0x8d, 0x0d, 0xac, 0xa8, + 0x23, 0xbf, 0x22, 0x92, 0x99, 0x49, 0x61, 0xde, 0xc6, 0x78, 0x46, 0xe2, 0xf5, 0x33, 0xd6, 0xb0, + 0x45, 0xd7, 0xc0, 0xaa, 0xe7, 0x75, 0x77, 0x53, 0x47, 0x7d, 0xc4, 0xa4, 0x31, 0x9d, 0x75, 0x6c, + 0xae, 0x30, 0x42, 0xf7, 0x01, 0xbc, 0xf4, 0x23, 0x89, 0xe0, 0xbf, 0xa0, 0xdb, 0x60, 0x2d, 0xf0, + 0xfa, 0x6d, 0x01, 0xf7, 0xb6, 0x85, 0xf3, 0xda, 0xb2, 0xe1, 0x0f, 0x61, 0x34, 0x02, 0x2f, 0xad, + 0x06, 0xaf, 0xbc, 0xf6, 0x0c, 0xc5, 0x97, 0x99, 0x22, 0xbe, 0x22, 0xd8, 0x8c, 0x92, 0x56, 0xa0, + 0xbd, 0x8f, 0xcb, 0x11, 0xda, 0xab, 0xc8, 0x1d, 0xfa, 0x5f, 0xf0, 0xc3, 0xa8, 0x7e, 0x88, 0xfe, + 0x18, 0xc7, 0xe6, 0x72, 0x41, 0x7d, 0x61, 0xd9, 0x64, 0xe5, 0xb0, 0x5c, 0x64, 0xc0, 0x8e, 0x2c, + 0x51, 0x94, 0x16, 0x7f, 0x73, 0x6c, 0x6e, 0x3b, 0x62, 0xe1, 0xc6, 0x02, 0x33, 0x61, 0xe7, 0x88, + 0x26, 0x17, 0x38, 0xb6, 0xc6, 0xe5, 0x9c, 0x58, 0x58, 0xce, 0xe3, 0x32, 0x58, 0x7e, 0x40, 0x19, + 0x94, 0x01, 0xd9, 0xee, 0xba, 0x69, 0x58, 0x58, 0x5f, 0xd9, 0xf0, 0x41, 0x18, 0xb8, 0x78, 0x29, + 0x85, 0x9f, 0xdd, 0xb3, 0x73, 0x5c, 0x03, 0x2b, 0x8b, 0x69, 0x20, 0xf5, 0x20, 0x1a, 0x48, 0x7f, + 0x57, 0x0d, 0x80, 0x39, 0x34, 0x50, 0x91, 0x3b, 0x81, 0x06, 0xde, 0x2c, 0x01, 0x66, 0x02, 0x50, + 0x83, 0x7a, 0x5b, 0x33, 0xba, 0x8b, 0xea, 0x20, 0x98, 0x5c, 0x43, 0xee, 0xe0, 0xb5, 0x8f, 0x98, + 0x5c, 0x43, 0xee, 0xf8, 0x93, 0x73, 0x95, 0x37, 0xbe, 0x48, 0xf1, 0x07, 0x5c, 0xa4, 0xfb, 0xff, + 0xad, 0x79, 0x50, 0x9a, 0xd6, 0x0b, 0xbf, 0x61, 0xfb, 0x5f, 0xe2, 0x20, 0x7e, 0x82, 0x54, 0xfa, + 0x25, 0xa0, 0x23, 0xee, 0x33, 0xbb, 0xd3, 0x44, 0x18, 0x79, 0x0b, 0x60, 0xff, 0x9c, 0x0b, 0xee, + 0xd7, 0x40, 0xbf, 0x00, 0xeb, 0x93, 0x17, 0x86, 0x3f, 0x66, 0x8e, 0x75, 0x6a, 0x58, 0xec, 0xe1, + 0x3c, 0xe8, 0xe9, 0x89, 0xdd, 0x99, 0xcd, 0x9e, 0xb8, 0x22, 0x77, 0xe6, 0x48, 0x1c, 0x5a, 0x53, + 0xfa, 0x15, 0x05, 0xf2, 0xd1, 0x3b, 0xba, 0x37, 0x73, 0x3c, 0x8f, 0xc1, 0xfe, 0x35, 0x2f, 0xc3, + 0xaf, 0xa2, 0xfa, 0xf4, 0xfa, 0xb6, 0x48, 0xdd, 0xdc, 0x16, 0xa9, 0x0f, 0xb7, 0x45, 0xea, 0xed, + 0x5d, 0x31, 0x76, 0x73, 0x57, 0x8c, 0xbd, 0xbb, 0x2b, 0xc6, 0xce, 0xfe, 0x51, 0x35, 0xf3, 0xbc, + 0xdf, 0x14, 0x64, 0xd8, 0x15, 0x65, 0x88, 0xba, 0x10, 0x79, 0x3f, 0xbb, 0xa8, 0xd5, 0x11, 0x2f, + 0xc5, 0xe0, 0xa6, 0xbc, 0x77, 0xb0, 0x1b, 0xba, 0x2c, 0x9b, 0x56, 0x4f, 0x41, 0xcd, 0x24, 0x3e, + 0x71, 0x0f, 0xbe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x4a, 0xeb, 0x3e, 0xdb, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -666,7 +663,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } if m.Version != nil { { @@ -678,7 +675,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } { size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i]) @@ -689,14 +686,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - if len(m.ConnectionId) > 0 { - i -= len(m.ConnectionId) - copy(dAtA[i:], m.ConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.ConnectionId))) - i-- - dAtA[i] = 0x12 - } + dAtA[i] = 0x12 if len(m.ClientId) > 0 { i -= len(m.ClientId) copy(dAtA[i:], m.ClientId) @@ -755,7 +745,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x62 + dAtA[i] = 0x5a } { size, err := m.ConsensusHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -766,27 +756,27 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x5a + dAtA[i] = 0x52 if len(m.ProofConsensus) > 0 { i -= len(m.ProofConsensus) copy(dAtA[i:], m.ProofConsensus) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofConsensus))) i-- - dAtA[i] = 0x52 + dAtA[i] = 0x4a } if len(m.ProofClient) > 0 { i -= len(m.ProofClient) copy(dAtA[i:], m.ProofClient) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofClient))) i-- - dAtA[i] = 0x4a + dAtA[i] = 0x42 } 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] = 0x42 + dAtA[i] = 0x3a } { size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -797,7 +787,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 if len(m.CounterpartyVersions) > 0 { for iNdEx := len(m.CounterpartyVersions) - 1; iNdEx >= 0; iNdEx-- { { @@ -809,7 +799,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } } { @@ -821,7 +811,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 if m.ClientState != nil { { size, err := m.ClientState.MarshalToSizedBuffer(dAtA[:i]) @@ -832,19 +822,12 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 - } - if len(m.CounterpartyChosenConnectionId) > 0 { - i -= len(m.CounterpartyChosenConnectionId) - copy(dAtA[i:], m.CounterpartyChosenConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyChosenConnectionId))) - i-- dAtA[i] = 0x1a } - if len(m.DesiredConnectionId) > 0 { - i -= len(m.DesiredConnectionId) - copy(dAtA[i:], m.DesiredConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.DesiredConnectionId))) + if len(m.PreviousConnectionId) > 0 { + i -= len(m.PreviousConnectionId) + copy(dAtA[i:], m.PreviousConnectionId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PreviousConnectionId))) i-- dAtA[i] = 0x12 } @@ -1111,10 +1094,6 @@ func (m *MsgConnectionOpenInit) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.ConnectionId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } l = m.Counterparty.Size() n += 1 + l + sovTx(uint64(l)) if m.Version != nil { @@ -1147,11 +1126,7 @@ func (m *MsgConnectionOpenTry) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.DesiredConnectionId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.CounterpartyChosenConnectionId) + l = len(m.PreviousConnectionId) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -1353,38 +1328,6 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { m.ClientId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Counterparty", wireType) } @@ -1417,7 +1360,7 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } @@ -1453,7 +1396,7 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -1625,7 +1568,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredConnectionId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreviousConnectionId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1653,41 +1596,9 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DesiredConnectionId = string(dAtA[iNdEx:postIndex]) + m.PreviousConnectionId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChosenConnectionId", 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.CounterpartyChosenConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ClientState", wireType) } @@ -1723,7 +1634,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Counterparty", wireType) } @@ -1756,7 +1667,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersions", wireType) } @@ -1790,7 +1701,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -1823,7 +1734,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) } @@ -1857,7 +1768,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofInit = []byte{} } iNdEx = postIndex - case 9: + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofClient", wireType) } @@ -1891,7 +1802,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofClient = []byte{} } iNdEx = postIndex - case 10: + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofConsensus", wireType) } @@ -1925,7 +1836,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofConsensus = []byte{} } iNdEx = postIndex - case 11: + case 10: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConsensusHeight", wireType) } @@ -1958,7 +1869,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 12: + case 11: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } diff --git a/x/ibc/core/04-channel/client/cli/query.go b/x/ibc/core/04-channel/client/cli/query.go index cfb10183d1..69cd46e3a1 100644 --- a/x/ibc/core/04-channel/client/cli/query.go +++ b/x/ibc/core/04-channel/client/cli/query.go @@ -463,7 +463,7 @@ func GetCmdQueryNextSequenceReceive() *cobra.Command { return err } - clientCtx = clientCtx.WithHeight(int64(sequenceRes.ProofHeight.VersionHeight)) + clientCtx = clientCtx.WithHeight(int64(sequenceRes.ProofHeight.RevisionHeight)) return clientCtx.PrintOutput(sequenceRes) }, } diff --git a/x/ibc/core/04-channel/client/cli/tx.go b/x/ibc/core/04-channel/client/cli/tx.go index f4f4176383..d3150f2c91 100644 --- a/x/ibc/core/04-channel/client/cli/tx.go +++ b/x/ibc/core/04-channel/client/cli/tx.go @@ -24,9 +24,9 @@ const ( // NewChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction func NewChannelOpenInitCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-init [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops]", + Use: "open-init [port-id] [counterparty-port-id] [connection-hops]", Short: "Creates and sends a ChannelOpenInit message", - Args: cobra.ExactArgs(5), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -35,16 +35,14 @@ func NewChannelOpenInitCmd() *cobra.Command { } portID := args[0] - channelID := args[1] - counterpartyPortID := args[2] - counterpartyChannelID := args[3] - hops := strings.Split(args[4], "/") + counterpartyPortID := args[1] + hops := strings.Split(args[2], "/") order := channelOrder(cmd.Flags()) version, _ := cmd.Flags().GetString(FlagIBCVersion) msg := types.NewMsgChannelOpenInit( - portID, channelID, version, order, hops, - counterpartyPortID, counterpartyChannelID, clientCtx.GetFromAddress(), + portID, version, order, hops, + counterpartyPortID, clientCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -64,9 +62,9 @@ func NewChannelOpenInitCmd() *cobra.Command { // NewChannelOpenTryCmd returns the command to create a MsgChannelOpenTry transaction func NewChannelOpenTryCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-try [port-id] [channel-id] [proved-channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof_init.json] [proof-height]", + Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof_init.json] [proof-height]", Short: "Creates and sends a ChannelOpenTry message", - Args: cobra.ExactArgs(8), + Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -76,27 +74,26 @@ func NewChannelOpenTryCmd() *cobra.Command { portID := args[0] channelID := args[1] - provedChannelID := args[2] - counterpartyPortID := args[3] - counterpartyChannelID := args[4] - hops := strings.Split(args[5], "/") + counterpartyPortID := args[2] + counterpartyChannelID := args[3] + hops := strings.Split(args[4], "/") order := channelOrder(cmd.Flags()) // TODO: Differentiate between channel and counterparty versions. version, _ := cmd.Flags().GetString(FlagIBCVersion) - proofInit, err := connectionutils.ParseProof(clientCtx.LegacyAmino, args[6]) + proofInit, err := connectionutils.ParseProof(clientCtx.LegacyAmino, args[5]) if err != nil { return err } - proofHeight, err := clienttypes.ParseHeight(args[7]) + proofHeight, err := clienttypes.ParseHeight(args[6]) if err != nil { return err } msg := types.NewMsgChannelOpenTry( - portID, channelID, provedChannelID, version, order, hops, + portID, channelID, version, order, hops, counterpartyPortID, counterpartyChannelID, version, proofInit, proofHeight, clientCtx.GetFromAddress(), ) diff --git a/x/ibc/core/04-channel/client/utils/utils.go b/x/ibc/core/04-channel/client/utils/utils.go index f28ffcf805..c10dc05c7f 100644 --- a/x/ibc/core/04-channel/client/utils/utils.go +++ b/x/ibc/core/04-channel/client/utils/utils.go @@ -101,10 +101,10 @@ func QueryChannelConsensusState( queryClient := types.NewQueryClient(clientCtx) req := &types.QueryChannelConsensusStateRequest{ - PortId: portID, - ChannelId: channelID, - VersionNumber: height.VersionNumber, - VersionHeight: height.VersionHeight, + PortId: portID, + ChannelId: channelID, + RevisionNumber: height.RevisionNumber, + RevisionHeight: height.RevisionHeight, } res, err := queryClient.ChannelConsensusState(context.Background(), req) diff --git a/x/ibc/core/04-channel/genesis.go b/x/ibc/core/04-channel/genesis.go index bd557bc5bf..07fad47d77 100644 --- a/x/ibc/core/04-channel/genesis.go +++ b/x/ibc/core/04-channel/genesis.go @@ -31,6 +31,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { for _, as := range gs.AckSequences { k.SetNextSequenceAck(ctx, as.PortId, as.ChannelId, as.Sequence) } + k.SetNextChannelSequence(ctx, gs.NextChannelSequence) } // ExportGenesis returns the ibc channel submodule's exported genesis. diff --git a/x/ibc/core/04-channel/handler.go b/x/ibc/core/04-channel/handler.go index 2bf542cfdf..375c35263e 100644 --- a/x/ibc/core/04-channel/handler.go +++ b/x/ibc/core/04-channel/handler.go @@ -9,20 +9,20 @@ import ( ) // HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit -func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenInit) (*sdk.Result, *capabilitytypes.Capability, error) { - capKey, err := k.ChanOpenInit( - ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.ChannelId, +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenInit) (*sdk.Result, string, *capabilitytypes.Capability, error) { + channelID, capKey, err := k.ChanOpenInit( + ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, portCap, msg.Channel.Counterparty, msg.Channel.Version, ) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "channel handshake open init failed") + return nil, "", nil, sdkerrors.Wrap(err, "channel handshake open init failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenInit, sdk.NewAttribute(types.AttributeKeyPortID, msg.PortId), - sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelId), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), sdk.NewAttribute(types.AttributeCounterpartyPortID, msg.Channel.Counterparty.PortId), sdk.NewAttribute(types.AttributeCounterpartyChannelID, msg.Channel.Counterparty.ChannelId), sdk.NewAttribute(types.AttributeKeyConnectionID, msg.Channel.ConnectionHops[0]), @@ -35,23 +35,23 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabil return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), - }, capKey, nil + }, channelID, capKey, nil } // HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry -func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenTry) (*sdk.Result, *capabilitytypes.Capability, error) { - capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.DesiredChannelId, msg.CounterpartyChosenChannelId, +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenTry) (*sdk.Result, string, *capabilitytypes.Capability, error) { + channelID, capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.PreviousChannelId, portCap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, ) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "channel handshake open try failed") + return nil, "", nil, sdkerrors.Wrap(err, "channel handshake open try failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenTry, sdk.NewAttribute(types.AttributeKeyPortID, msg.PortId), - sdk.NewAttribute(types.AttributeKeyChannelID, msg.DesiredChannelId), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), sdk.NewAttribute(types.AttributeCounterpartyPortID, msg.Channel.Counterparty.PortId), sdk.NewAttribute(types.AttributeCounterpartyChannelID, msg.Channel.Counterparty.ChannelId), sdk.NewAttribute(types.AttributeKeyConnectionID, msg.Channel.ConnectionHops[0]), @@ -64,7 +64,7 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabili return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), - }, capKey, nil + }, channelID, capKey, nil } // HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck diff --git a/x/ibc/core/04-channel/keeper/grpc_query.go b/x/ibc/core/04-channel/keeper/grpc_query.go index 355f192d75..30df0a33ac 100644 --- a/x/ibc/core/04-channel/keeper/grpc_query.go +++ b/x/ibc/core/04-channel/keeper/grpc_query.go @@ -182,7 +182,7 @@ func (q Keeper) ChannelConsensusState(c context.Context, req *types.QueryChannel ) } - consHeight := clienttypes.NewHeight(req.VersionNumber, req.VersionHeight) + consHeight := clienttypes.NewHeight(req.RevisionNumber, req.RevisionHeight) consensusState, found := q.clientKeeper.GetClientConsensusState(ctx, connection.ClientId, consHeight) if !found { return nil, status.Error( diff --git a/x/ibc/core/04-channel/keeper/grpc_query_test.go b/x/ibc/core/04-channel/keeper/grpc_query_test.go index 9e96d2b2fa..cd894520e8 100644 --- a/x/ibc/core/04-channel/keeper/grpc_query_test.go +++ b/x/ibc/core/04-channel/keeper/grpc_query_test.go @@ -439,8 +439,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: "", ChannelId: "test-channel-id", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -451,8 +451,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: "test-port-id", ChannelId: "", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -463,8 +463,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: "test-port-id", ChannelId: "test-channel-id", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -484,8 +484,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: channelA.PortID, ChannelId: channelA.ID, - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, }, @@ -497,8 +497,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: channelA.PortID, ChannelId: channelA.ID, - VersionNumber: 0, - VersionHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height + RevisionNumber: 0, + RevisionHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height } }, false, }, @@ -518,8 +518,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: channelA.PortID, ChannelId: channelA.ID, - VersionNumber: clientState.GetLatestHeight().GetVersionNumber(), - VersionHeight: clientState.GetLatestHeight().GetVersionHeight(), + RevisionNumber: clientState.GetLatestHeight().GetRevisionNumber(), + RevisionHeight: clientState.GetLatestHeight().GetRevisionHeight(), } }, true, diff --git a/x/ibc/core/04-channel/keeper/handshake.go b/x/ibc/core/04-channel/keeper/handshake.go index 75b0c1bd3d..2286deafec 100644 --- a/x/ibc/core/04-channel/keeper/handshake.go +++ b/x/ibc/core/04-channel/keeper/handshake.go @@ -34,30 +34,25 @@ func (k Keeper) CounterpartyHops(ctx sdk.Context, ch types.Channel) ([]string, b } // ChanOpenInit is called by a module to initiate a channel opening handshake with -// a module on another chain. +// a module on another chain. The counterparty channel identifier is validated to be +// empty in msg validation. func (k Keeper) ChanOpenInit( ctx sdk.Context, order types.Order, connectionHops []string, - portID, - channelID string, + portID string, portCap *capabilitytypes.Capability, counterparty types.Counterparty, version string, -) (*capabilitytypes.Capability, error) { - // channel identifier and connection hop length checked on msg.ValidateBasic() - _, found := k.GetChannel(ctx, portID, channelID) - if found { - return nil, sdkerrors.Wrapf(types.ErrChannelExists, "port ID (%s) channel ID (%s)", portID, channelID) - } - +) (string, *capabilitytypes.Capability, error) { + // connection hop length checked on msg.ValidateBasic() connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) + return "", nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) } if len(connectionEnd.GetVersions()) != 1 { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "single version must be negotiated on connection before opening channel, got: %v", connectionEnd.GetVersions(), @@ -65,7 +60,7 @@ func (k Keeper) ChanOpenInit( } if !connectiontypes.VerifySupportedFeature(connectionEnd.GetVersions()[0], order.String()) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "connection version %s does not support channel ordering: %s", connectionEnd.GetVersions()[0], order.String(), @@ -73,15 +68,16 @@ func (k Keeper) ChanOpenInit( } if !k.portKeeper.Authenticate(ctx, portCap, portID) { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) + return "", nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) } + channelID := k.GenerateChannelIdentifier(ctx) channel := types.NewChannel(types.INIT, order, counterparty, connectionHops, version) k.SetChannel(ctx, portID, channelID, channel) capKey, err := k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if err != nil { - return nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) + return "", nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) } k.SetNextSequenceSend(ctx, portID, channelID, 1) @@ -94,7 +90,7 @@ func (k Keeper) ChanOpenInit( telemetry.IncrCounter(1, "ibc", "channel", "open-init") }() - return capKey, nil + return channelID, capKey, nil } // ChanOpenTry is called by a module to accept the first step of a channel opening @@ -104,44 +100,65 @@ func (k Keeper) ChanOpenTry( order types.Order, connectionHops []string, portID, - desiredChannelID, - counterpartyChosenChannelID string, + previousChannelID string, portCap *capabilitytypes.Capability, counterparty types.Counterparty, version, counterpartyVersion string, proofInit []byte, proofHeight exported.Height, -) (*capabilitytypes.Capability, error) { - // channel identifier and connection hop length checked on msg.ValidateBasic() - previousChannel, found := k.GetChannel(ctx, portID, desiredChannelID) - if found && !(previousChannel.State == types.INIT && - previousChannel.Ordering == order && - previousChannel.Counterparty.PortId == counterparty.PortId && - previousChannel.Counterparty.ChannelId == counterparty.ChannelId && - previousChannel.ConnectionHops[0] == connectionHops[0] && - previousChannel.Version == version) { - return nil, sdkerrors.Wrap(types.ErrInvalidChannel, "cannot relay connection attempt") +) (string, *capabilitytypes.Capability, error) { + var ( + previousChannel types.Channel + previousChannelFound bool + ) + + channelID := previousChannelID + + // empty channel identifier indicates continuing a previous channel handshake + if previousChannelID != "" { + // channel identifier and connection hop length checked on msg.ValidateBasic() + // ensure that the previous channel exists + previousChannel, previousChannelFound = k.GetChannel(ctx, portID, previousChannelID) + if !previousChannelFound { + return "", nil, sdkerrors.Wrapf(types.ErrInvalidChannel, "previous channel does not exist for supplied previous channelID %s", previousChannelID) + } + // previous channel must use the same fields + if !(previousChannel.Ordering == order && + previousChannel.Counterparty.PortId == counterparty.PortId && + previousChannel.Counterparty.ChannelId == "" && + previousChannel.ConnectionHops[0] == connectionHops[0] && + previousChannel.Version == version) { + return "", nil, sdkerrors.Wrap(types.ErrInvalidChannel, "channel fields mismatch previous channel fields") + } + + if previousChannel.State != types.INIT { + return "", nil, sdkerrors.Wrapf(types.ErrInvalidChannelState, "previous channel state is in %s, expected INIT", previousChannel.State) + } + + } else { + // generate a new channel + channelID = k.GenerateChannelIdentifier(ctx) } if !k.portKeeper.Authenticate(ctx, portCap, portID) { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) + return "", nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) + return "", nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) } if len(connectionEnd.GetVersions()) != 1 { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "single version must be negotiated on connection before opening channel, got: %v", connectionEnd.GetVersions(), @@ -149,23 +166,13 @@ func (k Keeper) ChanOpenTry( } if !connectiontypes.VerifySupportedFeature(connectionEnd.GetVersions()[0], order.String()) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "connection version %s does not support channel ordering: %s", connectionEnd.GetVersions()[0], order.String(), ) } - // If the channel id chosen for this channel end by the counterparty is empty then - // flexible channel identifier selection is allowed by using the desired channel id. - // Otherwise the desiredChannelID must match the counterpartyChosenChannelID. - if counterpartyChosenChannelID != "" && counterpartyChosenChannelID != desiredChannelID { - return nil, sdkerrors.Wrapf( - types.ErrInvalidChannelIdentifier, - "counterparty chosen channel ID (%s) must be empty or equal to the desired channel ID (%s)", counterpartyChosenChannelID, desiredChannelID, - ) - } - // NOTE: this step has been switched with the one below to reverse the connection // hops channel := types.NewChannel(types.TRYOPEN, order, counterparty, connectionHops, version) @@ -178,7 +185,7 @@ func (k Keeper) ChanOpenTry( // expectedCounterpaty is the counterparty of the counterparty's channel end // (i.e self) - expectedCounterparty := types.NewCounterparty(portID, counterpartyChosenChannelID) + expectedCounterparty := types.NewCounterparty(portID, "") expectedChannel := types.NewChannel( types.INIT, channel.Ordering, expectedCounterparty, counterpartyHops, counterpartyVersion, @@ -188,7 +195,7 @@ func (k Keeper) ChanOpenTry( ctx, connectionEnd, proofHeight, proofInit, counterparty.PortId, counterparty.ChannelId, expectedChannel, ); err != nil { - return nil, err + return "", nil, err } var ( @@ -196,36 +203,34 @@ func (k Keeper) ChanOpenTry( err error ) - // Only create a capability and set the sequences if the previous channel does not exist - _, found = k.GetChannel(ctx, portID, desiredChannelID) - if !found { - capKey, err = k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, desiredChannelID)) + if !previousChannelFound { + capKey, err = k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if err != nil { - return nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, desiredChannelID) + return "", nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) } - k.SetNextSequenceSend(ctx, portID, desiredChannelID, 1) - k.SetNextSequenceRecv(ctx, portID, desiredChannelID, 1) - k.SetNextSequenceAck(ctx, portID, desiredChannelID, 1) + k.SetNextSequenceSend(ctx, portID, channelID, 1) + k.SetNextSequenceRecv(ctx, portID, channelID, 1) + k.SetNextSequenceAck(ctx, portID, channelID, 1) } else { // capability initialized in ChanOpenInit - capKey, found = k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, desiredChannelID)) + capKey, found = k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if !found { - return nil, sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, - "capability not found for existing channel, portID (%s) channelID (%s)", portID, desiredChannelID, + return "", nil, sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, + "capability not found for existing channel, portID (%s) channelID (%s)", portID, channelID, ) } } - k.SetChannel(ctx, portID, desiredChannelID, channel) + k.SetChannel(ctx, portID, channelID, channel) - k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", desiredChannelID, "previous-state", previousChannel.State.String(), "new-state", "TRYOPEN") + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "previous-state", previousChannel.State.String(), "new-state", "TRYOPEN") defer func() { telemetry.IncrCounter(1, "ibc", "channel", "open-try") }() - return capKey, nil + return channelID, capKey, nil } // ChanOpenAck is called by the handshake-originating module to acknowledge the @@ -256,16 +261,6 @@ func (k Keeper) ChanOpenAck( return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) } - // If the previously set channel end allowed for the counterparty to select its own - // channel identifier then we use the counterpartyChannelID. Otherwise the - // counterpartyChannelID must match the previously set counterparty channel ID. - if channel.Counterparty.ChannelId != "" && counterpartyChannelID != channel.Counterparty.ChannelId { - return sdkerrors.Wrapf( - types.ErrInvalidChannelIdentifier, - "counterparty channel identifier (%s) must be equal to stored channel ID for counterparty (%s)", counterpartyChannelID, channel.Counterparty.ChannelId, - ) - } - connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) diff --git a/x/ibc/core/04-channel/keeper/handshake_test.go b/x/ibc/core/04-channel/keeper/handshake_test.go index 857bba57d4..120e1f8fe2 100644 --- a/x/ibc/core/04-channel/keeper/handshake_test.go +++ b/x/ibc/core/04-channel/keeper/handshake_test.go @@ -34,8 +34,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { {"success", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) features = []string{"ORDER_ORDERED", "ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, true}, {"channel already exists", func() { _, _, connA, connB, _, _ = suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED) @@ -64,8 +64,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { connA.ID, conn, ) features = []string{"ORDER_ORDERED", "ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, false}, {"connection does not support ORDERED channels", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -82,8 +82,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { ) // NOTE: Opening UNORDERED channels is still expected to pass but ORDERED channels should fail features = []string{"ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, true}, } @@ -98,9 +98,9 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { counterparty := types.NewCounterparty(connB.FirstOrNextTestChannel(ibctesting.MockPort).PortID, connB.FirstOrNextTestChannel(ibctesting.MockPort).ID) channelA := connA.FirstOrNextTestChannel(ibctesting.MockPort) - cap, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( + channelID, cap, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( suite.chainA.GetContext(), order, []string{connA.ID}, - channelA.PortID, channelA.ID, portCap, counterparty, channelA.Version, + channelA.PortID, portCap, counterparty, channelA.Version, ) // check if order is supported by channel to determine expected behaviour @@ -116,6 +116,7 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { if tc.expPass && orderSupported { suite.Require().NoError(err) suite.Require().NotNil(cap) + suite.Require().Equal(types.FormatChannelIdentifier(0), channelID) chanCap, ok := suite.chainA.App.ScopedIBCKeeper.GetCapability( suite.chainA.GetContext(), @@ -125,6 +126,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { suite.Require().Equal(chanCap.String(), cap.String(), "channel capability is not correct") } else { suite.Require().Error(err) + suite.Require().Nil(cap) + suite.Require().Equal("", channelID) } } }) @@ -137,10 +140,11 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { // ChanOpenTry can succeed. func (suite *KeeperTestSuite) TestChanOpenTry() { var ( - connA *ibctesting.TestConnection - connB *ibctesting.TestConnection - portCap *capabilitytypes.Capability - heightDiff uint64 + connA *ibctesting.TestConnection + connB *ibctesting.TestConnection + previousChannelID string + portCap *capabilitytypes.Capability + heightDiff uint64 ) testCases := []testCase{ @@ -148,34 +152,16 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, true}, {"success with crossing hello", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - suite.coordinator.ChanOpenInitOnBothChains(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - }, true}, - {"success with empty counterparty chosen channel id", func() { - var clientA, clientB string - clientA, clientB, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) + _, channelB, err := suite.coordinator.ChanOpenInitOnBothChains(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) suite.Require().NoError(err) - // set the channel's counterparty channel identifier to empty string - channel := suite.chainA.GetChannel(channelA) - channel.Counterparty.ChannelId = "" - suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + previousChannelID = channelB.ID + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, true}, {"previous channel with invalid state", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -206,28 +192,15 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) heightDiff = 3 // consensus state doesn't exist at this height }, false}, - {"counterparty chosen channel id does not match desired channel id", func() { - _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.Require().NoError(err) - - // set the channel's counterparty channel identifier to empty string - channel := suite.chainA.GetChannel(channelA) - channel.Counterparty.ChannelId = "otherchannel" - suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel) - - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - }, false}, {"channel verification failed", func() { // not creating a channel on chainA will result in an invalid proof of existence _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, false}, {"port capability not found", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -249,8 +222,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.chainB.GetContext(), connB.ID, conn, ) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, false}, {"connection does not support ORDERED channels", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -266,8 +239,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.chainA.GetContext(), connA.ID, conn, ) - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, false}, } @@ -276,25 +249,19 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset heightDiff = 0 // must be explicitly changed in malleate + previousChannelID = "" tc.malleate() channelA := connA.FirstOrNextTestChannel(ibctesting.MockPort) channelB := connB.FirstOrNextTestChannel(ibctesting.MockPort) counterparty := types.NewCounterparty(channelA.PortID, channelA.ID) - // get counterpartyChosenChannelID - var counterpartyChosenChannelID string - channel, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) - if found { - counterpartyChosenChannelID = channel.Counterparty.ChannelId - } - channelKey := host.ChannelKey(counterparty.PortId, counterparty.ChannelId) proof, proofHeight := suite.chainA.QueryProof(channelKey) - cap, err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenTry( + channelID, cap, err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.chainB.GetContext(), types.ORDERED, []string{connB.ID}, - channelB.PortID, channelB.ID, counterpartyChosenChannelID, portCap, counterparty, channelB.Version, connA.FirstOrNextTestChannel(ibctesting.MockPort).Version, + channelB.PortID, previousChannelID, portCap, counterparty, channelB.Version, connA.FirstOrNextTestChannel(ibctesting.MockPort).Version, proof, malleateHeight(proofHeight, heightDiff), ) @@ -304,7 +271,7 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { chanCap, ok := suite.chainB.App.ScopedIBCKeeper.GetCapability( suite.chainB.GetContext(), - host.ChannelCapabilityPath(channelB.PortID, channelB.ID), + host.ChannelCapabilityPath(channelB.PortID, channelID), ) suite.Require().True(ok, "could not retrieve channel capapbility after successful ChanOpenTry") suite.Require().Equal(chanCap.String(), cap.String(), "channel capability is not correct") @@ -802,5 +769,5 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { } func malleateHeight(height exported.Height, diff uint64) exported.Height { - return clienttypes.NewHeight(height.GetVersionNumber(), height.GetVersionHeight()+diff) + return clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+diff) } diff --git a/x/ibc/core/04-channel/keeper/keeper.go b/x/ibc/core/04-channel/keeper/keeper.go index 99aee2c6da..2390fb41cf 100644 --- a/x/ibc/core/04-channel/keeper/keeper.go +++ b/x/ibc/core/04-channel/keeper/keeper.go @@ -55,6 +55,16 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", host.ModuleName, types.SubModuleName)) } +// GenerateChannelIdentifier returns the next channel identifier. +func (k Keeper) GenerateChannelIdentifier(ctx sdk.Context) string { + nextChannelSeq := k.GetNextChannelSequence(ctx) + channelID := types.FormatChannelIdentifier(nextChannelSeq) + + nextChannelSeq++ + k.SetNextChannelSequence(ctx, nextChannelSeq) + return channelID +} + // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { store := ctx.KVStore(k.storeKey) @@ -75,6 +85,24 @@ func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel ty store.Set(host.ChannelKey(portID, channelID), bz) } +// GetNextChannelSequence gets the next channel sequence from the store. +func (k Keeper) GetNextChannelSequence(ctx sdk.Context) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get([]byte(types.KeyNextChannelSequence)) + if bz == nil { + panic("next channel sequence is nil") + } + + return sdk.BigEndianToUint64(bz) +} + +// SetNextChannelSequence sets the next channel sequence to the store. +func (k Keeper) SetNextChannelSequence(ctx sdk.Context, sequence uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set([]byte(types.KeyNextChannelSequence), bz) +} + // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) diff --git a/x/ibc/core/04-channel/keeper/keeper_test.go b/x/ibc/core/04-channel/keeper/keeper_test.go index d1ea3de5da..fa24a66b9c 100644 --- a/x/ibc/core/04-channel/keeper/keeper_test.go +++ b/x/ibc/core/04-channel/keeper/keeper_test.go @@ -42,8 +42,8 @@ func (suite *KeeperTestSuite) TestSetChannel() { // create client and connections on both chains _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - // check for channel to be created on chainB - channelA := connA.NextTestChannel(ibctesting.MockPort) + // check for channel to be created on chainA + channelA := suite.chainA.NextTestChannel(connA, ibctesting.MockPort) _, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) suite.False(found) @@ -52,7 +52,8 @@ func (suite *KeeperTestSuite) TestSetChannel() { suite.NoError(err) storedChannel, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) - expectedCounterparty := types.NewCounterparty(channelB.PortID, channelB.ID) + // counterparty channel id is empty after open init + expectedCounterparty := types.NewCounterparty(channelB.PortID, "") suite.True(found) suite.Equal(types.INIT, storedChannel.State) @@ -83,9 +84,10 @@ func (suite KeeperTestSuite) TestGetAllChannels() { testchannel2, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA1, connB1, ibctesting.MockPort, ibctesting.MockPort, types.UNORDERED) suite.Require().NoError(err) + // counterparty channel id is empty after open init counterparty2 := types.Counterparty{ PortId: connB1.Channels[0].PortID, - ChannelId: connB1.Channels[0].ID, + ChannelId: "", } channel0 := types.NewChannel( diff --git a/x/ibc/core/04-channel/keeper/packet_test.go b/x/ibc/core/04-channel/keeper/packet_test.go index f53ed79475..62c8336212 100644 --- a/x/ibc/core/04-channel/keeper/packet_test.go +++ b/x/ibc/core/04-channel/keeper/packet_test.go @@ -148,8 +148,8 @@ func (suite *KeeperTestSuite) TestSendPacket() { }, false}, {"next sequence send not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) // manually creating channel prevents next sequence from being set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( @@ -298,8 +298,8 @@ func (suite *KeeperTestSuite) TestRecvPacket() { connB, connA, err := suite.coordinator.ConnOpenInit(suite.chainB, suite.chainA, clientB, clientA) suite.Require().NoError(err) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // pass channel check suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainB.GetContext(), @@ -322,8 +322,8 @@ func (suite *KeeperTestSuite) TestRecvPacket() { }, false}, {"next receive sequence is not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // manually creating channel prevents next recv sequence from being set suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel( @@ -570,8 +570,8 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // pass channel check suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainA.GetContext(), @@ -599,8 +599,8 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { }, false}, {"next ack sequence not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) // manually creating channel prevents next sequence acknowledgement from being set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( diff --git a/x/ibc/core/04-channel/types/genesis.go b/x/ibc/core/04-channel/types/genesis.go index 51de681271..28ab32f21a 100644 --- a/x/ibc/core/04-channel/types/genesis.go +++ b/x/ibc/core/04-channel/types/genesis.go @@ -44,28 +44,30 @@ func (ps PacketSequence) Validate() error { // NewGenesisState creates a GenesisState instance. func NewGenesisState( channels []IdentifiedChannel, acks, receipts, commitments []PacketState, - sendSeqs, recvSeqs, ackSeqs []PacketSequence, + sendSeqs, recvSeqs, ackSeqs []PacketSequence, nextChannelSequence uint64, ) GenesisState { return GenesisState{ - Channels: channels, - Acknowledgements: acks, - Commitments: commitments, - SendSequences: sendSeqs, - RecvSequences: recvSeqs, - AckSequences: ackSeqs, + Channels: channels, + Acknowledgements: acks, + Commitments: commitments, + SendSequences: sendSeqs, + RecvSequences: recvSeqs, + AckSequences: ackSeqs, + NextChannelSequence: nextChannelSequence, } } // DefaultGenesisState returns the ibc channel submodule's default genesis state. func DefaultGenesisState() GenesisState { return GenesisState{ - Channels: []IdentifiedChannel{}, - Acknowledgements: []PacketState{}, - Receipts: []PacketState{}, - Commitments: []PacketState{}, - SendSequences: []PacketSequence{}, - RecvSequences: []PacketSequence{}, - AckSequences: []PacketSequence{}, + Channels: []IdentifiedChannel{}, + Acknowledgements: []PacketState{}, + Receipts: []PacketState{}, + Commitments: []PacketState{}, + SendSequences: []PacketSequence{}, + RecvSequences: []PacketSequence{}, + AckSequences: []PacketSequence{}, + NextChannelSequence: 0, } } diff --git a/x/ibc/core/04-channel/types/genesis.pb.go b/x/ibc/core/04-channel/types/genesis.pb.go index ca26a9bb5d..51ff4e5077 100644 --- a/x/ibc/core/04-channel/types/genesis.pb.go +++ b/x/ibc/core/04-channel/types/genesis.pb.go @@ -32,6 +32,8 @@ type GenesisState struct { SendSequences []PacketSequence `protobuf:"bytes,5,rep,name=send_sequences,json=sendSequences,proto3" json:"send_sequences" yaml:"send_sequences"` RecvSequences []PacketSequence `protobuf:"bytes,6,rep,name=recv_sequences,json=recvSequences,proto3" json:"recv_sequences" yaml:"recv_sequences"` AckSequences []PacketSequence `protobuf:"bytes,7,rep,name=ack_sequences,json=ackSequences,proto3" json:"ack_sequences" yaml:"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" yaml:"next_channel_sequence"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -116,6 +118,13 @@ func (m *GenesisState) GetAckSequences() []PacketSequence { return nil } +func (m *GenesisState) GetNextChannelSequence() uint64 { + if m != nil { + return m.NextChannelSequence + } + return 0 +} + // PacketSequence defines the genesis type necessary to retrieve and store // next send and receive sequences. type PacketSequence struct { @@ -186,37 +195,39 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/genesis.proto", fileDescriptor_cb06ec201f452595) } var fileDescriptor_cb06ec201f452595 = []byte{ - // 471 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0xc7, 0xe3, 0x26, 0x4d, 0xd3, 0x6b, 0x13, 0xd1, 0xa3, 0x95, 0x4c, 0x04, 0x76, 0x30, 0x12, - 0x8a, 0x84, 0x6a, 0x53, 0xe8, 0x80, 0x18, 0xcd, 0x00, 0xd9, 0xd0, 0xb1, 0x21, 0xa1, 0xca, 0x39, - 0xbf, 0xba, 0x27, 0xc7, 0xbe, 0xe0, 0xbb, 0x06, 0xfa, 0x21, 0x10, 0x7c, 0xac, 0x8e, 0x1d, 0x99, - 0x2c, 0x94, 0x7c, 0x83, 0x8c, 0x4c, 0xc8, 0xe7, 0x8b, 0x9b, 0xa8, 0x11, 0x22, 0x4c, 0xf6, 0xbd, - 0xf7, 0x7f, 0xbf, 0xdf, 0x5b, 0x1e, 0x7a, 0xcc, 0x86, 0xd4, 0xa3, 0x3c, 0x03, 0x8f, 0x5e, 0x04, - 0x69, 0x0a, 0x23, 0x6f, 0x72, 0xe2, 0x45, 0x90, 0x82, 0x60, 0xc2, 0x1d, 0x67, 0x5c, 0x72, 0x7c, - 0x9f, 0x0d, 0xa9, 0x5b, 0x44, 0x5c, 0x1d, 0x71, 0x27, 0x27, 0xdd, 0xc3, 0x88, 0x47, 0x5c, 0xf5, - 0xbd, 0xe2, 0xaf, 0x8c, 0x76, 0xd7, 0xd2, 0x16, 0x53, 0x2a, 0xe2, 0x7c, 0xdb, 0x46, 0xfb, 0x6f, - 0x4b, 0xfe, 0x07, 0x19, 0x48, 0xc0, 0x9f, 0x50, 0x4b, 0x27, 0x84, 0x69, 0xf4, 0xea, 0xfd, 0xbd, - 0x17, 0x4f, 0xdd, 0x35, 0x46, 0x77, 0x10, 0x42, 0x2a, 0xd9, 0x39, 0x83, 0xf0, 0x4d, 0x59, 0xf4, - 0x1f, 0x5c, 0xe7, 0x76, 0xed, 0x77, 0x6e, 0x1f, 0xdc, 0x69, 0x91, 0x0a, 0x89, 0x09, 0xba, 0x17, - 0xd0, 0x38, 0xe5, 0x5f, 0x46, 0x10, 0x46, 0x90, 0x40, 0x2a, 0x85, 0xb9, 0xa5, 0x34, 0xbd, 0xb5, - 0x9a, 0xf7, 0x01, 0x8d, 0x41, 0xaa, 0xd5, 0xfc, 0x46, 0x21, 0x20, 0x77, 0xe6, 0xf1, 0x3b, 0xb4, - 0x47, 0x79, 0x92, 0x30, 0x59, 0xe2, 0xea, 0x1b, 0xe1, 0x96, 0x47, 0xb1, 0x8f, 0x5a, 0x19, 0x50, - 0x60, 0x63, 0x29, 0xcc, 0xc6, 0x46, 0x98, 0x6a, 0x0e, 0x33, 0xd4, 0x11, 0x90, 0x86, 0x67, 0x02, - 0x3e, 0x5f, 0x42, 0x4a, 0x41, 0x98, 0xdb, 0x8a, 0xf4, 0xe4, 0x6f, 0x24, 0x9d, 0xf5, 0x1f, 0x15, - 0xb0, 0x79, 0x6e, 0x1f, 0x5d, 0x05, 0xc9, 0xe8, 0xb5, 0xb3, 0x0a, 0x72, 0x48, 0xbb, 0x28, 0x2c, - 0xc2, 0x4a, 0x95, 0x01, 0x9d, 0x2c, 0xa9, 0x9a, 0xff, 0xad, 0x5a, 0x05, 0x39, 0xa4, 0x5d, 0x14, - 0x6e, 0x55, 0xe7, 0xa8, 0x1d, 0xd0, 0x78, 0xc9, 0xb4, 0xf3, 0xef, 0xa6, 0x87, 0xda, 0x74, 0x58, - 0x9a, 0x56, 0x38, 0x0e, 0xd9, 0x0f, 0x68, 0x5c, 0x79, 0x9c, 0xef, 0x06, 0xea, 0xac, 0x8e, 0xe3, - 0x67, 0x68, 0x67, 0xcc, 0x33, 0x79, 0xc6, 0x42, 0xd3, 0xe8, 0x19, 0xfd, 0x5d, 0x1f, 0xcf, 0x73, - 0xbb, 0x53, 0xb2, 0x74, 0xc3, 0x21, 0xcd, 0xe2, 0x6f, 0x10, 0xe2, 0x53, 0x84, 0xf4, 0x22, 0x45, - 0x7e, 0x4b, 0xe5, 0x8f, 0xe6, 0xb9, 0x7d, 0x50, 0xe6, 0x6f, 0x7b, 0x0e, 0xd9, 0xd5, 0x8f, 0x41, - 0x88, 0xbb, 0xa8, 0xb5, 0xd8, 0xc8, 0xac, 0xf7, 0x8c, 0x7e, 0x83, 0x54, 0x6f, 0x9f, 0x5c, 0x4f, - 0x2d, 0xe3, 0x66, 0x6a, 0x19, 0xbf, 0xa6, 0x96, 0xf1, 0x63, 0x66, 0xd5, 0x6e, 0x66, 0x56, 0xed, - 0xe7, 0xcc, 0xaa, 0x7d, 0x7c, 0x15, 0x31, 0x79, 0x71, 0x39, 0x74, 0x29, 0x4f, 0x3c, 0xca, 0x45, - 0xc2, 0x85, 0xfe, 0x1c, 0x8b, 0x30, 0xf6, 0xbe, 0x7a, 0xd5, 0xf5, 0x3d, 0x3f, 0x3d, 0x5e, 0x1c, - 0xa0, 0xbc, 0x1a, 0x83, 0x18, 0x36, 0xd5, 0xf1, 0xbd, 0xfc, 0x13, 0x00, 0x00, 0xff, 0xff, 0x70, - 0xac, 0x09, 0x09, 0xef, 0x03, 0x00, 0x00, + // 501 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0x87, 0xe3, 0x26, 0x4d, 0xd3, 0x6d, 0x13, 0xd1, 0x6d, 0x23, 0x99, 0xa8, 0xd8, 0xc6, 0x48, + 0x28, 0x12, 0xaa, 0x4d, 0xa1, 0x07, 0xc4, 0xd1, 0x1c, 0x20, 0x37, 0xb4, 0x70, 0x42, 0x42, 0x91, + 0xb3, 0x9e, 0xba, 0x2b, 0xc7, 0xde, 0xe0, 0xdd, 0x86, 0xf6, 0x29, 0xe0, 0xb1, 0x7a, 0xec, 0x91, + 0x93, 0x85, 0x92, 0x37, 0xc8, 0x91, 0x13, 0xf2, 0xdf, 0x24, 0x6a, 0x84, 0x68, 0x4f, 0xde, 0x9d, + 0xf9, 0xcd, 0xf7, 0xcd, 0xc1, 0x8b, 0x9e, 0xb2, 0x11, 0xb5, 0x29, 0x8f, 0xc1, 0xa6, 0x17, 0x6e, + 0x14, 0xc1, 0xd8, 0x9e, 0x9e, 0xda, 0x3e, 0x44, 0x20, 0x98, 0xb0, 0x26, 0x31, 0x97, 0x1c, 0x1f, + 0xb2, 0x11, 0xb5, 0xd2, 0x88, 0x55, 0x44, 0xac, 0xe9, 0x69, 0xef, 0xc8, 0xe7, 0x3e, 0xcf, 0xfa, + 0x76, 0x7a, 0xca, 0xa3, 0xbd, 0x8d, 0xb4, 0x72, 0x2a, 0x8b, 0x98, 0xf3, 0x6d, 0xb4, 0xff, 0x3e, + 0xe7, 0x7f, 0x92, 0xae, 0x04, 0xfc, 0x15, 0xb5, 0x8a, 0x84, 0x50, 0x15, 0xa3, 0xde, 0xdf, 0x7b, + 0xf5, 0xdc, 0xda, 0x60, 0xb4, 0x06, 0x1e, 0x44, 0x92, 0x9d, 0x33, 0xf0, 0xde, 0xe5, 0x45, 0xe7, + 0xf1, 0x4d, 0xa2, 0xd7, 0xfe, 0x24, 0xfa, 0xc1, 0x9d, 0x16, 0xa9, 0x90, 0x98, 0xa0, 0x47, 0x2e, + 0x0d, 0x22, 0xfe, 0x7d, 0x0c, 0x9e, 0x0f, 0x21, 0x44, 0x52, 0xa8, 0x5b, 0x99, 0xc6, 0xd8, 0xa8, + 0xf9, 0xe8, 0xd2, 0x00, 0x64, 0xb6, 0x9a, 0xd3, 0x48, 0x05, 0xe4, 0xce, 0x3c, 0xfe, 0x80, 0xf6, + 0x28, 0x0f, 0x43, 0x26, 0x73, 0x5c, 0xfd, 0x5e, 0xb8, 0xd5, 0x51, 0xec, 0xa0, 0x56, 0x0c, 0x14, + 0xd8, 0x44, 0x0a, 0xb5, 0x71, 0x2f, 0x4c, 0x35, 0x87, 0x19, 0xea, 0x08, 0x88, 0xbc, 0xa1, 0x80, + 0x6f, 0x97, 0x10, 0x51, 0x10, 0xea, 0x76, 0x46, 0x7a, 0xf6, 0x2f, 0x52, 0x91, 0x75, 0x9e, 0xa4, + 0xb0, 0x45, 0xa2, 0x77, 0xaf, 0xdd, 0x70, 0xfc, 0xd6, 0x5c, 0x07, 0x99, 0xa4, 0x9d, 0x16, 0xca, + 0x70, 0xa6, 0x8a, 0x81, 0x4e, 0x57, 0x54, 0xcd, 0x07, 0xab, 0xd6, 0x41, 0x26, 0x69, 0xa7, 0x85, + 0xa5, 0xea, 0x1c, 0xb5, 0x5d, 0x1a, 0xac, 0x98, 0x76, 0xfe, 0xdf, 0x74, 0x5c, 0x98, 0x8e, 0x72, + 0xd3, 0x1a, 0xc7, 0x24, 0xfb, 0x2e, 0x0d, 0x96, 0x9e, 0xcf, 0xa8, 0x1b, 0xc1, 0x95, 0x1c, 0x16, + 0xb4, 0x2a, 0xa8, 0xb6, 0x0c, 0xa5, 0xdf, 0x70, 0x8c, 0x45, 0xa2, 0x1f, 0xe7, 0x98, 0x8d, 0x31, + 0x93, 0x1c, 0xa6, 0xf5, 0xe2, 0xbf, 0x2b, 0xb1, 0xe6, 0x0f, 0x05, 0x75, 0xd6, 0x97, 0xc2, 0x2f, + 0xd0, 0xce, 0x84, 0xc7, 0x72, 0xc8, 0x3c, 0x55, 0x31, 0x94, 0xfe, 0xae, 0x83, 0x17, 0x89, 0xde, + 0xc9, 0xd1, 0x45, 0xc3, 0x24, 0xcd, 0xf4, 0x34, 0xf0, 0xf0, 0x19, 0x42, 0xa5, 0x89, 0x79, 0xea, + 0x56, 0x96, 0xef, 0x2e, 0x12, 0xfd, 0x20, 0xcf, 0x2f, 0x7b, 0x26, 0xd9, 0x2d, 0x2e, 0x03, 0x0f, + 0xf7, 0x50, 0xab, 0x5a, 0xbf, 0x9e, 0xae, 0x4f, 0xaa, 0xbb, 0x43, 0x6e, 0x66, 0x9a, 0x72, 0x3b, + 0xd3, 0x94, 0xdf, 0x33, 0x4d, 0xf9, 0x39, 0xd7, 0x6a, 0xb7, 0x73, 0xad, 0xf6, 0x6b, 0xae, 0xd5, + 0xbe, 0xbc, 0xf1, 0x99, 0xbc, 0xb8, 0x1c, 0x59, 0x94, 0x87, 0x36, 0xe5, 0x22, 0xe4, 0xa2, 0xf8, + 0x9c, 0x08, 0x2f, 0xb0, 0xaf, 0xec, 0xea, 0x4d, 0xbf, 0x3c, 0x3b, 0x29, 0x9f, 0xb5, 0xbc, 0x9e, + 0x80, 0x18, 0x35, 0xb3, 0x27, 0xfd, 0xfa, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x42, 0xc2, + 0x18, 0x45, 0x04, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -239,6 +250,11 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NextChannelSequence != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.NextChannelSequence)) + i-- + dAtA[i] = 0x40 + } if len(m.AckSequences) > 0 { for iNdEx := len(m.AckSequences) - 1; iNdEx >= 0; iNdEx-- { { @@ -441,6 +457,9 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if m.NextChannelSequence != 0 { + n += 1 + sovGenesis(uint64(m.NextChannelSequence)) + } return n } @@ -737,6 +756,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextChannelSequence", wireType) + } + m.NextChannelSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextChannelSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/ibc/core/04-channel/types/genesis_test.go b/x/ibc/core/04-channel/types/genesis_test.go index c1dbfd76e0..05e154296e 100644 --- a/x/ibc/core/04-channel/types/genesis_test.go +++ b/x/ibc/core/04-channel/types/genesis_test.go @@ -66,6 +66,7 @@ func TestValidateGenesis(t *testing.T) { []types.PacketSequence{ types.NewPacketSequence(testPort2, testChannel2, 1), }, + 0, ), expPass: true, }, diff --git a/x/ibc/core/04-channel/types/keys.go b/x/ibc/core/04-channel/types/keys.go index 60f24d5e74..b6c5745dda 100644 --- a/x/ibc/core/04-channel/types/keys.go +++ b/x/ibc/core/04-channel/types/keys.go @@ -1,5 +1,13 @@ package types +import ( + "fmt" + "strconv" + "strings" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + const ( // SubModuleName defines the IBC channels name SubModuleName = "channel" @@ -12,4 +20,40 @@ const ( // QuerierRoute is the querier route for IBC channels QuerierRoute = SubModuleName + + // KeyNextChannelSequence is the key used to store the next channel sequence in + // the keeper. + KeyNextChannelSequence = "nextChannelSequence" + + // ChannelPrefix is the prefix used when creating a channel identifier + ChannelPrefix = "channel-" ) + +// FormatChannelIdentifier returns the channel identifier with the sequence appended. +func FormatChannelIdentifier(sequence uint64) string { + return fmt.Sprintf("%s%d", ChannelPrefix, sequence) +} + +// IsValidChannelID return true if the channel identifier is valid. +func IsValidChannelID(channelID string) bool { + _, err := ParseChannelSequence(channelID) + return err == nil +} + +// ParseChannelSequence parses the channel sequence from the channel identifier. +func ParseChannelSequence(channelID string) (uint64, error) { + if !strings.HasPrefix(channelID, ChannelPrefix) { + return 0, sdkerrors.Wrapf(ErrInvalidChannelIdentifier, "doesn't contain prefix `%s`", ChannelPrefix) + } + + splitStr := strings.Split(channelID, ChannelPrefix) + if len(splitStr) != 2 { + return 0, sdkerrors.Wrap(ErrInvalidChannelIdentifier, "channel identifier must be in format: `channel-{N}`") + } + + sequence, err := strconv.ParseUint(splitStr[1], 10, 64) + if err != nil { + return 0, sdkerrors.Wrap(err, "failed to parse channel identifier sequence") + } + return sequence, nil +} diff --git a/x/ibc/core/04-channel/types/keys_test.go b/x/ibc/core/04-channel/types/keys_test.go new file mode 100644 index 0000000000..418174cb04 --- /dev/null +++ b/x/ibc/core/04-channel/types/keys_test.go @@ -0,0 +1,44 @@ +package types_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" + "github.com/stretchr/testify/require" +) + +// tests ParseChannelSequence and IsValidChannelID +func TestParseChannelSequence(t *testing.T) { + testCases := []struct { + name string + channelID string + expSeq uint64 + expPass bool + }{ + {"valid 0", "channel-0", 0, true}, + {"valid 1", "channel-1", 1, true}, + {"valid large sequence", "channel-234568219356718293", 234568219356718293, true}, + // uint64 == 20 characters + {"invalid large sequence", "channel-2345682193567182931243", 0, false}, + {"capital prefix", "Channel-0", 0, false}, + {"missing dash", "channel0", 0, false}, + {"blank id", " ", 0, false}, + {"empty id", "", 0, false}, + {"negative sequence", "channel--1", 0, false}, + } + + for _, tc := range testCases { + + seq, err := types.ParseChannelSequence(tc.channelID) + valid := types.IsValidChannelID(tc.channelID) + require.Equal(t, tc.expSeq, seq) + + if tc.expPass { + require.NoError(t, err, tc.name) + require.True(t, valid) + } else { + require.Error(t, err, tc.name) + require.False(t, valid) + } + } +} diff --git a/x/ibc/core/04-channel/types/msgs.go b/x/ibc/core/04-channel/types/msgs.go index 772a1204ef..da14a31030 100644 --- a/x/ibc/core/04-channel/types/msgs.go +++ b/x/ibc/core/04-channel/types/msgs.go @@ -12,19 +12,19 @@ import ( var _ sdk.Msg = &MsgChannelOpenInit{} -// NewMsgChannelOpenInit creates a new MsgChannelOpenInit +// NewMsgChannelOpenInit creates a new MsgChannelOpenInit. It sets the counterparty channel +// identifier to be empty. // nolint:interfacer func NewMsgChannelOpenInit( - portID, channelID string, version string, channelOrder Order, connectionHops []string, - counterpartyPortID, counterpartyChannelID string, signer sdk.AccAddress, + portID, version string, channelOrder Order, connectionHops []string, + counterpartyPortID string, signer sdk.AccAddress, ) *MsgChannelOpenInit { - counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) + counterparty := NewCounterparty(counterpartyPortID, "") channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) return &MsgChannelOpenInit{ - PortId: portID, - ChannelId: channelID, - Channel: channel, - Signer: signer.String(), + PortId: portID, + Channel: channel, + Signer: signer.String(), } } @@ -43,15 +43,15 @@ func (msg MsgChannelOpenInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") - } if msg.Channel.State != INIT { return sdkerrors.Wrapf(ErrInvalidChannelState, "channel state must be INIT in MsgChannelOpenInit. expected: %s, got: %s", INIT, msg.Channel.State, ) } + if msg.Channel.Counterparty.ChannelId != "" { + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty channel identifier must be empty") + } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) @@ -79,21 +79,20 @@ var _ sdk.Msg = &MsgChannelOpenTry{} // NewMsgChannelOpenTry creates a new MsgChannelOpenTry instance // nolint:interfacer func NewMsgChannelOpenTry( - portID, desiredChannelID, counterpartyChosenChannelID, version string, channelOrder Order, connectionHops []string, + portID, previousChannelID, version string, channelOrder Order, connectionHops []string, counterpartyPortID, counterpartyChannelID, counterpartyVersion string, proofInit []byte, proofHeight clienttypes.Height, signer sdk.AccAddress, ) *MsgChannelOpenTry { counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) channel := NewChannel(TRYOPEN, channelOrder, counterparty, connectionHops, version) return &MsgChannelOpenTry{ - PortId: portID, - DesiredChannelId: desiredChannelID, - CounterpartyChosenChannelId: counterpartyChosenChannelID, - Channel: channel, - CounterpartyVersion: counterpartyVersion, - ProofInit: proofInit, - ProofHeight: proofHeight, - Signer: signer.String(), + PortId: portID, + PreviousChannelId: previousChannelID, + Channel: channel, + CounterpartyVersion: counterpartyVersion, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer.String(), } } @@ -112,11 +111,10 @@ func (msg MsgChannelOpenTry) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.DesiredChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid desired channel ID") - } - if msg.CounterpartyChosenChannelId != "" && msg.CounterpartyChosenChannelId != msg.DesiredChannelId { - return sdkerrors.Wrap(ErrInvalidChannelIdentifier, "counterparty chosen channel ID must be empty or equal to desired channel ID") + if msg.PreviousChannelId != "" { + if !IsValidChannelID(msg.PreviousChannelId) { + return sdkerrors.Wrap(ErrInvalidChannelIdentifier, "invalid previous channel ID") + } } if len(msg.ProofInit) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") @@ -130,6 +128,11 @@ func (msg MsgChannelOpenTry) ValidateBasic() error { TRYOPEN, msg.Channel.State, ) } + // counterparty validate basic allows empty counterparty channel identifiers + if err := host.ChannelIdentifierValidator(msg.Channel.Counterparty.ChannelId); err != nil { + return sdkerrors.Wrap(err, "invalid counterparty channel ID") + } + _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) @@ -186,8 +189,8 @@ func (msg MsgChannelOpenAck) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if err := host.ChannelIdentifierValidator(msg.CounterpartyChannelId); err != nil { return sdkerrors.Wrap(err, "invalid counterparty channel ID") @@ -252,8 +255,8 @@ func (msg MsgChannelOpenConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if len(msg.ProofAck) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") @@ -312,8 +315,8 @@ func (msg MsgChannelCloseInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { @@ -369,8 +372,8 @@ func (msg MsgChannelCloseConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if len(msg.ProofInit) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") diff --git a/x/ibc/core/04-channel/types/msgs_test.go b/x/ibc/core/04-channel/types/msgs_test.go index 3a666b31be..9c27fd69ef 100644 --- a/x/ibc/core/04-channel/types/msgs_test.go +++ b/x/ibc/core/04-channel/types/msgs_test.go @@ -23,7 +23,7 @@ import ( const ( // valid constatns used for testing portid = "testportid" - chanid = "testchannel" + chanid = "channel-0" cpportid = "testcpport" cpchanid = "testcpchannel" @@ -35,7 +35,7 @@ const ( invalidLongPort = "invalidlongportinvalidlongportinvalidlongportidinvalidlongportidinvalid" invalidChannel = "(invalidchannel1)" - invalidShortChannel = "invalidch" + invalidShortChannel = "invalid" invalidLongChannel = "invalidlongchannelinvalidlongchannelinvalidlongchannelinvalidlongchannel" invalidConnection = "(invalidconnection1)" @@ -114,22 +114,18 @@ func (suite *TypesTestSuite) TestMsgChannelOpenInitValidateBasic() { msg *types.MsgChannelOpenInit expPass bool }{ - {"", types.NewMsgChannelOpenInit(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), true}, - {"too short port id", types.NewMsgChannelOpenInit(invalidShortPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too long port id", types.NewMsgChannelOpenInit(invalidLongPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"port id contains non-alpha", types.NewMsgChannelOpenInit(invalidPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too short channel id", types.NewMsgChannelOpenInit(portid, invalidShortChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too long channel id", types.NewMsgChannelOpenInit(portid, invalidLongChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"channel id contains non-alpha", types.NewMsgChannelOpenInit(portid, invalidChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"invalid channel order", types.NewMsgChannelOpenInit(portid, chanid, version, types.Order(3), connHops, cpportid, cpchanid, addr), false}, - {"connection hops more than 1 ", types.NewMsgChannelOpenInit(portid, chanid, version, types.ORDERED, invalidConnHops, cpportid, cpchanid, addr), false}, - {"too short connection id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, addr), false}, - {"too long connection id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, addr), false}, - {"connection id contains non-alpha", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, addr), false}, - {"", types.NewMsgChannelOpenInit(portid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, addr), true}, - {"invalid counterparty port id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, addr), false}, - {"invalid counterparty channel id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, addr), false}, - {"channel not in INIT state", &types.MsgChannelOpenInit{portid, chanid, tryOpenChannel, addr.String()}, false}, + {"", types.NewMsgChannelOpenInit(portid, version, types.ORDERED, connHops, cpportid, addr), true}, + {"too short port id", types.NewMsgChannelOpenInit(invalidShortPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"too long port id", types.NewMsgChannelOpenInit(invalidLongPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"port id contains non-alpha", types.NewMsgChannelOpenInit(invalidPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"invalid channel order", types.NewMsgChannelOpenInit(portid, version, types.Order(3), connHops, cpportid, addr), false}, + {"connection hops more than 1 ", types.NewMsgChannelOpenInit(portid, version, types.ORDERED, invalidConnHops, cpportid, addr), false}, + {"too short connection id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, invalidShortConnHops, cpportid, addr), false}, + {"too long connection id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, invalidLongConnHops, cpportid, addr), false}, + {"connection id contains non-alpha", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, []string{invalidConnection}, cpportid, addr), false}, + {"", types.NewMsgChannelOpenInit(portid, "", types.UNORDERED, connHops, cpportid, addr), true}, + {"invalid counterparty port id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, connHops, invalidPort, addr), false}, + {"channel not in INIT state", &types.MsgChannelOpenInit{portid, tryOpenChannel, addr.String()}, false}, } for _, tc := range testCases { @@ -155,27 +151,25 @@ func (suite *TypesTestSuite) TestMsgChannelOpenTryValidateBasic() { msg *types.MsgChannelOpenTry expPass bool }{ - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"too short port id", types.NewMsgChannelOpenTry(invalidShortPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long port id", types.NewMsgChannelOpenTry(invalidLongPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"port id contains non-alpha", types.NewMsgChannelOpenTry(invalidPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too short channel id", types.NewMsgChannelOpenTry(portid, invalidShortChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long channel id", types.NewMsgChannelOpenTry(portid, invalidLongChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"channel id contains non-alpha", types.NewMsgChannelOpenTry(portid, invalidChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, "", suite.proof, height, addr), true}, - {"proof height is zero", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, clienttypes.ZeroHeight(), addr), false}, - {"invalid channel order", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.Order(4), connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"connection hops more than 1 ", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too short connection id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long connection id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"connection id contains non-alpha", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"invalid counterparty port id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, version, suite.proof, height, addr), false}, - {"invalid counterparty channel id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, version, suite.proof, height, addr), false}, - {"empty proof", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, cpportid, cpchanid, version, emptyProof, height, addr), false}, - {"valid empty proved channel id", types.NewMsgChannelOpenTry(portid, chanid, "", version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"invalid proved channel id, doesn't match channel id", types.NewMsgChannelOpenTry(portid, chanid, "differentchannel", version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"channel not in TRYOPEN state", &types.MsgChannelOpenTry{portid, chanid, chanid, initChannel, version, suite.proof, height, addr.String()}, false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, + {"too short port id", types.NewMsgChannelOpenTry(invalidShortPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long port id", types.NewMsgChannelOpenTry(invalidLongPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"port id contains non-alpha", types.NewMsgChannelOpenTry(invalidPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too short channel id", types.NewMsgChannelOpenTry(portid, invalidShortChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long channel id", types.NewMsgChannelOpenTry(portid, invalidLongChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"channel id contains non-alpha", types.NewMsgChannelOpenTry(portid, invalidChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, "", suite.proof, height, addr), true}, + {"proof height is zero", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, clienttypes.ZeroHeight(), addr), false}, + {"invalid channel order", types.NewMsgChannelOpenTry(portid, chanid, version, types.Order(4), connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"connection hops more than 1 ", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too short connection id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long connection id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"connection id contains non-alpha", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, + {"invalid counterparty port id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, version, suite.proof, height, addr), false}, + {"invalid counterparty channel id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, version, suite.proof, height, addr), false}, + {"empty proof", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, cpportid, cpchanid, version, emptyProof, height, addr), false}, + {"channel not in TRYOPEN state", &types.MsgChannelOpenTry{portid, chanid, initChannel, version, suite.proof, height, addr.String()}, false}, } for _, tc := range testCases { diff --git a/x/ibc/core/04-channel/types/packet.go b/x/ibc/core/04-channel/types/packet.go index 18a3690b1e..b5c8d18043 100644 --- a/x/ibc/core/04-channel/types/packet.go +++ b/x/ibc/core/04-channel/types/packet.go @@ -12,7 +12,7 @@ import ( ) // CommitPacket returns the packet commitment bytes. The commitment consists of: -// sha256_hash(timeout_timestamp + timeout_height.VersionNumber + timeout_height.VersionHeight + sha256_hash(data)) +// sha256_hash(timeout_timestamp + timeout_height.RevisionNumber + timeout_height.RevisionHeight + sha256_hash(data)) // from a given packet. This results in a fixed length preimage. // NOTE: sdk.Uint64ToBigEndian sets the uint64 to a slice of length 8. func CommitPacket(cdc codec.BinaryMarshaler, packet exported.PacketI) []byte { @@ -20,11 +20,11 @@ func CommitPacket(cdc codec.BinaryMarshaler, packet exported.PacketI) []byte { buf := sdk.Uint64ToBigEndian(packet.GetTimeoutTimestamp()) - versionNumber := sdk.Uint64ToBigEndian(timeoutHeight.GetVersionNumber()) - buf = append(buf, versionNumber...) + revisionNumber := sdk.Uint64ToBigEndian(timeoutHeight.GetRevisionNumber()) + buf = append(buf, revisionNumber...) - versionHeight := sdk.Uint64ToBigEndian(timeoutHeight.GetVersionHeight()) - buf = append(buf, versionHeight...) + revisionHeight := sdk.Uint64ToBigEndian(timeoutHeight.GetRevisionHeight()) + buf = append(buf, revisionHeight...) dataHash := sha256.Sum256(packet.GetData()) buf = append(buf, dataHash[:]...) diff --git a/x/ibc/core/04-channel/types/query.pb.go b/x/ibc/core/04-channel/types/query.pb.go index 7015a2acf9..d163f3d8ce 100644 --- a/x/ibc/core/04-channel/types/query.pb.go +++ b/x/ibc/core/04-channel/types/query.pb.go @@ -512,10 +512,10 @@ type QueryChannelConsensusStateRequest struct { PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` // channel unique identifier ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` - // version number of the consensus state - VersionNumber uint64 `protobuf:"varint,3,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty"` - // version height of the consensus state - VersionHeight uint64 `protobuf:"varint,4,opt,name=version_height,json=versionHeight,proto3" json:"version_height,omitempty"` + // revision number of the consensus state + RevisionNumber uint64 `protobuf:"varint,3,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty"` + // revision height of the consensus state + RevisionHeight uint64 `protobuf:"varint,4,opt,name=revision_height,json=revisionHeight,proto3" json:"revision_height,omitempty"` } func (m *QueryChannelConsensusStateRequest) Reset() { *m = QueryChannelConsensusStateRequest{} } @@ -565,16 +565,16 @@ func (m *QueryChannelConsensusStateRequest) GetChannelId() string { return "" } -func (m *QueryChannelConsensusStateRequest) GetVersionNumber() uint64 { +func (m *QueryChannelConsensusStateRequest) GetRevisionNumber() uint64 { if m != nil { - return m.VersionNumber + return m.RevisionNumber } return 0 } -func (m *QueryChannelConsensusStateRequest) GetVersionHeight() uint64 { +func (m *QueryChannelConsensusStateRequest) GetRevisionHeight() uint64 { if m != nil { - return m.VersionHeight + return m.RevisionHeight } return 0 } @@ -1699,100 +1699,100 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/query.proto", fileDescriptor_1034a1e9abc4cca1) } var fileDescriptor_1034a1e9abc4cca1 = []byte{ - // 1487 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xdf, 0x6b, 0x14, 0xd7, - 0x17, 0xcf, 0xdd, 0x44, 0x4d, 0x8e, 0xbf, 0x6f, 0x12, 0x8d, 0x63, 0x5c, 0xe3, 0x7e, 0xbf, 0x6d, - 0xa3, 0xe0, 0x5c, 0x13, 0xad, 0x15, 0x8a, 0x2d, 0x31, 0x50, 0x1b, 0x50, 0x6b, 0x47, 0x6d, 0x55, - 0x5a, 0x97, 0xd9, 0xd9, 0xeb, 0x66, 0x48, 0x32, 0xb3, 0xee, 0xcc, 0xc6, 0x84, 0xb0, 0xd0, 0x56, - 0x90, 0x52, 0x2a, 0x14, 0xa4, 0x14, 0xfa, 0xd2, 0x97, 0x42, 0xf1, 0xb1, 0xff, 0x43, 0x1f, 0x7c, - 0xe8, 0x83, 0xd0, 0x16, 0x2c, 0x05, 0x2b, 0x5a, 0xa8, 0x0f, 0x7d, 0x6e, 0x5f, 0xcb, 0xdc, 0x7b, - 0xe6, 0xd7, 0xee, 0xcc, 0x24, 0xeb, 0x66, 0x41, 0xfa, 0x94, 0x9d, 0x3b, 0xe7, 0x9c, 0xfb, 0xf9, - 0x7c, 0xce, 0x3d, 0x67, 0xef, 0xd9, 0xc0, 0x7e, 0xb3, 0x64, 0x30, 0xc3, 0xae, 0x71, 0x66, 0xcc, - 0xea, 0x96, 0xc5, 0xe7, 0xd9, 0xe2, 0x04, 0xbb, 0x51, 0xe7, 0xb5, 0x65, 0xb5, 0x5a, 0xb3, 0x5d, - 0x9b, 0x0e, 0x9a, 0x25, 0x43, 0xf5, 0x0c, 0x54, 0x34, 0x50, 0x17, 0x27, 0x94, 0x88, 0xd7, 0xbc, - 0xc9, 0x2d, 0xd7, 0x73, 0x92, 0x9f, 0xa4, 0x97, 0x72, 0xc8, 0xb0, 0x9d, 0x05, 0xdb, 0x61, 0x25, - 0xdd, 0xe1, 0x32, 0x1c, 0x5b, 0x9c, 0x28, 0x71, 0x57, 0x9f, 0x60, 0x55, 0xbd, 0x62, 0x5a, 0xba, - 0x6b, 0xda, 0x16, 0xda, 0x1e, 0x48, 0x82, 0xe0, 0x6f, 0x26, 0x4d, 0x46, 0x2b, 0xb6, 0x5d, 0x99, - 0xe7, 0x4c, 0xaf, 0x9a, 0x4c, 0xb7, 0x2c, 0xdb, 0x15, 0xfe, 0x0e, 0xbe, 0xdd, 0x83, 0x6f, 0xc5, - 0x53, 0xa9, 0x7e, 0x9d, 0xe9, 0x16, 0xa2, 0x57, 0x86, 0x2a, 0x76, 0xc5, 0x16, 0x1f, 0x99, 0xf7, - 0x49, 0xae, 0x16, 0xce, 0xc2, 0xe0, 0xbb, 0x1e, 0xa6, 0x69, 0xb9, 0x89, 0xc6, 0x6f, 0xd4, 0xb9, - 0xe3, 0xd2, 0xdd, 0xb0, 0xa9, 0x6a, 0xd7, 0xdc, 0xa2, 0x59, 0x1e, 0x21, 0x63, 0x64, 0x7c, 0x40, - 0xdb, 0xe8, 0x3d, 0xce, 0x94, 0xe9, 0x3e, 0x00, 0xc4, 0xe3, 0xbd, 0xcb, 0x89, 0x77, 0x03, 0xb8, - 0x32, 0x53, 0x2e, 0xdc, 0x23, 0x30, 0x14, 0x8f, 0xe7, 0x54, 0x6d, 0xcb, 0xe1, 0xf4, 0x38, 0x6c, - 0x42, 0x2b, 0x11, 0x70, 0xf3, 0xe4, 0xa8, 0x9a, 0xa0, 0xa6, 0xea, 0xbb, 0xf9, 0xc6, 0x74, 0x08, - 0x36, 0x54, 0x6b, 0xb6, 0x7d, 0x5d, 0x6c, 0xb5, 0x45, 0x93, 0x0f, 0x74, 0x1a, 0xb6, 0x88, 0x0f, - 0xc5, 0x59, 0x6e, 0x56, 0x66, 0xdd, 0x91, 0x5e, 0x11, 0x52, 0x89, 0x84, 0x94, 0x19, 0x58, 0x9c, - 0x50, 0xdf, 0x16, 0x16, 0xa7, 0xfa, 0xee, 0x3f, 0xda, 0xdf, 0xa3, 0x6d, 0x16, 0x5e, 0x72, 0xa9, - 0x70, 0x2d, 0x0e, 0xd5, 0xf1, 0xb9, 0xbf, 0x05, 0x10, 0x26, 0x06, 0xd1, 0xbe, 0xac, 0xca, 0x2c, - 0xaa, 0x5e, 0x16, 0x55, 0x79, 0x28, 0x30, 0x8b, 0xea, 0x79, 0xbd, 0xc2, 0xd1, 0x57, 0x8b, 0x78, - 0x16, 0x1e, 0x11, 0x18, 0x6e, 0xda, 0x00, 0xc5, 0x38, 0x05, 0xfd, 0xc8, 0xcf, 0x19, 0x21, 0x63, - 0xbd, 0x22, 0x7e, 0x92, 0x1a, 0x33, 0x65, 0x6e, 0xb9, 0xe6, 0x75, 0x93, 0x97, 0x7d, 0x5d, 0x02, - 0x3f, 0x7a, 0x3a, 0x86, 0x32, 0x27, 0x50, 0xbe, 0xb2, 0x2a, 0x4a, 0x09, 0x20, 0x0a, 0x93, 0x9e, - 0x80, 0x8d, 0x6d, 0xaa, 0x88, 0xf6, 0x85, 0x4f, 0x09, 0xe4, 0x25, 0x41, 0xdb, 0xb2, 0xb8, 0xe1, - 0x45, 0x6b, 0xd6, 0x32, 0x0f, 0x60, 0x04, 0x2f, 0xf1, 0x28, 0x45, 0x56, 0x9a, 0xb4, 0xce, 0x3d, - 0xb7, 0xd6, 0xcf, 0x08, 0xec, 0x4f, 0x85, 0xf2, 0xdf, 0x52, 0xfd, 0xb2, 0x2f, 0xba, 0xc4, 0x34, - 0x2d, 0xac, 0x2f, 0xb8, 0xba, 0xcb, 0x3b, 0x2d, 0xde, 0xdf, 0x03, 0x11, 0x13, 0x42, 0xa3, 0x88, - 0x3a, 0xec, 0x36, 0x03, 0x7d, 0x8a, 0x12, 0x6a, 0xd1, 0xf1, 0x4c, 0xb0, 0x52, 0x0e, 0x26, 0x11, - 0x89, 0x48, 0x1a, 0x89, 0x39, 0x6c, 0x26, 0x2d, 0x77, 0xb3, 0xe4, 0xef, 0x11, 0x38, 0x10, 0x63, - 0xe8, 0x71, 0xb2, 0x9c, 0xba, 0xb3, 0x1e, 0xfa, 0xd1, 0x97, 0x60, 0xdb, 0x22, 0xaf, 0x39, 0xa6, - 0x6d, 0x15, 0xad, 0xfa, 0x42, 0x89, 0xd7, 0x04, 0xc8, 0x3e, 0x6d, 0x2b, 0xae, 0x9e, 0x13, 0x8b, - 0x51, 0x33, 0xe4, 0xd2, 0x17, 0x33, 0x43, 0xac, 0xbf, 0x11, 0x28, 0x64, 0x61, 0xc5, 0x84, 0x9c, - 0x84, 0xed, 0x86, 0xff, 0x26, 0x96, 0x88, 0x21, 0x55, 0x7e, 0x17, 0xa8, 0xfe, 0x77, 0x81, 0x3a, - 0x65, 0x2d, 0x6b, 0xdb, 0x8c, 0x58, 0x18, 0xba, 0x17, 0x06, 0x30, 0x89, 0x01, 0xa3, 0x7e, 0xb9, - 0x30, 0x53, 0x0e, 0x33, 0xd1, 0x9b, 0x95, 0x89, 0xbe, 0xe7, 0xc9, 0x44, 0x0d, 0x46, 0x05, 0xb9, - 0xf3, 0xba, 0x31, 0xc7, 0xdd, 0x69, 0x7b, 0x61, 0xc1, 0x74, 0x17, 0xb8, 0xe5, 0x76, 0x9a, 0x03, - 0x05, 0xfa, 0x1d, 0x2f, 0x84, 0x65, 0x70, 0x54, 0x3f, 0x78, 0x2e, 0x7c, 0x4d, 0x60, 0x5f, 0xca, - 0xa6, 0x28, 0xa6, 0x68, 0x57, 0xfe, 0xaa, 0xd8, 0x78, 0x8b, 0x16, 0x59, 0xe9, 0xe6, 0xd1, 0xfc, - 0x26, 0x0d, 0x9c, 0xd3, 0xa9, 0x24, 0xf1, 0x1e, 0xdb, 0xfb, 0xdc, 0x3d, 0xf6, 0x4f, 0xbf, 0xdd, - 0x27, 0x20, 0x0c, 0x5a, 0xec, 0xe6, 0x50, 0x2d, 0xbf, 0xcb, 0x8e, 0x25, 0x76, 0x59, 0x19, 0x44, - 0x9e, 0xe5, 0xa8, 0xd3, 0x8b, 0xd0, 0x62, 0x6d, 0xd8, 0x13, 0x21, 0xaa, 0x71, 0x83, 0x9b, 0xd5, - 0xae, 0x9e, 0xcc, 0xbb, 0x04, 0x94, 0xa4, 0x1d, 0x51, 0x56, 0x05, 0xfa, 0x6b, 0xde, 0xd2, 0x22, - 0x97, 0x71, 0xfb, 0xb5, 0xe0, 0xb9, 0x9b, 0x35, 0x7a, 0x13, 0x9b, 0xa5, 0x04, 0x35, 0x65, 0xcc, - 0x59, 0xf6, 0xcd, 0x79, 0x5e, 0xae, 0xf0, 0x6e, 0x17, 0xea, 0x3d, 0xbf, 0xf5, 0xa5, 0xec, 0x8c, - 0xb2, 0x8c, 0xc3, 0x76, 0x3d, 0xfe, 0x0a, 0x4b, 0xb6, 0x79, 0xb9, 0x9b, 0x75, 0xfb, 0x6d, 0x26, - 0xd6, 0x17, 0xa6, 0x78, 0xff, 0x26, 0xf0, 0xbf, 0x4c, 0x98, 0xa8, 0xe9, 0x19, 0xd8, 0xd1, 0x24, - 0xde, 0xda, 0xcb, 0xb8, 0xc5, 0xf3, 0x45, 0xa8, 0xe5, 0xaf, 0xfc, 0xbe, 0x7a, 0xc9, 0xf2, 0x6b, - 0x46, 0x62, 0xee, 0x38, 0x35, 0x6f, 0xc0, 0xde, 0xaa, 0x88, 0x54, 0x0c, 0xdb, 0x57, 0xd1, 0x3f, - 0xc3, 0xce, 0x48, 0xef, 0x58, 0xef, 0x78, 0x9f, 0xb6, 0xa7, 0xda, 0xd4, 0x2c, 0x2f, 0xf8, 0x06, - 0x85, 0x25, 0x6c, 0xa7, 0x09, 0xc0, 0x30, 0x19, 0xa3, 0x30, 0x10, 0xc6, 0x23, 0x22, 0x5e, 0xb8, - 0x10, 0xd1, 0x24, 0xd7, 0xa6, 0x26, 0xb7, 0xfd, 0x76, 0x13, 0x6e, 0x3d, 0x65, 0xcc, 0x75, 0x2c, - 0xc8, 0x11, 0x18, 0x42, 0x41, 0x74, 0x63, 0xae, 0x45, 0x09, 0x5a, 0xf5, 0x4f, 0x5e, 0x28, 0x41, - 0x1d, 0xf6, 0x26, 0xe2, 0xe8, 0x32, 0xff, 0x2b, 0x78, 0xcf, 0x3d, 0xc7, 0x97, 0x82, 0x7c, 0x68, - 0x12, 0x40, 0xa7, 0x77, 0xe8, 0xef, 0x09, 0x8c, 0xa5, 0xc7, 0x46, 0x5e, 0x93, 0x30, 0x6c, 0xf1, - 0xa5, 0xf0, 0xb0, 0x14, 0x91, 0xbd, 0xd8, 0xaa, 0x4f, 0x1b, 0xb4, 0x5a, 0x7d, 0xbb, 0xd8, 0xc2, - 0x26, 0x7f, 0xdc, 0x05, 0x1b, 0x04, 0x66, 0xfa, 0x1d, 0x81, 0x4d, 0x78, 0xdd, 0xa4, 0xe3, 0x89, - 0xf5, 0x9e, 0xf0, 0x63, 0x81, 0x72, 0x70, 0x0d, 0x96, 0x92, 0x79, 0xe1, 0xf4, 0x27, 0x3f, 0xfd, - 0x71, 0x37, 0x37, 0x45, 0xdf, 0x64, 0x09, 0xbf, 0x74, 0xc8, 0x1f, 0x45, 0xfc, 0x59, 0x8b, 0xad, - 0x84, 0x3a, 0x37, 0x98, 0xa7, 0xbe, 0xc3, 0x56, 0x30, 0x27, 0x0d, 0x7a, 0x87, 0x40, 0xbf, 0x3f, - 0xe1, 0xd1, 0xd5, 0x01, 0xf8, 0x67, 0x5b, 0x39, 0xb4, 0x16, 0x53, 0x04, 0x7b, 0x48, 0x80, 0xfd, - 0x3f, 0x2d, 0xac, 0x0e, 0x96, 0xfe, 0x40, 0x80, 0xb6, 0xce, 0x9e, 0xf4, 0x68, 0xc6, 0x76, 0x69, - 0x43, 0xb3, 0x72, 0xac, 0x3d, 0x27, 0x44, 0x3b, 0x2d, 0xd0, 0x9e, 0xa4, 0xaf, 0x67, 0xa0, 0x0d, - 0xbc, 0x3d, 0x75, 0x83, 0x87, 0x46, 0x48, 0xe3, 0x17, 0x8f, 0x46, 0xcb, 0xf4, 0x97, 0x49, 0x23, - 0x6d, 0x0c, 0xcd, 0xa4, 0x91, 0x3a, 0x60, 0x16, 0x2e, 0x0a, 0x1a, 0xe7, 0xe8, 0x99, 0x0e, 0x4f, - 0x08, 0x8b, 0xce, 0xa6, 0xf4, 0xcb, 0x1c, 0x0c, 0x27, 0xce, 0x51, 0xf4, 0xf8, 0xea, 0x28, 0x93, - 0x86, 0x44, 0xe5, 0xb5, 0xb6, 0xfd, 0x90, 0xe0, 0x67, 0x44, 0x30, 0xbc, 0x45, 0xe8, 0x47, 0xa4, - 0x63, 0x8e, 0xf1, 0xc9, 0x8f, 0xe1, 0x04, 0xc9, 0x56, 0xe2, 0x73, 0x68, 0x83, 0xc9, 0xf6, 0x10, - 0xae, 0xcb, 0xe7, 0x06, 0x7d, 0x4c, 0x60, 0x47, 0xf3, 0x75, 0x9e, 0x4e, 0xa4, 0x53, 0x4b, 0x19, - 0xd7, 0x94, 0xc9, 0x76, 0x5c, 0x50, 0x08, 0x2e, 0x74, 0x28, 0xd2, 0x0f, 0x3b, 0x55, 0xa1, 0xe5, - 0x5b, 0xd8, 0x61, 0x2b, 0x7e, 0x6b, 0x6d, 0xd0, 0x87, 0x04, 0x76, 0xb6, 0x4c, 0x2c, 0xb4, 0x0d, - 0xc0, 0x41, 0x5d, 0x1e, 0x6d, 0xcb, 0x07, 0x59, 0x5e, 0x15, 0x2c, 0x2f, 0x52, 0x6d, 0xfd, 0x59, - 0xd2, 0x9f, 0x09, 0x6c, 0x8d, 0x4d, 0x0c, 0x54, 0x5d, 0x0d, 0x62, 0x7c, 0x98, 0x51, 0xd8, 0x9a, - 0xed, 0x91, 0x4e, 0x49, 0xd0, 0xf9, 0x80, 0x5e, 0x5d, 0x27, 0x3a, 0x35, 0x19, 0x3f, 0x96, 0xb1, - 0x67, 0x04, 0x86, 0x13, 0xaf, 0xa9, 0x59, 0xc5, 0x9a, 0x35, 0xa4, 0x64, 0x15, 0x6b, 0xe6, 0x88, - 0x51, 0xb8, 0x26, 0xe8, 0x5e, 0xa6, 0xef, 0xad, 0x13, 0x5d, 0xdd, 0x98, 0x8b, 0x51, 0xfd, 0x8b, - 0xc0, 0xae, 0xe4, 0x1b, 0x39, 0x6d, 0x17, 0x73, 0x70, 0x4c, 0x4f, 0xb4, 0xef, 0x88, 0x6c, 0x8b, - 0x82, 0xed, 0x15, 0xfa, 0xfe, 0xfa, 0xb1, 0x8d, 0x73, 0xfa, 0x3c, 0x07, 0x3b, 0x5b, 0xae, 0xbb, - 0x59, 0xb5, 0x98, 0x76, 0x69, 0xcf, 0xaa, 0xc5, 0xd4, 0xfb, 0x74, 0xe1, 0x8e, 0x6c, 0xbd, 0xb7, - 0x09, 0xbd, 0x45, 0xba, 0xd1, 0x74, 0x32, 0xc6, 0x81, 0x06, 0xab, 0x07, 0xb0, 0x8a, 0x55, 0x24, - 0xfe, 0x0f, 0x81, 0x6d, 0xf1, 0xab, 0x2f, 0x65, 0x6b, 0xe1, 0x15, 0xb9, 0xac, 0x2b, 0x47, 0xd6, - 0xee, 0x80, 0x2a, 0x7c, 0x2c, 0x55, 0x58, 0xa1, 0xcb, 0x5d, 0xd4, 0x20, 0x36, 0x01, 0xc4, 0xc8, - 0x7b, 0x25, 0x40, 0x7f, 0x25, 0x30, 0x98, 0x70, 0x43, 0xa6, 0x19, 0x77, 0x86, 0xf4, 0xcb, 0xba, - 0xf2, 0x6a, 0x9b, 0x5e, 0x28, 0xc4, 0x25, 0xa1, 0xc3, 0x3b, 0xf4, 0x6c, 0xa7, 0x3a, 0xc4, 0x2e, - 0xf3, 0xa7, 0xb4, 0xfb, 0x4f, 0xf2, 0xe4, 0xc1, 0x93, 0x3c, 0x79, 0xfc, 0x24, 0x4f, 0xbe, 0x78, - 0x9a, 0xef, 0x79, 0xf0, 0x34, 0xdf, 0xf3, 0xf0, 0x69, 0xbe, 0xe7, 0xea, 0x89, 0x8a, 0xe9, 0xce, - 0xd6, 0x4b, 0xaa, 0x61, 0x2f, 0x30, 0xfc, 0xaf, 0xa0, 0xfc, 0x73, 0xd8, 0x29, 0xcf, 0xb1, 0xa5, - 0x10, 0xc6, 0x91, 0x63, 0x87, 0x7d, 0x24, 0xee, 0x72, 0x95, 0x3b, 0xa5, 0x8d, 0xe2, 0x47, 0xdc, - 0xa3, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x48, 0x61, 0x15, 0x26, 0xa4, 0x1c, 0x00, 0x00, + // 1482 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xdd, 0x6f, 0x14, 0x55, + 0x14, 0xef, 0xdd, 0x16, 0x68, 0x0f, 0xc8, 0xc7, 0x6d, 0x0b, 0x65, 0x28, 0x4b, 0x19, 0x8d, 0x14, + 0x12, 0xe6, 0xd2, 0x82, 0x48, 0x62, 0xd0, 0x94, 0x26, 0x62, 0x13, 0x40, 0x1c, 0x40, 0x81, 0x28, + 0x9b, 0xd9, 0xd9, 0xcb, 0x76, 0xd2, 0x76, 0x66, 0xd8, 0x99, 0x2d, 0x6d, 0x9a, 0x7d, 0x50, 0x13, + 0xe2, 0x83, 0x24, 0x26, 0x3c, 0x68, 0x7c, 0xf1, 0xc5, 0xc4, 0xf0, 0xe0, 0x83, 0xff, 0x83, 0x0f, + 0xbc, 0x49, 0xa2, 0x26, 0x18, 0x13, 0x24, 0x60, 0x22, 0x0f, 0x3e, 0xeb, 0xab, 0x99, 0xfb, 0x31, + 0x1f, 0xbb, 0x33, 0xd3, 0x2e, 0xdb, 0x4d, 0x1a, 0x9f, 0xba, 0x73, 0xe7, 0x9c, 0x73, 0x7f, 0xbf, + 0xdf, 0xb9, 0xe7, 0xec, 0x3d, 0x5b, 0x38, 0x60, 0x95, 0x4d, 0x62, 0x3a, 0x35, 0x4a, 0xcc, 0x59, + 0xc3, 0xb6, 0xe9, 0x3c, 0x59, 0x9c, 0x20, 0xb7, 0xea, 0xb4, 0xb6, 0xac, 0xb9, 0x35, 0xc7, 0x77, + 0xf0, 0xa0, 0x55, 0x36, 0xb5, 0xc0, 0x40, 0x13, 0x06, 0xda, 0xe2, 0x84, 0x12, 0xf3, 0x9a, 0xb7, + 0xa8, 0xed, 0x07, 0x4e, 0xfc, 0x13, 0xf7, 0x52, 0x8e, 0x98, 0x8e, 0xb7, 0xe0, 0x78, 0xa4, 0x6c, + 0x78, 0x94, 0x87, 0x23, 0x8b, 0x13, 0x65, 0xea, 0x1b, 0x13, 0xc4, 0x35, 0xaa, 0x96, 0x6d, 0xf8, + 0x96, 0x63, 0x0b, 0xdb, 0x83, 0x69, 0x10, 0xe4, 0x66, 0xdc, 0x64, 0xb4, 0xea, 0x38, 0xd5, 0x79, + 0x4a, 0x0c, 0xd7, 0x22, 0x86, 0x6d, 0x3b, 0x3e, 0xf3, 0xf7, 0xc4, 0xdb, 0xbd, 0xe2, 0x2d, 0x7b, + 0x2a, 0xd7, 0x6f, 0x12, 0xc3, 0x16, 0xe8, 0x95, 0xa1, 0xaa, 0x53, 0x75, 0xd8, 0x47, 0x12, 0x7c, + 0xe2, 0xab, 0xea, 0x79, 0x18, 0x7c, 0x2f, 0xc0, 0x34, 0xcd, 0x37, 0xd1, 0xe9, 0xad, 0x3a, 0xf5, + 0x7c, 0xbc, 0x07, 0xb6, 0xb8, 0x4e, 0xcd, 0x2f, 0x59, 0x95, 0x11, 0x34, 0x86, 0xc6, 0x07, 0xf4, + 0xcd, 0xc1, 0xe3, 0x4c, 0x05, 0xef, 0x07, 0x10, 0x78, 0x82, 0x77, 0x05, 0xf6, 0x6e, 0x40, 0xac, + 0xcc, 0x54, 0xd4, 0xfb, 0x08, 0x86, 0x92, 0xf1, 0x3c, 0xd7, 0xb1, 0x3d, 0x8a, 0x4f, 0xc2, 0x16, + 0x61, 0xc5, 0x02, 0x6e, 0x9d, 0x1c, 0xd5, 0x52, 0xd4, 0xd4, 0xa4, 0x9b, 0x34, 0xc6, 0x43, 0xb0, + 0xc9, 0xad, 0x39, 0xce, 0x4d, 0xb6, 0xd5, 0x36, 0x9d, 0x3f, 0xe0, 0x69, 0xd8, 0xc6, 0x3e, 0x94, + 0x66, 0xa9, 0x55, 0x9d, 0xf5, 0x47, 0x7a, 0x59, 0x48, 0x25, 0x16, 0x92, 0x67, 0x60, 0x71, 0x42, + 0x7b, 0x87, 0x59, 0x9c, 0xe9, 0x7b, 0xf0, 0xf8, 0x40, 0x8f, 0xbe, 0x95, 0x79, 0xf1, 0x25, 0xf5, + 0x46, 0x12, 0xaa, 0x27, 0xb9, 0xbf, 0x0d, 0x10, 0x25, 0x46, 0xa0, 0x7d, 0x55, 0xe3, 0x59, 0xd4, + 0x82, 0x2c, 0x6a, 0xfc, 0x50, 0x88, 0x2c, 0x6a, 0x17, 0x8d, 0x2a, 0x15, 0xbe, 0x7a, 0xcc, 0x53, + 0x7d, 0x8c, 0x60, 0xb8, 0x69, 0x03, 0x21, 0xc6, 0x19, 0xe8, 0x17, 0xfc, 0xbc, 0x11, 0x34, 0xd6, + 0xcb, 0xe2, 0xa7, 0xa9, 0x31, 0x53, 0xa1, 0xb6, 0x6f, 0xdd, 0xb4, 0x68, 0x45, 0xea, 0x12, 0xfa, + 0xe1, 0xb3, 0x09, 0x94, 0x05, 0x86, 0xf2, 0xd0, 0xaa, 0x28, 0x39, 0x80, 0x38, 0x4c, 0x7c, 0x0a, + 0x36, 0xb7, 0xa9, 0xa2, 0xb0, 0x57, 0x3f, 0x43, 0x50, 0xe4, 0x04, 0x1d, 0xdb, 0xa6, 0x66, 0x10, + 0xad, 0x59, 0xcb, 0x22, 0x80, 0x19, 0xbe, 0x14, 0x47, 0x29, 0xb6, 0xd2, 0xa4, 0x75, 0xe1, 0x85, + 0xb5, 0x7e, 0x8e, 0xe0, 0x40, 0x26, 0x94, 0xff, 0x97, 0xea, 0x57, 0xa5, 0xe8, 0x1c, 0xd3, 0x34, + 0xb3, 0xbe, 0xe4, 0x1b, 0x3e, 0xed, 0xb4, 0x78, 0xff, 0x08, 0x45, 0x4c, 0x09, 0x2d, 0x44, 0x34, + 0x60, 0x8f, 0x15, 0xea, 0x53, 0xe2, 0x50, 0x4b, 0x5e, 0x60, 0x22, 0x2a, 0xe5, 0x70, 0x1a, 0x91, + 0x98, 0xa4, 0xb1, 0x98, 0xc3, 0x56, 0xda, 0x72, 0x37, 0x4b, 0xfe, 0x7b, 0x04, 0x07, 0x13, 0x0c, + 0x03, 0x4e, 0xb6, 0x57, 0xf7, 0xd6, 0x43, 0x3f, 0x7c, 0x08, 0x76, 0xd4, 0xe8, 0xa2, 0xe5, 0x59, + 0x8e, 0x5d, 0xb2, 0xeb, 0x0b, 0x65, 0x5a, 0x63, 0x28, 0xfb, 0xf4, 0xed, 0x72, 0xf9, 0x02, 0x5b, + 0x4d, 0x18, 0x0a, 0x3a, 0x7d, 0x49, 0x43, 0x81, 0xf7, 0x77, 0x04, 0x6a, 0x1e, 0x5e, 0x91, 0x94, + 0xd3, 0xb0, 0xc3, 0x94, 0x6f, 0x12, 0xc9, 0x18, 0xd2, 0xf8, 0xf7, 0x81, 0x26, 0xbf, 0x0f, 0xb4, + 0x29, 0x7b, 0x59, 0xdf, 0x6e, 0x26, 0xc2, 0xe0, 0x7d, 0x30, 0x20, 0x12, 0x19, 0xb2, 0xea, 0xe7, + 0x0b, 0x33, 0x95, 0x28, 0x1b, 0xbd, 0x79, 0xd9, 0xe8, 0x7b, 0x91, 0x6c, 0xd4, 0x60, 0x94, 0x91, + 0xbb, 0x68, 0x98, 0x73, 0xd4, 0x9f, 0x76, 0x16, 0x16, 0x2c, 0x7f, 0x81, 0xda, 0x7e, 0xa7, 0x79, + 0x50, 0xa0, 0xdf, 0x0b, 0x42, 0xd8, 0x26, 0x15, 0x09, 0x08, 0x9f, 0xd5, 0xaf, 0x11, 0xec, 0xcf, + 0xd8, 0x54, 0x88, 0xc9, 0x5a, 0x96, 0x5c, 0x65, 0x1b, 0x6f, 0xd3, 0x63, 0x2b, 0xdd, 0x3c, 0x9e, + 0xdf, 0x64, 0x81, 0xf3, 0x3a, 0x95, 0x24, 0xd9, 0x67, 0x7b, 0x5f, 0xb8, 0xcf, 0xfe, 0x25, 0x5b, + 0x7e, 0x0a, 0xc2, 0xb0, 0xcd, 0x6e, 0x8d, 0xd4, 0x92, 0x9d, 0x76, 0x2c, 0xb5, 0xd3, 0xf2, 0x20, + 0xfc, 0x2c, 0xc7, 0x9d, 0x36, 0x42, 0x9b, 0x75, 0x60, 0x6f, 0x8c, 0xa8, 0x4e, 0x4d, 0x6a, 0xb9, + 0x5d, 0x3d, 0x99, 0xf7, 0x10, 0x28, 0x69, 0x3b, 0x0a, 0x59, 0x15, 0xe8, 0xaf, 0x05, 0x4b, 0x8b, + 0x94, 0xc7, 0xed, 0xd7, 0xc3, 0xe7, 0x6e, 0xd6, 0xe8, 0x6d, 0xd1, 0x30, 0x39, 0xa8, 0x29, 0x73, + 0xce, 0x76, 0x6e, 0xcf, 0xd3, 0x4a, 0x95, 0x76, 0xbb, 0x50, 0xef, 0xcb, 0xd6, 0x97, 0xb1, 0xb3, + 0x90, 0x65, 0x1c, 0x76, 0x18, 0xc9, 0x57, 0xa2, 0x64, 0x9b, 0x97, 0xbb, 0x59, 0xb7, 0xdf, 0xe6, + 0x62, 0xdd, 0x30, 0xc5, 0xfb, 0x0f, 0x82, 0x97, 0x73, 0x61, 0x0a, 0x4d, 0xcf, 0xc1, 0xce, 0x26, + 0xf1, 0xd6, 0x5e, 0xc6, 0x2d, 0x9e, 0x1b, 0xa1, 0x96, 0xbf, 0x94, 0x7d, 0xf5, 0x8a, 0x2d, 0x6b, + 0x86, 0x63, 0xee, 0x38, 0x35, 0x6f, 0xc2, 0x3e, 0x97, 0x45, 0x2a, 0x45, 0xed, 0xab, 0x24, 0xcf, + 0xb0, 0x37, 0xd2, 0x3b, 0xd6, 0x3b, 0xde, 0xa7, 0xef, 0x75, 0x9b, 0x9a, 0xe5, 0x25, 0x69, 0xa0, + 0x2e, 0x89, 0x76, 0x9a, 0x02, 0x4c, 0x24, 0x63, 0x14, 0x06, 0xa2, 0x78, 0x88, 0xc5, 0x8b, 0x16, + 0x62, 0x9a, 0x14, 0xda, 0xd4, 0xe4, 0x8e, 0x6c, 0x37, 0xd1, 0xd6, 0x53, 0xe6, 0x5c, 0xc7, 0x82, + 0x1c, 0x83, 0x21, 0x21, 0x88, 0x61, 0xce, 0xb5, 0x28, 0x81, 0x5d, 0x79, 0xf2, 0x22, 0x09, 0xea, + 0xb0, 0x2f, 0x15, 0x47, 0x97, 0xf9, 0x5f, 0x13, 0x77, 0xdd, 0x0b, 0x74, 0x29, 0xcc, 0x87, 0xce, + 0x01, 0x74, 0x7a, 0x8f, 0xfe, 0x01, 0xc1, 0x58, 0x76, 0x6c, 0xc1, 0x6b, 0x12, 0x86, 0x6d, 0xba, + 0x14, 0x1d, 0x96, 0x92, 0x60, 0xcf, 0xb6, 0xea, 0xd3, 0x07, 0xed, 0x56, 0xdf, 0x2e, 0xb6, 0xb0, + 0xc9, 0x9f, 0x76, 0xc3, 0x26, 0x86, 0x19, 0x7f, 0x87, 0x60, 0x8b, 0xb8, 0x6e, 0xe2, 0xf1, 0xd4, + 0x7a, 0x4f, 0xf9, 0xc1, 0x40, 0x39, 0xbc, 0x06, 0x4b, 0xce, 0x5c, 0x3d, 0xfb, 0xc9, 0xcf, 0x7f, + 0xde, 0x2b, 0x4c, 0xe1, 0xb7, 0x48, 0xca, 0xaf, 0x1d, 0xfc, 0x87, 0x11, 0x39, 0x6f, 0x91, 0x95, + 0x48, 0xe7, 0x06, 0x09, 0xd4, 0xf7, 0xc8, 0x8a, 0xc8, 0x49, 0x03, 0xdf, 0x45, 0xd0, 0x2f, 0xa7, + 0x3c, 0xbc, 0x3a, 0x00, 0x79, 0xb6, 0x95, 0x23, 0x6b, 0x31, 0x15, 0x60, 0x8f, 0x30, 0xb0, 0xaf, + 0x60, 0x75, 0x75, 0xb0, 0xf8, 0x47, 0x04, 0xb8, 0x75, 0xfe, 0xc4, 0xc7, 0x73, 0xb6, 0xcb, 0x1a, + 0x9c, 0x95, 0x13, 0xed, 0x39, 0x09, 0xb4, 0xd3, 0x0c, 0xed, 0x69, 0xfc, 0x46, 0x0e, 0xda, 0xd0, + 0x3b, 0x50, 0x37, 0x7c, 0x68, 0x44, 0x34, 0x7e, 0x0d, 0x68, 0xb4, 0x4c, 0x80, 0xb9, 0x34, 0xb2, + 0x46, 0xd1, 0x5c, 0x1a, 0x99, 0x43, 0xa6, 0x7a, 0x99, 0xd1, 0xb8, 0x80, 0xcf, 0x75, 0x78, 0x42, + 0x48, 0x7c, 0x3e, 0xc5, 0x5f, 0x15, 0x60, 0x38, 0x75, 0x8e, 0xc2, 0x27, 0x57, 0x47, 0x99, 0x36, + 0x28, 0x2a, 0xaf, 0xb7, 0xed, 0x27, 0x08, 0xde, 0x45, 0x8c, 0xe1, 0x1d, 0x84, 0x3f, 0x45, 0x1d, + 0x73, 0x4c, 0x4e, 0x7e, 0x44, 0x8e, 0x90, 0x64, 0xa5, 0x69, 0x18, 0x6d, 0x10, 0xde, 0x20, 0x62, + 0x2f, 0xf8, 0x42, 0x03, 0x3f, 0x41, 0xb0, 0xb3, 0xf9, 0x46, 0x8f, 0x27, 0xb2, 0xd9, 0x65, 0x4c, + 0x6c, 0xca, 0x64, 0x3b, 0x2e, 0x42, 0x0b, 0xca, 0xa4, 0x28, 0xe1, 0x8f, 0x3a, 0x15, 0xa2, 0xe5, + 0x8b, 0xd8, 0x23, 0x2b, 0xb2, 0xbb, 0x36, 0xf0, 0x23, 0x04, 0xbb, 0x5a, 0x86, 0x16, 0xdc, 0x06, + 0xe0, 0xb0, 0x34, 0x8f, 0xb7, 0xe5, 0x23, 0x58, 0x5e, 0x67, 0x2c, 0x2f, 0x63, 0x7d, 0xfd, 0x59, + 0xe2, 0x5f, 0x10, 0xbc, 0x94, 0x18, 0x1a, 0xb0, 0xb6, 0x1a, 0xc4, 0xe4, 0x3c, 0xa3, 0x90, 0x35, + 0xdb, 0x0b, 0x3a, 0x65, 0x46, 0xe7, 0x43, 0x7c, 0x7d, 0x9d, 0xe8, 0xd4, 0x78, 0xfc, 0x44, 0xc6, + 0x9e, 0x23, 0x18, 0x4e, 0xbd, 0xa9, 0xe6, 0xd5, 0x6b, 0xde, 0x9c, 0x92, 0x57, 0xaf, 0xb9, 0x53, + 0x86, 0x7a, 0x83, 0xd1, 0xbd, 0x8a, 0xdf, 0x5f, 0x27, 0xba, 0x86, 0x39, 0x97, 0xa0, 0xfa, 0x37, + 0x82, 0xdd, 0xe9, 0x97, 0x72, 0xdc, 0x2e, 0xe6, 0xf0, 0x98, 0x9e, 0x6a, 0xdf, 0x51, 0xb0, 0x2d, + 0x31, 0xb6, 0xd7, 0xf0, 0x07, 0xeb, 0xc7, 0x36, 0xc9, 0xe9, 0xf3, 0x02, 0xec, 0x6a, 0xb9, 0xf1, + 0xe6, 0xd5, 0x62, 0xd6, 0xbd, 0x3d, 0xaf, 0x16, 0x33, 0xaf, 0xd4, 0xeb, 0xda, 0x7d, 0xd3, 0x9a, + 0x4e, 0xce, 0x44, 0xd0, 0x20, 0xf5, 0x10, 0x56, 0xc9, 0x15, 0xc4, 0xff, 0x45, 0xb0, 0x3d, 0x79, + 0xfb, 0xc5, 0x64, 0x2d, 0xbc, 0x62, 0xf7, 0x75, 0xe5, 0xd8, 0xda, 0x1d, 0x84, 0x0a, 0x1f, 0x73, + 0x15, 0x56, 0xf0, 0x72, 0x17, 0x35, 0x48, 0x0c, 0x01, 0x09, 0xf2, 0x41, 0x09, 0xe0, 0xdf, 0x10, + 0x0c, 0xa6, 0x5c, 0x92, 0x71, 0xce, 0xb5, 0x21, 0xfb, 0xbe, 0xae, 0xbc, 0xd6, 0xa6, 0x97, 0x10, + 0xe2, 0x0a, 0xd3, 0xe1, 0x5d, 0x7c, 0xbe, 0x53, 0x1d, 0x12, 0xf7, 0xf9, 0x33, 0xfa, 0x83, 0xa7, + 0x45, 0xf4, 0xf0, 0x69, 0x11, 0x3d, 0x79, 0x5a, 0x44, 0x5f, 0x3c, 0x2b, 0xf6, 0x3c, 0x7c, 0x56, + 0xec, 0x79, 0xf4, 0xac, 0xd8, 0x73, 0xfd, 0x54, 0xd5, 0xf2, 0x67, 0xeb, 0x65, 0xcd, 0x74, 0x16, + 0x88, 0xf8, 0xe7, 0x20, 0xff, 0x73, 0xd4, 0xab, 0xcc, 0x91, 0xa5, 0x08, 0xc6, 0xb1, 0x13, 0x47, + 0x25, 0x12, 0x7f, 0xd9, 0xa5, 0x5e, 0x79, 0x33, 0xfb, 0x1d, 0xf7, 0xf8, 0x7f, 0x01, 0x00, 0x00, + 0xff, 0xff, 0xce, 0x1d, 0x1b, 0xcd, 0xab, 0x1c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2740,13 +2740,13 @@ func (m *QueryChannelConsensusStateRequest) MarshalToSizedBuffer(dAtA []byte) (i _ = i var l int _ = l - if m.VersionHeight != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionHeight)) i-- dAtA[i] = 0x20 } - if m.VersionNumber != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionNumber)) i-- dAtA[i] = 0x18 } @@ -3775,11 +3775,11 @@ func (m *QueryChannelConsensusStateRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - if m.VersionNumber != 0 { - n += 1 + sovQuery(uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + n += 1 + sovQuery(uint64(m.RevisionNumber)) } - if m.VersionHeight != 0 { - n += 1 + sovQuery(uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + n += 1 + sovQuery(uint64(m.RevisionHeight)) } return n } @@ -5295,9 +5295,9 @@ func (m *QueryChannelConsensusStateRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionNumber", wireType) } - m.VersionNumber = 0 + m.RevisionNumber = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -5307,16 +5307,16 @@ func (m *QueryChannelConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionNumber |= uint64(b&0x7F) << shift + m.RevisionNumber |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHeight", wireType) } - m.VersionHeight = 0 + m.RevisionHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -5326,7 +5326,7 @@ func (m *QueryChannelConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionHeight |= uint64(b&0x7F) << shift + m.RevisionHeight |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ibc/core/04-channel/types/query.pb.gw.go b/x/ibc/core/04-channel/types/query.pb.gw.go index 270aa3db9f..bb5a94aba7 100644 --- a/x/ibc/core/04-channel/types/query.pb.gw.go +++ b/x/ibc/core/04-channel/types/query.pb.gw.go @@ -324,26 +324,26 @@ func request_Query_ChannelConsensusState_0(ctx context.Context, marshaler runtim return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } msg, err := client.ChannelConsensusState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -384,26 +384,26 @@ func local_request_Query_ChannelConsensusState_0(ctx context.Context, marshaler return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } msg, err := server.ChannelConsensusState(ctx, &protoReq) @@ -1744,7 +1744,7 @@ var ( pattern_Query_ChannelClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1beta1", "channels", "channel_id", "ports", "port_id", "client_state"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_ChannelConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 2, 9, 1, 0, 4, 1, 5, 10, 2, 11, 1, 0, 4, 1, 5, 12}, []string{"ibc", "core", "channel", "v1beta1", "channels", "channel_id", "ports", "port_id", "consensus_state", "version", "version_number", "height", "version_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ChannelConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 2, 9, 1, 0, 4, 1, 5, 10, 2, 11, 1, 0, 4, 1, 5, 12}, []string{"ibc", "core", "channel", "v1beta1", "channels", "channel_id", "ports", "port_id", "consensus_state", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_PacketCommitment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "channel", "v1beta1", "channels", "channel_id", "ports", "port_id", "packet_commitments", "sequence"}, "", runtime.AssumeColonVerbOpt(true))) diff --git a/x/ibc/core/04-channel/types/tx.pb.go b/x/ibc/core/04-channel/types/tx.pb.go index 608f573a77..9d2f3e221e 100644 --- a/x/ibc/core/04-channel/types/tx.pb.go +++ b/x/ibc/core/04-channel/types/tx.pb.go @@ -32,10 +32,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It // is called by a relayer on Chain A. type MsgChannelOpenInit struct { - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` - ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"` - Channel Channel `protobuf:"bytes,3,opt,name=channel,proto3" json:"channel"` - Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` + Channel Channel `protobuf:"bytes,2,opt,name=channel,proto3" json:"channel"` + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgChannelOpenInit) Reset() { *m = MsgChannelOpenInit{} } @@ -111,14 +110,15 @@ var xxx_messageInfo_MsgChannelOpenInitResponse proto.InternalMessageInfo // MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel // on Chain B. type MsgChannelOpenTry struct { - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` - DesiredChannelId string `protobuf:"bytes,2,opt,name=desired_channel_id,json=desiredChannelId,proto3" json:"desired_channel_id,omitempty" yaml:"desired_channel_id"` - CounterpartyChosenChannelId string `protobuf:"bytes,3,opt,name=counterparty_chosen_channel_id,json=counterpartyChosenChannelId,proto3" json:"counterparty_chosen_channel_id,omitempty" yaml:"counterparty_chosen_channel_id"` - Channel Channel `protobuf:"bytes,4,opt,name=channel,proto3" json:"channel"` - CounterpartyVersion string `protobuf:"bytes,5,opt,name=counterparty_version,json=counterpartyVersion,proto3" json:"counterparty_version,omitempty" yaml:"counterparty_version"` - ProofInit []byte `protobuf:"bytes,6,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` - ProofHeight types.Height `protobuf:"bytes,7,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` - Signer string `protobuf:"bytes,8,opt,name=signer,proto3" json:"signer,omitempty"` + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` + // in the case of crossing hello's, when both chains call OpenInit, we need the channel identifier + // of the previous channel in state INIT + PreviousChannelId string `protobuf:"bytes,2,opt,name=previous_channel_id,json=previousChannelId,proto3" json:"previous_channel_id,omitempty" yaml:"previous_channel_id"` + Channel Channel `protobuf:"bytes,3,opt,name=channel,proto3" json:"channel"` + CounterpartyVersion string `protobuf:"bytes,4,opt,name=counterparty_version,json=counterpartyVersion,proto3" json:"counterparty_version,omitempty" yaml:"counterparty_version"` + ProofInit []byte `protobuf:"bytes,5,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` + ProofHeight types.Height `protobuf:"bytes,6,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` + Signer string `protobuf:"bytes,7,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgChannelOpenTry) Reset() { *m = MsgChannelOpenTry{} } @@ -853,80 +853,77 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/tx.proto", fileDescriptor_bc4637e0ac3fc7b7) } var fileDescriptor_bc4637e0ac3fc7b7 = []byte{ - // 1158 bytes of a gzipped FileDescriptorProto + // 1120 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6e, 0xdb, 0x46, - 0x10, 0xd6, 0x9f, 0x65, 0x7b, 0xec, 0xc6, 0x0e, 0xfd, 0xa7, 0x50, 0xb6, 0xe8, 0x12, 0x68, 0xe2, - 0xa6, 0x88, 0x14, 0x3b, 0x01, 0xda, 0x06, 0xbd, 0x58, 0x02, 0x8a, 0x1a, 0x81, 0x91, 0x82, 0x71, - 0x7b, 0x30, 0x0a, 0x08, 0xf2, 0x6a, 0x43, 0x11, 0xb2, 0x76, 0x55, 0x92, 0x56, 0xac, 0x37, 0xe8, - 0x31, 0xe7, 0x9e, 0x72, 0xef, 0x21, 0x7d, 0x87, 0x5e, 0x72, 0xcc, 0x2d, 0x45, 0x0f, 0x44, 0x61, - 0x5f, 0x7a, 0xe6, 0x13, 0x14, 0x5c, 0x2e, 0x7f, 0x44, 0x91, 0x31, 0x5d, 0x57, 0x6a, 0x4f, 0x22, - 0x67, 0xbe, 0x9d, 0x9d, 0xfd, 0xe6, 0xdb, 0xd9, 0xa5, 0x60, 0x53, 0x3b, 0x41, 0x35, 0x44, 0x75, - 0x5c, 0x43, 0x9d, 0x16, 0x21, 0xf8, 0xb4, 0x36, 0xd8, 0xad, 0x99, 0xe7, 0xd5, 0xbe, 0x4e, 0x4d, - 0x2a, 0xac, 0x68, 0x27, 0xa8, 0xea, 0x78, 0xab, 0xdc, 0x5b, 0x1d, 0xec, 0x8a, 0xab, 0x2a, 0x55, - 0x29, 0xf3, 0xd7, 0x9c, 0x27, 0x17, 0x2a, 0x4a, 0x41, 0xa0, 0x53, 0x0d, 0x13, 0xd3, 0x89, 0xe3, - 0x3e, 0x71, 0xc0, 0xc7, 0x71, 0x33, 0x79, 0x61, 0x19, 0x44, 0x7e, 0x9f, 0x05, 0xe1, 0xd0, 0x50, - 0x1b, 0xae, 0xf1, 0x59, 0x1f, 0x93, 0x03, 0xa2, 0x99, 0xc2, 0x67, 0x30, 0xdb, 0xa7, 0xba, 0xd9, - 0xd4, 0xda, 0xa5, 0xec, 0x76, 0x76, 0x67, 0xbe, 0x2e, 0xd8, 0x96, 0x74, 0x6b, 0xd8, 0xea, 0x9d, - 0x3e, 0x91, 0xb9, 0x43, 0x56, 0x8a, 0xce, 0xd3, 0x41, 0x5b, 0x78, 0x0c, 0xc0, 0x83, 0x3a, 0xf8, - 0x1c, 0xc3, 0xaf, 0xd9, 0x96, 0x74, 0xdb, 0xc5, 0x07, 0x3e, 0x59, 0x99, 0xe7, 0x2f, 0x07, 0x6d, - 0xe1, 0x2b, 0x98, 0xe5, 0x2f, 0xa5, 0xfc, 0x76, 0x76, 0x67, 0x61, 0x6f, 0xb3, 0x1a, 0xb3, 0xf4, - 0x2a, 0xcf, 0xac, 0x5e, 0x78, 0x6b, 0x49, 0x19, 0xc5, 0x1b, 0x22, 0xac, 0x43, 0xd1, 0xd0, 0x54, - 0x82, 0xf5, 0x52, 0xc1, 0x99, 0x4f, 0xe1, 0x6f, 0x4f, 0xe6, 0x7e, 0x7a, 0x2d, 0x65, 0xfe, 0x7a, - 0x2d, 0x65, 0xe4, 0x4d, 0x10, 0xc7, 0x17, 0xa6, 0x60, 0xa3, 0x4f, 0x89, 0x81, 0xe5, 0xdf, 0x0a, - 0x70, 0x7b, 0xd4, 0x7d, 0xa4, 0x0f, 0xaf, 0xb7, 0xec, 0xa7, 0x20, 0xb4, 0xb1, 0xa1, 0xe9, 0xb8, - 0xdd, 0x1c, 0x5b, 0xfe, 0x96, 0x6d, 0x49, 0x77, 0xdc, 0x71, 0xe3, 0x18, 0x59, 0x59, 0xe6, 0xc6, - 0x86, 0xcf, 0x06, 0x81, 0x0a, 0xa2, 0x67, 0xc4, 0xc4, 0x7a, 0xbf, 0xa5, 0x9b, 0xc3, 0x26, 0xea, - 0x50, 0x03, 0x93, 0x70, 0xe0, 0x3c, 0x0b, 0xfc, 0xa9, 0x6d, 0x49, 0x9f, 0x70, 0x5e, 0x3f, 0x88, - 0x97, 0x95, 0x72, 0x18, 0xd0, 0x60, 0xfe, 0x46, 0x1c, 0xfb, 0x85, 0xeb, 0xb3, 0xaf, 0xc0, 0xea, - 0xc8, 0xec, 0x03, 0xac, 0x1b, 0x1a, 0x25, 0xa5, 0x19, 0x96, 0xa3, 0x64, 0x5b, 0x52, 0x39, 0x26, - 0x47, 0x8e, 0x92, 0x95, 0x95, 0xb0, 0xf9, 0x7b, 0xd7, 0xea, 0xa8, 0xa8, 0xaf, 0x53, 0xfa, 0xa2, - 0xa9, 0x11, 0xcd, 0x2c, 0x15, 0xb7, 0xb3, 0x3b, 0x8b, 0x61, 0x15, 0x05, 0x3e, 0x59, 0x99, 0x67, - 0x2f, 0x4c, 0xa8, 0xc7, 0xb0, 0xe8, 0x7a, 0x3a, 0x58, 0x53, 0x3b, 0x66, 0x69, 0x96, 0x2d, 0x46, - 0x0c, 0x2d, 0xc6, 0xdd, 0x10, 0x83, 0xdd, 0xea, 0x37, 0x0c, 0x51, 0x2f, 0x3b, 0x4b, 0xb1, 0x2d, - 0x69, 0x25, 0x1c, 0xd7, 0x1d, 0x2d, 0x2b, 0x0b, 0xec, 0xd5, 0x45, 0x86, 0x34, 0x36, 0x97, 0xa0, - 0xb1, 0x32, 0xdc, 0x19, 0x13, 0x91, 0x2f, 0xb1, 0xf7, 0xf9, 0xa8, 0xc4, 0xf6, 0x51, 0x77, 0x1a, - 0x3b, 0xeb, 0x18, 0x36, 0x22, 0xda, 0x88, 0x88, 0x48, 0xb6, 0x2d, 0xa9, 0x12, 0x2b, 0xa2, 0x20, - 0xde, 0xda, 0xa8, 0x7a, 0xbc, 0xd8, 0x49, 0x95, 0x2f, 0xdc, 0xa0, 0xf2, 0xbb, 0xe0, 0x16, 0xb4, - 0x69, 0xea, 0x43, 0x26, 0xa1, 0xc5, 0xfa, 0xaa, 0x6d, 0x49, 0xcb, 0xe1, 0x02, 0x99, 0xfa, 0x50, - 0x56, 0xe6, 0xd8, 0xb3, 0xb3, 0x51, 0xa3, 0x65, 0x2f, 0x4e, 0xa4, 0xec, 0xb3, 0x69, 0xcb, 0xbe, - 0x8f, 0xba, 0x7e, 0xd9, 0x7f, 0xc9, 0xc1, 0xda, 0xa8, 0xb7, 0x41, 0xc9, 0x0b, 0x4d, 0xef, 0x4d, - 0xa3, 0xf4, 0x3e, 0x95, 0x2d, 0xd4, 0x65, 0xc5, 0x8e, 0xa1, 0xb2, 0x85, 0xba, 0x1e, 0x95, 0x8e, - 0x20, 0xa3, 0x54, 0x16, 0x26, 0x42, 0xe5, 0x4c, 0x02, 0x95, 0x12, 0x6c, 0xc5, 0x92, 0xe5, 0xd3, - 0xf9, 0x73, 0x16, 0x56, 0x02, 0x44, 0xe3, 0x94, 0x1a, 0x78, 0x5a, 0x27, 0x54, 0x90, 0x7d, 0x3e, - 0x21, 0xfb, 0x2d, 0x28, 0xc7, 0xe4, 0xe6, 0xe7, 0xfe, 0x26, 0x07, 0xeb, 0x11, 0xff, 0x14, 0xb5, - 0x30, 0xda, 0x50, 0xf3, 0xff, 0xb0, 0xa1, 0x4e, 0x57, 0x0e, 0xdb, 0x50, 0x89, 0x27, 0xcc, 0xe7, - 0xf4, 0x55, 0x0e, 0x3e, 0x3a, 0x34, 0x54, 0x05, 0xa3, 0xc1, 0xb7, 0x2d, 0xd4, 0xc5, 0xa6, 0xf0, - 0x25, 0x14, 0xfb, 0xec, 0x89, 0x31, 0xb9, 0xb0, 0x57, 0x8e, 0x3d, 0xc9, 0x5c, 0x30, 0x3f, 0xc8, - 0xf8, 0x00, 0xe1, 0x6b, 0x58, 0x76, 0xd3, 0x45, 0xb4, 0xd7, 0xd3, 0xcc, 0x1e, 0x26, 0x26, 0xa3, - 0x77, 0xb1, 0x5e, 0xb6, 0x2d, 0x69, 0x23, 0xbc, 0xa0, 0x00, 0x21, 0x2b, 0x4b, 0xcc, 0xd4, 0xf0, - 0x2d, 0x63, 0xa4, 0xe5, 0x27, 0x42, 0x5a, 0xd2, 0x4d, 0x67, 0x83, 0x35, 0x9c, 0x80, 0x11, 0x9f, - 0xab, 0x3f, 0x72, 0x00, 0x87, 0x86, 0x7a, 0xa4, 0xf5, 0x30, 0x3d, 0xfb, 0x77, 0x88, 0x3a, 0x23, - 0x3a, 0x46, 0x58, 0x1b, 0xe0, 0x76, 0x12, 0x51, 0x01, 0xc2, 0x23, 0xea, 0x3b, 0xdf, 0x32, 0x51, - 0xa2, 0x9e, 0x82, 0x40, 0xf0, 0xb9, 0xd9, 0x34, 0xf0, 0x8f, 0x67, 0x98, 0x20, 0xdc, 0xd4, 0x31, - 0x1a, 0x30, 0xd2, 0x0a, 0xe1, 0xfb, 0xd8, 0x38, 0x46, 0x56, 0x96, 0x1d, 0xe3, 0x73, 0x6e, 0x73, - 0x88, 0x4c, 0x21, 0xd5, 0x55, 0x76, 0x71, 0xe6, 0xdc, 0x06, 0xed, 0xca, 0x3d, 0xf4, 0xb9, 0xf9, - 0x19, 0x61, 0x1a, 0xfe, 0x3f, 0x30, 0xff, 0x39, 0x2c, 0x70, 0x21, 0x3b, 0x19, 0xf1, 0x76, 0xb0, - 0x6e, 0x5b, 0x92, 0x30, 0xa2, 0x72, 0xc7, 0x29, 0x2b, 0x6e, 0xe3, 0x70, 0x73, 0x9f, 0x64, 0x43, - 0x88, 0x2f, 0xd9, 0xcc, 0x4d, 0x4b, 0x56, 0xfc, 0xe0, 0xb9, 0x3d, 0x5a, 0x1b, 0xbf, 0x72, 0xbf, - 0xe6, 0x58, 0x41, 0xf7, 0x51, 0x97, 0xd0, 0x97, 0xa7, 0xb8, 0xad, 0x62, 0xb6, 0xb5, 0x6f, 0x50, - 0xba, 0x1d, 0x58, 0x6a, 0x8d, 0x46, 0x73, 0x2b, 0xa7, 0x44, 0xcd, 0x41, 0x71, 0x9c, 0x81, 0xed, - 0xa4, 0xe2, 0x30, 0xa7, 0x57, 0x9c, 0x7d, 0xe7, 0xe5, 0x3f, 0xee, 0xd6, 0xee, 0x27, 0x56, 0x84, - 0x31, 0x8f, 0xd0, 0xbd, 0x37, 0x73, 0x90, 0x3f, 0x34, 0x54, 0xa1, 0x0b, 0x4b, 0xd1, 0xcf, 0xcb, - 0x7b, 0xb1, 0x24, 0x8e, 0x7f, 0xae, 0x89, 0xb5, 0x94, 0x40, 0x6f, 0x52, 0xa1, 0x03, 0xb7, 0x22, - 0xdf, 0x74, 0x77, 0x53, 0x84, 0x38, 0xd2, 0x87, 0x62, 0x35, 0x1d, 0x2e, 0x61, 0x26, 0xe7, 0x26, - 0x95, 0x66, 0xa6, 0x7d, 0xd4, 0x4d, 0x35, 0x53, 0xe8, 0x46, 0x29, 0x98, 0x20, 0xc4, 0xdc, 0x26, - 0xef, 0xa7, 0x88, 0xc2, 0xb1, 0xe2, 0x5e, 0x7a, 0xac, 0x3f, 0x2b, 0x81, 0xe5, 0xb1, 0x4b, 0xd7, - 0xce, 0x15, 0x71, 0x7c, 0xa4, 0xf8, 0x30, 0x2d, 0xd2, 0x9f, 0xef, 0x25, 0xac, 0xc4, 0x5e, 0x94, - 0xd2, 0x04, 0xf2, 0xd6, 0xf9, 0xe8, 0x1a, 0x60, 0x7f, 0xe2, 0x1f, 0x00, 0x42, 0xb7, 0x09, 0x39, - 0x29, 0x44, 0x80, 0x11, 0xef, 0x5f, 0x8d, 0xf1, 0xa3, 0x3f, 0x87, 0x59, 0xef, 0xfc, 0x95, 0x92, - 0x86, 0x71, 0x80, 0x78, 0xef, 0x0a, 0x40, 0x58, 0x7b, 0x91, 0x13, 0xe6, 0xee, 0x15, 0x43, 0x39, - 0x2e, 0x59, 0x7b, 0xf1, 0x5d, 0xd1, 0xd9, 0xbc, 0xd1, 0x8e, 0x98, 0x98, 0x65, 0x04, 0x98, 0xbc, - 0x79, 0x13, 0x3a, 0x46, 0x5d, 0x79, 0x7b, 0x51, 0xc9, 0xbe, 0xbb, 0xa8, 0x64, 0xff, 0xbc, 0xa8, - 0x64, 0x5f, 0x5d, 0x56, 0x32, 0xef, 0x2e, 0x2b, 0x99, 0xdf, 0x2f, 0x2b, 0x99, 0xe3, 0x2f, 0x54, - 0xcd, 0xec, 0x9c, 0x9d, 0x54, 0x11, 0xed, 0xd5, 0x10, 0x35, 0x7a, 0xd4, 0xe0, 0x3f, 0x0f, 0x8c, - 0x76, 0xb7, 0x76, 0x5e, 0xf3, 0xff, 0xe8, 0x7a, 0xf8, 0xf8, 0x81, 0xf7, 0x5f, 0x97, 0x39, 0xec, - 0x63, 0xe3, 0xa4, 0xc8, 0xfe, 0xe7, 0x7a, 0xf4, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x07, - 0x48, 0xeb, 0x76, 0x13, 0x00, 0x00, + 0x10, 0xd6, 0x8f, 0x2d, 0xdb, 0x63, 0x37, 0xb6, 0x29, 0xff, 0x28, 0x94, 0x2d, 0xba, 0x3c, 0x24, + 0x42, 0x8a, 0x48, 0xb1, 0x63, 0xa0, 0x6d, 0xd0, 0x8b, 0x64, 0xa0, 0x68, 0x50, 0xb8, 0x29, 0x18, + 0xb7, 0x07, 0xa3, 0x80, 0x20, 0xaf, 0x36, 0x14, 0x21, 0x89, 0xab, 0x92, 0x94, 0x62, 0xbd, 0x41, + 0x8f, 0x39, 0xf7, 0x94, 0x9e, 0x7b, 0x48, 0x1f, 0x23, 0xc7, 0x9c, 0xda, 0xa2, 0x07, 0xa2, 0xb0, + 0x2f, 0x3d, 0xf3, 0x09, 0x0a, 0xee, 0x2e, 0x29, 0x4a, 0x22, 0x2b, 0x2a, 0xa9, 0x9c, 0x9c, 0xb4, + 0x9c, 0xf9, 0x76, 0x76, 0xf6, 0xfb, 0x86, 0xb3, 0x4b, 0xc1, 0x9e, 0x76, 0x81, 0xca, 0x88, 0x18, + 0xb8, 0x8c, 0x9a, 0x75, 0x5d, 0xc7, 0xed, 0x72, 0xff, 0xb0, 0x6c, 0x5d, 0x96, 0xba, 0x06, 0xb1, + 0x88, 0x90, 0xd5, 0x2e, 0x50, 0xc9, 0xf5, 0x96, 0xb8, 0xb7, 0xd4, 0x3f, 0x14, 0xb7, 0x54, 0xa2, + 0x12, 0xea, 0x2f, 0xbb, 0x23, 0x06, 0x15, 0xa5, 0x61, 0xa0, 0xb6, 0x86, 0x75, 0xcb, 0x8d, 0xc3, + 0x46, 0x1c, 0xf0, 0x71, 0xd8, 0x4a, 0x5e, 0x58, 0x0a, 0x91, 0x7f, 0x49, 0x82, 0x70, 0x6a, 0xaa, + 0x27, 0xcc, 0xf8, 0xa4, 0x8b, 0xf5, 0xc7, 0xba, 0x66, 0x09, 0x9f, 0xc0, 0x52, 0x97, 0x18, 0x56, + 0x4d, 0x6b, 0xe4, 0x92, 0x07, 0xc9, 0xe2, 0x4a, 0x55, 0x70, 0x6c, 0xe9, 0xd6, 0xa0, 0xde, 0x69, + 0x3f, 0x92, 0xb9, 0x43, 0x56, 0x32, 0xee, 0xe8, 0x71, 0x43, 0xf8, 0x02, 0x96, 0x78, 0xd0, 0x5c, + 0xea, 0x20, 0x59, 0x5c, 0x3d, 0xda, 0x2b, 0x85, 0x6c, 0xa2, 0xc4, 0xd7, 0xa8, 0x2e, 0xbc, 0xb6, + 0xa5, 0x84, 0xe2, 0x4d, 0x11, 0x76, 0x20, 0x63, 0x6a, 0xaa, 0x8e, 0x8d, 0x5c, 0xda, 0x5d, 0x49, + 0xe1, 0x4f, 0x8f, 0x96, 0x7f, 0x7a, 0x29, 0x25, 0xfe, 0x79, 0x29, 0x25, 0xe4, 0x3d, 0x10, 0x27, + 0x53, 0x54, 0xb0, 0xd9, 0x25, 0xba, 0x89, 0xe5, 0xdf, 0xd3, 0xb0, 0x39, 0xea, 0x3e, 0x33, 0x06, + 0xb3, 0x6d, 0xe0, 0x1b, 0xc8, 0x76, 0x0d, 0xdc, 0xd7, 0x48, 0xcf, 0xac, 0xf1, 0xb4, 0xdc, 0x89, + 0x29, 0x3a, 0xb1, 0xe0, 0xd8, 0x92, 0xc8, 0x27, 0x4e, 0x82, 0x64, 0x65, 0xd3, 0xb3, 0xf2, 0x0c, + 0x46, 0x09, 0x49, 0xcf, 0x4e, 0x88, 0x02, 0x5b, 0x88, 0xf4, 0x74, 0x0b, 0x1b, 0xdd, 0xba, 0x61, + 0x0d, 0x6a, 0x7d, 0x6c, 0x98, 0x1a, 0xd1, 0x73, 0x0b, 0x34, 0x1d, 0xc9, 0xb1, 0xa5, 0x3c, 0x4b, + 0x27, 0x0c, 0x25, 0x2b, 0xd9, 0xa0, 0xf9, 0x7b, 0x66, 0x15, 0x8e, 0x01, 0xba, 0x06, 0x21, 0xcf, + 0x6a, 0x9a, 0xae, 0x59, 0xb9, 0xc5, 0x83, 0x64, 0x71, 0xad, 0xba, 0xed, 0xd8, 0xd2, 0xa6, 0xb7, + 0x31, 0xcf, 0x27, 0x2b, 0x2b, 0xf4, 0x81, 0x56, 0xc1, 0x39, 0xac, 0x31, 0x4f, 0x13, 0x6b, 0x6a, + 0xd3, 0xca, 0x65, 0xe8, 0x66, 0xc4, 0xc0, 0x66, 0x58, 0xb5, 0xf5, 0x0f, 0x4b, 0x5f, 0x51, 0x44, + 0x35, 0xef, 0x6e, 0xc5, 0xb1, 0xa5, 0x6c, 0x30, 0x2e, 0x9b, 0x2d, 0x2b, 0xab, 0xf4, 0x91, 0x21, + 0x03, 0xb2, 0x2f, 0x45, 0xc8, 0x9e, 0x87, 0xdb, 0x13, 0xba, 0xfa, 0xaa, 0xff, 0x31, 0xa1, 0x7a, + 0x05, 0xb5, 0x66, 0x53, 0xfd, 0x18, 0x60, 0x42, 0xec, 0x00, 0x27, 0x41, 0x8d, 0x57, 0x90, 0xaf, + 0xed, 0x39, 0xec, 0x8e, 0xf0, 0x1e, 0x08, 0x41, 0xeb, 0xb7, 0x2a, 0x3b, 0xb6, 0x54, 0x08, 0x11, + 0x28, 0x18, 0x6f, 0x3b, 0xe8, 0x19, 0xd6, 0xcd, 0x3c, 0x94, 0x3f, 0x04, 0x26, 0x68, 0xcd, 0x32, + 0x06, 0x5c, 0xf8, 0x2d, 0xc7, 0x96, 0x36, 0x82, 0x02, 0x59, 0xc6, 0x40, 0x56, 0x96, 0xe9, 0xd8, + 0x7d, 0x77, 0x3e, 0x30, 0xd9, 0x2b, 0xa8, 0xe5, 0xcb, 0xfe, 0x6b, 0x0a, 0xb6, 0x47, 0xbd, 0x27, + 0x44, 0x7f, 0xa6, 0x19, 0x9d, 0x9b, 0x90, 0xde, 0xa7, 0xb2, 0x8e, 0x5a, 0x54, 0xec, 0x10, 0x2a, + 0xeb, 0xa8, 0xe5, 0x51, 0xe9, 0x16, 0xe4, 0x38, 0x95, 0x0b, 0x73, 0xa1, 0x72, 0x31, 0x82, 0x4a, + 0x09, 0xf6, 0x43, 0xc9, 0xf2, 0xe9, 0xfc, 0x39, 0x09, 0xd9, 0x21, 0xe2, 0xa4, 0x4d, 0x4c, 0x3c, + 0x7b, 0xfb, 0x7f, 0x3b, 0x32, 0xa7, 0xb7, 0xfd, 0x7d, 0xc8, 0x87, 0xe4, 0xe6, 0xe7, 0xfe, 0x2a, + 0x05, 0x3b, 0x63, 0xfe, 0x1b, 0xac, 0x85, 0xd1, 0x86, 0x9a, 0x7e, 0xcb, 0x86, 0x7a, 0xb3, 0xe5, + 0x70, 0x00, 0x85, 0x70, 0xc2, 0x7c, 0x4e, 0x5f, 0xa4, 0xe0, 0xa3, 0x53, 0x53, 0x55, 0x30, 0xea, + 0x7f, 0x5b, 0x47, 0x2d, 0x6c, 0x09, 0x9f, 0x43, 0xa6, 0x4b, 0x47, 0x94, 0xc9, 0xd5, 0xa3, 0x7c, + 0xe8, 0x49, 0xc6, 0xc0, 0xfc, 0x20, 0xe3, 0x13, 0x84, 0x2f, 0x61, 0x83, 0xa5, 0x8b, 0x48, 0xa7, + 0xa3, 0x59, 0x1d, 0xac, 0x5b, 0x94, 0xde, 0xb5, 0x6a, 0xde, 0xb1, 0xa5, 0xdd, 0xe0, 0x86, 0x86, + 0x08, 0x59, 0x59, 0xa7, 0xa6, 0x13, 0xdf, 0x32, 0x41, 0x5a, 0x7a, 0x2e, 0xa4, 0x2d, 0x44, 0x90, + 0xb6, 0x4b, 0x1b, 0xce, 0x90, 0x11, 0x9f, 0xab, 0xbf, 0x52, 0x00, 0xa7, 0xa6, 0x7a, 0xa6, 0x75, + 0x30, 0xe9, 0xfd, 0x3f, 0x44, 0xf5, 0x74, 0x03, 0x23, 0xac, 0xf5, 0x71, 0x23, 0x8a, 0xa8, 0x21, + 0xc2, 0x23, 0xea, 0x3b, 0xdf, 0x32, 0x57, 0xa2, 0xbe, 0x06, 0x41, 0xc7, 0x97, 0x56, 0xcd, 0xc4, + 0x3f, 0xf6, 0xb0, 0x8e, 0x70, 0xcd, 0xc0, 0xa8, 0x4f, 0x49, 0x5b, 0xa8, 0xee, 0x3b, 0xb6, 0x74, + 0x9b, 0x45, 0x98, 0xc4, 0xc8, 0xca, 0x86, 0x6b, 0x7c, 0xca, 0x6d, 0x2e, 0x91, 0x31, 0x4a, 0x75, + 0x8b, 0xde, 0x4a, 0x39, 0xb7, 0xc3, 0x76, 0xc5, 0x0e, 0x7d, 0x6e, 0x7e, 0xa2, 0xd3, 0x1a, 0xfe, + 0x10, 0x98, 0xff, 0x14, 0x56, 0x79, 0x21, 0xbb, 0x19, 0xf1, 0x76, 0xb0, 0xe3, 0xd8, 0x92, 0x30, + 0x52, 0xe5, 0xae, 0x53, 0x56, 0x58, 0xe3, 0x60, 0xb9, 0xcf, 0xb3, 0x21, 0x84, 0x4b, 0xb6, 0xf8, + 0xae, 0x92, 0x65, 0xfe, 0xf3, 0xdc, 0x1e, 0xd5, 0xc6, 0x57, 0xee, 0xb7, 0x14, 0x15, 0xb4, 0x82, + 0x5a, 0x3a, 0x79, 0xde, 0xc6, 0x0d, 0x15, 0xd3, 0x57, 0xfb, 0x1d, 0xa4, 0x2b, 0xc2, 0x7a, 0x7d, + 0x34, 0x1a, 0x53, 0x4e, 0x19, 0x37, 0x0f, 0xc5, 0x71, 0x27, 0x36, 0xa2, 0xc4, 0xa1, 0x4e, 0x4f, + 0x9c, 0x8a, 0xfb, 0xf0, 0x9e, 0xbb, 0x35, 0xfb, 0xea, 0x19, 0x63, 0xcc, 0x23, 0xf4, 0xe8, 0xd5, + 0x32, 0xa4, 0x4f, 0x4d, 0x55, 0x68, 0xc1, 0xfa, 0xf8, 0xb7, 0xdb, 0xdd, 0x50, 0x12, 0x27, 0xbf, + 0xa0, 0xc4, 0x72, 0x4c, 0xa0, 0xb7, 0xa8, 0xd0, 0x84, 0x5b, 0x63, 0x9f, 0x59, 0x77, 0x62, 0x84, + 0x38, 0x33, 0x06, 0x62, 0x29, 0x1e, 0x2e, 0x62, 0x25, 0xf7, 0x26, 0x15, 0x67, 0xa5, 0x0a, 0x6a, + 0xc5, 0x5a, 0x29, 0x70, 0xa3, 0x14, 0x2c, 0x10, 0x42, 0x6e, 0x93, 0xf7, 0x62, 0x44, 0xe1, 0x58, + 0xf1, 0x28, 0x3e, 0xd6, 0x5f, 0x55, 0x87, 0x8d, 0x89, 0x4b, 0x57, 0x71, 0x4a, 0x1c, 0x1f, 0x29, + 0x3e, 0x88, 0x8b, 0xf4, 0xd7, 0x7b, 0x0e, 0xd9, 0xd0, 0x8b, 0x52, 0x9c, 0x40, 0xde, 0x3e, 0x1f, + 0xce, 0x00, 0xf6, 0x17, 0xfe, 0x01, 0x20, 0x70, 0x9b, 0x90, 0xa3, 0x42, 0x0c, 0x31, 0xe2, 0xbd, + 0xe9, 0x18, 0x3f, 0xfa, 0x53, 0x58, 0xf2, 0xce, 0x5f, 0x29, 0x6a, 0x1a, 0x07, 0x88, 0x77, 0xa7, + 0x00, 0x82, 0xb5, 0x37, 0x76, 0xc2, 0xdc, 0x99, 0x32, 0x95, 0xe3, 0xa2, 0x6b, 0x2f, 0xbc, 0x2b, + 0xba, 0x2f, 0xef, 0x78, 0x47, 0x8c, 0xcc, 0x72, 0x0c, 0x18, 0xfd, 0xf2, 0x46, 0x74, 0x8c, 0xaa, + 0xf2, 0xfa, 0xaa, 0x90, 0x7c, 0x73, 0x55, 0x48, 0xfe, 0x7d, 0x55, 0x48, 0xbe, 0xb8, 0x2e, 0x24, + 0xde, 0x5c, 0x17, 0x12, 0x7f, 0x5e, 0x17, 0x12, 0xe7, 0x9f, 0xa9, 0x9a, 0xd5, 0xec, 0x5d, 0x94, + 0x10, 0xe9, 0x94, 0x11, 0x31, 0x3b, 0xc4, 0xe4, 0x3f, 0xf7, 0xcd, 0x46, 0xab, 0x7c, 0x59, 0xf6, + 0xff, 0x45, 0x7a, 0x70, 0x7c, 0xdf, 0xfb, 0x23, 0xc9, 0x1a, 0x74, 0xb1, 0x79, 0x91, 0xa1, 0x7f, + 0x22, 0x3d, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0xe9, 0x16, 0xfa, 0xd3, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1378,7 +1375,7 @@ func (m *MsgChannelOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } { size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) @@ -1389,14 +1386,7 @@ func (m *MsgChannelOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { 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 - } + dAtA[i] = 0x12 if len(m.PortId) > 0 { i -= len(m.PortId) copy(dAtA[i:], m.PortId) @@ -1455,7 +1445,7 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x42 + dAtA[i] = 0x3a } { size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -1466,20 +1456,20 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + 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] = 0x32 + 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] = 0x2a + dAtA[i] = 0x22 } { size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) @@ -1490,18 +1480,11 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 - if len(m.CounterpartyChosenChannelId) > 0 { - i -= len(m.CounterpartyChosenChannelId) - copy(dAtA[i:], m.CounterpartyChosenChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyChosenChannelId))) - i-- - dAtA[i] = 0x1a - } - if len(m.DesiredChannelId) > 0 { - i -= len(m.DesiredChannelId) - copy(dAtA[i:], m.DesiredChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.DesiredChannelId))) + 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 } @@ -2236,10 +2219,6 @@ func (m *MsgChannelOpenInit) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } l = m.Channel.Size() n += 1 + l + sovTx(uint64(l)) l = len(m.Signer) @@ -2268,11 +2247,7 @@ func (m *MsgChannelOpenTry) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.DesiredChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.CounterpartyChosenChannelId) + l = len(m.PreviousChannelId) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -2652,38 +2627,6 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { 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 Channel", wireType) } @@ -2716,7 +2659,7 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -2888,7 +2831,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredChannelId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreviousChannelId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2916,41 +2859,9 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DesiredChannelId = string(dAtA[iNdEx:postIndex]) + m.PreviousChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChosenChannelId", 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.CounterpartyChosenChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) } @@ -2983,7 +2894,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersion", wireType) } @@ -3015,7 +2926,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { } m.CounterpartyVersion = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) } @@ -3049,7 +2960,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { m.ProofInit = []byte{} } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -3082,7 +2993,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } diff --git a/x/ibc/core/24-host/validate.go b/x/ibc/core/24-host/validate.go index d589223f58..10458e8d3a 100644 --- a/x/ibc/core/24-host/validate.go +++ b/x/ibc/core/24-host/validate.go @@ -70,10 +70,10 @@ func ConnectionIdentifierValidator(id string) error { } // ChannelIdentifierValidator is the default validator function for Channel identifiers. -// A valid Identifier must be between 10-64 characters and only contain alphanumeric and some allowed +// A valid Identifier must be between 8-64 characters and only contain alphanumeric and some allowed // special characters (see IsValidID). func ChannelIdentifierValidator(id string) error { - return defaultIdentifierValidator(id, 10, DefaultMaxCharacterLength) + return defaultIdentifierValidator(id, 8, DefaultMaxCharacterLength) } // PortIdentifierValidator is the default validator function for Port identifiers. diff --git a/x/ibc/core/client/query.go b/x/ibc/core/client/query.go index dad0c28998..7055f1c740 100644 --- a/x/ibc/core/client/query.go +++ b/x/ibc/core/client/query.go @@ -62,6 +62,6 @@ func QueryTendermintProof(clientCtx client.Context, key []byte) ([]byte, []byte, return nil, nil, clienttypes.Height{}, err } - version := clienttypes.ParseChainID(clientCtx.ChainID) - return res.Value, proofBz, clienttypes.NewHeight(version, uint64(res.Height)+1), nil + revision := clienttypes.ParseChainID(clientCtx.ChainID) + return res.Value, proofBz, clienttypes.NewHeight(revision, uint64(res.Height)+1), nil } diff --git a/x/ibc/core/exported/client.go b/x/ibc/core/exported/client.go index 10d437cbce..67c71526d1 100644 --- a/x/ibc/core/exported/client.go +++ b/x/ibc/core/exported/client.go @@ -39,13 +39,19 @@ type ClientState interface { CheckProposedHeaderAndUpdateState(sdk.Context, codec.BinaryMarshaler, sdk.KVStore, Header) (ClientState, ConsensusState, error) // Upgrade functions + // NOTE: proof heights are not included as upgrade to a new revision is expected to pass only on the last + // height committed by the current revision. Clients are responsible for ensuring that the planned last + // height of the current revision is somehow encoded in the proof verification process. + // This is to ensure that no premature upgrades occur, since upgrade plans committed to by the counterparty + // may be cancelled or modified before the last planned height. VerifyUpgradeAndUpdateState( ctx sdk.Context, cdc codec.BinaryMarshaler, store sdk.KVStore, newClient ClientState, - upgradeHeight Height, - proofUpgrade []byte, + newConsState ConsensusState, + proofUpgradeClient, + proofUpgradeConsState []byte, ) (ClientState, ConsensusState, error) // Utility function that zeroes out any client customizable fields in client state // Ledger enforced fields are maintained while all custom fields are zero values @@ -176,8 +182,8 @@ type Height interface { EQ(Height) bool GT(Height) bool GTE(Height) bool - GetVersionNumber() uint64 - GetVersionHeight() uint64 + GetRevisionNumber() uint64 + GetRevisionHeight() uint64 Decrement() (Height, bool) String() string } diff --git a/x/ibc/core/genesis_test.go b/x/ibc/core/genesis_test.go index d435cf8566..29a26aad74 100644 --- a/x/ibc/core/genesis_test.go +++ b/x/ibc/core/genesis_test.go @@ -105,6 +105,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), ChannelGenesis: channeltypes.NewGenesisState( []channeltypes.IdentifiedChannel{ @@ -133,6 +134,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []channeltypes.PacketSequence{ channeltypes.NewPacketSequence(port2, channel2, 1), }, + 0, ), }, expPass: true, @@ -168,6 +170,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), }, expPass: false, @@ -244,6 +247,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), ChannelGenesis: channeltypes.NewGenesisState( []channeltypes.IdentifiedChannel{ @@ -272,6 +276,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { []channeltypes.PacketSequence{ channeltypes.NewPacketSequence(port2, channel2, 1), }, + 0, ), }, }, diff --git a/x/ibc/core/keeper/msg_server.go b/x/ibc/core/keeper/msg_server.go index c7579fdbba..2b655ff9a2 100644 --- a/x/ibc/core/keeper/msg_server.go +++ b/x/ibc/core/keeper/msg_server.go @@ -83,8 +83,13 @@ func (k Keeper) UpgradeClient(goCtx context.Context, msg *clienttypes.MsgUpgrade if err != nil { return nil, err } + upgradedConsState, err := clienttypes.UnpackConsensusState(msg.ConsensusState) + if err != nil { + return nil, err + } - if err = k.ClientKeeper.UpgradeClient(ctx, msg.ClientId, upgradedClient, msg.UpgradeHeight, msg.ProofUpgrade); err != nil { + if err = k.ClientKeeper.UpgradeClient(ctx, msg.ClientId, upgradedClient, upgradedConsState, + msg.ProofUpgradeClient, msg.ProofUpgradeConsensusState); err != nil { return nil, err } @@ -127,16 +132,15 @@ func (k Keeper) SubmitMisbehaviour(goCtx context.Context, msg *clienttypes.MsgSu func (k Keeper) ConnectionOpenInit(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenInit) (*connectiontypes.MsgConnectionOpenInitResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if err := k.ConnectionKeeper.ConnOpenInit( - ctx, msg.ConnectionId, msg.ClientId, msg.Counterparty, msg.Version, - ); err != nil { + connectionID, err := k.ConnectionKeeper.ConnOpenInit(ctx, msg.ClientId, msg.Counterparty, msg.Version) + if err != nil { return nil, sdkerrors.Wrap(err, "connection handshake open init failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( connectiontypes.EventTypeConnectionOpenInit, - sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.ConnectionId), + sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, connectionID), sdk.NewAttribute(connectiontypes.AttributeKeyClientID, msg.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, msg.Counterparty.ConnectionId), @@ -159,18 +163,19 @@ func (k Keeper) ConnectionOpenTry(goCtx context.Context, msg *connectiontypes.Ms return nil, sdkerrors.Wrapf(err, "client in msg is not exported.ClientState. invalid client: %v.", targetClient) } - if err := k.ConnectionKeeper.ConnOpenTry( - ctx, msg.DesiredConnectionId, msg.CounterpartyChosenConnectionId, msg.Counterparty, msg.ClientId, targetClient, + connectionID, err := k.ConnectionKeeper.ConnOpenTry( + ctx, msg.PreviousConnectionId, msg.Counterparty, msg.ClientId, targetClient, connectiontypes.ProtoVersionsToExported(msg.CounterpartyVersions), msg.ProofInit, msg.ProofClient, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, - ); err != nil { + ) + if err != nil { return nil, sdkerrors.Wrap(err, "connection handshake open try failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( connectiontypes.EventTypeConnectionOpenTry, - sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.DesiredConnectionId), + sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, connectionID), sdk.NewAttribute(connectiontypes.AttributeKeyClientID, msg.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, msg.Counterparty.ConnectionId), @@ -258,7 +263,7 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } - _, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg) + _, channelID, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg) if err != nil { return nil, err } @@ -269,7 +274,7 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.ChannelId, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil { + if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil { return nil, sdkerrors.Wrap(err, "channel open init callback failed") } @@ -285,7 +290,7 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } - _, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg) + _, channelID, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg) if err != nil { return nil, err } @@ -296,7 +301,7 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - if err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.DesiredChannelId, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion); err != nil { + if err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion); err != nil { return nil, sdkerrors.Wrap(err, "channel open try callback failed") } diff --git a/x/ibc/core/keeper/msg_server_test.go b/x/ibc/core/keeper/msg_server_test.go index 69a80fcb72..1af4cdc18e 100644 --- a/x/ibc/core/keeper/msg_server_test.go +++ b/x/ibc/core/keeper/msg_server_test.go @@ -2,7 +2,6 @@ package keeper_test import ( "testing" - "time" "github.com/stretchr/testify/suite" @@ -611,10 +610,11 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { func (suite *KeeperTestSuite) TestUpgradeClient() { var ( - clientA string - upgradedClient exported.ClientState - upgradeHeight exported.Height - msg *clienttypes.MsgUpgradeClient + clientA string + upgradedClient exported.ClientState + upgradedConsState exported.ConsensusState + lastHeight exported.Height + msg *clienttypes.MsgUpgradeClient ) newClientHeight := clienttypes.NewHeight(1, 1) @@ -628,13 +628,20 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { name: "successful upgrade", setup: func() { - upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient + upgradedClient = upgradedClient.ZeroCustomFields() - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -645,46 +652,33 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradeClient, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) - msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradeHeight, proofUpgrade, suite.chainA.SenderAccount.GetAddress()) + msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradedConsState, + proofUpgradeClient, proofUpgradedConsState, suite.chainA.SenderAccount.GetAddress()) suite.Require().NoError(err) }, expPass: true, }, - { - name: "invalid upgrade: msg.ClientState does not contain valid clientstate", - setup: func() { - - cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) - suite.Require().True(found) - - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - - proofUpgrade, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - - consState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("app_hash")), []byte("next_vals_hash")) - consAny, err := clienttypes.PackConsensusState(consState) - suite.Require().NoError(err) - - height, _ := upgradeHeight.(clienttypes.Height) - - msg = &clienttypes.MsgUpgradeClient{ClientId: clientA, ClientState: consAny, UpgradeHeight: &height, ProofUpgrade: proofUpgrade, Signer: suite.chainA.SenderAccount.GetAddress().String()} - }, - expPass: false, - }, { name: "VerifyUpgrade fails", setup: func() { - upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient + upgradedClient = upgradedClient.ZeroCustomFields() - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -692,7 +686,7 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) suite.Require().NoError(err) - msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradeHeight, nil, suite.chainA.SenderAccount.GetAddress()) + msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradedConsState, nil, nil, suite.chainA.SenderAccount.GetAddress()) suite.Require().NoError(err) }, expPass: false, @@ -711,7 +705,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { suite.Require().NoError(err, "upgrade handler failed on valid case: %s", tc.name) newClient, ok := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(ok) - suite.Require().Equal(upgradedClient, newClient) + newChainSpecifiedClient := newClient.ZeroCustomFields() + suite.Require().Equal(upgradedClient, newChainSpecifiedClient) } else { suite.Require().Error(err, "upgrade handler passed on invalid case: %s", tc.name) } diff --git a/x/ibc/core/spec/01_concepts.md b/x/ibc/core/spec/01_concepts.md index 079e6fa702..c3059e5f58 100644 --- a/x/ibc/core/spec/01_concepts.md +++ b/x/ibc/core/spec/01_concepts.md @@ -78,38 +78,38 @@ IBC Client Heights are represented by the struct: ```go type Height struct { - VersionNumber uint64 - VersionHeight uint64 + RevisionNumber uint64 + RevisionHeight uint64 } ``` -The `VersionNumber` represents the version of the chain that the height is representing. -An version typically represents a continuous, monotonically increasing range of block-heights. -The `VersionHeight` represents the height of the chain within the given version. +The `RevisionNumber` represents the revision of the chain that the height is representing. +An revision typically represents a continuous, monotonically increasing range of block-heights. +The `RevisionHeight` represents the height of the chain within the given revision. -On any reset of the `VersionHeight`, for example, when hard-forking a Tendermint chain, -the `VersionNumber` will get incremented. This allows IBC clients to distinguish between a -block-height `n` of a previous version of the chain (at version `p`) and block-height `n` of the current -version of the chain (at version `e`). +On any reset of the `RevisionHeight`, for example, when hard-forking a Tendermint chain, +the `RevisionNumber` will get incremented. This allows IBC clients to distinguish between a +block-height `n` of a previous revision of the chain (at revision `p`) and block-height `n` of the current +revision of the chain (at revision `e`). -`Heights` that share the same version number can be compared by simply comparing their respective `VersionHeights`. -Heights that do not share the same version number will only be compared using their respective `VersionNumbers`. -Thus a height `h` with version number `e+1` will always be greater than a height `g` with version number `e`, -**REGARDLESS** of the difference in version heights. +`Heights` that share the same revision number can be compared by simply comparing their respective `RevisionHeights`. +Heights that do not share the same revision number will only be compared using their respective `RevisionNumbers`. +Thus a height `h` with revision number `e+1` will always be greater than a height `g` with revision number `e`, +**REGARDLESS** of the difference in revision heights. Ex: ```go -Height{VersionNumber: 3, VersionHeight: 0} > Height{VersionNumber: 2, VersionHeight: 100000000000} +Height{RevisionNumber: 3, RevisionHeight: 0} > Height{RevisionNumber: 2, RevisionHeight: 100000000000} ``` -When a Tendermint chain is running a particular version, relayers can simply submit headers and proofs with the version number -given by the chain's chainID, and the version height given by the Tendermint block height. When a chain updates using a hard-fork -and resets its block-height, it is responsible for updating its chain-id to increment the version number. -IBC Tendermint clients then verifies the version number against their `ChainId` and treat the `VersionHeight` as the Tendermint block-height. +When a Tendermint chain is running a particular revision, relayers can simply submit headers and proofs with the revision number +given by the chain's chainID, and the revision height given by the Tendermint block height. When a chain updates using a hard-fork +and resets its block-height, it is responsible for updating its chain-id to increment the revision number. +IBC Tendermint clients then verifies the revision number against their `ChainId` and treat the `RevisionHeight` as the Tendermint block-height. -Tendermint chains wishing to use versions to maintain persistent IBC connections even across height-resetting upgrades must format their chain-ids -in the following manner: `{chainID}-{version_number}`. On any height-resetting upgrade, the chainID **MUST** be updated with a higher version number +Tendermint chains wishing to use revisions to maintain persistent IBC connections even across height-resetting upgrades must format their chain-ids +in the following manner: `{chainID}-{revision_number}`. On any height-resetting upgrade, the chainID **MUST** be updated with a higher revision number than the previous value. Ex: @@ -117,8 +117,8 @@ Ex: - Before upgrade ChainID: `gaiamainnet-3` - After upgrade ChainID: `gaiamainnet-4` -Clients that do not require versions, such as the solo-machine client, simply hardcode `0` into the version number whenever they -need to return an IBC height when implementing IBC interfaces and use the `VersionHeight` exclusively. +Clients that do not require revisions, such as the solo-machine client, simply hardcode `0` into the revision number whenever they +need to return an IBC height when implementing IBC interfaces and use the `RevisionHeight` exclusively. Other client-types may implement their own logic to verify the IBC Heights that relayers provide in their `Update`, `Misbehavior`, and `Verify` functions respectively. @@ -131,16 +131,18 @@ The IBC interfaces expect an `ibcexported.Height` interface, however all clients The connection handshake occurs in 4 steps as defined in [ICS 03](https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics). `ConnOpenInit` is the first attempt to initialize a connection on the executing chain. -The handshake is expected to succeed if the connection identifier selected is not used and the -version selected is supported. The connection identifier for the counterparty connection may -be left empty indicating that the counterparty may select its own identifier. The connection -is set and stored in the INIT state upon success. +The handshake is expected to succeed if the version selected is supported. The connection +identifier for the counterparty connection must be left empty indicating that the counterparty +must select its own identifier. The connection identifier is auto derived in the format: +`connection{N}` where N is the next sequence to be used. The counter begins at 0 and increments +by 1. The connection is set and stored in the INIT state upon success. `ConnOpenTry` is a response to a chain executing `ConnOpenInit`. The executing chain will validate -the chain level parameters the counterparty has stored such as its chainID and consensus parameters. -The executing chain will also verify that if a previous connection exists for the specified -connection identifier that all the parameters match and its previous state was in INIT. This -may occur when both chains execute `ConnOpenInit` simultaneously. The executing chain will verify +the chain level parameters the counterparty has stored such as its chainID. The executing chain +will also verify that if a previous connection exists for the specified connection identifier +that all the parameters match and its previous state was in INIT. This may occur when both +chains execute `ConnOpenInit` simultaneously. If the connection does not exist then a connection +identifier is generated in the same format done in `ConnOpenInit`. The executing chain will verify that the counterparty created a connection in INIT state. The executing chain will also verify The `ClientState` and `ConsensusState` the counterparty stores for the executing chain. The executing chain will select a version from the intersection of its supported versions and the @@ -208,23 +210,25 @@ versions should have a unique version identifier. The channel handshake occurs in 4 steps as defined in [ICS 04](https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics). `ChanOpenInit` is the first attempt to initialize a channel on top of an existing connection. -The handshake is expected to succeed if the channel identifier selected is not used and the -version selected for the existing connection is a supported IBC version. The portID must correspond -to a port already binded upon `InitChain`. The channel identifier for the counterparty channel -may be left empty indicating that the counterparty may select its own identifier. The channel is -set and stored in the INIT state upon success. The channel parameters `NextSequenceSend`, -`NextSequenceRecv`, and `NextSequenceAck` are all set to 1 and a channel capability is created -for the given portID and channelID path. +The handshake is expected to succeed if the version selected for the existing connection is a +supported IBC version. The portID must correspond to a port already binded upon `InitChain`. +The channel identifier for the counterparty channel must be left empty indicating that the +counterparty must select its own identifier. The channel identifier is auto derived in the +format: `channel{N}` where N is the next sequence to be used. The channel is set and stored +in the INIT state upon success. The channel parameters `NextSequenceSend`, `NextSequenceRecv`, +and `NextSequenceAck` are all set to 1 and a channel capability is created for the given +portID and channelID path. `ChanOpenTry` is a response to a chain executing `ChanOpenInit`. If the executing chain is calling `ChanOpenTry` after previously executing `ChanOpenInit` then the provided channel parameters must -match the previously selected parameters. The connection the channel is created on top of must be -an OPEN state and its IBC version must support the desired channel type being created (ORDERED, -UNORDERED, etc). The executing chain will verify that the channel state of the counterparty is -in INIT. The executing chain will set and store the channel state in TRYOPEN. The channel -parameters `NextSequenceSend`, `NextSequenceRecv`, and `NextSequenceAck` are all set to 1 and -a channel capability is created for the given portID and channelID path only if the channel -did not previously exist. +match the previously selected parameters. If the previous channel does not exist then a channel +identifier is generated in the same format as done in `ChanOpenInit`. The connection the channel +is created on top of must be an OPEN state and its IBC version must support the desired channel +type being created (ORDERED, UNORDERED, etc). The executing chain will verify that the channel +state of the counterparty is in INIT. The executing chain will set and store the channel state +in TRYOPEN. The channel parameters `NextSequenceSend`, `NextSequenceRecv`, and `NextSequenceAck` +are all set to 1 and a channel capability is created for the given portID and channelID path only +if the channel did not previously exist. `ChanOpenAck` may be called on a chain when the counterparty channel has entered TRYOPEN. A previous channel on the executing chain must exist be in either INIT or TRYOPEN state. If the diff --git a/x/ibc/core/spec/06_events.md b/x/ibc/core/spec/06_events.md index 9f96b089b3..528a30cffa 100644 --- a/x/ibc/core/spec/06_events.md +++ b/x/ibc/core/spec/06_events.md @@ -66,7 +66,6 @@ callbacks to IBC applications. | connection_open_init | connection_id | {connectionId} | | connection_open_init | client_id | {clientId} | | connection_open_init | counterparty_client_id | {counterparty.clientId} | -| connection_open_init | counterparty_connection_id | {counterparty.connectionId} | | message | action | connection_open_init | | message | module | ibc_connection | @@ -112,7 +111,6 @@ callbacks to IBC applications. | channel_open_init | port_id | {portId} | | channel_open_init | channel_id | {channelId} | | channel_open_init | counterparty_port_id | {channel.counterparty.portId} | -| channel_open_init | counterparty_channel_id | {channel.counterparty.channelId} | | channel_open_init | connection_id | {channel.connectionHops} | | message | action | channel_open_init | | message | module | ibc_channel | diff --git a/x/ibc/light-clients/06-solomachine/types/client_state.go b/x/ibc/light-clients/06-solomachine/types/client_state.go index 4a6fb86962..38004b292b 100644 --- a/x/ibc/light-clients/06-solomachine/types/client_state.go +++ b/x/ibc/light-clients/06-solomachine/types/client_state.go @@ -33,7 +33,7 @@ func (cs ClientState) ClientType() string { // GetLatestHeight returns the latest sequence number. // Return exported.Height to satisfy ClientState interface -// Version number is always 0 for a solo-machine. +// Revision number is always 0 for a solo-machine. func (cs ClientState) GetLatestHeight() exported.Height { return clienttypes.NewHeight(0, cs.Sequence) } @@ -45,7 +45,7 @@ func (cs ClientState) IsFrozen() bool { // GetFrozenHeight returns the frozen sequence of the client. // Return exported.Height to satisfy interface -// Version number is always 0 for a solo-machine +// Revision number is always 0 for a solo-machine func (cs ClientState) GetFrozenHeight() exported.Height { return clienttypes.NewHeight(0, cs.FrozenSequence) } @@ -77,7 +77,7 @@ func (cs ClientState) ZeroCustomFields() exported.ClientState { // VerifyUpgradeAndUpdateState returns an error since solomachine client does not support upgrades func (cs ClientState) VerifyUpgradeAndUpdateState( _ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, - _ exported.ClientState, _ exported.Height, _ []byte, + _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, ) (exported.ClientState, exported.ConsensusState, error) { return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade solomachine client") } @@ -398,11 +398,11 @@ func produceVerificationArgs( prefix exported.Prefix, proof []byte, ) (cryptotypes.PubKey, signing.SignatureData, uint64, uint64, error) { - if version := height.GetVersionNumber(); version != 0 { - return nil, nil, 0, 0, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "version must be 0 for solomachine, got version-number: %d", version) + if revision := height.GetRevisionNumber(); revision != 0 { + return nil, nil, 0, 0, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "revision must be 0 for solomachine, got revision-number: %d", revision) } - // sequence is encoded in the version height of height struct - sequence := height.GetVersionHeight() + // sequence is encoded in the revision height of height struct + sequence := height.GetRevisionHeight() if cs.IsFrozen() { return nil, nil, 0, 0, clienttypes.ErrClientFrozen } @@ -440,7 +440,7 @@ func produceVerificationArgs( return nil, nil, 0, 0, sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "consensus state cannot be empty") } - latestSequence := cs.GetLatestHeight().GetVersionHeight() + latestSequence := cs.GetLatestHeight().GetRevisionHeight() if latestSequence != sequence { return nil, nil, 0, 0, sdkerrors.Wrapf( sdkerrors.ErrInvalidHeight, diff --git a/x/ibc/light-clients/06-solomachine/types/header.go b/x/ibc/light-clients/06-solomachine/types/header.go index dc43cee4f7..60a9bfeeb7 100644 --- a/x/ibc/light-clients/06-solomachine/types/header.go +++ b/x/ibc/light-clients/06-solomachine/types/header.go @@ -18,7 +18,7 @@ func (Header) ClientType() string { // GetHeight returns the current sequence number as the height. // Return clientexported.Height to satisfy interface -// Version number is always 0 for a solo-machine +// Revision number is always 0 for a solo-machine func (h Header) GetHeight() exported.Height { return clienttypes.NewHeight(0, h.Sequence) } diff --git a/x/ibc/light-clients/06-solomachine/types/misbehaviour.go b/x/ibc/light-clients/06-solomachine/types/misbehaviour.go index 8a59eb2d9a..65b8a4ee47 100644 --- a/x/ibc/light-clients/06-solomachine/types/misbehaviour.go +++ b/x/ibc/light-clients/06-solomachine/types/misbehaviour.go @@ -30,7 +30,7 @@ func (misbehaviour Misbehaviour) Type() string { // GetHeight returns the sequence at which misbehaviour occurred. // Return exported.Height to satisfy interface -// Version number is always 0 for a solo-machine +// Revision number is always 0 for a solo-machine func (misbehaviour Misbehaviour) GetHeight() exported.Height { return clienttypes.NewHeight(0, misbehaviour.Sequence) } diff --git a/x/ibc/light-clients/06-solomachine/types/misbehaviour_test.go b/x/ibc/light-clients/06-solomachine/types/misbehaviour_test.go index a976186eab..7c1f9168aa 100644 --- a/x/ibc/light-clients/06-solomachine/types/misbehaviour_test.go +++ b/x/ibc/light-clients/06-solomachine/types/misbehaviour_test.go @@ -11,8 +11,8 @@ func (suite *SoloMachineTestSuite) TestMisbehaviour() { suite.Require().Equal(exported.Solomachine, misbehaviour.ClientType()) suite.Require().Equal(suite.solomachine.ClientID, misbehaviour.GetClientID()) - suite.Require().Equal(uint64(0), misbehaviour.GetHeight().GetVersionNumber()) - suite.Require().Equal(suite.solomachine.Sequence, misbehaviour.GetHeight().GetVersionHeight()) + suite.Require().Equal(uint64(0), misbehaviour.GetHeight().GetRevisionNumber()) + suite.Require().Equal(suite.solomachine.Sequence, misbehaviour.GetHeight().GetRevisionHeight()) } func (suite *SoloMachineTestSuite) TestMisbehaviourValidateBasic() { diff --git a/x/ibc/light-clients/06-solomachine/types/proposal_handle_test.go b/x/ibc/light-clients/06-solomachine/types/proposal_handle_test.go index 86d5c78dcc..da5c815ecb 100644 --- a/x/ibc/light-clients/06-solomachine/types/proposal_handle_test.go +++ b/x/ibc/light-clients/06-solomachine/types/proposal_handle_test.go @@ -79,7 +79,7 @@ func (suite *SoloMachineTestSuite) TestCheckProposedHeaderAndUpdateState() { suite.Require().Equal(headerPubKey, consStatePubKey) suite.Require().Equal(smHeader.NewDiversifier, smConsState.Diversifier) suite.Require().Equal(smHeader.Timestamp, smConsState.Timestamp) - suite.Require().Equal(smHeader.GetHeight().GetVersionHeight(), cs.(*types.ClientState).Sequence) + suite.Require().Equal(smHeader.GetHeight().GetRevisionHeight(), cs.(*types.ClientState).Sequence) } else { suite.Require().Error(err) suite.Require().Nil(cs) diff --git a/x/ibc/light-clients/06-solomachine/types/solomachine_test.go b/x/ibc/light-clients/06-solomachine/types/solomachine_test.go index b3b647d829..0d9e726411 100644 --- a/x/ibc/light-clients/06-solomachine/types/solomachine_test.go +++ b/x/ibc/light-clients/06-solomachine/types/solomachine_test.go @@ -55,7 +55,7 @@ func (suite *SoloMachineTestSuite) GetSequenceFromStore() uint64 { var clientState exported.ClientState err := codec.UnmarshalAny(suite.chainA.Codec, &clientState, bz) suite.Require().NoError(err) - return clientState.GetLatestHeight().GetVersionHeight() + return clientState.GetLatestHeight().GetRevisionHeight() } func (suite *SoloMachineTestSuite) GetInvalidProof() []byte { diff --git a/x/ibc/light-clients/07-tendermint/client/cli/tx.go b/x/ibc/light-clients/07-tendermint/client/cli/tx.go index be2b4c4725..3bd2f0c0b7 100644 --- a/x/ibc/light-clients/07-tendermint/client/cli/tx.go +++ b/x/ibc/light-clients/07-tendermint/client/cli/tx.go @@ -39,7 +39,7 @@ func NewCreateClientCmd() *cobra.Command { Long: `Create a new tendermint IBC client. - 'trust-level' flag can be a fraction (eg: '1/3') or 'default' - 'proof-specs' flag can be JSON input, a path to a .json file or 'default' - - 'upgrade-path' flag is a string specifying the upgrade path for this chain where a future upgraded client will be stored. The path represents a keypath for the store with each key separated by a '/'. Any slash within a key must be escaped. + - 'upgrade-path' flag is a string specifying the upgrade path for this chain where a future upgraded client will be stored. The path is a comma-separated list representing the keys in order of the keyPath to the committed upgraded client. e.g. 'upgrade/upgradedClient'`, Example: fmt.Sprintf("%s tx ibc %s create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] [max_clock_drift] --trust-level default --consensus-params [path/to/consensus-params.json] --proof-specs [path/to/proof-specs.json] --upgrade-path upgrade/upgradedClient --from node0 --home ../node0/cli --chain-id $CID", version.AppName, types.SubModuleName), Args: cobra.ExactArgs(5), @@ -119,7 +119,8 @@ func NewCreateClientCmd() *cobra.Command { allowUpdateAfterExpiry, _ := cmd.Flags().GetBool(flagAllowUpdateAfterExpiry) allowUpdateAfterMisbehaviour, _ := cmd.Flags().GetBool(flagAllowUpdateAfterMisbehaviour) - upgradePath, _ := cmd.Flags().GetString(flagUpgradePath) + upgradePathStr, _ := cmd.Flags().GetString(flagUpgradePath) + upgradePath := strings.Split(upgradePathStr, ",") // validate header if err := header.ValidateBasic(); err != nil { diff --git a/x/ibc/light-clients/07-tendermint/types/client_state.go b/x/ibc/light-clients/07-tendermint/types/client_state.go index 8cfc849541..10f3bc3baa 100644 --- a/x/ibc/light-clients/07-tendermint/types/client_state.go +++ b/x/ibc/light-clients/07-tendermint/types/client_state.go @@ -25,7 +25,7 @@ func NewClientState( chainID string, trustLevel Fraction, trustingPeriod, ubdPeriod, maxClockDrift time.Duration, latestHeight clienttypes.Height, specs []*ics23.ProofSpec, - upgradePath string, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour bool, + upgradePath []string, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour bool, ) *ClientState { return &ClientState{ ChainId: chainID, @@ -92,8 +92,8 @@ func (cs ClientState) Validate() error { if cs.MaxClockDrift == 0 { return sdkerrors.Wrap(ErrInvalidMaxClockDrift, "max clock drift cannot be zero") } - if cs.LatestHeight.VersionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "tendermint version height cannot be zero") + if cs.LatestHeight.RevisionHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "tendermint revision height cannot be zero") } if cs.TrustingPeriod >= cs.UnbondingPeriod { return sdkerrors.Wrapf( @@ -105,17 +105,15 @@ func (cs ClientState) Validate() error { if cs.ProofSpecs == nil { return sdkerrors.Wrap(ErrInvalidProofSpecs, "proof specs cannot be nil for tm client") } - for _, spec := range cs.ProofSpecs { + for i, spec := range cs.ProofSpecs { if spec == nil { - return sdkerrors.Wrap(ErrInvalidProofSpecs, "proof spec cannot be nil") + return sdkerrors.Wrapf(ErrInvalidProofSpecs, "proof spec cannot be nil at index: %d", i) } } - if cs.UpgradePath != "" { - keys := strings.Split(cs.UpgradePath, "/") - for _, k := range keys { - if strings.TrimSpace(k) == "" { - return sdkerrors.Wrapf(clienttypes.ErrInvalidUpgradeClient, "upgrade path contains an empty string when splitting by '/': %s", cs.UpgradePath) - } + // UpgradePath may be empty, but if it isn't, each key must be non-empty + for i, k := range cs.UpgradePath { + if strings.TrimSpace(k) == "" { + return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "key in upgrade path at index %d cannot be empty", i) } } diff --git a/x/ibc/light-clients/07-tendermint/types/client_state_test.go b/x/ibc/light-clients/07-tendermint/types/client_state_test.go index 71f9f3fc3b..80be1472f8 100644 --- a/x/ibc/light-clients/07-tendermint/types/client_state_test.go +++ b/x/ibc/light-clients/07-tendermint/types/client_state_test.go @@ -38,7 +38,7 @@ func (suite *TendermintTestSuite) TestValidate() { }, { name: "valid client with nil upgrade path", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), "", false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), nil, false, false), expPass: true, }, { @@ -137,7 +137,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "client is frozen", - clientState: &types.ClientState{LatestHeight: height, FrozenHeight: clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-1)}, + clientState: &types.ClientState{LatestHeight: height, FrozenHeight: clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-1)}, consensusState: types.ConsensusState{ Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), }, diff --git a/x/ibc/light-clients/07-tendermint/types/header.go b/x/ibc/light-clients/07-tendermint/types/header.go index 40858c7350..b5829e5f96 100644 --- a/x/ibc/light-clients/07-tendermint/types/header.go +++ b/x/ibc/light-clients/07-tendermint/types/header.go @@ -32,8 +32,8 @@ func (h Header) ClientType() string { // header is nil. // NOTE: the header.Header is checked to be non nil in ValidateBasic. func (h Header) GetHeight() exported.Height { - version := clienttypes.ParseChainID(h.Header.ChainID) - return clienttypes.NewHeight(version, uint64(h.Header.Height)) + revision := clienttypes.ParseChainID(h.Header.ChainID) + return clienttypes.NewHeight(revision, uint64(h.Header.Height)) } // GetTime returns the current block timestamp. It returns a zero time if diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour.go index d4de93504e..5158766040 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour.go @@ -60,11 +60,11 @@ func (misbehaviour Misbehaviour) ValidateBasic() error { if misbehaviour.Header2 == nil { return sdkerrors.Wrap(ErrInvalidHeader, "misbehaviour Header2 cannot be nil") } - if misbehaviour.Header1.TrustedHeight.VersionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header1 cannot have zero version height") + if misbehaviour.Header1.TrustedHeight.RevisionHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header1 cannot have zero revision height") } - if misbehaviour.Header2.TrustedHeight.VersionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header2 cannot have zero version height") + if misbehaviour.Header2.TrustedHeight.RevisionHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header2 cannot have zero revision height") } if misbehaviour.Header1.TrustedValidators == nil { return sdkerrors.Wrap(ErrInvalidValidatorSet, "trusted validator set in Header1 cannot be empty") diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go index 1f1a6943ce..4c55552d30 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go @@ -102,10 +102,10 @@ func checkMisbehaviourHeader( } chainID := clientState.GetChainID() - // If chainID is in version format, then set version number of chainID with the version number + // If chainID is in revision format, then set revision number of chainID with the revision number // of the misbehaviour header - if clienttypes.IsVersionFormat(chainID) { - chainID, _ = clienttypes.SetVersionNumber(chainID, header.GetHeight().GetVersionNumber()) + if clienttypes.IsRevisionFormat(chainID) { + chainID, _ = clienttypes.SetRevisionNumber(chainID, header.GetHeight().GetRevisionNumber()) } // - ValidatorSet must have TrustLevel similarity with trusted FromValidatorSet diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go index 65ec7163d8..3ca2e4dc11 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go @@ -35,8 +35,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { altSigners := []tmtypes.PrivValidator{altPrivVal} - heightMinus1 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-1) - heightMinus3 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-3) + heightMinus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-1) + heightMinus3 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-3) testCases := []struct { name string @@ -57,8 +57,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -72,8 +72,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -87,53 +87,53 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, true, }, { - "valid misbehaviour at a previous version", - types.NewClientState(chainIDVersion1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + "valid misbehaviour at a previous revision", + types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDVersion0, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDVersion0, int64(height.VersionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, true, }, { - "valid misbehaviour at a future version", - types.NewClientState(chainIDVersion0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + "valid misbehaviour at a future revision", + types.NewClientState(chainIDRevision0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDVersion0, 3, heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDVersion0, 3, heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainIDRevision0, 3, heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainIDRevision0, 3, heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, true, }, { - "valid misbehaviour with trusted heights at a previous version", - types.NewClientState(chainIDVersion1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + "valid misbehaviour with trusted heights at a previous revision", + types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDVersion1, 1, heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDVersion1, 1, heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, @@ -147,8 +147,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, @@ -162,8 +162,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader("ethermint", int64(height.VersionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -177,8 +177,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, @@ -192,8 +192,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -207,8 +207,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -222,8 +222,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -248,8 +248,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -263,8 +263,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now.Add(trustingPeriod), @@ -278,8 +278,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, @@ -293,8 +293,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, altValSet, bothValSet, altSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, altValSet, bothValSet, altSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -308,8 +308,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), ClientId: chainID, }, suite.now, @@ -323,8 +323,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, altValSet, bothValSet, altSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, altValSet, bothValSet, altSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), ClientId: chainID, }, suite.now, diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour_test.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour_test.go index c8e4416612..dede4e6021 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour_test.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour_test.go @@ -16,11 +16,11 @@ import ( func (suite *TendermintTestSuite) TestMisbehaviour() { signers := []tmtypes.PrivValidator{suite.privVal} - heightMinus1 := clienttypes.NewHeight(0, height.VersionHeight-1) + heightMinus1 := clienttypes.NewHeight(0, height.RevisionHeight-1) misbehaviour := &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), ClientId: clientID, } @@ -34,9 +34,9 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { altPubKey, err := altPrivVal.GetPubKey() suite.Require().NoError(err) - versionHeight := int64(height.VersionHeight) + revisionHeight := int64(height.RevisionHeight) - altVal := tmtypes.NewValidator(altPubKey, versionHeight) + altVal := tmtypes.NewValidator(altPubKey, revisionHeight) // Create bothValSet with both suite validator and altVal bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) @@ -51,7 +51,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { altSigners := []tmtypes.PrivValidator{altPrivVal} - heightMinus1 := clienttypes.NewHeight(0, height.VersionHeight-1) + heightMinus1 := clienttypes.NewHeight(0, height.RevisionHeight-1) testCases := []struct { name string @@ -63,7 +63,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "valid misbehaviour", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -85,7 +85,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "valid misbehaviour with different trusted headers", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), clienttypes.NewHeight(0, height.VersionHeight-3), suite.now.Add(time.Minute), suite.valSet, bothValSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.NewHeight(0, height.RevisionHeight-3), suite.now.Add(time.Minute), suite.valSet, bothValSet, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -94,7 +94,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "trusted height is 0 in Header1", &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), Header2: suite.header, ClientId: clientID, }, @@ -105,7 +105,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "trusted height is 0 in Header2", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -114,7 +114,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "trusted valset is nil in Header1", &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, nil, signers), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, nil, signers), Header2: suite.header, ClientId: clientID, }, @@ -125,7 +125,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "trusted valset is nil in Header2", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, nil, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, nil, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -135,7 +135,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "invalid client ID ", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), ClientId: "GAIA", }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -145,7 +145,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "chainIDs do not match", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.VersionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -174,19 +174,19 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "header 1 doesn't have 2/3 majority", &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), Header2: suite.header, ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { // voteSet contains only altVal which is less than 2/3 of total power (height/1height) - wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header1.GetHeight().GetVersionHeight()), 1, tmproto.PrecommitType, altValSet) + wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header1.GetHeight().GetRevisionHeight()), 1, tmproto.PrecommitType, altValSet) blockID, err := tmtypes.BlockIDFromProto(&misbehaviour.Header1.Commit.BlockID) if err != nil { return err } - tmCommit, err := tmtypes.MakeCommit(*blockID, int64(misbehaviour.Header2.GetHeight().GetVersionHeight()), misbehaviour.Header1.Commit.Round, wrongVoteSet, altSigners, suite.now) + tmCommit, err := tmtypes.MakeCommit(*blockID, int64(misbehaviour.Header2.GetHeight().GetRevisionHeight()), misbehaviour.Header1.Commit.Round, wrongVoteSet, altSigners, suite.now) misbehaviour.Header1.Commit = tmCommit.ToProto() return err }, @@ -196,18 +196,18 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "header 2 doesn't have 2/3 majority", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { // voteSet contains only altVal which is less than 2/3 of total power (height/1height) - wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header2.GetHeight().GetVersionHeight()), 1, tmproto.PrecommitType, altValSet) + wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header2.GetHeight().GetRevisionHeight()), 1, tmproto.PrecommitType, altValSet) blockID, err := tmtypes.BlockIDFromProto(&misbehaviour.Header2.Commit.BlockID) if err != nil { return err } - tmCommit, err := tmtypes.MakeCommit(*blockID, int64(misbehaviour.Header2.GetHeight().GetVersionHeight()), misbehaviour.Header2.Commit.Round, wrongVoteSet, altSigners, suite.now) + tmCommit, err := tmtypes.MakeCommit(*blockID, int64(misbehaviour.Header2.GetHeight().GetRevisionHeight()), misbehaviour.Header2.Commit.Round, wrongVoteSet, altSigners, suite.now) misbehaviour.Header2.Commit = tmCommit.ToProto() return err }, @@ -217,7 +217,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "validators sign off on wrong commit", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { diff --git a/x/ibc/light-clients/07-tendermint/types/tendermint.pb.go b/x/ibc/light-clients/07-tendermint/types/tendermint.pb.go index df0967ef02..9993ed261d 100644 --- a/x/ibc/light-clients/07-tendermint/types/tendermint.pb.go +++ b/x/ibc/light-clients/07-tendermint/types/tendermint.pb.go @@ -51,8 +51,12 @@ type ClientState struct { LatestHeight types.Height `protobuf:"bytes,7,opt,name=latest_height,json=latestHeight,proto3" json:"latest_height" yaml:"latest_height"` // Proof specifications used in verifying counterparty state ProofSpecs []*_go.ProofSpec `protobuf:"bytes,8,rep,name=proof_specs,json=proofSpecs,proto3" json:"proof_specs,omitempty" yaml:"proof_specs"` - // Path at which next upgraded client will be committed - UpgradePath string `protobuf:"bytes,9,opt,name=upgrade_path,json=upgradePath,proto3" json:"upgrade_path,omitempty" yaml:"upgrade_path"` + // Path at which next upgraded client will be committed. + // Each element corresponds to the key for a single CommitmentProof in the chained proof. + // NOTE: ClientState must stored under `{upgradePath}/{upgradeHeight}/clientState` + // ConsensusState must be stored under `{upgradepath}/{upgradeHeight}/consensusState` + // For SDK chains using the default upgrade module, upgrade_path should be []string{"upgrade", "upgradedIBCState"}` + UpgradePath []string `protobuf:"bytes,9,rep,name=upgrade_path,json=upgradePath,proto3" json:"upgrade_path,omitempty" yaml:"upgrade_path"` // This flag, when set to true, will allow governance to recover a client // which has expired AllowUpdateAfterExpiry bool `protobuf:"varint,10,opt,name=allow_update_after_expiry,json=allowUpdateAfterExpiry,proto3" json:"allow_update_after_expiry,omitempty" yaml:"allow_update_after_expiry"` @@ -317,75 +321,75 @@ func init() { } var fileDescriptor_c6d6cf2b288949be = []byte{ - // 1079 bytes of a gzipped FileDescriptorProto + // 1081 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcf, 0x6f, 0xe3, 0xc4, - 0x17, 0x6f, 0xda, 0x7e, 0xb7, 0xe9, 0x24, 0xdd, 0xf6, 0xeb, 0x2d, 0xdd, 0xb4, 0x74, 0xe3, 0xc8, - 0xa0, 0xa5, 0x42, 0xaa, 0x4d, 0xb2, 0x48, 0x48, 0x15, 0x17, 0xdc, 0x82, 0x5a, 0xc4, 0x4a, 0x95, - 0xcb, 0x0f, 0x09, 0x09, 0xcc, 0xc4, 0x9e, 0x24, 0xa3, 0xda, 0x1e, 0xe3, 0x99, 0x84, 0x94, 0xbf, + 0x17, 0x6f, 0xda, 0x7e, 0xb7, 0xc9, 0x24, 0xdd, 0xf6, 0xeb, 0x2d, 0xdd, 0xb4, 0x74, 0xe3, 0xc8, + 0xa0, 0x25, 0x42, 0xaa, 0x4d, 0xb2, 0x48, 0x48, 0x15, 0x17, 0xdc, 0x82, 0x5a, 0xc4, 0x4a, 0x95, + 0xcb, 0x0f, 0x09, 0x09, 0xcc, 0xc4, 0x9e, 0xc4, 0xa3, 0xda, 0x1e, 0xe3, 0x99, 0x84, 0x94, 0xbf, 0x00, 0x0e, 0x48, 0x7b, 0x44, 0x9c, 0x38, 0xf0, 0xc7, 0xec, 0xb1, 0x47, 0x4e, 0x06, 0xb5, 0x17, - 0xce, 0x39, 0x72, 0x42, 0xf3, 0xc3, 0xf6, 0x34, 0xdb, 0xa5, 0x5a, 0x2e, 0xed, 0xbc, 0xf7, 0x3e, - 0xef, 0xf3, 0xc9, 0xbc, 0x79, 0xf3, 0xc6, 0xc0, 0xc1, 0xfd, 0xc0, 0x89, 0xf0, 0x70, 0xc4, 0x82, - 0x08, 0xa3, 0x84, 0x51, 0x87, 0xa1, 0x24, 0x44, 0x59, 0x8c, 0x13, 0xe6, 0x4c, 0xba, 0x9a, 0x65, - 0xa7, 0x19, 0x61, 0xc4, 0x68, 0xe3, 0x7e, 0x60, 0xeb, 0x09, 0xb6, 0x06, 0x99, 0x74, 0x77, 0x3a, - 0x5a, 0x3e, 0xbb, 0x48, 0x11, 0x75, 0x26, 0x30, 0xc2, 0x21, 0x64, 0x24, 0x93, 0x0c, 0x3b, 0xbb, - 0x2f, 0x20, 0xc4, 0x5f, 0x15, 0x7d, 0x10, 0x90, 0x64, 0x80, 0x89, 0x93, 0x66, 0x84, 0x0c, 0x0a, - 0x67, 0x7b, 0x48, 0xc8, 0x30, 0x42, 0x8e, 0xb0, 0xfa, 0xe3, 0x81, 0x13, 0x8e, 0x33, 0xc8, 0x30, - 0x49, 0x54, 0xdc, 0x9c, 0x8f, 0x33, 0x1c, 0x23, 0xca, 0x60, 0x9c, 0x16, 0x00, 0xbe, 0xcd, 0x80, - 0x64, 0xc8, 0x91, 0xbf, 0x9a, 0x6f, 0x4d, 0xae, 0x14, 0xe0, 0xad, 0x0a, 0x40, 0xe2, 0x18, 0xb3, - 0xb8, 0x00, 0x95, 0x96, 0x02, 0x6e, 0x0e, 0xc9, 0x90, 0x88, 0xa5, 0xc3, 0x57, 0xd2, 0x6b, 0xfd, - 0xb5, 0x02, 0x1a, 0x87, 0x82, 0xef, 0x8c, 0x41, 0x86, 0x8c, 0x6d, 0x50, 0x0f, 0x46, 0x10, 0x27, - 0x3e, 0x0e, 0x5b, 0xb5, 0x4e, 0x6d, 0x6f, 0xd5, 0x5b, 0x11, 0xf6, 0x49, 0x68, 0x20, 0xd0, 0x60, - 0xd9, 0x98, 0x32, 0x3f, 0x42, 0x13, 0x14, 0xb5, 0x16, 0x3b, 0xb5, 0xbd, 0x46, 0x6f, 0xcf, 0xfe, - 0xf7, 0xb2, 0xda, 0x1f, 0x65, 0x30, 0xe0, 0x1b, 0x76, 0x77, 0x9e, 0xe7, 0xe6, 0xc2, 0x2c, 0x37, - 0x8d, 0x0b, 0x18, 0x47, 0x07, 0x96, 0x46, 0x65, 0x79, 0x40, 0x58, 0x9f, 0x70, 0xc3, 0x18, 0x80, - 0x75, 0x61, 0xe1, 0x64, 0xe8, 0xa7, 0x28, 0xc3, 0x24, 0x6c, 0x2d, 0x09, 0xa9, 0x6d, 0x5b, 0x16, - 0xcb, 0x2e, 0x8a, 0x65, 0x1f, 0xa9, 0x62, 0xba, 0x96, 0xe2, 0xde, 0xd2, 0xb8, 0xab, 0x7c, 0xeb, - 0xe7, 0x3f, 0xcc, 0x9a, 0x77, 0xbf, 0xf0, 0x9e, 0x0a, 0xa7, 0x81, 0xc1, 0xc6, 0x38, 0xe9, 0x93, - 0x24, 0xd4, 0x84, 0x96, 0xef, 0x12, 0x7a, 0x43, 0x09, 0x3d, 0x94, 0x42, 0xf3, 0x04, 0x52, 0x69, - 0xbd, 0x74, 0x2b, 0x29, 0x04, 0xd6, 0x63, 0x38, 0xf5, 0x83, 0x88, 0x04, 0xe7, 0x7e, 0x98, 0xe1, - 0x01, 0x6b, 0xfd, 0xef, 0x15, 0xb7, 0x34, 0x97, 0x2f, 0x85, 0xd6, 0x62, 0x38, 0x3d, 0xe4, 0xce, - 0x23, 0xee, 0x33, 0xbe, 0x02, 0x6b, 0x83, 0x8c, 0x7c, 0x8f, 0x12, 0x7f, 0x84, 0xf8, 0x81, 0xb4, - 0xee, 0x09, 0x91, 0x1d, 0x71, 0x44, 0xbc, 0x45, 0x6c, 0xd5, 0x39, 0x93, 0xae, 0x7d, 0x2c, 0x10, - 0xee, 0xae, 0x52, 0xd9, 0x94, 0x2a, 0x37, 0xd2, 0x2d, 0xaf, 0x29, 0x6d, 0x89, 0xe5, 0xf4, 0x11, - 0x64, 0x88, 0xb2, 0x82, 0x7e, 0xe5, 0x55, 0xe9, 0x6f, 0xa4, 0x5b, 0x5e, 0x53, 0xda, 0x8a, 0xfe, - 0x04, 0x34, 0xc4, 0xd5, 0xf1, 0x69, 0x8a, 0x02, 0xda, 0xaa, 0x77, 0x96, 0xf6, 0x1a, 0xbd, 0x0d, - 0x1b, 0x07, 0xb4, 0xf7, 0xc4, 0x3e, 0xe5, 0x91, 0xb3, 0x14, 0x05, 0xee, 0x56, 0xd5, 0x42, 0x1a, - 0xdc, 0xf2, 0x40, 0x5a, 0x40, 0xa8, 0x71, 0x00, 0x9a, 0xe3, 0x74, 0x98, 0xc1, 0x10, 0xf9, 0x29, - 0x64, 0xa3, 0xd6, 0x2a, 0x6f, 0x64, 0xf7, 0xe1, 0x2c, 0x37, 0x1f, 0xa8, 0x73, 0xd3, 0xa2, 0x96, - 0xd7, 0x50, 0xe6, 0x29, 0x64, 0x23, 0xc3, 0x07, 0xdb, 0x30, 0x8a, 0xc8, 0x77, 0xfe, 0x38, 0x0d, - 0x21, 0x43, 0x3e, 0x1c, 0x30, 0x94, 0xf9, 0x68, 0x9a, 0xe2, 0xec, 0xa2, 0x05, 0x3a, 0xb5, 0xbd, - 0xba, 0xfb, 0xe6, 0x2c, 0x37, 0x3b, 0x92, 0xe8, 0xa5, 0x50, 0xcb, 0xdb, 0x12, 0xb1, 0xcf, 0x44, - 0xe8, 0x03, 0x1e, 0xf9, 0x50, 0x04, 0x8c, 0x6f, 0x81, 0x79, 0x4b, 0x56, 0x8c, 0x69, 0x1f, 0x8d, - 0xe0, 0x04, 0x93, 0x71, 0xd6, 0x6a, 0x08, 0x99, 0xb7, 0x67, 0xb9, 0xf9, 0xf8, 0xa5, 0x32, 0x7a, - 0x82, 0xe5, 0xed, 0xce, 0x8b, 0x3d, 0xd5, 0xc2, 0x07, 0xcb, 0x3f, 0xfc, 0x6a, 0x2e, 0x58, 0xbf, - 0x2d, 0x82, 0xfb, 0x87, 0x24, 0xa1, 0x28, 0xa1, 0x63, 0x2a, 0x6f, 0xbb, 0x0b, 0x56, 0xcb, 0x81, - 0x23, 0xae, 0x3b, 0x3f, 0xce, 0xf9, 0x96, 0xfc, 0xb4, 0x40, 0xb8, 0x75, 0x7e, 0x9c, 0xcf, 0x78, - 0xe7, 0x55, 0x69, 0xc6, 0xfb, 0x60, 0x39, 0x23, 0x84, 0xa9, 0x79, 0x60, 0x69, 0xdd, 0x50, 0x4d, - 0xa0, 0x49, 0xd7, 0x7e, 0x8a, 0xb2, 0xf3, 0x08, 0x79, 0x84, 0x30, 0x77, 0x99, 0xd3, 0x78, 0x22, - 0xcb, 0xf8, 0xb1, 0x06, 0x36, 0x13, 0x34, 0x65, 0x7e, 0x39, 0x6c, 0xa9, 0x3f, 0x82, 0x74, 0x24, - 0xee, 0x7c, 0xd3, 0xfd, 0x62, 0x96, 0x9b, 0xaf, 0xcb, 0x1a, 0xdc, 0x86, 0xb2, 0xfe, 0xce, 0xcd, - 0x77, 0x87, 0x98, 0x8d, 0xc6, 0x7d, 0x2e, 0xa7, 0x3f, 0x01, 0xda, 0x32, 0xc2, 0x7d, 0xea, 0xf4, - 0x2f, 0x18, 0xa2, 0xf6, 0x31, 0x9a, 0xba, 0x7c, 0xe1, 0x19, 0x9c, 0xee, 0xf3, 0x92, 0xed, 0x18, - 0xd2, 0x91, 0x2a, 0xd3, 0x4f, 0x8b, 0xa0, 0xa9, 0x57, 0xcf, 0xe8, 0x82, 0x55, 0xd9, 0xd8, 0xe5, - 0x4c, 0x74, 0x37, 0x67, 0xb9, 0xb9, 0x21, 0x7f, 0x56, 0x19, 0xb2, 0xbc, 0xba, 0x5c, 0x9f, 0x84, - 0x06, 0x04, 0xf5, 0x11, 0x82, 0x21, 0xca, 0xfc, 0xae, 0xaa, 0xcb, 0xe3, 0xbb, 0xe6, 0xe4, 0xb1, - 0xc0, 0xbb, 0xed, 0xab, 0xdc, 0x5c, 0x91, 0xeb, 0xee, 0x2c, 0x37, 0xd7, 0xa5, 0x48, 0x41, 0x66, - 0x79, 0x2b, 0x72, 0xd9, 0xd5, 0x24, 0x7a, 0x6a, 0x3e, 0xfe, 0x07, 0x89, 0xde, 0x0b, 0x12, 0xbd, - 0x52, 0xa2, 0xa7, 0xea, 0xf1, 0xcb, 0x12, 0xb8, 0x27, 0xd1, 0x06, 0x04, 0x6b, 0x14, 0x0f, 0x13, - 0x14, 0xfa, 0x12, 0xa2, 0x5a, 0xa6, 0xad, 0xeb, 0xc8, 0x27, 0xf1, 0x4c, 0xc0, 0x94, 0xe0, 0xee, - 0x65, 0x6e, 0xd6, 0xaa, 0x29, 0x70, 0x83, 0xc2, 0xf2, 0x9a, 0x54, 0xc3, 0xf2, 0x21, 0x53, 0x9e, - 0xb1, 0x4f, 0x51, 0xd1, 0x56, 0xb7, 0x48, 0x94, 0x87, 0x77, 0x86, 0x98, 0xdb, 0xaa, 0xe8, 0x6f, - 0xa4, 0x5b, 0x5e, 0x73, 0xa2, 0xe1, 0x8c, 0x6f, 0x80, 0x7c, 0x06, 0x84, 0xbe, 0x18, 0x62, 0x4b, - 0x77, 0x0e, 0xb1, 0x47, 0x6a, 0x88, 0xbd, 0xa6, 0x3d, 0x2e, 0x65, 0xbe, 0xe5, 0xad, 0x29, 0x87, - 0x1a, 0x63, 0x11, 0x30, 0x0a, 0x44, 0xd5, 0xac, 0xea, 0x61, 0xb9, 0x6b, 0x17, 0x8f, 0x66, 0xb9, - 0xb9, 0x7d, 0x53, 0xa5, 0xe2, 0xb0, 0xbc, 0xff, 0x2b, 0x67, 0xd5, 0xb6, 0xd6, 0xc7, 0xa0, 0x5e, - 0x3c, 0xb0, 0xc6, 0x2e, 0x58, 0x4d, 0xc6, 0x31, 0xca, 0x78, 0x44, 0x9c, 0xcc, 0xb2, 0x57, 0x39, - 0x8c, 0x0e, 0x68, 0x84, 0x28, 0x21, 0x31, 0x4e, 0x44, 0x7c, 0x51, 0xc4, 0x75, 0x97, 0xfb, 0xf5, - 0xf3, 0xab, 0x76, 0xed, 0xf2, 0xaa, 0x5d, 0xfb, 0xf3, 0xaa, 0x5d, 0x7b, 0x76, 0xdd, 0x5e, 0xb8, - 0xbc, 0x6e, 0x2f, 0xfc, 0x7e, 0xdd, 0x5e, 0xf8, 0xf2, 0x48, 0xbb, 0x62, 0x01, 0xa1, 0x31, 0xa1, - 0xea, 0xdf, 0x3e, 0x0d, 0xcf, 0x9d, 0x69, 0xf5, 0x29, 0xb6, 0x5f, 0x7c, 0x8b, 0xbd, 0xf3, 0xde, - 0xfe, 0xfc, 0xc7, 0x52, 0xff, 0x9e, 0x98, 0x28, 0x4f, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x4c, - 0xb7, 0x2c, 0x8e, 0xba, 0x09, 0x00, 0x00, + 0xce, 0x39, 0x72, 0x42, 0x9e, 0x19, 0xdb, 0xd3, 0x6c, 0x97, 0x6a, 0xb9, 0xb4, 0xf3, 0xde, 0xfb, + 0xbc, 0xcf, 0x27, 0xf3, 0xe6, 0xcd, 0x1b, 0x03, 0x0b, 0x0f, 0x3d, 0x2b, 0xc4, 0xe3, 0x80, 0x79, + 0x21, 0x46, 0x31, 0xa3, 0x16, 0x43, 0xb1, 0x8f, 0xd2, 0x08, 0xc7, 0xcc, 0x9a, 0xf6, 0x15, 0xcb, + 0x4c, 0x52, 0xc2, 0x88, 0xd6, 0xc1, 0x43, 0xcf, 0x54, 0x13, 0x4c, 0x05, 0x32, 0xed, 0xef, 0x76, + 0x95, 0x7c, 0x76, 0x91, 0x20, 0x6a, 0x4d, 0x61, 0x88, 0x7d, 0xc8, 0x48, 0x2a, 0x18, 0x76, 0xf7, + 0x5e, 0x40, 0xf0, 0xbf, 0x32, 0xfa, 0xc0, 0x23, 0xf1, 0x08, 0x13, 0x2b, 0x49, 0x09, 0x19, 0x15, + 0xce, 0xce, 0x98, 0x90, 0x71, 0x88, 0x2c, 0x6e, 0x0d, 0x27, 0x23, 0xcb, 0x9f, 0xa4, 0x90, 0x61, + 0x12, 0xcb, 0xb8, 0xbe, 0x18, 0x67, 0x38, 0x42, 0x94, 0xc1, 0x28, 0x29, 0x00, 0xf9, 0x36, 0x3d, + 0x92, 0x22, 0x4b, 0xfc, 0xea, 0x7c, 0x6b, 0x62, 0x25, 0x01, 0x6f, 0x55, 0x00, 0x12, 0x45, 0x98, + 0x45, 0x05, 0xa8, 0xb4, 0x24, 0x70, 0x6b, 0x4c, 0xc6, 0x84, 0x2f, 0xad, 0x7c, 0x25, 0xbc, 0xc6, + 0x5f, 0x6b, 0xa0, 0x79, 0xc8, 0xf9, 0xce, 0x18, 0x64, 0x48, 0xdb, 0x01, 0x75, 0x2f, 0x80, 0x38, + 0x76, 0xb1, 0xdf, 0xae, 0x75, 0x6b, 0xbd, 0x86, 0xb3, 0xc6, 0xed, 0x13, 0x5f, 0x43, 0xa0, 0xc9, + 0xd2, 0x09, 0x65, 0x6e, 0x88, 0xa6, 0x28, 0x6c, 0x2f, 0x77, 0x6b, 0xbd, 0xe6, 0xa0, 0x67, 0xfe, + 0x7b, 0x59, 0xcd, 0x8f, 0x52, 0xe8, 0xe5, 0x1b, 0xb6, 0x77, 0x9f, 0x67, 0xfa, 0xd2, 0x3c, 0xd3, + 0xb5, 0x0b, 0x18, 0x85, 0x07, 0x86, 0x42, 0x65, 0x38, 0x80, 0x5b, 0x9f, 0xe4, 0x86, 0x36, 0x02, + 0x1b, 0xdc, 0xc2, 0xf1, 0xd8, 0x4d, 0x50, 0x8a, 0x89, 0xdf, 0x5e, 0xe1, 0x52, 0x3b, 0xa6, 0x28, + 0x96, 0x59, 0x14, 0xcb, 0x3c, 0x92, 0xc5, 0xb4, 0x0d, 0xc9, 0xbd, 0xad, 0x70, 0x57, 0xf9, 0xc6, + 0xcf, 0x7f, 0xe8, 0x35, 0xe7, 0x7e, 0xe1, 0x3d, 0xe5, 0x4e, 0x0d, 0x83, 0xcd, 0x49, 0x3c, 0x24, + 0xb1, 0xaf, 0x08, 0xad, 0xde, 0x25, 0xf4, 0x86, 0x14, 0x7a, 0x28, 0x84, 0x16, 0x09, 0x84, 0xd2, + 0x46, 0xe9, 0x96, 0x52, 0x08, 0x6c, 0x44, 0x70, 0xe6, 0x7a, 0x21, 0xf1, 0xce, 0x5d, 0x3f, 0xc5, + 0x23, 0xd6, 0xfe, 0xdf, 0x2b, 0x6e, 0x69, 0x21, 0x5f, 0x08, 0xad, 0x47, 0x70, 0x76, 0x98, 0x3b, + 0x8f, 0x72, 0x9f, 0xf6, 0x15, 0x58, 0x1f, 0xa5, 0xe4, 0x7b, 0x14, 0xbb, 0x01, 0xca, 0x0f, 0xa4, + 0x7d, 0x8f, 0x8b, 0xec, 0xf2, 0x23, 0xca, 0x5b, 0xc4, 0x94, 0x9d, 0x33, 0xed, 0x9b, 0xc7, 0x1c, + 0x61, 0xef, 0x49, 0x95, 0x2d, 0xa1, 0x72, 0x23, 0xdd, 0x70, 0x5a, 0xc2, 0x16, 0xd8, 0x9c, 0x3e, + 0x84, 0x0c, 0x51, 0x56, 0xd0, 0xaf, 0xbd, 0x2a, 0xfd, 0x8d, 0x74, 0xc3, 0x69, 0x09, 0x5b, 0xd2, + 0x9f, 0x80, 0x26, 0xbf, 0x3a, 0x2e, 0x4d, 0x90, 0x47, 0xdb, 0xf5, 0xee, 0x4a, 0xaf, 0x39, 0xd8, + 0x34, 0xb1, 0x47, 0x07, 0x4f, 0xcc, 0xd3, 0x3c, 0x72, 0x96, 0x20, 0xcf, 0xde, 0xae, 0x5a, 0x48, + 0x81, 0x1b, 0x0e, 0x48, 0x0a, 0x08, 0xd5, 0x0e, 0x40, 0x6b, 0x92, 0x8c, 0x53, 0xe8, 0x23, 0x37, + 0x81, 0x2c, 0x68, 0x37, 0xba, 0x2b, 0xbd, 0x86, 0xfd, 0x70, 0x9e, 0xe9, 0x0f, 0xe4, 0xb9, 0x29, + 0x51, 0xc3, 0x69, 0x4a, 0xf3, 0x14, 0xb2, 0x40, 0x73, 0xc1, 0x0e, 0x0c, 0x43, 0xf2, 0x9d, 0x3b, + 0x49, 0x7c, 0xc8, 0x90, 0x0b, 0x47, 0x0c, 0xa5, 0x2e, 0x9a, 0x25, 0x38, 0xbd, 0x68, 0x83, 0x6e, + 0xad, 0x57, 0xb7, 0xdf, 0x9c, 0x67, 0x7a, 0x57, 0x10, 0xbd, 0x14, 0x6a, 0x38, 0xdb, 0x3c, 0xf6, + 0x19, 0x0f, 0x7d, 0x90, 0x47, 0x3e, 0xe4, 0x01, 0xed, 0x5b, 0xa0, 0xdf, 0x92, 0x15, 0x61, 0x3a, + 0x44, 0x01, 0x9c, 0x62, 0x32, 0x49, 0xdb, 0x4d, 0x2e, 0xf3, 0xf6, 0x3c, 0xd3, 0x1f, 0xbf, 0x54, + 0x46, 0x4d, 0x30, 0x9c, 0xbd, 0x45, 0xb1, 0xa7, 0x4a, 0xf8, 0x60, 0xf5, 0x87, 0x5f, 0xf5, 0x25, + 0xe3, 0xb7, 0x65, 0x70, 0xff, 0x90, 0xc4, 0x14, 0xc5, 0x74, 0x42, 0xc5, 0x6d, 0xb7, 0x41, 0xa3, + 0x1c, 0x38, 0xfc, 0xba, 0xe7, 0xc7, 0xb9, 0xd8, 0x92, 0x9f, 0x16, 0x08, 0xbb, 0x9e, 0x1f, 0xe7, + 0xb3, 0xbc, 0xf3, 0xaa, 0x34, 0xed, 0x7d, 0xb0, 0x9a, 0x12, 0xc2, 0xe4, 0x3c, 0x30, 0x94, 0x6e, + 0xa8, 0x26, 0xd0, 0xb4, 0x6f, 0x3e, 0x45, 0xe9, 0x79, 0x88, 0x1c, 0x42, 0x98, 0xbd, 0x9a, 0xd3, + 0x38, 0x3c, 0x4b, 0xfb, 0xb1, 0x06, 0xb6, 0x62, 0x34, 0x63, 0x6e, 0x39, 0x6c, 0xa9, 0x1b, 0x40, + 0x1a, 0xf0, 0x3b, 0xdf, 0xb2, 0xbf, 0x98, 0x67, 0xfa, 0xeb, 0xa2, 0x06, 0xb7, 0xa1, 0x8c, 0xbf, + 0x33, 0xfd, 0xdd, 0x31, 0x66, 0xc1, 0x64, 0x98, 0xcb, 0xa9, 0x4f, 0x80, 0xb2, 0x0c, 0xf1, 0x90, + 0x5a, 0xc3, 0x0b, 0x86, 0xa8, 0x79, 0x8c, 0x66, 0x76, 0xbe, 0x70, 0xb4, 0x9c, 0xee, 0xf3, 0x92, + 0xed, 0x18, 0xd2, 0x40, 0x96, 0xe9, 0xa7, 0x65, 0xd0, 0x52, 0xab, 0xa7, 0xf5, 0x41, 0x43, 0x34, + 0x76, 0x39, 0x13, 0xed, 0xad, 0x79, 0xa6, 0x6f, 0x8a, 0x9f, 0x55, 0x86, 0x0c, 0xa7, 0x2e, 0xd6, + 0x27, 0xbe, 0x06, 0x41, 0x3d, 0x40, 0xd0, 0x47, 0xa9, 0xdb, 0x97, 0x75, 0x79, 0x7c, 0xd7, 0x9c, + 0x3c, 0xe6, 0x78, 0xbb, 0x73, 0x95, 0xe9, 0x6b, 0x62, 0xdd, 0x9f, 0x67, 0xfa, 0x86, 0x10, 0x29, + 0xc8, 0x0c, 0x67, 0x4d, 0x2c, 0xfb, 0x8a, 0xc4, 0x40, 0xce, 0xc7, 0xff, 0x20, 0x31, 0x78, 0x41, + 0x62, 0x50, 0x4a, 0x0c, 0x64, 0x3d, 0x7e, 0x59, 0x01, 0xf7, 0x04, 0x5a, 0x83, 0x60, 0x9d, 0xe2, + 0x71, 0x8c, 0x7c, 0x57, 0x40, 0x64, 0xcb, 0x74, 0x54, 0x1d, 0xf1, 0x24, 0x9e, 0x71, 0x98, 0x14, + 0xdc, 0xbb, 0xcc, 0xf4, 0x5a, 0x35, 0x05, 0x6e, 0x50, 0x18, 0x4e, 0x8b, 0x2a, 0xd8, 0x7c, 0xc8, + 0x94, 0x67, 0xec, 0x52, 0x54, 0xb4, 0xd5, 0x2d, 0x12, 0xe5, 0xe1, 0x9d, 0x21, 0x66, 0xb7, 0x2b, + 0xfa, 0x1b, 0xe9, 0x86, 0xd3, 0x9a, 0x2a, 0x38, 0xed, 0x1b, 0x20, 0x9e, 0x01, 0xae, 0xcf, 0x87, + 0xd8, 0xca, 0x9d, 0x43, 0xec, 0x91, 0x1c, 0x62, 0xaf, 0x29, 0x8f, 0x4b, 0x99, 0x6f, 0x38, 0xeb, + 0xd2, 0x21, 0xc7, 0x58, 0x08, 0xb4, 0x02, 0x51, 0x35, 0xab, 0x7c, 0x58, 0xee, 0xda, 0xc5, 0xa3, + 0x79, 0xa6, 0xef, 0xdc, 0x54, 0xa9, 0x38, 0x0c, 0xe7, 0xff, 0xd2, 0x59, 0xb5, 0xad, 0xf1, 0x31, + 0xa8, 0x17, 0x0f, 0xac, 0xb6, 0x07, 0x1a, 0xf1, 0x24, 0x42, 0x69, 0x1e, 0xe1, 0x27, 0xb3, 0xea, + 0x54, 0x0e, 0xad, 0x0b, 0x9a, 0x3e, 0x8a, 0x49, 0x84, 0x63, 0x1e, 0x5f, 0xe6, 0x71, 0xd5, 0x65, + 0x7f, 0xfd, 0xfc, 0xaa, 0x53, 0xbb, 0xbc, 0xea, 0xd4, 0xfe, 0xbc, 0xea, 0xd4, 0x9e, 0x5d, 0x77, + 0x96, 0x2e, 0xaf, 0x3b, 0x4b, 0xbf, 0x5f, 0x77, 0x96, 0xbe, 0x3c, 0x52, 0xae, 0x98, 0x47, 0x68, + 0x44, 0xa8, 0xfc, 0xb7, 0x4f, 0xfd, 0x73, 0x6b, 0x56, 0x7d, 0x8a, 0xed, 0x17, 0xdf, 0x62, 0xef, + 0xbc, 0xb7, 0xbf, 0xf8, 0xb1, 0x34, 0xbc, 0xc7, 0x27, 0xca, 0x93, 0x7f, 0x02, 0x00, 0x00, 0xff, + 0xff, 0x8f, 0xde, 0xf9, 0xa9, 0xba, 0x09, 0x00, 0x00, } func (m *ClientState) Marshal() (dAtA []byte, err error) { @@ -429,11 +433,13 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x50 } if len(m.UpgradePath) > 0 { - i -= len(m.UpgradePath) - copy(dAtA[i:], m.UpgradePath) - i = encodeVarintTendermint(dAtA, i, uint64(len(m.UpgradePath))) - i-- - dAtA[i] = 0x4a + for iNdEx := len(m.UpgradePath) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.UpgradePath[iNdEx]) + copy(dAtA[i:], m.UpgradePath[iNdEx]) + i = encodeVarintTendermint(dAtA, i, uint64(len(m.UpgradePath[iNdEx]))) + i-- + dAtA[i] = 0x4a + } } if len(m.ProofSpecs) > 0 { for iNdEx := len(m.ProofSpecs) - 1; iNdEx >= 0; iNdEx-- { @@ -756,9 +762,11 @@ func (m *ClientState) Size() (n int) { n += 1 + l + sovTendermint(uint64(l)) } } - l = len(m.UpgradePath) - if l > 0 { - n += 1 + l + sovTendermint(uint64(l)) + if len(m.UpgradePath) > 0 { + for _, s := range m.UpgradePath { + l = len(s) + n += 1 + l + sovTendermint(uint64(l)) + } } if m.AllowUpdateAfterExpiry { n += 2 @@ -1174,7 +1182,7 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.UpgradePath = string(dAtA[iNdEx:postIndex]) + m.UpgradePath = append(m.UpgradePath, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 10: if wireType != 0 { diff --git a/x/ibc/light-clients/07-tendermint/types/tendermint_test.go b/x/ibc/light-clients/07-tendermint/types/tendermint_test.go index c30a784a5c..4f9b8142bf 100644 --- a/x/ibc/light-clients/07-tendermint/types/tendermint_test.go +++ b/x/ibc/light-clients/07-tendermint/types/tendermint_test.go @@ -1,7 +1,6 @@ package types_test import ( - "fmt" "testing" "time" @@ -20,19 +19,19 @@ import ( ) const ( - chainID = "gaia" - chainIDVersion0 = "gaia-version-0" - chainIDVersion1 = "gaia-version-1" - clientID = "gaiamainnet" - trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 - ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 - maxClockDrift time.Duration = time.Second * 10 + chainID = "gaia" + chainIDRevision0 = "gaia-revision-0" + chainIDRevision1 = "gaia-revision-1" + clientID = "gaiamainnet" + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 + maxClockDrift time.Duration = time.Second * 10 ) var ( height = clienttypes.NewHeight(0, 4) newClientHeight = clienttypes.NewHeight(1, 1) - upgradePath = fmt.Sprintf("%s/%s", "upgrade", "upgradedClient") + upgradePath = []string{"upgrade", "upgradedIBCState"} ) type TendermintTestSuite struct { @@ -82,12 +81,12 @@ func (suite *TendermintTestSuite) SetupTest() { pubKey, err := suite.privVal.GetPubKey() suite.Require().NoError(err) - heightMinus1 := clienttypes.NewHeight(0, height.VersionHeight-1) + heightMinus1 := clienttypes.NewHeight(0, height.RevisionHeight-1) val := tmtypes.NewValidator(pubKey, 10) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) suite.valsHash = suite.valSet.Hash() - suite.header = suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, Time: suite.now}) } diff --git a/x/ibc/light-clients/07-tendermint/types/update.go b/x/ibc/light-clients/07-tendermint/types/update.go index 50adcb1c1f..cee0015a1d 100644 --- a/x/ibc/light-clients/07-tendermint/types/update.go +++ b/x/ibc/light-clients/07-tendermint/types/update.go @@ -22,7 +22,7 @@ import ( // - the client or header provided are not parseable to tendermint types // - the header is invalid // - header height is less than or equal to the trusted header height -// - header version is not equal to trusted header version +// - header revision is not equal to trusted header revision // - header valset commit verification fails // - header timestamp is past the trusting period in relation to the consensus state // - header timestamp is less than or equal to the consensus state timestamp @@ -33,8 +33,8 @@ import ( // If we are updating to a past height, a consensus state is created for that height to be persisted in client store // If we are updating to a future height, the consensus state is created and the client state is updated to reflect // the new latest height -// UpdateClient must only be used to update within a single version, thus header version number and trusted height's version -// number must be the same. To update to a new version, use a separate upgrade path +// UpdateClient must only be used to update within a single revision, thus header revision number and trusted height's revision +// number must be the same. To update to a new revision, use a separate upgrade path // Tendermint client validity checking uses the bisection algorithm described // in the [Tendermint spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md). func (cs ClientState) CheckHeaderAndUpdateState( @@ -94,13 +94,13 @@ func checkValidity( return err } - // UpdateClient only accepts updates with a header at the same version + // UpdateClient only accepts updates with a header at the same revision // as the trusted consensus state - if header.GetHeight().GetVersionNumber() != header.TrustedHeight.VersionNumber { + if header.GetHeight().GetRevisionNumber() != header.TrustedHeight.RevisionNumber { return sdkerrors.Wrapf( ErrInvalidHeaderHeight, - "header height version %d does not match trusted header version %d", - header.GetHeight().GetVersionNumber(), header.TrustedHeight.VersionNumber, + "header height revision %d does not match trusted header revision %d", + header.GetHeight().GetRevisionNumber(), header.TrustedHeight.RevisionNumber, ) } @@ -128,21 +128,21 @@ func checkValidity( } chainID := clientState.GetChainID() - // If chainID is in version format, then set version number of chainID with the version number + // If chainID is in revision format, then set revision number of chainID with the revision number // of the header we are verifying - // This is useful if the update is at a previous version rather than an update to the latest version + // This is useful if the update is at a previous revision rather than an update to the latest revision // of the client. - // The chainID must be set correctly for the previous version before attempting verification. - // Updates for previous versions are not supported if the chainID is not in version format. - if clienttypes.IsVersionFormat(chainID) { - chainID, _ = clienttypes.SetVersionNumber(chainID, header.GetHeight().GetVersionNumber()) + // The chainID must be set correctly for the previous revision before attempting verification. + // Updates for previous revisions are not supported if the chainID is not in revision format. + if clienttypes.IsRevisionFormat(chainID) { + chainID, _ = clienttypes.SetRevisionNumber(chainID, header.GetHeight().GetRevisionNumber()) } // Construct a trusted header using the fields in consensus state // Only Height, Time, and NextValidatorsHash are necessary for verification trustedHeader := tmtypes.Header{ ChainID: chainID, - Height: int64(header.TrustedHeight.VersionHeight), + Height: int64(header.TrustedHeight.RevisionHeight), Time: consState.Timestamp, NextValidatorsHash: consState.NextValidatorsHash, } diff --git a/x/ibc/light-clients/07-tendermint/types/update_test.go b/x/ibc/light-clients/07-tendermint/types/update_test.go index b75d71b827..d9e550ed01 100644 --- a/x/ibc/light-clients/07-tendermint/types/update_test.go +++ b/x/ibc/light-clients/07-tendermint/types/update_test.go @@ -26,15 +26,15 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { altPubKey, err := altPrivVal.GetPubKey() suite.Require().NoError(err) - versionHeight := int64(height.VersionHeight) + revisionHeight := int64(height.RevisionHeight) // create modified heights to use for test-cases - heightPlus1 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight+1) - heightMinus1 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-1) - heightMinus3 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-3) - heightPlus5 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight+5) + heightPlus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight+1) + heightMinus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-1) + heightMinus3 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-3) + heightPlus5 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight+5) - altVal := tmtypes.NewValidator(altPubKey, versionHeight) + altVal := tmtypes.NewValidator(altPubKey, revisionHeight) // Create bothValSet with both suite validator and altVal. Would be valid update bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) @@ -57,9 +57,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "successful update with next height and same validator set", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: true, @@ -67,9 +67,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "successful update with future height and different validator set", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.VersionHeight), height, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -77,9 +77,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "successful update with next height and different validator set", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), bothValSet.Hash()) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, bothValSet, bothValSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, bothValSet, bothValSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -87,20 +87,20 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "successful update for a previous height", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) consStateHeight = heightMinus3 - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.VersionHeight), heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.RevisionHeight), heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: true, }, { - name: "successful update for a previous version", + name: "successful update for a previous revision", setup: func() { - clientState = types.NewClientState(chainIDVersion1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainIDVersion0, int64(height.VersionHeight), heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight), heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -108,29 +108,29 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update with incorrect header chain-id", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader("ethermint", int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader("ethermint", int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, }, { - name: "unsuccessful update to a future version", + name: "unsuccessful update to a future revision", setup: func() { - clientState = types.NewClientState(chainIDVersion0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainIDRevision0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainIDVersion1, 1, height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, }, { - name: "unsuccessful update: header height version and trusted height version mismatch", + name: "unsuccessful update: header height revision and trusted height revision mismatch", setup: func() { - clientState = types.NewClientState(chainIDVersion1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainIDVersion1, 3, height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision1, 3, height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -138,9 +138,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update with next height: update header mismatches nextValSetHash", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: false, @@ -148,9 +148,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update with next height: update header mismatches different nextValSetHash", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), bothValSet.Hash()) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, bothValSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, bothValSet, signers) currentTime = suite.now }, expPass: false, @@ -158,9 +158,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update with future height: too much change in validator set", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.VersionHeight), height, suite.headerTime, altValSet, suite.valSet, altSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, altValSet, suite.valSet, altSigners) currentTime = suite.now }, expPass: false, @@ -168,9 +168,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful updates, passed in incorrect trusted validators for given consensus state", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.VersionHeight), height, suite.headerTime, bothValSet, bothValSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, bothValSet, bothValSet, bothSigners) currentTime = suite.now }, expPass: false, @@ -178,9 +178,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update: trusting period has passed since last client timestamp", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) // make current time pass trusting period from last timestamp on clientstate currentTime = suite.now.Add(trustingPeriod) }, @@ -189,9 +189,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update: header timestamp is past current timestamp", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -199,9 +199,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update: header timestamp is not past last client timestamp", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.clientTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.clientTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -209,11 +209,11 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "header basic validation failed", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) // cause new header to fail validatebasic by changing commit height to mismatch header height - newHeader.SignedHeader.Commit.Height = versionHeight - 1 + newHeader.SignedHeader.Commit.Height = revisionHeight - 1 currentTime = suite.now }, expPass: false, @@ -221,10 +221,10 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "header height < consensus height", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(height.VersionNumber, heightPlus5.VersionHeight), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(height.RevisionNumber, heightPlus5.RevisionHeight), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) // Make new header at height less than latest client state - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, diff --git a/x/ibc/light-clients/07-tendermint/types/upgrade.go b/x/ibc/light-clients/07-tendermint/types/upgrade.go index dcd3cd1a5f..e3f230bbbf 100644 --- a/x/ibc/light-clients/07-tendermint/types/upgrade.go +++ b/x/ibc/light-clients/07-tendermint/types/upgrade.go @@ -2,8 +2,6 @@ package types import ( "fmt" - "net/url" - "strings" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,6 +9,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) // VerifyUpgradeAndUpdateState checks if the upgraded client has been committed by the current client @@ -18,7 +17,7 @@ import ( // in client state that must be the same across all valid Tendermint clients for the new chain. // VerifyUpgrade will return an error if: // - the upgradedClient is not a Tendermint ClientState -// - the lastest height of the client state does not have the same version number or has a greater +// - the lastest height of the client state does not have the same revision number or has a greater // height than the committed client. // - the height of upgraded client is not greater than that of current client // - the latest height of the new client does not match or is greater than the height in committed client @@ -26,102 +25,130 @@ import ( // and ProofSpecs do not match parameters set by committed client func (cs ClientState) VerifyUpgradeAndUpdateState( ctx sdk.Context, cdc codec.BinaryMarshaler, clientStore sdk.KVStore, - upgradedClient exported.ClientState, upgradeHeight exported.Height, proofUpgrade []byte, + upgradedClient exported.ClientState, upgradedConsState exported.ConsensusState, + proofUpgradeClient, proofUpgradeConsState []byte, ) (exported.ClientState, exported.ConsensusState, error) { - if cs.UpgradePath == "" { + if len(cs.UpgradePath) == 0 { return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade client, no upgrade path set") } - upgradePath, err := constructUpgradeMerklePath(cs.UpgradePath, upgradeHeight) - if err != nil { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade client, unescaping key with URL format failed: %v", err) - } - // UpgradeHeight must be in same version as client state height - if cs.GetLatestHeight().GetVersionNumber() != upgradeHeight.GetVersionNumber() { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "version at which upgrade occurs must be same as current client version. expected version %d, got %d", - cs.GetLatestHeight().GetVersionNumber(), upgradeHeight.GetVersionNumber()) - } + // last height of current counterparty chain must be client's latest height + lastHeight := cs.GetLatestHeight() - // UpgradeHeight must be greater than or equal to current client state height - if cs.GetLatestHeight().GetVersionHeight() > upgradeHeight.GetVersionHeight() { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "version height at which upgrade occurs must be greater than or equal to current client height (%d > %d)", - cs.GetLatestHeight().GetVersionHeight(), upgradeHeight.GetVersionHeight(), - ) - } - - if !upgradedClient.GetLatestHeight().GT(cs.GetLatestHeight()) { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "upgraded client height %s must be greater than current client height %s", - upgradedClient.GetLatestHeight(), cs.GetLatestHeight()) - } - - if len(proofUpgrade) == 0 { - return nil, nil, sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "proof of upgrade is empty") - } - - var merkleProof commitmenttypes.MerkleProof - if err := cdc.UnmarshalBinaryBare(proofUpgrade, &merkleProof); err != nil { - return nil, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal merkle proof: %v", err) + if upgradedClient.GetLatestHeight().GetRevisionNumber() <= lastHeight.GetRevisionNumber() { + return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "upgraded client height %s must be at greater revision than current client height %s", + upgradedClient.GetLatestHeight(), lastHeight) } // counterparty chain must commit the upgraded client with all client-customizable fields zeroed out // at the upgrade path specified by current client - committedClient := upgradedClient.ZeroCustomFields() - bz, err := codec.MarshalAny(cdc, committedClient) - if err != nil { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "could not marshal client state: %v", err) + // counterparty must also commit to the upgraded consensus state at a sub-path under the upgrade path specified + tmUpgradeClient, ok := upgradedClient.(*ClientState) + if !ok { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "upgraded client must be Tendermint client. expected: %T got: %T", + &ClientState{}, upgradedClient) + } + tmUpgradeConsState, ok := upgradedConsState.(*ConsensusState) + if !ok { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "upgraded consensus state must be Tendermint consensus state. expected %T, got: %T", + &ConsensusState{}, upgradedConsState) + } + + // unmarshal proofs + var merkleProofClient, merkleProofConsState commitmenttypes.MerkleProof + if err := cdc.UnmarshalBinaryBare(proofUpgradeClient, &merkleProofClient); err != nil { + return nil, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal client merkle proof: %v", err) + } + if err := cdc.UnmarshalBinaryBare(proofUpgradeConsState, &merkleProofConsState); err != nil { + return nil, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal consensus state merkle proof: %v", err) } // Must prove against latest consensus state to ensure we are verifying against latest upgrade plan - // This verifies that upgrade is intended for the provided version, since committed client must exist + // This verifies that upgrade is intended for the provided revision, since committed client must exist // at this consensus state - consState, err := GetConsensusState(clientStore, cdc, upgradeHeight) + consState, err := GetConsensusState(clientStore, cdc, lastHeight) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "could not retrieve consensus state for upgradeHeight") + return nil, nil, sdkerrors.Wrap(err, "could not retrieve consensus state for lastHeight") } if cs.IsExpired(consState.Timestamp, ctx.BlockTime()) { return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidClient, "cannot upgrade an expired client") } - tmCommittedClient, ok := committedClient.(*ClientState) - if !ok { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "upgraded client must be Tendermint client. expected: %T got: %T", - &ClientState{}, upgradedClient) + // Verify client proof + bz, err := codec.MarshalAny(cdc, upgradedClient) + if err != nil { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "could not marshal client state: %v", err) } - - // Relayer chosen client parameters are ignored. - // All chain-chosen parameters come from committed client, all client-chosen parameters - // come from current client. - updatedClientState := NewClientState( - tmCommittedClient.ChainId, cs.TrustLevel, cs.TrustingPeriod, tmCommittedClient.UnbondingPeriod, - cs.MaxClockDrift, tmCommittedClient.LatestHeight, tmCommittedClient.ProofSpecs, tmCommittedClient.UpgradePath, - cs.AllowUpdateAfterExpiry, cs.AllowUpdateAfterMisbehaviour, - ) - - if err := updatedClientState.Validate(); err != nil { - return nil, nil, sdkerrors.Wrap(err, "updated client state failed basic validation") - } - - if err := merkleProof.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradePath, bz); err != nil { + // construct clientState Merkle path + upgradeClientPath := constructUpgradeClientMerklePath(cs.UpgradePath, lastHeight) + if err := merkleProofClient.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradeClientPath, bz); err != nil { return nil, nil, err } - // TODO: Return valid consensus state https://github.com/cosmos/cosmos-sdk/issues/7708 - return updatedClientState, &ConsensusState{}, nil + // Verify consensus state proof + bz, err = codec.MarshalAny(cdc, upgradedConsState) + if err != nil { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "could not marshal consensus state: %v", err) + } + // construct consensus state Merkle path + upgradeConsStatePath := constructUpgradeConsStateMerklePath(cs.UpgradePath, lastHeight) + if err := merkleProofConsState.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradeConsStatePath, bz); err != nil { + return nil, nil, err + } + + // Construct new client state and consensus state + // Relayer chosen client parameters are ignored. + // All chain-chosen parameters come from committed client, all client-chosen parameters + // come from current client. + newClientState := NewClientState( + tmUpgradeClient.ChainId, cs.TrustLevel, cs.TrustingPeriod, tmUpgradeClient.UnbondingPeriod, + cs.MaxClockDrift, tmUpgradeClient.LatestHeight, tmUpgradeClient.ProofSpecs, tmUpgradeClient.UpgradePath, + cs.AllowUpdateAfterExpiry, cs.AllowUpdateAfterMisbehaviour, + ) + + if err := newClientState.Validate(); err != nil { + return nil, nil, sdkerrors.Wrap(err, "updated client state failed basic validation") + } + + // The new consensus state is merely used as a trusted kernel against which headers on the new + // chain can be verified. The root is empty as it cannot be known in advance, thus no proof verification will pass. + // The timestamp and the NextValidatorsHash of the consensus state is the blocktime and NextValidatorsHash + // of the last block committed by the old chain. This will allow the first block of the new chain to be verified against + // the last validators of the old chain so long as it is submitted within the TrustingPeriod of this client. + newConsState := NewConsensusState( + tmUpgradeConsState.Timestamp, commitmenttypes.MerkleRoot{}, tmUpgradeConsState.NextValidatorsHash, + ) + + return newClientState, newConsState, nil } -// construct MerklePath from upgradePath -func constructUpgradeMerklePath(upgradePath string, upgradeHeight exported.Height) (commitmenttypes.MerklePath, error) { - // assume that all keys here are separated by `/` and - // any `/` within a merkle key is correctly escaped - upgradeKeys := strings.Split(upgradePath, "/") - // unescape the last key so that we can append `/{height}` to the last key - lastKey, err := url.PathUnescape(upgradeKeys[len(upgradeKeys)-1]) - if err != nil { - return commitmenttypes.MerklePath{}, err - } - // append upgradeHeight to last key in merkle path +// construct MerklePath for the committed client from upgradePath +func constructUpgradeClientMerklePath(upgradePath []string, lastHeight exported.Height) commitmenttypes.MerklePath { + // copy all elements from upgradePath except final element + clientPath := make([]string, len(upgradePath)-1) + copy(clientPath, upgradePath) + + // append lastHeight and `upgradedClient` to last key of upgradePath and use as lastKey of clientPath // this will create the IAVL key that is used to store client in upgrade store - upgradeKeys[len(upgradeKeys)-1] = fmt.Sprintf("%s/%d", lastKey, upgradeHeight.GetVersionHeight()) - return commitmenttypes.NewMerklePath(upgradeKeys...), nil + lastKey := upgradePath[len(upgradePath)-1] + appendedKey := fmt.Sprintf("%s/%d/%s", lastKey, lastHeight.GetRevisionHeight(), upgradetypes.KeyUpgradedClient) + + clientPath = append(clientPath, appendedKey) + return commitmenttypes.NewMerklePath(clientPath...) +} + +// construct MerklePath for the committed consensus state from upgradePath +func constructUpgradeConsStateMerklePath(upgradePath []string, lastHeight exported.Height) commitmenttypes.MerklePath { + // copy all elements from upgradePath except final element + consPath := make([]string, len(upgradePath)-1) + copy(consPath, upgradePath) + + // append lastHeight and `upgradedClient` to last key of upgradePath and use as lastKey of clientPath + // this will create the IAVL key that is used to store client in upgrade store + lastKey := upgradePath[len(upgradePath)-1] + appendedKey := fmt.Sprintf("%s/%d/%s", lastKey, lastHeight.GetRevisionHeight(), upgradetypes.KeyUpgradedConsState) + + consPath = append(consPath, appendedKey) + return commitmenttypes.NewMerklePath(consPath...) } diff --git a/x/ibc/light-clients/07-tendermint/types/upgrade_test.go b/x/ibc/light-clients/07-tendermint/types/upgrade_test.go index 6bffb19408..c6a40385d2 100644 --- a/x/ibc/light-clients/07-tendermint/types/upgrade_test.go +++ b/x/ibc/light-clients/07-tendermint/types/upgrade_test.go @@ -10,10 +10,11 @@ import ( func (suite *TendermintTestSuite) TestVerifyUpgrade() { var ( - upgradedClient exported.ClientState - upgradeHeight clienttypes.Height - clientA string - proofUpgrade []byte + upgradedClient exported.ClientState + upgradedConsState exported.ConsensusState + lastHeight clienttypes.Height + clientA string + proofUpgradedClient, proofUpgradedConsState []byte ) testCases := []struct { @@ -26,12 +27,16 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -42,52 +47,26 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: true, }, { - name: "successful upgrade with different client chosen parameters set in upgraded client", + name: "unsuccessful upgrade: upgrade height revision height is more than the current client revision height", setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // upgrade Height is 10 blocks from now + lastHeight = clienttypes.NewHeight(10, uint64(suite.chainB.GetContext().BlockHeight()+10)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) - - // change upgradedClient client-specified parameters - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) - - suite.coordinator.CommitBlock(suite.chainB) - err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) - suite.Require().True(found) - - // Previous client-chosen parameters must be the same as upgraded client chosen parameters - tmClient, _ := cs.(*types.ClientState) - oldClient := types.NewClientState(tmClient.ChainId, types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, tmClient.LatestHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) - suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), clientA, oldClient) - - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - }, - expPass: true, - }, - { - name: "unsuccessful upgrade: upgrade height version does not match current client version", - setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(10, uint64(suite.chainB.GetContext().BlockHeight()+1)) - - // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -98,47 +77,26 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, - { - name: "unsuccessful upgrade: upgrade height version height is less than the current client version height", - setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(10, uint64(suite.chainB.GetContext().BlockHeight()-1)) - - // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) - - // commit upgrade store changes and update clients - - suite.coordinator.CommitBlock(suite.chainB) - err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) - suite.Require().True(found) - - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - }, - expPass: false, - }, - { name: "unsuccessful upgrade: chain-specified parameters do not match committed client", setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // change upgradedClient client-specified parameters upgradedClient = types.NewClientState("wrongchainID", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, true) @@ -150,7 +108,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -158,12 +117,17 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { name: "unsuccessful upgrade: client-specified parameters do not match previous client", setup: func() { - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // change upgradedClient client-specified parameters - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, upgradeHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) suite.coordinator.CommitBlock(suite.chainB) err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) @@ -172,39 +136,124 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, { - name: "unsuccessful upgrade: proof is empty", + name: "unsuccessful upgrade: relayer-submitted consensus state does not match counterparty-committed consensus state", setup: func() { + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - proofUpgrade = []byte{} - }, - expPass: false, - }, - { - name: "unsuccessful upgrade: proof unmarshal failed", - setup: func() { - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - proofUpgrade = []byte("proof") - }, - expPass: false, - }, - { - name: "unsuccessful upgrade: proof verification failed", - setup: func() { - // create but do not store upgraded client - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + // zero custom fields and store in upgrade store + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + + // change submitted upgradedConsensusState + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("maliciousValidators"), + } + + // commit upgrade store changes and update clients + + suite.coordinator.CommitBlock(suite.chainB) + err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) + suite.Require().NoError(err) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: client proof unmarshal failed", + setup: func() { + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + + proofUpgradedClient = []byte("proof") + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: consensus state proof unmarshal failed", + setup: func() { + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + + proofUpgradedConsState = []byte("proof") + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: client proof verification failed", + setup: func() { + // create but do not store upgraded client + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // upgrade Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: consensus state proof verification failed", + setup: func() { + // create but do not store upgraded client + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // upgrade Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -213,12 +262,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -229,41 +281,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) // SetClientState with empty upgrade path tmClient, _ := cs.(*types.ClientState) - tmClient.UpgradePath = "" - suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), clientA, tmClient) - }, - expPass: false, - }, - { - name: "unsuccessful upgrade: upgrade path is malformed and cannot be correctly unescaped", - setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - - // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) - - // commit upgrade store changes and update clients - - suite.coordinator.CommitBlock(suite.chainB) - err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) - suite.Require().True(found) - - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - - // SetClientState with nil upgrade path - tmClient, _ := cs.(*types.ClientState) - tmClient.UpgradePath = "upgraded%Client" + tmClient.UpgradePath = []string{""} suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), clientA, tmClient) }, expPass: false, @@ -273,12 +296,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -289,7 +315,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -298,12 +325,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+100)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+100)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -314,7 +344,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -322,9 +353,13 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { name: "unsuccessful upgrade: client is expired", setup: func() { - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -338,7 +373,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -347,12 +383,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -363,7 +402,39 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: final client is not valid", + setup: func() { + + // new client has smaller unbonding period such that old trusting period is no longer valid + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // upgrade Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + // zero custom fields and store in upgrade store + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) + + // commit upgrade store changes and update clients + + suite.coordinator.CommitBlock(suite.chainB) + err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) + suite.Require().NoError(err) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -382,13 +453,17 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs := suite.chainA.GetClientState(clientA) clientStore := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA) + // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient + upgradedClient = upgradedClient.ZeroCustomFields() + clientState, consensusState, err := cs.VerifyUpgradeAndUpdateState( suite.chainA.GetContext(), suite.cdc, clientStore, upgradedClient, - upgradeHeight, - proofUpgrade, + upgradedConsState, + proofUpgradedClient, + proofUpgradedConsState, ) if tc.expPass { diff --git a/x/ibc/light-clients/09-localhost/types/client_state.go b/x/ibc/light-clients/09-localhost/types/client_state.go index 32b799fccd..b828aa029a 100644 --- a/x/ibc/light-clients/09-localhost/types/client_state.go +++ b/x/ibc/light-clients/09-localhost/types/client_state.go @@ -58,8 +58,8 @@ func (cs ClientState) Validate() error { if strings.TrimSpace(cs.ChainId) == "" { return sdkerrors.Wrap(sdkerrors.ErrInvalidChainID, "chain id cannot be blank") } - if cs.Height.VersionHeight == 0 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "local version height cannot be zero") + if cs.Height.RevisionHeight == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "local revision height cannot be zero") } return nil } @@ -80,8 +80,8 @@ func (cs *ClientState) CheckHeaderAndUpdateState( ) (exported.ClientState, exported.ConsensusState, error) { // use the chain ID from context since the localhost client is from the running chain (i.e self). cs.ChainId = ctx.ChainID() - version := clienttypes.ParseChainID(cs.ChainId) - cs.Height = clienttypes.NewHeight(version, uint64(ctx.BlockHeight())) + revision := clienttypes.ParseChainID(cs.ChainId) + cs.Height = clienttypes.NewHeight(revision, uint64(ctx.BlockHeight())) return cs, nil, nil } @@ -105,7 +105,7 @@ func (cs ClientState) CheckProposedHeaderAndUpdateState( // VerifyUpgradeAndUpdateState returns an error since localhost cannot be upgraded func (cs ClientState) VerifyUpgradeAndUpdateState( _ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, - _ exported.ClientState, _ exported.Height, _ []byte, + _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, ) (exported.ClientState, exported.ConsensusState, error) { return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade localhost client") } diff --git a/x/ibc/light-clients/09-localhost/types/client_state_test.go b/x/ibc/light-clients/09-localhost/types/client_state_test.go index a4443867d7..17555b9453 100644 --- a/x/ibc/light-clients/09-localhost/types/client_state_test.go +++ b/x/ibc/light-clients/09-localhost/types/client_state_test.go @@ -123,8 +123,8 @@ func (suite *LocalhostTestSuite) TestCheckHeaderAndUpdateState() { clientState := types.NewClientState("chainID", clientHeight) cs, _, err := clientState.CheckHeaderAndUpdateState(suite.ctx, nil, nil, nil) suite.Require().NoError(err) - suite.Require().Equal(uint64(0), cs.GetLatestHeight().GetVersionNumber()) - suite.Require().Equal(suite.ctx.BlockHeight(), int64(cs.GetLatestHeight().GetVersionHeight())) + suite.Require().Equal(uint64(0), cs.GetLatestHeight().GetRevisionNumber()) + suite.Require().Equal(suite.ctx.BlockHeight(), int64(cs.GetLatestHeight().GetRevisionHeight())) suite.Require().Equal(suite.ctx.BlockHeader().ChainID, clientState.ChainId) } diff --git a/x/ibc/testing/chain.go b/x/ibc/testing/chain.go index 2d3172b938..b63e72c3e9 100644 --- a/x/ibc/testing/chain.go +++ b/x/ibc/testing/chain.go @@ -67,7 +67,7 @@ var ( TestHash = tmhash.Sum([]byte("TESTING HASH")) TestCoin = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) - UpgradePath = fmt.Sprintf("%s/%s", "upgrade", "upgradedClient") + UpgradePath = []string{"upgrade", "upgradedIBCState"} ConnectionVersion = connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions())[0] @@ -187,12 +187,12 @@ func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) { proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof) require.NoError(chain.t, err) - version := clienttypes.ParseChainID(chain.ChainID) + revision := clienttypes.ParseChainID(chain.ChainID) // proof height + 1 is returned as the proof created corresponds to the height the proof // was created in the IAVL tree. Tendermint and subsequently the clients that rely on it // have heights 1 above the IAVL tree. Thus we return proof height + 1 - return proof, clienttypes.NewHeight(version, uint64(res.Height)+1) + return proof, clienttypes.NewHeight(revision, uint64(res.Height)+1) } // QueryUpgradeProof performs an abci query with the given key and returns the proto encoded merkle proof @@ -211,12 +211,12 @@ func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, cl proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof) require.NoError(chain.t, err) - version := clienttypes.ParseChainID(chain.ChainID) + revision := clienttypes.ParseChainID(chain.ChainID) // proof height + 1 is returned as the proof created corresponds to the height the proof // was created in the IAVL tree. Tendermint and subsequently the clients that rely on it // have heights 1 above the IAVL tree. Thus we return proof height + 1 - return proof, clienttypes.NewHeight(version, uint64(res.Height+1)) + return proof, clienttypes.NewHeight(revision, uint64(res.Height+1)) } // QueryClientStateProof performs and abci query for a client state @@ -388,7 +388,7 @@ func (chain *TestChain) AddTestConnection(clientID, counterpartyClientID string) // created given a clientID and counterparty clientID. The connection id // format: -conn func (chain *TestChain) ConstructNextTestConnection(clientID, counterpartyClientID string) *TestConnection { - connectionID := fmt.Sprintf("%s-%s%d", chain.ChainID, ConnectionIDPrefix, len(chain.Connections)) + connectionID := connectiontypes.FormatConnectionIdentifier(uint64(len(chain.Connections))) return &TestConnection{ ID: connectionID, ClientID: clientID, @@ -407,6 +407,34 @@ func (chain *TestChain) GetFirstTestConnection(clientID, counterpartyClientID st return chain.ConstructNextTestConnection(clientID, counterpartyClientID) } +// AddTestChannel appends a new TestChannel which contains references to the port and channel ID +// used for channel creation and interaction. See 'NextTestChannel' for channel ID naming format. +func (chain *TestChain) AddTestChannel(conn *TestConnection, portID string) TestChannel { + channel := chain.NextTestChannel(conn, portID) + conn.Channels = append(conn.Channels, channel) + return channel +} + +// NextTestChannel returns the next test channel to be created on this connection, but does not +// add it to the list of created channels. This function is expected to be used when the caller +// has not created the associated channel in app state, but would still like to refer to the +// non-existent channel usually to test for its non-existence. +// +// channel ID format: -chan +// +// The port is passed in by the caller. +func (chain *TestChain) NextTestChannel(conn *TestConnection, portID string) TestChannel { + nextChanSeq := chain.App.IBCKeeper.ChannelKeeper.GetNextChannelSequence(chain.GetContext()) + channelID := channeltypes.FormatChannelIdentifier(nextChanSeq) + return TestChannel{ + PortID: portID, + ID: channelID, + ClientID: conn.ClientID, + CounterpartyClientID: conn.CounterpartyClientID, + Version: conn.NextChannelVersion, + } +} + // ConstructMsgCreateClient constructs a message to create a new client state (tendermint or solomachine). // NOTE: a solo machine client will be created with an empty diversifier. func (chain *TestChain) ConstructMsgCreateClient(counterparty *TestChain, clientID string, clientType string) *clienttypes.MsgCreateClient { @@ -482,13 +510,13 @@ func (chain *TestChain) ConstructUpdateTMClientHeader(counterparty *TestChain, c // since the last trusted validators for a header at height h // is the NextValidators at h+1 committed to in header h by // NextValidatorsHash - tmTrustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight.VersionHeight + 1)) + tmTrustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight.RevisionHeight + 1)) if !ok { return nil, sdkerrors.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) } } // inject trusted fields into last header - // for now assume version number is 0 + // for now assume revision number is 0 header.TrustedHeight = trustedHeight trustedVals, err := tmTrustedVals.ToProto() @@ -613,8 +641,8 @@ func (chain *TestChain) ConnectionOpenInit( connection, counterpartyConnection *TestConnection, ) error { msg := connectiontypes.NewMsgConnectionOpenInit( - connection.ID, connection.ClientID, - counterpartyConnection.ID, connection.CounterpartyClientID, + connection.ClientID, + connection.CounterpartyClientID, counterparty.GetPrefix(), DefaultOpenInitVersion, chain.SenderAccount.GetAddress(), ) @@ -634,7 +662,7 @@ func (chain *TestChain) ConnectionOpenTry( proofConsensus, consensusHeight := counterparty.QueryConsensusStateProof(counterpartyConnection.ClientID) msg := connectiontypes.NewMsgConnectionOpenTry( - connection.ID, connection.ID, connection.ClientID, // testing doesn't use flexible selection + "", connection.ClientID, // does not support handshake continuation counterpartyConnection.ID, counterpartyConnection.ClientID, counterpartyClient, counterparty.GetPrefix(), []*connectiontypes.Version{ConnectionVersion}, proofInit, proofClient, proofConsensus, @@ -756,9 +784,9 @@ func (chain *TestChain) ChanOpenInit( connectionID string, ) error { msg := channeltypes.NewMsgChannelOpenInit( - ch.PortID, ch.ID, + ch.PortID, ch.Version, order, []string{connectionID}, - counterparty.PortID, counterparty.ID, + counterparty.PortID, chain.SenderAccount.GetAddress(), ) return chain.sendMsgs(msg) @@ -774,10 +802,9 @@ func (chain *TestChain) ChanOpenTry( proof, height := counterparty.QueryProof(host.ChannelKey(counterpartyCh.PortID, counterpartyCh.ID)) msg := channeltypes.NewMsgChannelOpenTry( - ch.PortID, ch.ID, ch.ID, // testing doesn't use flexible selection + ch.PortID, "", // does not support handshake continuation ch.Version, order, []string{connectionID}, - counterpartyCh.PortID, counterpartyCh.ID, - counterpartyCh.Version, + counterpartyCh.PortID, counterpartyCh.ID, counterpartyCh.Version, proof, height, chain.SenderAccount.GetAddress(), ) diff --git a/x/ibc/testing/coordinator.go b/x/ibc/testing/coordinator.go index b1c6e99d3f..aecdcd4b70 100644 --- a/x/ibc/testing/coordinator.go +++ b/x/ibc/testing/coordinator.go @@ -394,6 +394,46 @@ func (coord *Coordinator) ConnOpenInit( return sourceConnection, counterpartyConnection, nil } +// ConnOpenInitOnBothChains initializes a connection on the source chain with the state INIT +// using the OpenInit handshake call. +func (coord *Coordinator) ConnOpenInitOnBothChains( + source, counterparty *TestChain, + clientID, counterpartyClientID string, +) (*TestConnection, *TestConnection, error) { + sourceConnection := source.AddTestConnection(clientID, counterpartyClientID) + counterpartyConnection := counterparty.AddTestConnection(counterpartyClientID, clientID) + + // initialize connection on source + if err := source.ConnectionOpenInit(counterparty, sourceConnection, counterpartyConnection); err != nil { + return sourceConnection, counterpartyConnection, err + } + coord.IncrementTime() + + // initialize connection on counterparty + if err := counterparty.ConnectionOpenInit(source, counterpartyConnection, sourceConnection); err != nil { + return sourceConnection, counterpartyConnection, err + } + coord.IncrementTime() + + // update counterparty client on source connection + if err := coord.UpdateClient( + source, counterparty, + clientID, exported.Tendermint, + ); err != nil { + return sourceConnection, counterpartyConnection, err + } + + // update source client on counterparty connection + if err := coord.UpdateClient( + counterparty, source, + counterpartyClientID, exported.Tendermint, + ); err != nil { + return sourceConnection, counterpartyConnection, err + } + + return sourceConnection, counterpartyConnection, nil +} + // ConnOpenTry initializes a connection on the source chain with the state TRYOPEN // using the OpenTry handshake call. func (coord *Coordinator) ConnOpenTry( @@ -461,8 +501,8 @@ func (coord *Coordinator) ChanOpenInit( sourcePortID, counterpartyPortID string, order channeltypes.Order, ) (TestChannel, TestChannel, error) { - sourceChannel := connection.AddTestChannel(sourcePortID) - counterpartyChannel := counterpartyConnection.AddTestChannel(counterpartyPortID) + sourceChannel := source.AddTestChannel(connection, sourcePortID) + counterpartyChannel := counterparty.AddTestChannel(counterpartyConnection, counterpartyPortID) // NOTE: only creation of a capability for a transfer or mock port is supported // Other applications must bind to the port in InitGenesis or modify this code. @@ -494,8 +534,8 @@ func (coord *Coordinator) ChanOpenInitOnBothChains( sourcePortID, counterpartyPortID string, order channeltypes.Order, ) (TestChannel, TestChannel, error) { - sourceChannel := connection.AddTestChannel(sourcePortID) - counterpartyChannel := counterpartyConnection.AddTestChannel(counterpartyPortID) + sourceChannel := source.AddTestChannel(connection, sourcePortID) + counterpartyChannel := counterparty.AddTestChannel(counterpartyConnection, counterpartyPortID) // NOTE: only creation of a capability for a transfer or mock port is supported // Other applications must bind to the port in InitGenesis or modify this code. diff --git a/x/ibc/testing/solomachine.go b/x/ibc/testing/solomachine.go index 03fe887b85..52621f8ad1 100644 --- a/x/ibc/testing/solomachine.go +++ b/x/ibc/testing/solomachine.go @@ -102,7 +102,7 @@ func (solo *Solomachine) ConsensusState() *solomachinetypes.ConsensusState { } } -// GetHeight returns an exported.Height with Sequence as VersionHeight +// GetHeight returns an exported.Height with Sequence as RevisionHeight func (solo *Solomachine) GetHeight() exported.Height { return clienttypes.NewHeight(0, solo.Sequence) } diff --git a/x/ibc/testing/types.go b/x/ibc/testing/types.go index c71b0ebd97..16cda6216b 100644 --- a/x/ibc/testing/types.go +++ b/x/ibc/testing/types.go @@ -1,7 +1,7 @@ package ibctesting import ( - "fmt" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" ) // TestConnection is a testing helper struct to keep track of the connectionID, source clientID, @@ -15,33 +15,6 @@ type TestConnection struct { Channels []TestChannel } -// AddTestChannel appends a new TestChannel which contains references to the port and channel ID -// used for channel creation and interaction. See 'NextTestChannel' for channel ID naming format. -func (conn *TestConnection) AddTestChannel(portID string) TestChannel { - channel := conn.NextTestChannel(portID) - conn.Channels = append(conn.Channels, channel) - return channel -} - -// NextTestChannel returns the next test channel to be created on this connection, but does not -// add it to the list of created channels. This function is expected to be used when the caller -// has not created the associated channel in app state, but would still like to refer to the -// non-existent channel usually to test for its non-existence. -// -// channel ID format: -chan -// -// The port is passed in by the caller. -func (conn *TestConnection) NextTestChannel(portID string) TestChannel { - channelID := fmt.Sprintf("%s-%s%d", conn.ID, ChannelIDPrefix, len(conn.Channels)) - return TestChannel{ - PortID: portID, - ID: channelID, - ClientID: conn.ClientID, - CounterpartyClientID: conn.CounterpartyClientID, - Version: conn.NextChannelVersion, - } -} - // FirstOrNextTestChannel returns the first test channel if it exists, otherwise it // returns the next test channel to be created. This function is expected to be used // when the caller does not know if the channel has or has not been created in app @@ -50,7 +23,13 @@ func (conn *TestConnection) FirstOrNextTestChannel(portID string) TestChannel { if len(conn.Channels) > 0 { return conn.Channels[0] } - return conn.NextTestChannel(portID) + return TestChannel{ + PortID: portID, + ID: channeltypes.FormatChannelIdentifier(0), + ClientID: conn.ClientID, + CounterpartyClientID: conn.CounterpartyClientID, + Version: conn.NextChannelVersion, + } } // TestChannel is a testing helper struct to keep track of the portID and channelID diff --git a/x/upgrade/abci.go b/x/upgrade/abci.go index 71a2609d22..9ca8f1a3f9 100644 --- a/x/upgrade/abci.go +++ b/x/upgrade/abci.go @@ -10,6 +10,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" ) // BeginBlock will check if there is a scheduled plan and if it is ready to be executed. @@ -28,6 +30,19 @@ func BeginBlocker(k keeper.Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) { return } + // Once we are at the last block this chain will commit, set the upgraded consensus state + // so that IBC clients can use the last NextValidatorsHash as a trusted kernel for verifying + // headers on the next version of the chain. + // Set the time to the last block time of the current chain. + // In order for a client to upgrade successfully, the first block of the new chain must be committed + // within the trusting period of the last block time on this chain. + if plan.IsIBCPlan() && ctx.BlockHeight() == plan.Height-1 { + upgradedConsState := &ibctmtypes.ConsensusState{ + Timestamp: ctx.BlockTime(), + NextValidatorsHash: ctx.BlockHeader().NextValidatorsHash, + } + k.SetUpgradedConsensusState(ctx, ctx.BlockHeight(), upgradedConsState) + } // To make sure clear upgrade is executed at the same block if plan.ShouldExecute(ctx) { // If skip upgrade has been set for current height, we clear the upgrade plan diff --git a/x/upgrade/abci_test.go b/x/upgrade/abci_test.go index e2dd5c8a12..20ca573d13 100644 --- a/x/upgrade/abci_test.go +++ b/x/upgrade/abci_test.go @@ -120,6 +120,58 @@ func TestCanOverwriteScheduleUpgrade(t *testing.T) { VerifyDoUpgrade(t) } +func VerifyDoIBCLastBlock(t *testing.T) { + t.Log("Verify that chain committed to consensus state on the last height it will commit") + nextValsHash := []byte("nextValsHash") + newCtx := s.ctx.WithBlockHeader(tmproto.Header{ + Height: s.ctx.BlockHeight(), + NextValidatorsHash: nextValsHash, + }) + + req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} + s.module.BeginBlock(newCtx, req) + + consState, err := s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()) + require.NoError(t, err) + require.Equal(t, &ibctmtypes.ConsensusState{Timestamp: newCtx.BlockTime(), NextValidatorsHash: nextValsHash}, consState) +} + +func VerifyDoIBCUpgrade(t *testing.T) { + t.Log("Verify that a panic happens at the upgrade time/height") + newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now()) + + // Check IBC state is set before upgrade using last height: s.ctx.BlockHeight() + cs, err := s.keeper.GetUpgradedClient(newCtx, s.ctx.BlockHeight()) + require.NoError(t, err, "could not retrieve upgraded client before upgrade plan is applied") + require.NotNil(t, cs, "IBC client is nil before upgrade") + + consState, err := s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()) + require.NoError(t, err, "could not retrieve upgraded consensus state before upgrade plan is applied") + require.NotNil(t, consState, "IBC consensus state is nil before upgrade") + + req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} + require.Panics(t, func() { + s.module.BeginBlock(newCtx, req) + }) + + t.Log("Verify that the upgrade can be successfully applied with a handler") + s.keeper.SetUpgradeHandler("test", func(ctx sdk.Context, plan types.Plan) {}) + require.NotPanics(t, func() { + s.module.BeginBlock(newCtx, req) + }) + + VerifyCleared(t, newCtx) + + // Check IBC state is cleared after upgrade using last height: s.ctx.BlockHeight() + cs, err = s.keeper.GetUpgradedClient(newCtx, s.ctx.BlockHeight()) + require.Error(t, err, "retrieved upgraded client after upgrade plan is applied") + require.Nil(t, cs, "IBC client is not-nil after upgrade") + + consState, err = s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()) + require.Error(t, err, "retrieved upgraded consensus state after upgrade plan is applied") + require.Nil(t, consState, "IBC consensus state is not-nil after upgrade") +} + func VerifyDoUpgrade(t *testing.T) { t.Log("Verify that a panic happens at the upgrade time/height") newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now()) @@ -414,6 +466,27 @@ func TestUpgradeWithoutSkip(t *testing.T) { VerifyDone(t, s.ctx, "test") } +func TestIBCUpgradeWithoutSkip(t *testing.T) { + s := setupTest(10, map[int64]bool{}) + cs, err := clienttypes.PackClientState(&ibctmtypes.ClientState{}) + require.NoError(t, err) + err = s.handler(s.ctx, &types.SoftwareUpgradeProposal{ + Title: "prop", + Plan: types.Plan{ + Name: "test", + Height: s.ctx.BlockHeight() + 1, + UpgradedClientState: cs, + }, + }) + require.Nil(t, err) + + t.Log("Verify if last height stores consensus state") + VerifyDoIBCLastBlock(t) + + VerifyDoUpgrade(t) + VerifyDone(t, s.ctx, "test") +} + func TestDumpUpgradeInfoToFile(t *testing.T) { s := setupTest(10, map[int64]bool{}) diff --git a/x/upgrade/keeper/grpc_query.go b/x/upgrade/keeper/grpc_query.go index ba7bd959c6..26e7860c86 100644 --- a/x/upgrade/keeper/grpc_query.go +++ b/x/upgrade/keeper/grpc_query.go @@ -4,6 +4,7 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) @@ -32,3 +33,22 @@ func (k Keeper) AppliedPlan(c context.Context, req *types.QueryAppliedPlanReques return &types.QueryAppliedPlanResponse{Height: applied}, nil } + +// UpgradedConsensusState implements the Query/UpgradedConsensusState gRPC method +func (k Keeper) UpgradedConsensusState(c context.Context, req *types.QueryUpgradedConsensusStateRequest) (*types.QueryUpgradedConsensusStateResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + + consState, err := k.GetUpgradedConsensusState(ctx, req.LastHeight) + if err != nil { + return nil, err + } + + cs, err := clienttypes.PackConsensusState(consState) + if err != nil { + return nil, err + } + + return &types.QueryUpgradedConsensusStateResponse{ + UpgradedConsensusState: cs, + }, nil +} diff --git a/x/upgrade/keeper/keeper.go b/x/upgrade/keeper/keeper.go index cc9965f7a7..861fd0393a 100644 --- a/x/upgrade/keeper/keeper.go +++ b/x/upgrade/keeper/keeper.go @@ -8,8 +8,6 @@ import ( "os" "path" "path/filepath" - "strconv" - "strings" "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" @@ -76,39 +74,33 @@ func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error { } store := ctx.KVStore(k.storeKey) + + // clear any old IBC state stored by previous plan + oldPlan, exists := k.GetUpgradePlan(ctx) + if exists && oldPlan.IsIBCPlan() { + k.ClearIBCState(ctx, oldPlan.Height-1) + } + bz := k.cdc.MustMarshalBinaryBare(&plan) store.Set(types.PlanKey(), bz) - if plan.UpgradedClientState == nil { - // if latest UpgradedClientState is nil, but upgraded client exists in store, - // then delete client state from store. - _, height, _ := k.GetUpgradedClient(ctx) - if height != 0 { - store.Delete(types.UpgradedClientKey(height)) + if plan.IsIBCPlan() { + // Set UpgradedClientState in store + clientState, err := clienttypes.UnpackClientState(plan.UpgradedClientState) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not unpack clientstate: %v", err) } - return nil + // sets the new upgraded client in last height committed on this chain is at plan.Height - 1, + // since the chain will panic at plan.Height and new chain will resume at plan.Height + return k.SetUpgradedClient(ctx, plan.Height-1, clientState) } - - // Set UpgradedClientState in store - clientState, err := clienttypes.UnpackClientState(plan.UpgradedClientState) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not unpack clientstate: %v", err) - } - // deletes any previously stored upgraded client and sets the new upgraded client in - return k.SetUpgradedClient(ctx, plan.Height, clientState) + return nil } -// SetUpgradedClient sets the expected upgraded client for the next version of this chain -func (k Keeper) SetUpgradedClient(ctx sdk.Context, upgradeHeight int64, cs ibcexported.ClientState) error { +// SetUpgradedClient sets the expected upgraded client for the next version of this chain at the last height the current chain will commit. +func (k Keeper) SetUpgradedClient(ctx sdk.Context, lastHeight int64, cs ibcexported.ClientState) error { store := ctx.KVStore(k.storeKey) - // delete any previously stored upgraded client before setting a new one - // since there should only ever be one upgraded client in the store at any given time - _, setHeight, _ := k.GetUpgradedClient(ctx) - if setHeight != 0 { - store.Delete(types.UpgradedClientKey(setHeight)) - } - // zero out any custom fields before setting cs = cs.ZeroCustomFields() bz, err := clienttypes.MarshalClientState(k.cdc, cs) @@ -116,49 +108,52 @@ func (k Keeper) SetUpgradedClient(ctx sdk.Context, upgradeHeight int64, cs ibcex return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not marshal clientstate: %v", err) } - store.Set(types.UpgradedClientKey(upgradeHeight), bz) + store.Set(types.UpgradedClientKey(lastHeight), bz) return nil } // GetUpgradedClient gets the expected upgraded client for the next version of this chain -// along with the planned upgrade height -// Since there is only ever one upgraded client in store, we do not need to know key beforehand -func (k Keeper) GetUpgradedClient(ctx sdk.Context) (ibcexported.ClientState, int64, error) { +func (k Keeper) GetUpgradedClient(ctx sdk.Context, height int64) (ibcexported.ClientState, error) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte(types.KeyUpgradedClient)) - var ( - count, height int - bz []byte - ) - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - count++ - // we must panic if the upgraded clients in store is ever more than one since - // that would break upgrade functionality and chain must halt and fix issue manually - if count > 1 { - panic("more than 1 upgrade client stored in state") - } - - keySplit := strings.Split(string(iterator.Key()), "/") - var err error - height, err = strconv.Atoi(keySplit[len(keySplit)-1]) - if err != nil { - return nil, 0, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not parse upgrade height from key: %s", err) - } - - bz = iterator.Value() - } - - if count == 0 { - return nil, 0, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "upgrade client not found in store") + bz := store.Get(types.UpgradedClientKey(height)) + if len(bz) == 0 { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "upgraded client not found in store for height %d", height) } clientState, err := clienttypes.UnmarshalClientState(k.cdc, bz) if err != nil { - return nil, 0, err + return nil, err } - return clientState, int64(height), nil + return clientState, nil +} + +// SetUpgradedConsensusState set the expected upgraded consensus state for the next version of this chain +// using the last height committed on this chain. +func (k Keeper) SetUpgradedConsensusState(ctx sdk.Context, lastHeight int64, cs ibcexported.ConsensusState) error { + store := ctx.KVStore(k.storeKey) + bz, err := clienttypes.MarshalConsensusState(k.cdc, cs) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not marshal consensus state: %v", err) + } + + store.Set(types.UpgradedConsStateKey(lastHeight), bz) + return nil +} + +// GetUpgradedConsensusState set the expected upgraded consensus state for the next version of this chain +func (k Keeper) GetUpgradedConsensusState(ctx sdk.Context, lastHeight int64) (ibcexported.ConsensusState, error) { + store := ctx.KVStore(k.storeKey) + + bz := store.Get(types.UpgradedConsStateKey(lastHeight)) + if len(bz) == 0 { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "upgraded consensus state not found in store for height: %d", lastHeight) + } + consState, err := clienttypes.UnmarshalConsensusState(k.cdc, bz) + if err != nil { + return nil, err + } + return consState, nil } // GetDoneHeight returns the height at which the given upgrade was executed @@ -172,6 +167,14 @@ func (k Keeper) GetDoneHeight(ctx sdk.Context, name string) int64 { return int64(binary.BigEndian.Uint64(bz)) } +// ClearIBCState clears any planned IBC state +func (k Keeper) ClearIBCState(ctx sdk.Context, lastHeight int64) { + // delete IBC client and consensus state from store if this is IBC plan + store := ctx.KVStore(k.storeKey) + store.Delete(types.UpgradedClientKey(lastHeight)) + store.Delete(types.UpgradedConsStateKey(lastHeight)) +} + // ClearUpgradePlan clears any schedule upgrade func (k Keeper) ClearUpgradePlan(ctx sdk.Context) { store := ctx.KVStore(k.storeKey) @@ -219,6 +222,11 @@ func (k Keeper) ApplyUpgrade(ctx sdk.Context, plan types.Plan) { handler(ctx, plan) + // Must clear IBC state after upgrade is applied as it is stored separately from the upgrade plan. + // This will prevent resubmission of upgrade msg after upgrade is already completed. + if plan.IsIBCPlan() { + k.ClearIBCState(ctx, plan.Height-1) + } k.ClearUpgradePlan(ctx) k.setDone(ctx, plan.Name) } diff --git a/x/upgrade/keeper/keeper_test.go b/x/upgrade/keeper/keeper_test.go index c53a2d3857..f22edc00d6 100644 --- a/x/upgrade/keeper/keeper_test.go +++ b/x/upgrade/keeper/keeper_test.go @@ -235,13 +235,12 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { if tc.expPass { s.Require().NoError(err, "valid test case failed") if tc.plan.UpgradedClientState != nil { - got, height, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx) + got, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.plan.Height-1) s.Require().NoError(err) - s.Require().Equal(tc.plan.Height, height, "upgradedClient not stored at correct upgrade height") s.Require().Equal(clientState, got, "upgradedClient not equal to expected value") } else { // check that upgraded client is empty if latest plan does not specify an upgraded client - got, _, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx) + got, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.plan.Height-1) s.Require().Error(err) s.Require().Nil(got) } @@ -255,36 +254,24 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { func (s *KeeperTestSuite) TestSetUpgradedClient() { var ( clientState ibcexported.ClientState - height int64 ) cases := []struct { name string + height int64 setup func() exists bool }{ { name: "no upgraded client exists", + height: 10, setup: func() {}, exists: false, }, { - name: "success", + name: "success", + height: 10, setup: func() { clientState = &ibctmtypes.ClientState{ChainId: "gaiachain"} - height = 10 - - s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, clientState) - }, - exists: true, - }, - { - name: "successful overwrite", - setup: func() { - clientState = &ibctmtypes.ClientState{ChainId: "gaiachain"} - altCs := &ibctmtypes.ClientState{ChainId: "ethermint"} - height = 10 - - s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 50, altCs) s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, clientState) }, exists: true, @@ -298,14 +285,12 @@ func (s *KeeperTestSuite) TestSetUpgradedClient() { // setup test case tc.setup() - gotCs, gotHeight, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx) + gotCs, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.height) if tc.exists { s.Require().Equal(clientState, gotCs, "valid case: %s did not retrieve correct client state", tc.name) - s.Require().Equal(height, gotHeight, "valid case: %s did not retrieve correct upgrade height", tc.name) s.Require().NoError(err, "valid case: %s returned error") } else { s.Require().Nil(gotCs, "invalid case: %s retrieved valid client state", tc.name) - s.Require().Equal(int64(0), gotHeight, "invalid case: %s retrieved valid upgrade height", tc.name) s.Require().Error(err, "invalid case: %s did not return error", tc.name) } } diff --git a/x/upgrade/types/keys.go b/x/upgrade/types/keys.go index cef1f09366..410f63597c 100644 --- a/x/upgrade/types/keys.go +++ b/x/upgrade/types/keys.go @@ -22,8 +22,14 @@ const ( // DoneByte is a prefix for to look up completed upgrade plan by name DoneByte = 0x1 - // KeyUpgradedClient is the key under which upgraded client is stored in the upgrade store + // KeyUpgradedIBCState is the key under which upgraded ibc state is stored in the upgrade store + KeyUpgradedIBCState = "upgradedIBCState" + + // KeyUpgradedClient is the sub-key under which upgraded client state will be stored KeyUpgradedClient = "upgradedClient" + + // KeyUpgradedConsState is the sub-key under which upgraded consensus state will be stored + KeyUpgradedConsState = "upgradedConsState" ) // PlanKey is the key under which the current plan is saved @@ -36,5 +42,12 @@ func PlanKey() []byte { // Connecting IBC chains can verify against the upgraded client in this path before // upgrading their clients func UpgradedClientKey(height int64) []byte { - return []byte(fmt.Sprintf("%s/%d", KeyUpgradedClient, height)) + return []byte(fmt.Sprintf("%s/%d/%s", KeyUpgradedIBCState, height, KeyUpgradedClient)) +} + +// UpgradedConsStateKey is the key under which the upgraded consensus state is saved +// Connecting IBC chains can verify against the upgraded consensus state in this path before +// upgrading their clients. +func UpgradedConsStateKey(height int64) []byte { + return []byte(fmt.Sprintf("%s/%d/%s", KeyUpgradedIBCState, height, KeyUpgradedConsState)) } diff --git a/x/upgrade/types/plan.go b/x/upgrade/types/plan.go index e853ac6797..f9f9db15e9 100644 --- a/x/upgrade/types/plan.go +++ b/x/upgrade/types/plan.go @@ -72,6 +72,11 @@ func (p Plan) DueAt() string { return fmt.Sprintf("height: %d", p.Height) } +// IsIBCPlan will return true if plan includes IBC client information +func (p Plan) IsIBCPlan() bool { + return p.UpgradedClientState != nil +} + // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (p Plan) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { // UpgradedClientState may be nil diff --git a/x/upgrade/types/plan_test.go b/x/upgrade/types/plan_test.go index 881a1a3229..436cb83a94 100644 --- a/x/upgrade/types/plan_test.go +++ b/x/upgrade/types/plan_test.go @@ -1,4 +1,4 @@ -package types +package types_test import ( "fmt" @@ -12,6 +12,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" + "github.com/cosmos/cosmos-sdk/x/upgrade/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -29,11 +30,11 @@ func TestPlanString(t *testing.T) { require.NoError(t, err) cases := map[string]struct { - p Plan + p types.Plan expect string }{ "with time": { - p: Plan{ + p: types.Plan{ Name: "due_time", Info: "https://foo.bar", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -41,7 +42,7 @@ func TestPlanString(t *testing.T) { expect: "Upgrade Plan\n Name: due_time\n Time: 2019-07-08T11:33:55Z\n Info: https://foo.bar.\n Upgraded IBC Client: no upgraded client provided", }, "with height": { - p: Plan{ + p: types.Plan{ Name: "by height", Info: "https://foo.bar/baz", Height: 7890, @@ -49,7 +50,7 @@ func TestPlanString(t *testing.T) { expect: "Upgrade Plan\n Name: by height\n Height: 7890\n Info: https://foo.bar/baz.\n Upgraded IBC Client: no upgraded client provided", }, "with IBC client": { - p: Plan{ + p: types.Plan{ Name: "by height", Info: "https://foo.bar/baz", Height: 7890, @@ -59,7 +60,7 @@ func TestPlanString(t *testing.T) { }, "neither": { - p: Plan{ + p: types.Plan{ Name: "almost-empty", }, expect: "Upgrade Plan\n Name: almost-empty\n Height: 0\n Info: .\n Upgraded IBC Client: no upgraded client provided", @@ -80,11 +81,11 @@ func TestPlanValid(t *testing.T) { require.NoError(t, err) cases := map[string]struct { - p Plan + p types.Plan valid bool }{ "proper": { - p: Plan{ + p: types.Plan{ Name: "all-good", Info: "some text here", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -92,7 +93,7 @@ func TestPlanValid(t *testing.T) { valid: true, }, "proper ibc upgrade": { - p: Plan{ + p: types.Plan{ Name: "ibc-all-good", Info: "some text here", Height: 123450000, @@ -101,31 +102,31 @@ func TestPlanValid(t *testing.T) { valid: true, }, "proper by height": { - p: Plan{ + p: types.Plan{ Name: "all-good", Height: 123450000, }, valid: true, }, "no name": { - p: Plan{ + p: types.Plan{ Height: 123450000, }, }, "no due at": { - p: Plan{ + p: types.Plan{ Name: "missing", Info: "important", }, }, "negative height": { - p: Plan{ + p: types.Plan{ Name: "minus", Height: -12345, }, }, "time due date defined for IBC plan": { - p: Plan{ + p: types.Plan{ Name: "ibc-all-good", Info: "some text here", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -151,13 +152,13 @@ func TestPlanValid(t *testing.T) { func TestShouldExecute(t *testing.T) { cases := map[string]struct { - p Plan + p types.Plan ctxTime time.Time ctxHeight int64 expected bool }{ "past time": { - p: Plan{ + p: types.Plan{ Name: "do-good", Info: "some text here", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -167,7 +168,7 @@ func TestShouldExecute(t *testing.T) { expected: false, }, "on time": { - p: Plan{ + p: types.Plan{ Name: "do-good", Time: mustParseTime("2019-07-08T11:33:55Z"), }, @@ -176,7 +177,7 @@ func TestShouldExecute(t *testing.T) { expected: true, }, "future time": { - p: Plan{ + p: types.Plan{ Name: "do-good", Time: mustParseTime("2019-07-08T11:33:55Z"), }, @@ -185,7 +186,7 @@ func TestShouldExecute(t *testing.T) { expected: true, }, "past height": { - p: Plan{ + p: types.Plan{ Name: "do-good", Height: 1234, }, @@ -194,7 +195,7 @@ func TestShouldExecute(t *testing.T) { expected: false, }, "on height": { - p: Plan{ + p: types.Plan{ Name: "do-good", Height: 1234, }, @@ -203,7 +204,7 @@ func TestShouldExecute(t *testing.T) { expected: true, }, "future height": { - p: Plan{ + p: types.Plan{ Name: "do-good", Height: 1234, }, diff --git a/x/upgrade/types/proposal_test.go b/x/upgrade/types/proposal_test.go index 0756776ddf..8f5ffb07a7 100644 --- a/x/upgrade/types/proposal_test.go +++ b/x/upgrade/types/proposal_test.go @@ -1,4 +1,4 @@ -package types +package types_test import ( "testing" @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" gov "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) type ProposalWrapper struct { @@ -23,7 +24,7 @@ func TestContentAccessors(t *testing.T) { str string }{ "upgrade": { - p: NewSoftwareUpgradeProposal("Title", "desc", Plan{ + p: types.NewSoftwareUpgradeProposal("Title", "desc", types.Plan{ Name: "due_time", Info: "https://foo.bar", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -34,7 +35,7 @@ func TestContentAccessors(t *testing.T) { str: "Software Upgrade Proposal:\n Title: Title\n Description: desc\n", }, "cancel": { - p: NewCancelSoftwareUpgradeProposal("Cancel", "bad idea"), + p: types.NewCancelSoftwareUpgradeProposal("Cancel", "bad idea"), title: "Cancel", desc: "bad idea", typ: "CancelSoftwareUpgrade", @@ -44,7 +45,7 @@ func TestContentAccessors(t *testing.T) { cdc := codec.NewLegacyAmino() gov.RegisterLegacyAminoCodec(cdc) - RegisterLegacyAminoCodec(cdc) + types.RegisterLegacyAminoCodec(cdc) for name, tc := range cases { tc := tc // copy to local variable for scopelint diff --git a/x/upgrade/types/query.pb.go b/x/upgrade/types/query.pb.go index 5175e183ed..3c49f6c4ad 100644 --- a/x/upgrade/types/query.pb.go +++ b/x/upgrade/types/query.pb.go @@ -6,6 +6,7 @@ package types import ( context "context" fmt "fmt" + types "github.com/cosmos/cosmos-sdk/codec/types" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -207,11 +208,107 @@ func (m *QueryAppliedPlanResponse) GetHeight() int64 { return 0 } +// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState +// RPC method. +type QueryUpgradedConsensusStateRequest struct { + // last height of the current chain must be sent in request + // as this is the height under which next consensus state is stored + LastHeight int64 `protobuf:"varint,1,opt,name=last_height,json=lastHeight,proto3" json:"last_height,omitempty"` +} + +func (m *QueryUpgradedConsensusStateRequest) Reset() { *m = QueryUpgradedConsensusStateRequest{} } +func (m *QueryUpgradedConsensusStateRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradedConsensusStateRequest) ProtoMessage() {} +func (*QueryUpgradedConsensusStateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_4a334d07ad8374f0, []int{4} +} +func (m *QueryUpgradedConsensusStateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradedConsensusStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradedConsensusStateRequest.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 *QueryUpgradedConsensusStateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradedConsensusStateRequest.Merge(m, src) +} +func (m *QueryUpgradedConsensusStateRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradedConsensusStateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradedConsensusStateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradedConsensusStateRequest proto.InternalMessageInfo + +func (m *QueryUpgradedConsensusStateRequest) GetLastHeight() int64 { + if m != nil { + return m.LastHeight + } + return 0 +} + +// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState +// RPC method. +type QueryUpgradedConsensusStateResponse struct { + UpgradedConsensusState *types.Any `protobuf:"bytes,1,opt,name=upgraded_consensus_state,json=upgradedConsensusState,proto3" json:"upgraded_consensus_state,omitempty"` +} + +func (m *QueryUpgradedConsensusStateResponse) Reset() { *m = QueryUpgradedConsensusStateResponse{} } +func (m *QueryUpgradedConsensusStateResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradedConsensusStateResponse) ProtoMessage() {} +func (*QueryUpgradedConsensusStateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_4a334d07ad8374f0, []int{5} +} +func (m *QueryUpgradedConsensusStateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradedConsensusStateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradedConsensusStateResponse.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 *QueryUpgradedConsensusStateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradedConsensusStateResponse.Merge(m, src) +} +func (m *QueryUpgradedConsensusStateResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradedConsensusStateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradedConsensusStateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradedConsensusStateResponse proto.InternalMessageInfo + +func (m *QueryUpgradedConsensusStateResponse) GetUpgradedConsensusState() *types.Any { + if m != nil { + return m.UpgradedConsensusState + } + return nil +} + func init() { proto.RegisterType((*QueryCurrentPlanRequest)(nil), "cosmos.upgrade.v1beta1.QueryCurrentPlanRequest") proto.RegisterType((*QueryCurrentPlanResponse)(nil), "cosmos.upgrade.v1beta1.QueryCurrentPlanResponse") proto.RegisterType((*QueryAppliedPlanRequest)(nil), "cosmos.upgrade.v1beta1.QueryAppliedPlanRequest") proto.RegisterType((*QueryAppliedPlanResponse)(nil), "cosmos.upgrade.v1beta1.QueryAppliedPlanResponse") + proto.RegisterType((*QueryUpgradedConsensusStateRequest)(nil), "cosmos.upgrade.v1beta1.QueryUpgradedConsensusStateRequest") + proto.RegisterType((*QueryUpgradedConsensusStateResponse)(nil), "cosmos.upgrade.v1beta1.QueryUpgradedConsensusStateResponse") } func init() { @@ -219,30 +316,38 @@ func init() { } var fileDescriptor_4a334d07ad8374f0 = []byte{ - // 362 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3d, 0x4f, 0xfa, 0x40, - 0x1c, 0xc7, 0x39, 0xfe, 0xfc, 0x49, 0x3c, 0xb6, 0x1b, 0x10, 0x09, 0x69, 0xcc, 0x85, 0x18, 0x13, - 0xa1, 0xc7, 0xc3, 0x2b, 0x50, 0x13, 0x27, 0x07, 0x65, 0x74, 0x31, 0x07, 0xfc, 0x52, 0x1a, 0xcb, - 0xdd, 0xd1, 0xbb, 0x1a, 0x89, 0x71, 0xf1, 0x15, 0x98, 0xb8, 0xbb, 0xf9, 0x5e, 0x1c, 0x49, 0x5c, - 0x1c, 0x0d, 0xf8, 0x42, 0x0c, 0xd7, 0x62, 0x6a, 0xa0, 0xc1, 0xa9, 0x6d, 0xfa, 0x7d, 0xf8, 0xdc, - 0xb7, 0xc5, 0x74, 0x20, 0xf5, 0x58, 0x6a, 0x16, 0x29, 0x2f, 0xe4, 0x43, 0x60, 0xb7, 0xed, 0x3e, - 0x18, 0xde, 0x66, 0x93, 0x08, 0xc2, 0xa9, 0xab, 0x42, 0x69, 0x24, 0x29, 0xc7, 0x1a, 0x37, 0xd1, - 0xb8, 0x89, 0xa6, 0x5a, 0xf3, 0xa4, 0xf4, 0x02, 0x60, 0x5c, 0xf9, 0x8c, 0x0b, 0x21, 0x0d, 0x37, - 0xbe, 0x14, 0x3a, 0x76, 0x55, 0xeb, 0x19, 0xc9, 0xab, 0x14, 0xab, 0xa2, 0x7b, 0x78, 0xf7, 0x72, - 0x59, 0x75, 0x1a, 0x85, 0x21, 0x08, 0x73, 0x11, 0x70, 0xd1, 0x83, 0x49, 0x04, 0xda, 0xd0, 0x73, - 0x5c, 0x59, 0x7f, 0xa5, 0x95, 0x14, 0x1a, 0x48, 0x0b, 0x17, 0x54, 0xc0, 0x45, 0x05, 0xed, 0xa3, - 0xc3, 0x52, 0xa7, 0xe6, 0x6e, 0x26, 0x74, 0xad, 0xc7, 0x2a, 0x69, 0x33, 0x29, 0x3a, 0x56, 0x2a, - 0xf0, 0x61, 0x98, 0x2a, 0x22, 0x04, 0x17, 0x04, 0x1f, 0x83, 0x0d, 0xdb, 0xe9, 0xd9, 0x7b, 0xda, - 0x49, 0xca, 0x7f, 0xc9, 0x93, 0xf2, 0x32, 0x2e, 0x8e, 0xc0, 0xf7, 0x46, 0xc6, 0x3a, 0xfe, 0xf5, - 0x92, 0xa7, 0xce, 0x2c, 0x8f, 0xff, 0x5b, 0x13, 0x79, 0x41, 0xb8, 0x94, 0xc2, 0x26, 0x2c, 0x0b, - 0x30, 0xe3, 0xec, 0xd5, 0xd6, 0xdf, 0x0d, 0x31, 0x14, 0x6d, 0x3c, 0xbe, 0x7f, 0x3d, 0xe7, 0x0f, - 0x48, 0x9d, 0x65, 0xec, 0x3e, 0x88, 0x4d, 0xd7, 0xcb, 0x35, 0xc8, 0x2b, 0xc2, 0xa5, 0xd4, 0xd1, - 0xb6, 0x00, 0xae, 0x6f, 0xb6, 0x05, 0x70, 0xc3, 0x6a, 0xb4, 0x6b, 0x01, 0x9b, 0xe4, 0x28, 0x0b, - 0x90, 0xc7, 0x26, 0x0b, 0xc8, 0xee, 0x97, 0x5f, 0xe1, 0xe1, 0xe4, 0xec, 0x6d, 0xee, 0xa0, 0xd9, - 0xdc, 0x41, 0x9f, 0x73, 0x07, 0x3d, 0x2d, 0x9c, 0xdc, 0x6c, 0xe1, 0xe4, 0x3e, 0x16, 0x4e, 0xee, - 0xaa, 0xe1, 0xf9, 0x66, 0x14, 0xf5, 0xdd, 0x81, 0x1c, 0xaf, 0x02, 0xe3, 0x4b, 0x53, 0x0f, 0x6f, - 0xd8, 0xdd, 0x4f, 0xba, 0x99, 0x2a, 0xd0, 0xfd, 0xa2, 0xfd, 0xdb, 0xba, 0xdf, 0x01, 0x00, 0x00, - 0xff, 0xff, 0xca, 0xa9, 0x39, 0xfe, 0xef, 0x02, 0x00, 0x00, + // 487 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x41, 0x8b, 0x13, 0x31, + 0x18, 0x6d, 0xb4, 0x2e, 0x98, 0xde, 0x82, 0xd4, 0x6e, 0x59, 0x46, 0x89, 0x8b, 0x08, 0x6e, 0x93, + 0xdd, 0xee, 0x4d, 0x41, 0x5c, 0x17, 0x17, 0x0f, 0x22, 0x5a, 0xf1, 0xe2, 0xa5, 0xa4, 0x9d, 0x38, + 0x1d, 0x9c, 0x26, 0xd9, 0x49, 0x22, 0x96, 0x65, 0x2f, 0xfe, 0x02, 0xc1, 0xbb, 0x37, 0x6f, 0xfe, + 0x10, 0x8f, 0x0b, 0x5e, 0xf4, 0x26, 0xad, 0x3f, 0x44, 0x26, 0xc9, 0x48, 0x97, 0x76, 0x66, 0xc5, + 0x53, 0x3b, 0x93, 0xf7, 0xbe, 0xf7, 0xbe, 0xbc, 0x37, 0x10, 0x8f, 0xa5, 0x9e, 0x4a, 0x4d, 0xad, + 0x4a, 0x72, 0x16, 0x73, 0xfa, 0x6e, 0x6f, 0xc4, 0x0d, 0xdb, 0xa3, 0xc7, 0x96, 0xe7, 0x33, 0xa2, + 0x72, 0x69, 0x24, 0x6a, 0x7b, 0x0c, 0x09, 0x18, 0x12, 0x30, 0xdd, 0xcd, 0x44, 0xca, 0x24, 0xe3, + 0xd4, 0xa1, 0x46, 0xf6, 0x0d, 0x65, 0x22, 0x50, 0xba, 0x5b, 0xe1, 0x88, 0xa9, 0x94, 0x32, 0x21, + 0xa4, 0x61, 0x26, 0x95, 0x42, 0x87, 0xd3, 0xed, 0x0a, 0xd1, 0x52, 0xc0, 0xa1, 0xf0, 0x26, 0xbc, + 0xfe, 0xa2, 0x70, 0x71, 0x68, 0xf3, 0x9c, 0x0b, 0xf3, 0x3c, 0x63, 0x62, 0xc0, 0x8f, 0x2d, 0xd7, + 0x06, 0x3f, 0x85, 0x9d, 0xd5, 0x23, 0xad, 0xa4, 0xd0, 0x1c, 0xed, 0xc2, 0xa6, 0xca, 0x98, 0xe8, + 0x80, 0x9b, 0xe0, 0x4e, 0xab, 0xbf, 0x45, 0xd6, 0x9b, 0x27, 0x8e, 0xe3, 0x90, 0xb8, 0x17, 0x84, + 0x0e, 0x94, 0xca, 0x52, 0x1e, 0x2f, 0x09, 0x21, 0x04, 0x9b, 0x82, 0x4d, 0xb9, 0x1b, 0x76, 0x75, + 0xe0, 0xfe, 0xe3, 0x7e, 0x10, 0x3f, 0x07, 0x0f, 0xe2, 0x6d, 0xb8, 0x31, 0xe1, 0x69, 0x32, 0x31, + 0x8e, 0x71, 0x79, 0x10, 0x9e, 0xf0, 0x63, 0x88, 0x1d, 0xe7, 0x95, 0x77, 0x11, 0x1f, 0x16, 0x68, + 0xa1, 0xad, 0x7e, 0x69, 0x98, 0xe1, 0xa5, 0xda, 0x0d, 0xd8, 0xca, 0x98, 0x36, 0xc3, 0x73, 0x23, + 0x60, 0xf1, 0xea, 0x89, 0x1f, 0x63, 0xe1, 0xad, 0xda, 0x31, 0xc1, 0xc5, 0x33, 0xd8, 0x09, 0xeb, + 0xc6, 0xc3, 0x71, 0x09, 0x19, 0xea, 0x02, 0x13, 0xae, 0xe5, 0x1a, 0xf1, 0x01, 0x91, 0x32, 0x3b, + 0x72, 0x20, 0x66, 0x83, 0xb6, 0x5d, 0x3b, 0xb7, 0xff, 0xb5, 0x09, 0xaf, 0x38, 0x5d, 0xf4, 0x19, + 0xc0, 0xd6, 0xd2, 0xa5, 0x23, 0x5a, 0x75, 0xbd, 0x15, 0xc9, 0x75, 0x77, 0xff, 0x9d, 0xe0, 0x97, + 0xc1, 0x3b, 0x1f, 0xbe, 0xff, 0xfe, 0x74, 0xe9, 0x36, 0xda, 0xa6, 0x15, 0xad, 0x19, 0x7b, 0xd2, + 0xb0, 0xc8, 0x12, 0x7d, 0x01, 0xb0, 0xb5, 0x14, 0xcc, 0x05, 0x06, 0x57, 0x13, 0xbf, 0xc0, 0xe0, + 0x9a, 0xcc, 0xf1, 0xbe, 0x33, 0xd8, 0x43, 0x77, 0xab, 0x0c, 0x32, 0x4f, 0x72, 0x06, 0xe9, 0x49, + 0xd1, 0xa1, 0x53, 0xf4, 0x13, 0xc0, 0xf6, 0xfa, 0x14, 0xd1, 0xbd, 0x5a, 0x07, 0xb5, 0x0d, 0xea, + 0xde, 0xff, 0x2f, 0x6e, 0x58, 0xe4, 0xc8, 0x2d, 0xf2, 0x10, 0x3d, 0xa0, 0xf5, 0xdf, 0xe7, 0x4a, + 0xa9, 0xe8, 0xc9, 0x52, 0x6d, 0x4f, 0x1f, 0x1d, 0x7d, 0x9b, 0x47, 0xe0, 0x6c, 0x1e, 0x81, 0x5f, + 0xf3, 0x08, 0x7c, 0x5c, 0x44, 0x8d, 0xb3, 0x45, 0xd4, 0xf8, 0xb1, 0x88, 0x1a, 0xaf, 0x77, 0x92, + 0xd4, 0x4c, 0xec, 0x88, 0x8c, 0xe5, 0xb4, 0xd4, 0xf0, 0x3f, 0x3d, 0x1d, 0xbf, 0xa5, 0xef, 0xff, + 0x0a, 0x9a, 0x99, 0xe2, 0x7a, 0xb4, 0xe1, 0xca, 0xb9, 0xff, 0x27, 0x00, 0x00, 0xff, 0xff, 0xee, + 0x4b, 0xe2, 0xe8, 0xa4, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -261,6 +366,11 @@ type QueryClient interface { CurrentPlan(ctx context.Context, in *QueryCurrentPlanRequest, opts ...grpc.CallOption) (*QueryCurrentPlanResponse, error) // AppliedPlan queries a previously applied upgrade plan by its name. AppliedPlan(ctx context.Context, in *QueryAppliedPlanRequest, opts ...grpc.CallOption) (*QueryAppliedPlanResponse, error) + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + UpgradedConsensusState(ctx context.Context, in *QueryUpgradedConsensusStateRequest, opts ...grpc.CallOption) (*QueryUpgradedConsensusStateResponse, error) } type queryClient struct { @@ -289,12 +399,26 @@ func (c *queryClient) AppliedPlan(ctx context.Context, in *QueryAppliedPlanReque return out, nil } +func (c *queryClient) UpgradedConsensusState(ctx context.Context, in *QueryUpgradedConsensusStateRequest, opts ...grpc.CallOption) (*QueryUpgradedConsensusStateResponse, error) { + out := new(QueryUpgradedConsensusStateResponse) + err := c.cc.Invoke(ctx, "/cosmos.upgrade.v1beta1.Query/UpgradedConsensusState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // CurrentPlan queries the current upgrade plan. CurrentPlan(context.Context, *QueryCurrentPlanRequest) (*QueryCurrentPlanResponse, error) // AppliedPlan queries a previously applied upgrade plan by its name. AppliedPlan(context.Context, *QueryAppliedPlanRequest) (*QueryAppliedPlanResponse, error) + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + UpgradedConsensusState(context.Context, *QueryUpgradedConsensusStateRequest) (*QueryUpgradedConsensusStateResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -307,6 +431,9 @@ func (*UnimplementedQueryServer) CurrentPlan(ctx context.Context, req *QueryCurr func (*UnimplementedQueryServer) AppliedPlan(ctx context.Context, req *QueryAppliedPlanRequest) (*QueryAppliedPlanResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AppliedPlan not implemented") } +func (*UnimplementedQueryServer) UpgradedConsensusState(ctx context.Context, req *QueryUpgradedConsensusStateRequest) (*QueryUpgradedConsensusStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpgradedConsensusState not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -348,6 +475,24 @@ func _Query_AppliedPlan_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Query_UpgradedConsensusState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUpgradedConsensusStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UpgradedConsensusState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.upgrade.v1beta1.Query/UpgradedConsensusState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UpgradedConsensusState(ctx, req.(*QueryUpgradedConsensusStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "cosmos.upgrade.v1beta1.Query", HandlerType: (*QueryServer)(nil), @@ -360,6 +505,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "AppliedPlan", Handler: _Query_AppliedPlan_Handler, }, + { + MethodName: "UpgradedConsensusState", + Handler: _Query_UpgradedConsensusState_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cosmos/upgrade/v1beta1/query.proto", @@ -481,6 +630,69 @@ func (m *QueryAppliedPlanResponse) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *QueryUpgradedConsensusStateRequest) 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 *QueryUpgradedConsensusStateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradedConsensusStateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.LastHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.LastHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryUpgradedConsensusStateResponse) 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 *QueryUpgradedConsensusStateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradedConsensusStateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UpgradedConsensusState != nil { + { + size, err := m.UpgradedConsensusState.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 @@ -539,6 +751,31 @@ func (m *QueryAppliedPlanResponse) Size() (n int) { return n } +func (m *QueryUpgradedConsensusStateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.LastHeight != 0 { + n += 1 + sovQuery(uint64(m.LastHeight)) + } + return n +} + +func (m *QueryUpgradedConsensusStateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UpgradedConsensusState != nil { + l = m.UpgradedConsensusState.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -844,6 +1081,167 @@ func (m *QueryAppliedPlanResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryUpgradedConsensusStateRequest) 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: QueryUpgradedConsensusStateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUpgradedConsensusStateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastHeight", wireType) + } + m.LastHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUpgradedConsensusStateResponse) 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: QueryUpgradedConsensusStateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUpgradedConsensusStateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradedConsensusState", 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.UpgradedConsensusState == nil { + m.UpgradedConsensusState = &types.Any{} + } + if err := m.UpgradedConsensusState.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 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/upgrade/types/query.pb.gw.go b/x/upgrade/types/query.pb.gw.go index 6d311b5778..cf1f9def8e 100644 --- a/x/upgrade/types/query.pb.gw.go +++ b/x/upgrade/types/query.pb.gw.go @@ -103,6 +103,60 @@ func local_request_Query_AppliedPlan_0(ctx context.Context, marshaler runtime.Ma } +func request_Query_UpgradedConsensusState_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradedConsensusStateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["last_height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "last_height") + } + + protoReq.LastHeight, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "last_height", err) + } + + msg, err := client.UpgradedConsensusState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_UpgradedConsensusState_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradedConsensusStateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["last_height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "last_height") + } + + protoReq.LastHeight, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "last_height", err) + } + + msg, err := server.UpgradedConsensusState(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. @@ -149,6 +203,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_UpgradedConsensusState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + 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_UpgradedConsensusState_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UpgradedConsensusState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -230,6 +304,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_UpgradedConsensusState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + 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_UpgradedConsensusState_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_UpgradedConsensusState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -237,10 +331,14 @@ var ( pattern_Query_CurrentPlan_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "upgrade", "v1beta1", "current_plan"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_AppliedPlan_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "upgrade", "v1beta1", "applied_plan", "name"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_UpgradedConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "upgrade", "v1beta1", "upgraded_consensus_state", "last_height"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( forward_Query_CurrentPlan_0 = runtime.ForwardResponseMessage forward_Query_AppliedPlan_0 = runtime.ForwardResponseMessage + + forward_Query_UpgradedConsensusState_0 = runtime.ForwardResponseMessage )