# ADR 005: UpdateClient Events - ClientState Consensus Heights ## Changelog - 25/04/2022: initial draft ## Status Accepted ## Context The `ibc-go` implementation leverages the [Cosmos-SDK's EventManager](https://github.com/cosmos/cosmos-sdk/blob/v0.45.4/docs/core/events.md#EventManager) to provide subscribers a method of reacting to application specific events. Some IBC relayers depend on the [`consensus_height`](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/core/02-client/keeper/events.go#L33) attribute emitted as part of `UpdateClient` events in order to run `07-tendermint` misbehaviour detection by cross-checking the details of the *Header* emitted at a given consensus height against those of the *Header* from the originating chain. This includes such details as: - The `SignedHeader` containing the commitment root. - The `ValidatorSet` that signed the *Header*. - The `TrustedHeight` seen by the client at less than or equal to the height of *Header*. - The last `TrustedValidatorSet` at the trusted height. Following the refactor of the `02-client` submodule and associated `ClientState` interfaces, it will now be possible for light client implementations to perform such actions as batch updates, inserting `N` number of `ConsensusState`s into the application state tree with a single `UpdateClient` message. This flexibility is provided in `ibc-go` by the usage of the [Protobuf `Any`](https://developers.google.com/protocol-buffers/docs/proto3#any) field contained within the [`UpdateClient`](https://github.com/cosmos/ibc-go/blob/v3.0.0/proto/ibc/core/client/v1/tx.proto#L44) message. For example, a batched client update message serialized as a Protobuf `Any` type for the `07-tendermint` lightclient implementation could be defined as follows: ```protobuf message BatchedHeaders { repeated Header headers = 1; } ``` To complement this flexibility, the `UpdateClient` handler will now support the submission of [client misbehaviour](https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics#misbehaviour) by consolidating the `Header` and `Misbehaviour` interfaces into a single `ClientMessage` interface type: ```go // ClientMessage is an interface used to update an IBC client. // The update may be done by a single header, a batch of headers, misbehaviour, or any type which when verified produces // a change to state of the IBC client type ClientMessage interface { proto.Message ClientType() string ValidateBasic() error } ``` To support this functionality the `GetHeight()` method has been omitted from the new `ClientMessage` interface. Emission of standardised events from the `02-client` submodule now becomes problematic and is two-fold: 1. The `02-client` submodule previously depended upon the `GetHeight()` method of `Header` types in order to [retrieve the updated consensus height](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/core/02-client/keeper/client.go#L90). 2. Emitting a single `consensus_height` event attribute is not sufficient in the case of a batched client update containing multiple *Headers*. ## Decision The following decisions have been made in order to provide flexibility to consumers of `UpdateClient` events in a non-breaking fashion: 1. Return a list of updated consensus heights `[]exported.Height` from the new `UpdateState` method of the `ClientState` interface. ```go // UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. // Upon successful update, a list of consensus heights is returned. It assumes the ClientMessage has already been verified. UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) []Height ``` 2. Maintain the `consensus_height` event attribute emitted from the `02-client` update handler, but mark as deprecated for future removal. For example, with tendermint lightclients this will simply be `consensusHeights[0]` following a successful update using a single *Header*. 3. Add an additional `consensus_heights` event attribute, containing a comma separated list of updated heights. This provides flexibility for emitting a single consensus height or multiple consensus heights in the example use-case of batched header updates. ## Consequences ### Positive - Subscribers of IBC core events can act upon `UpdateClient` events containing one or more consensus heights. - Deprecation of the existing `consensus_height` attribute allows consumers to continue to process `UpdateClient` events as normal, with a path to upgrade to using the `consensus_heights` attribute moving forward. ### Negative - Consumers of IBC core `UpdateClient` events are forced to make future code changes. ### Neutral ## References Discussions: - [#1208](https://github.com/cosmos/ibc-go/pull/1208#discussion_r839691927) Issues: - [#594](https://github.com/cosmos/ibc-go/issues/594) PRs: - [#1285](https://github.com/cosmos/ibc-go/pull/1285)