在一些不常见的情况下,某个高价值客户端可能会因为不可控因素而被冻结或过期。一个高价值客户端可能承载着数百个正在活跃使用的通道,其中一些通道中还可能锁定了大量用于 ICS 20 的代币。

冻结的轻客户端

如果该客户端所代表链的验证者集合中有三分之一决定串通,他们就可以分别对两份都有效、但彼此冲突的区块头进行签名,而这两份区块头又各自得到了另外三分之一诚实验证者集合的签名。这样一来,轻客户端就可能在同一高度被更新为两份都有效但彼此冲突的区块头。轻客户端无法判断哪一份区块头可信,因此这类作恶证据很可能会被提交,最终导致轻客户端被冻结。 被冻结的轻客户端在任何情况下都无法更新,除非通过治理提案。由于达到法定人数的验证者可以对任意状态根签名,而这些状态根未必来自状态机的有效执行,因此引入了治理提案机制,以降低对已经“卡住”的客户端进行解冻或更新的复杂度。如果没有这一机制,验证者集合就必须自行构造一个状态根来为客户端解冻。客户端解冻后,将重新启用所有构建在该客户端之上的通道,这可能使原本会丢失的资金得以恢复。

过期的轻客户端

如果 Tendermint 轻客户端自上次更新以来已经超过信任期,就可能变为过期状态。如果中继者停止提交新的区块头来更新客户端,就可能发生这种情况。 对手链发生未计划升级也可能导致客户端过期。如果对手链进行了未计划升级,那么在链 ID 变更之前,验证者集合可能没有对该升级签署任何承诺。在这种情况下,轻客户端最后一次有效更新所对应的验证者集合预计将不会再产生任何新的有效区块头,因为链 ID 已经改变,这最终会导致链上轻客户端过期。

如何通过治理提案恢复过期客户端

这些信息适用于谁? 虽然从技术上讲任何人都可以提交治理提案来恢复过期客户端,但通常会由中继者运营方来执行这件事(至少负责协调提交流程)。
当某个高价值轻客户端被冻结、过期,或变得无法更新时,可以提交治理提案来更新该客户端,该客户端被称为 subject client。提案中会包含该 subject 客户端的客户端标识符,以及一个 substitute 客户端的客户端标识符。轻客户端实现可以定义自定义更新逻辑,但在大多数情况下,如果提案通过,subject 客户端会被更新为 substitute 客户端的最新共识状态。substitute 客户端在 subject 客户端处于审查状态时充当“替身”。最佳实践是在 subject 客户端被冻结之后再创建 substitute 客户端,以避免 substitute 客户端也被冻结。一个保持活跃的 substitute 客户端可以在投票期间持续接收区块头更新,从而避免提案通过后因意外过期而无法使用。 另请参阅相关文档:ADR-026、IBC 客户端恢复机制

前置条件

  • 存在一个指向同一条对手链的活跃客户端(且已知其客户端标识符),它与该过期客户端对应的是同一条对手链。
  • 治理押金。

步骤

第 1 步

检查该客户端是否绑定到了预期的 chain_id。例如,对于一个表示 Akash 链的已过期 Tendermint 客户端,查询其客户端状态时结果如下:
{
  client_id: 07-tendermint-146
  client_state:
  '@type': /ibc.lightclients.tendermint.v1.ClientState
  allow_update_after_expiry: true
  allow_update_after_misbehaviour: true
  chain_id: akashnet-2
}
该客户端已绑定到预期的 Akash chain_id。请注意,尽管参数 allow_update_after_expiry 和 allow_update_after_misbehaviour 仍然存在,用于表达意图,但这些参数已经被弃用,并且不会对客户端恢复生效时执行任何检查。关于这一弃用的更多背景,请参阅 ADR-026。

第 2 步

任何人都可以通过 CLI 执行以下命令来提交治理提案,以恢复该客户端。 如果链上使用的 ibc-go 版本早于 v8,请参阅相关文档。
  • 从 ibc-go v8 开始
    <binary> tx gov submit-proposal [path-to-proposal-json]
    
    其中 proposal.json 内容如下:
    {
      "messages": [
        {
      "@type": "/ibc.core.client.v1.MsgRecoverClient",
      "subject_client_id": "<expired-client-id>",
      "substitute_client_id": "<active-client-id>",
      "signer": "<gov-address>"
        }
      ],
      "metadata": "<metadata>",
      "deposit": "10stake"
      "title": "My proposal",
      "summary": "A short summary of my proposal",
      "expedited": false
    }
    
<expired-client-id> 标识符表示提议要更新的客户端。该客户端必须处于冻结或过期状态。 <active-client-id> 表示 substitute 客户端。它承载了可用于更新目标客户端的全部状态。它必须与待更新客户端具有相同的客户端参数和链参数(最新高度、冻结高度以及链 ID 除外)。在投票期间,应持续对其进行更新。 完成这些之后,剩下的就是决定由谁来承担治理押金,并确保治理提案通过。如果提案通过,处于审查状态的客户端将被更新为 substitute 客户端的最新状态。

重要注意事项

请注意,如果对手侧客户端也已过期,那么那个客户端也需要更新。此流程一次只更新一个客户端。
In uncommon situations, a highly valued client may become frozen or expire due to uncontrollable circumstances. A highly valued client might have hundreds of channels being actively used. Some of those channels might have a significant amount of locked tokens used for ICS 20.

Frozen Light Clients

If the one third of the validator set of the chain the client represents decides to collude, they can sign off on two valid but conflicting headers each signed by the other one third of the honest validator set. The light client can now be updated with two valid, but conflicting headers at the same height. The light client cannot know which header is trustworthy and therefore evidence of such misbehaviour is likely to be submitted resulting in a frozen light client. Frozen light clients cannot be updated under any circumstance except via a governance proposal. Since a quorum of validators can sign arbitrary state roots which may not be valid executions of the state machine, a governance proposal has been added to ease the complexity of unfreezing or updating clients which have become “stuck”. Without this mechanism, validator sets would need to construct a state root to unfreeze the client. Unfreezing clients, re-enables all of the channels built upon that client. This may result in recovery of otherwise lost funds.

Expired Light Clients

Tendermint light clients may become expired if the trusting period has passed since their last update. This may occur if relayers stop submitting headers to update the clients. An unplanned upgrade by the counterparty chain may also result in expired clients. If the counterparty chain undergoes an unplanned upgrade, there may be no commitment to that upgrade signed by the validator set before the chain ID changes. In this situation, the validator set of the last valid update for the light client is never expected to produce another valid header since the chain ID has changed, which will ultimately lead the on-chain light client to become expired.

How to recover an expired client with a governance proposal

Who is this information for? Although technically anyone can submit the governance proposal to recover an expired client, often it will be relayer operators (at least coordinating the submission).
In the case that a highly valued light client is frozen, expired, or rendered non-updateable, a governance proposal may be submitted to update this client, known as the subject client. The proposal includes the client identifier for the subject and the client identifier for a substitute client. Light client implementations may implement custom updating logic, but in most cases, the subject will be updated to the latest consensus state of the substitute client, if the proposal passes. The substitute client is used as a “stand in” while the subject is on trial. It is best practice to create a substitute client after the subject has become frozen to avoid the substitute from also becoming frozen. An active substitute client allows headers to be submitted during the voting period to prevent accidental expiry once the proposal passes. See also the relevant documentation: ADR-026, IBC client recovery mechanisms

Preconditions

  • There exists an active client (with a known client identifier) for the same counterparty chain as the expired client.
  • The governance deposit.

Steps

Step 1

Check if the client is attached to the expected chain_id. For example, for an expired Tendermint client representing the Akash chain the client state looks like this on querying the client state:
{
  client_id: 07-tendermint-146
  client_state:
  '@type': /ibc.lightclients.tendermint.v1.ClientState
  allow_update_after_expiry: true
  allow_update_after_misbehaviour: true
  chain_id: akashnet-2
}
The client is attached to the expected Akash chain_id. Note that although the parameters (allow_update_after_expiry and allow_update_after_misbehaviour) exist to signal intent, these parameters have been deprecated and will not enforce any checks on the revival of client. See ADR-026 for more context on this deprecation.

Step 2

Anyone can submit the governance proposal to recover the client by executing the following via CLI. If the chain is on an ibc-go version older than v8, please see the relevant documentation.
  • From ibc-go v8 onwards
    <binary> tx gov submit-proposal [path-to-proposal-json]
    
    where proposal.json contains:
    {
      "messages": [
        {
      "@type": "/ibc.core.client.v1.MsgRecoverClient",
      "subject_client_id": "<expired-client-id>",
      "substitute_client_id": "<active-client-id>",
      "signer": "<gov-address>"
        }
      ],
      "metadata": "<metadata>",
      "deposit": "10stake"
      "title": "My proposal",
      "summary": "A short summary of my proposal",
      "expedited": false
    }
    
The <expired-client-id> identifier is the proposed client to be updated. This client must be either frozen or expired. The <active-client-id> represents a substitute client. It carries all the state for the client which may be updated. It must have identical client and chain parameters to the client which may be updated (except for latest height, frozen height, and chain ID). It should be continually updated during the voting period. After this, all that remains is deciding who funds the governance deposit and ensuring the governance proposal passes. If it does, the client on trial will be updated to the latest state of the substitute.

Important considerations

Please note that if the counterparty client is also expired, that client will also need to update. This process updates only one client.