变更记录

  • 25-04-2022:初始草案

状态

已接受

背景

ibc-go 实现利用了 Cosmos-SDK 的 EventManager,为订阅者提供了一种对应用特定事件作出响应的方法。 一些 IBC 中继器依赖于在 UpdateClient 事件中发出的 consensus_height 属性,以便通过将某一共识高度下发出的 Header 细节与源链上的 Header 细节进行交叉比对,来执行 07-tendermint 误行为检测。其中包括如下细节:
  • 包含承诺根的 SignedHeader。
  • 对该 Header 进行签名的 ValidatorSet。
  • 客户端在不高于 Header 高度时看到的 TrustedHeight。
  • 该可信高度上的最后一个 TrustedValidatorSet。
随着 02-client 子模块及其相关 ClientState 接口完成重构,轻客户端实现现在可以执行批量更新等操作,即通过一条 UpdateClient 消息将 N 个 ConsensusState 写入应用状态树。这种灵活性在 ibc-go 中是通过使用 UpdateClient 消息中包含的 Protobuf Any 字段来实现的。 例如,对于 07-tendermint 轻客户端实现,可以将序列化为 Protobuf Any 类型的批量客户端更新消息定义如下:
message BatchedHeaders {
  repeated Header headers = 1;
}
为配合这种灵活性,UpdateClient 处理器现在还将支持提交客户端误行为,方式是将 Header 和 Misbehaviour 接口合并为一个统一的 ClientMessage 接口类型:
// 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
}
为支持这一功能,新 ClientMessage 接口中省略了 GetHeight() 方法。 因此,从 02-client 子模块发出标准化事件会变得棘手,具体体现在两个方面:
  1. 02-client 子模块此前依赖 Header 类型的 GetHeight() 方法来获取更新后的共识高度。
  2. 当批量客户端更新包含多个 Header 时,仅发出单个 consensus_height 事件属性是不够的。

决策

为了以非破坏性方式为 UpdateClient 事件的消费者提供灵活性,现作出如下决策:
  1. 让 ClientState 接口的新 UpdateState 方法返回一个已更新的共识高度列表 []exported.Height。
// 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
  1. 保留 02-client 更新处理器发出的 consensus_height 事件属性,但将其标记为已弃用,未来会移除。例如,对于 tendermint 轻客户端,在使用单个 Header 成功更新后,该值将直接为 consensusHeights[0]。
  2. 新增 consensus_heights 事件属性,其中包含一个以逗号分隔的已更新高度列表。这为发出单个共识高度或多个共识高度提供了灵活性,适用于批量头更新这一示例用例。

影响

正面

  • IBC 核心事件的订阅者可以处理包含一个或多个共识高度的 UpdateClient 事件。
  • 现有 consensus_height 属性的弃用,使消费者仍可像往常一样继续处理 UpdateClient 事件,同时也为后续升级到 consensus_heights 属性提供了路径。

负面

  • IBC 核心 UpdateClient 事件的消费者将被迫在未来修改代码。

中性

参考资料

讨论: 问题: PR:

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 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:
  1. The 02-client submodule previously depended upon the GetHeight() method of Header types in order to retrieve the updated consensus height.
  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.
// 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
  1. 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.
  2. 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: Issues: PRs: