Implementation of zero-knowledge proof circuits for Tendermint.
Tendermint X's core contract is TendermintX
, which stores the headers of Tendermint blocks. Users can query a TendermintX
contract for the header of a specific block height, or for the latest header.
There are two entrypoints to a TendermintX
contract, step
and skip
.
skip
is used to jump from the current header to a non-consecutive header.
For example, let's say block N has already been proven in the light client, and we want to prove block N+10. We can skip from block N to block N+10 if 1) the validators who have signed the commit for block N+10 comprise > 1/3 of the voting power on block N and 2) validators comprimising > 2/3 of the voting power on block N+10 have signed the commit for block N+10.
The methodology for doing so is described in the section 6 of A Tendermint Light Client.
step
is used to sequentially verify the next header after the current header.
This is rarely used, as step
will only be invoked when the validator set changes by more than 2/3 in a single block.
-
Fork this repository: https://github.com/succinctlabs/tendermintx
-
Update the
VALIDATOR_SET_SIZE_MAX
to match that of your Tendermint chain incircuits/consts.rs
. Push the changes to your fork. -
Add a new circuit config for your Tendermint chain in
circuits/config.rs
. Replacecelestia
with the chain ID (network name) of your Tendermint chain./// Example chain config for Celestia pub const CELESTIA_CHAIN_ID_BYTES: &[u8] = b"celestia"; pub const CELESTIA_CHAIN_ID_SIZE_BYTES: usize = CELESTIA_CHAIN_ID_BYTES.len(); #[derive(Debug, Clone, PartialEq)] pub struct CelestiaConfig; impl TendermintConfig<CELESTIA_CHAIN_ID_SIZE_BYTES> for CelestiaConfig { const CHAIN_ID_BYTES: &'static [u8] = CELESTIA_CHAIN_ID_BYTES; const SKIP_MAX: usize = SKIP_MAX; }
-
Update
bin/skip.rs
andbin/step.rs
to use your new chain config instead ofCelestiaConfig
.
-
Go to the Succinct Platform.
-
Sign up for an account on the platform.
-
Create a new project on the Succinct Platform by importing your fork of
tendermintx
. -
In your project on the platform, go to
Releases
. Create two new releases, one forstep
and one forskip
. Use themain
branch and set the entrypoint accordingly. -
In your project on the platform, go to
Settings
. SetTENDERMINT_RPC_URL
inEnvironment Variables
. This should be a valid full node RPC for your Tendermint chain. -
Once the releases are completed building, go to
Deployments
to deploy the verifiers forstep
andskip
.
-
Open the code for your fork of
tendermintx
again. -
Update
contracts/.env
accoridng tocontracts/.env.example
. Note: The genesis parameters are typically sourced from a recent header from your Tendermint chain. -
Deploy your
TendermintX
contract and initialize it with your function ID & genesis parameters using the commands below.
forge install
forge script script/Deploy.s.sol --rpc-url $ETHEREUM_RPC_URL --private-key $PRIVATE_KEY --etherscan-api-key $ETHERSCAN_API_KEY --verify TendermintX --broadcast
-
Update
.env
according to.env.example
.- Get
SUCCINCT_API_KEY
from your Succinct Platform user/project settings. SUCCINCT_RPC_URL
=https://alpha.succinct.xyz/api
- Get
-
Run
TendermintX
script to update the light client continuously (currently set to update once every 4 hours).
cargo run --bin tendermintx --release
- Now, go the platform to monitor the status of your proofs. Generating a Tendermint LC proof takes anywhere from 4-10 minutes, depending on your validator set size.
To find a list of RPC's for most Tendermint chains, check out this page created by @deving_zone.
Tendermint X is configured to work with CometBFT block protocol version 11. If this changes in the future, the Tendermint X circuits might need to be updated.
- Tendermint X has been audited by Informal Systems. The audit report can be found here.