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 to provide subscribers a method of reacting to application specific events.
Some IBC relayers depend on the consensus_height 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
SignedHeadercontaining the commitment root. - The
ValidatorSetthat signed the Header. - The
TrustedHeightseen by the client at less than or equal to the height of Header. - The last
TrustedValidatorSetat 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 ConsensusStates into the application state tree with a single UpdateClient message. This flexibility is provided in ibc-go by the usage of the Protobuf Any field contained within the UpdateClient 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:
message BatchedHeaders {
repeated Header headers = 1;
}
To complement this flexibility, the UpdateClient handler will now support the submission of client misbehaviour by consolidating the Header and Misbehaviour interfaces into a single ClientMessage interface type:
// 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:
- The
02-clientsubmodule previously depended upon theGetHeight()method ofHeadertypes in order to retrieve the updated consensus height. - Emitting a single
consensus_heightevent 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:
- Return a list of updated consensus heights
[]exported.Heightfrom the newUpdateStatemethod of theClientStateinterface.
// 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
Maintain the
consensus_heightevent attribute emitted from the02-clientupdate handler, but mark as deprecated for future removal. For example, with tendermint lightclients this will simply beconsensusHeights[0]following a successful update using a single Header.Add an additional
consensus_heightsevent 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
UpdateClientevents containing one or more consensus heights. - Deprecation of the existing
consensus_heightattribute allows consumers to continue to processUpdateClientevents as normal, with a path to upgrade to using theconsensus_heightsattribute moving forward.
Negative
- Consumers of IBC core
UpdateClientevents are forced to make future code changes.
Neutral
References
Discussions:
Issues:
PRs: