Home

Awesome

SP1 ICS07-Tendermint IBC Light Client

<div align="center">

Github Actions SP1 License: MIT

</div>

This is a WIP example of an ICS-07 IBC light client on Ethereum powered by SP1 and ibc-rs.

Light Mode DiagramDark Mode Diagram

Table of Contents

<!-- TOC --> <!-- /TOC -->

Overview

sp1-ics07-tendermint is an example ZK IBC tendermint light client on Ethereum.

Project Structure

This project is structured as a cargo workspace with the following directories:

Programs

This project contains the following programs

ProgramsDescriptionStatus
update-clientOnce the initial client state and consensus state are submitted, future consensus states can be added to the client by submitting IBC Headers. These headers contain all necessary information to run the Comet BFT Light Client protocol. Also supports partial misbehavior check.
membershipAs consensus states are added to the client, they can be used for proof verification by relayers wishing to prove packet flow messages against a particular height on the counterparty. This uses the verify_membership and verify_non_membership methods on the tendermint client.
uc-and-membershipThis is a program that combines update-client and membership to update the client, and prove membership of packet flow messages against the new consensus state.
misbehaviourIn case, the malicious subset of the validators exceeds the trust level of the client; then the client can be deceived into accepting invalid blocks and the connection is no longer secure. The tendermint client has some mitigations in place to prevent this.
upgrade-clientThe chain which this light client is tracking can elect to write a special pre-determined key in state to allow the light client to update its client state (e.g. with a new chain ID or revision).

Requirements

Foundry typically uses git submodules to manage contract dependencies, but this repository uses Node.js packages (via Bun) because submodules don't scale. You can install the contracts dependencies by running the following command:

bun install

Build the programs

You should build the programs for zkVM by running the following command:

just build-programs

The programs will be built in the elf/ directory which is ignored by .gitignore but are needed for the operator to build.

Run ICS-07 Tendermint Light Client End to End

  1. Set the environment variables by filling in the .env file with the following:

    cp .env.example .env
    

    You need to fill in the PRIVATE_KEY, SP1_PROVER, TENDERMINT_RPC_URL, and RPC_URL. You also need the SP1_PRIVATE_KEY field if you are using the SP1 prover network.

  2. Deploy the SP1ICS07Tendermint contract:

    just deploy-contracts
    

    This will generate the contracts/script/genesis.json file which contains the initialization parameters for the contract. And then deploy the contract using contracts/script/SP1ICS07Tendermint.s.sol. If you see the following error, add --legacy to the command in the justfile:

    Error: Failed to get EIP-1559 fees    
    
  3. Your deployed contract address will be printed to the terminal.

    == Return ==
    0: address <CONTRACT_ADDRESS>
    

    This will be used when you run the operator in step 5. So add this to your .env file.

    CONTRACT_ADDRESS=<CONTRACT_ADDRESS>
    
  4. Run the Tendermint operator.

    To run the operator, you need to select the prover type for SP1. This is set in the .env file with the SP1_PROVER value (network|local|mock). If you run the operator with the network prover, you need to provide your SP1 network private key with SP1_PRIVATE_KEY=0xyourprivatekey in .env.

    just operator
    

EVM-Compatible Proof Generation & Verification

[!WARNING] You will need at least 128GB RAM to generate the PLONK proofs locally.

Here, I will show you how to generate a proof to be used in the fixtures for the foundry tests. You can do this locally or by using the SP1 prover network. To do this on your local machine, run the following command:

just fixtures local

To use the SP1 prover network, set SP1_PROVER=network and provide your SP1 network private key with SP1_PRIVATE_KEY="0xyourprivatekey in the .env file. After this, you can run the following command:

just fixtures network

Solidity Proof Verification

After generating the verify the proof with the SP1 EVM verifier.

just test-foundry

The recipe also accepts a testname argument that will only run the test with the given name. For example:

just test-foundry test_success_sendTransfer

End to End Testing

There are several end-to-end tests in the e2e/interchaintestv8 directory. These tests are written in Go and use the interchaintest library. It spins up a local Ethereum and a Tendermint network and runs the tests found in e2e/interchaintestv8/sp1_ics07_test.go. Some of the tests use the prover network to generate the proofs, so you need to provide your SP1 network private key to .env for these tests to pass.

[!NOTE] If you are running on a Mac with an M chip, you will need to do the following:

To run the tests, run the following command:

just test-e2e $TEST_NAME

Where $TEST_NAME is the name of the test you want to run, for example:

just test-e2e TestDeploy