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
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
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-client
submodule previously depended upon theGetHeight()
method ofHeader
types in order to retrieve the updated consensus height. - 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:
- Return a list of updated consensus heights
[]exported.Height
from the newUpdateState
method of theClientState
interface.
// 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_height
event attribute emitted from the02-client
update 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_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 processUpdateClient
events as normal, with a path to upgrade to using theconsensus_heights
attribute moving forward.
Negative
- Consumers of IBC core
UpdateClient
events are forced to make future code changes.
Neutral
References
Discussions:
Issues:
PRs: