Component: cs-ics08-wasm-eth
Description
This is the CosmWasm implementation that can be used with ibc-go's 08-wasm light-client wrapper. It handles the client and consensus state and calls into packages/ethereum-light-client
for all the light-client--related logic.
The packages/ethereum-light-client
performs stateless verification. It contains all the core logic for verifying Ethereum consensus, proving state — verifying (non)membership — and the headers submitted to update the light client. The state is handled by the CosmWasm code.
The contract has three entry points:
instantiate
— This initializes the initialclient_state
and the consensus state.sudo
— The sudo entry point could only be called via the trusted modules and are used for verification of membership/misbehavior and updating the state.query
— This is used to query the state.
The packages/ethereum-light-client
performs the following verifications:
verify_membership
, which is used to verify the membership of a key in the storage.verify_misbehaviour
, which verifies if a consensus misbehavior is valid by checking if the two conflicting light-client updates are valid.verify_header
, which verifies the header of the light client.
Invariants
During the
SudoMsg::UpdateState
message, theupdate_consensus_state
function must be invoked with the current client state, current consensus state, and a new header, resulting in the updated consensus state being stored and, if required, the updated client state being stored as well.The
SudoMsg::UpdateStateOnMisbehaviour
message should set theis_frozen
variable to true in the ETH client state.The
SudoMsg::VerifyMembership
should verify the membership proof at the given consensus height and the current client state. And theSudoMsg::VerifyNonMembership
should perform similar actions but for nonmembership proofs.The
QueryMsg::VerifyClientMessage
message should correctly verify the header that will be used for updating the state of the light client. The verification of the header is done inethereum_light_client::verify::verify_header
, which must verify theaccount_proof
and that the update has been signed by at least two thirds of the sync committee. In the case the type of theclient_message
is ofEthereumMisbehaviourMsg
, it should verify the misbehavior viaethereum_light_client::misbehaviour::verify_misbehaviour
.The
QueryMsg::CheckForMisbehaviour
should return true if the providedclient_message
corresponds to two conflicting headers.The
validate_light_client_update
function must perform the verification of the update as per the consensus specification↗.The
update_consensus_state
should also update the consensus state as per the consensus specification.
Test coverage
Cases covered
Membership verification is working as expected.
Header verification is working as expected.
Updating consensus states via
update_consensus_state
returns the expectedupdated_slot
,new_consensus_state
, andnew_client_state
.
Cases not covered
Unit tests for misbehavior verification.
Attack surface
The ibc-go first performs the verification via the query message and then updates the states via the sudo message. It is crucial for the verification logic to be similar to the specification mentioned in the sync protocol docs. Any deviation from the proposed specification might lead to critical issues in the verification process. We verified the implementation against the specification and found several instances where the implementation did not follow the specification:
Finding ref↗: Merkle verification could be bypassed.
Finding ref↗: Attested header is stored instead of finalized header.
There were a few instances where the provided user input was used as trusted states, which might lead to issues as the user input is untrusted. The issue is discussed in detail in Finding ref↗.