Enclave Light Client (ELC)
ELCは、LCP Enclave内に実装されるLight Clientである。その主な役割は次の2つである
- ICS-02を実装するLight Clientを管理する
- Light Client verficationの結果を示すCommitmentおよびProofの生成
ELCは、Appを通じて初期化された後にUpstreamのHeaderによる状態更新、およびCommitment Proofを検証する。ELCはそれらの検証の結果として、それぞれ対応する2つのcommitmentを生成する。それが、UpdateClient CommitmentとState Commitmentである。また、これらのcommitmentにEnclave Keyで署名をしたものをproofとする。これらのcommitmentはpublic Enclave Keyを持つLCP Clientにより検証が可能である。
UpdateClient Commitment
UpdateClient Commitmentは、initializeClient
とupdateClient
によるELCのClientの状態遷移を示すcommitmentである。DownstreamはLCP Clientを用いてこのcommitmentを検証することでUpstreamの状態を追跡する。
UpdateClient Commitmentは、ELCのClientのHeaderを検証した時の状態とHeaderを適用した後の状態から主に構成される。Clientの各状態は後述するStateIDで表現される。commitmentの定義は次のようになる:
pub struct UpdateClientCommitment {
pub prev_state_id: Option<StateID>,
pub new_state_id: StateID,
pub new_state: Option<Vec<u8>>,
pub prev_height: Option<Height>,
pub new_height: Height,
pub timestamp: u128,
pub validation_context: ValidationContext,
}
prev_state_id
は、ELCの参照した状態を示すStateIDである。これは、update_client
時のみ含まれる。new_state_id
は、ELCの更新後の状態を示すStateIDである。new_state
は、new_state_id
に対応するELCの更新後の状態である。これは、Light Clientの更新仕様ごとに含まれる。prev_height
およびnew_height
はそれぞれELCの事前、事後の高さである。timestamp
はnew_height
に対応するupstream headerのtimestampである。validation_context
は後述するELCの検証時のコンテキストを示す。これはValidation-Contextで後述する。
StateID
StateIDは、ある高さにおけるELCのClientの状態を一意に示す識別子である。ICS-02に従うClientの場合、StateIDはClientStateとConsensusStateをconcatしたバイト列のHash値である。
通常、各ClientのClientStateは検証に関するパラメータとともに初期化され、以後検証に関する情報は不変である。また、ConsensusStateは高さごとに存在し、対象ChainのHeader情報から生成される状態である。ここで多くのLight Clientには作成者による独自のパラメータが存在することに注意する。これにより、同一のClient定義であっても構成次第で異なる検証結果が得られる場合がある。
そのため、ELCはUpdateClient Commitmentに更新前(つまり検証時)と更新後の両方のStateIDを含む。(なお、initializeClientのcommitmentは、更新前状態は空とする。) これにより初期commitmentに含まれる更新後StateIDに基づき、あるUpdateClient Commitmentに至るまでの更新の連鎖が一意に定まることを保証する。つまり、検証者はproofの検証に加え、このcommitmentの連鎖を検証することにより、特定のLight Clientにより生成された検証パラメータが一貫したcommitmentのみで更新されることを保証することができるようになる。
Validation Context
Validation Contextは、ELCのClientによるHeader検証時のコンテキストを示す。これは検証者の現在時間を含む。
通常、Light ClientはHeader検証時には次の2つを確認する:
- ある状態のValidatorSetを元にHeaderに含まれる署名が十分に集まっていることの検証
- 検証するClientの状態が現在有効であることの確認
1.については、ECDSAを始めとする署名アルゴリズムにより得られた署名の検証である。これはELCによりEnclave内で行われる。 一方、2.については、現在時刻とその状態が関連づくtimestampを入力とし真偽値を返す、妥当性を確認する述語として定義されることが多い。例えば、Cosmosにおけるtrusting periodを用いた検証がこれに該当する。しかし、一般的にTEEにおいて信頼できるtimestampは存在しないため、TEE内での現在時刻を参照する検証は信頼できない。
そこで、ELCはUpdateClient commitmentに、現在時刻を入力として有効性の真偽値を返す述語を含める。そのため、commitmentの検証者は、public Enclave Keyを用いたCommitment Proofの署名検証に加え、検証者の現在時刻を用いてこの述語を評価する必要がある。例えば、検証者がOn-chainのLCP Clientの場合、現在時刻としてLatest Block Timestampを参照する必要がある。
State Commitment
ELCは、Upstreamのstateに対するcommitmentに加え、ELCによるそのcommitmentの検証時の自身の状態を含めたState Commitmentを生成する。
StateCommitmentの定義は次の通りである:
pub struct StateCommitment {
pub prefix: CommitmentPrefix,
pub path: Path,
pub value: Vec<u8>,
pub height: Height,
pub state_id: StateID,
}
prefix
はストアでの接頭辞で、検証時にpath
に適用される。
path
は、Upstreamのcommitment pathであり、value
はpath
に対応する値である。
height
はUpstreamのcommitmentと対応する高さであり、state_id
は検証に用いたELCの状態を示すStateIDである。