This repository contains all the code for the Bankai Ethereum Light client. It consists of 3 main components: Cairo0 circuits for verifying epoch and sync committee updates, a Rust client for generating circuit inputs, the trace and submitting them to Starknet, and a Cairo1 contract (deployed on Starknet) for decommitting and storing verified beacon chain headers.
To keep the light client in sync there are 2 main operations that need to be performed: Verifying new epoch/slots and updating the sync committee, keeping up with the validator set.
To perform these operations, we have two separate circuits available, that work together in keeping the light client in sync. The proofs of these circuits are proven and then verified using the Integrity verifier, deployed on Starknet. The Bankai Cairo1 contract checks the proof was verified correctly and decommits the proof to its contract storage, making the verified data available to the Starknet network.
Overall, the steps for generating an update proof (epoch or sync committee) are pretty similiar:
- Check the latest light client state, deriving what inputs to generate
- Generate the inputs for the circuit. This involves querying the beacon chain for the relevant data. The circuit results are also computed
- Using the inputs and the relevant circuit, generate the trace
- Prove this trace using Atlantic in off-chain mode
- Retrieve the proof from Atlantic
- Submit the proof to atlantic, wrapping it to another layout. This step is required, as Integrity cant verify the proof using dynamic layout. The resulting (wrapped) proof uses the
recursive_with_poseidon
layout which can be verified by Integrity - Atlantic now submits the proof to Starknet, where it is verified by the Integrity verifier.
- The proof is now decommited in the Bankai contract. This is achieved by constructing the expected fact hash, and checking if this fact hash is available in the Integrity fact registry. If this is the case, the verified state is written to the contract storage.
The two main circuits used for doing the mayority of cryptographic operations are implemented in Cairo-Zero. Using Cairo-Zero enables the utilization of hints, which greatly increaces flexibility and performance.
The verification of an Beacon chain epoch requires the following steps:
- ✓ Compute block hash and signing root
- ✓ Convert message (signing root) to G2 point (hash_to_curve)
- ✓ Aggregate signer public keys
- ✓ Validate signature
- ✓ Compute committee hash
- ✓ Count number of signers
- ✓ Generate verification outputs
Implementation details can be found in epoch_update.cairo
(~175k steps).
To maintain continuous operation, the system validates sync committee updates through:
- ✓ Merkle path validation
- ✓ Public key decompression
- ✓ Committee hash computation
- ✓ Hash verification
Implementation details can be found in committee_update.cairo
(~40k steps).
- Beacon Chain RPC endpoint
- Rust toolchain
- Cairo development environment
# Install dependencies and setup environment
make setup
Addionally, an .env
file is required. These are the variables that need to be set:
STARKNET_ADDRESS=0x7b3d8f42e9a4c89e5b1f8d9f2e39c7d2b6e4a15c9d8f36e7a2b4c1d5e8f9a3b
STARKNET_PRIVATE_KEY=0x4f8a9c2b5e7d6f3a1b8c4d5e6f7a2b3c4d5e6f7a8b9c1d2e3f4a5b6c7d8e9f
STARKNET_RPC_URL=https://starknet-sepolia.infura.io/v3/your-api-key
BEACON_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/your-api-key
PROOF_REGISTRY=https://example-registry.s3.amazonaws.com/proofs/
ATLANTIC_API_KEY=a1b2c3d4-e5f6-7890-abcd-ef1234567890
PROOF_WRAPPER_PROGRAM_HASH=0x193641eb151b0f41674641089952e60bc3aded26e3cf42793655c562b8c3aa0
(The examples above are invalid, please use your own values)
The Bankai client provides the following command categories:
Generate JSON inputs for circuits and debugging:
# Initialize contract with starting slot
cargo run -- contract-init --slot <SLOT> [--export <FILE>]
# Generate epoch update inputs
cargo run -- epoch-update --slot <SLOT> [--export <FILE>]
# Generate sync committee update inputs
cargo run -- committee-update --slot <SLOT> [--export <FILE>]
Generate and manage proofs for the light client state:
# Generate proof for next epoch
cargo run -- prove-next-epoch
# Generate proof for next committee
cargo run -- prove-next-committee
# Wrap and resubmit proof (required for dynamic layouts)
cargo run -- submit-wrapped-proof --batch-id <BATCH_ID>
# Check proof generation status
cargo run -- check-batch-status --batch-id <BATCH_ID>
Deploy and interact with the Starknet contract:
# Deploy Bankai contract
cargo run -- deploy-contract --slot <SLOT>
# Verify and decommit proofs
cargo run -- verify-epoch --batch-id <BATCH_ID> --slot <SLOT> # For epoch updates
cargo run -- verify-committee --batch-id <BATCH_ID> --slot <SLOT> # For committee updates
Note: All commands that generate proofs will automatically create input files, generate traces, and submit to Atlantic for proving. The returned batch ID can be used to track the proof status.
The cairo circuits can also be run locally. For this, ensure to be in the python environment (make venv
). Inputs for the circuits can be generated using the client.
# Copy CLI output to epoch_input.json, then:
make build-epoch
make run-epoch
# Copy CLI output to committee_input.json, then:
make build-committee
make run-committee
All of this wouldnt be possible without Garaga. Amazing stuff! Thx for your support Felt!