Skip to content

Commit

Permalink
feat: info endpoint in evm prover (#140)
Browse files Browse the repository at this point in the history
## Overview

Fixes #141 
Fixes #79

---------

Co-authored-by: Javed Khan <tuxcanfly@gmail.com>
  • Loading branch information
ninabarbakadze and tuxcanfly authored Feb 11, 2025
1 parent 434c625 commit 0070f43
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 5 deletions.
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ PROTO_DESCRIPTOR_PATH="./provers/celestia-prover/proto_descriptor.bin"
# RPC of a celestia-node (light, bridge, or full)
export CELESTIA_NODE_URL="http://localhost:52351"
# Auth token for the celestia-node
export CELESTIA_NODE_AUTH_TOKEN=""
export CELESTIA_NODE_AUTH_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJwdWJsaWMiLCJyZWFkIiwid3JpdGUiLCJhZG1pbiJdfQ.qxoN_a-k7aZZE77VSpfgyvI_0eNvJ_OgBsT35zxUQnQ"
# Namespace of the rollup on Celestia Mainnet
export CELESTIA_NAMESPACE="0f0f0f0f0f0f0f0f0f0f"
# RPC url of the simapp simulating Celestia
export SIMAPP_RPC_URL=grpc://127.0.0.1:9190
29 changes: 29 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"provers/celestia-prover/prover",
"provers/celestia-prover/programs/sp1/mock-update-client",
"provers/celestia-prover/programs/sp1/mock-membership",
"provers/evm-prover"
]
resolver = "2"

Expand Down
31 changes: 31 additions & 0 deletions provers/evm-prover/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "evm-prover"
version = "0.1.0"
edition = { workspace = true }

[dependencies]
tonic.workspace = true
prost.workspace = true
tokio = { workspace = true, features = ["full"] }
futures = "0.3"
tonic-reflection.workspace = true
tendermint-rpc = { workspace = true, features = ["http-client"] }
ibc-client-tendermint-types.workspace = true
reqwest.workspace = true
alloy = { workspace = true, features = ["providers"] }
alloy-provider = { workspace = true }
ibc-eureka-solidity-types.workspace = true
sp1-sdk = { workspace = true, features = ["network"] }
sp1-ics07-tendermint-prover.workspace = true
sp1-ics07-tendermint-utils.workspace = true
ibc-core-commitment-types = { workspace = true }
ibc-proto = { workspace = true }
dotenv = "0.15.0"
anyhow = "1.0.94"
bincode = "1.3.3"
serde = "1.0.217"
prost-types = "0.13.4"

[build-dependencies]
tonic-build.workspace = true
sp1-helper = "4.0.1"
26 changes: 26 additions & 0 deletions provers/evm-prover/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# EVM Prover

The EVM Prover is a gRPC service that generates zero-knowledge proofs for EVM state transitions. It is designed to work with IBC (Inter-Blockchain Communication) and specifically implements proofs compatible with the ICS-07 Tendermint client specification.

## Usage

> [!WARNING]
> This gRPC service is still under development and may not lack some features or not work as described.
Before running this program, please follow the steps outlined in this [README.md](https://github.com/celestiaorg/celestia-zkevm-ibc-demo/blob/main/README.md).

To then run the server (on port `:50052`):

```shell
cargo run
```

The only endpoint currently working is:

```shell
grpcurl -plaintext localhost:50052 celestia.prover.v1.Prover/Info
```

## Protobuf

gRPC depends on proto defined types. These are stored in `proto/prover/v1` from the root directory.
16 changes: 16 additions & 0 deletions provers/evm-prover/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use sp1_helper::build_program_with_args;

fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::configure()
.build_server(true)
.file_descriptor_set_path("proto_descriptor.bin")
.compile_protos(
&[
"../../proto/prover/v1/prover.proto",
"../../proto/ibc/lightclients/groth16/v1/groth16.proto",
],
&["../../proto"],
)?;
build_program_with_args("../blevm/blevm-mock", Default::default());
Ok(())
}
93 changes: 93 additions & 0 deletions provers/evm-prover/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use sp1_sdk::HashableKey;
use std::env;
use std::fs;
use tonic::{transport::Server, Request, Response, Status};

// Import the generated proto rust code
pub mod prover {
tonic::include_proto!("celestia.prover.v1");
tonic::include_proto!("celestia.ibc.lightclients.groth16.v1");
}

use prover::prover_server::{Prover, ProverServer};
use prover::{
InfoRequest, InfoResponse, ProveStateMembershipRequest, ProveStateMembershipResponse,
ProveStateTransitionRequest, ProveStateTransitionResponse,
};
use sp1_sdk::{include_elf, ProverClient, SP1ProvingKey};

// The ELF file for the Succinct RISC-V zkVM.
const BLEVM_ELF: &[u8] = include_elf!("blevm-mock");
pub struct ProverService {
sp1_proving_key: SP1ProvingKey,
}

impl ProverService {
async fn new() -> Result<Self, Box<dyn std::error::Error>> {
let sp1_prover = ProverClient::from_env();
let (pk, _) = sp1_prover.setup(&BLEVM_ELF);

Ok(ProverService {
sp1_proving_key: pk,
})
}
}

#[tonic::async_trait]
impl Prover for ProverService {
async fn info(&self, _request: Request<InfoRequest>) -> Result<Response<InfoResponse>, Status> {
let state_transition_verifier_key = self.sp1_proving_key.vk.bytes32();
// Empty string membership verifier key because currently membership proofs are not supported
let state_membership_verifier_key = String::new();
let response = InfoResponse {
state_membership_verifier_key,
state_transition_verifier_key,
};

Ok(Response::new(response))
}

async fn prove_state_transition(
&self,
_request: Request<ProveStateTransitionRequest>,
) -> Result<Response<ProveStateTransitionResponse>, Status> {
Err(Status::unimplemented(
"State transition proofs not yet implemented",
))
}

async fn prove_state_membership(
&self,
_request: Request<ProveStateMembershipRequest>,
) -> Result<Response<ProveStateMembershipResponse>, Status> {
Err(Status::unimplemented(
"Membership proofs not yet implemented",
))
}
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv::dotenv().ok();

let addr = "[::1]:50052".parse()?;
let prover = ProverService::new().await?;

println!("BLEVM Prover Server listening on {}", addr);

// Load the file descriptor set
let file_descriptor_set = fs::read("proto_descriptor.bin")?;

Server::builder()
.add_service(ProverServer::new(prover))
.add_service(
tonic_reflection::server::Builder::configure()
.register_encoded_file_descriptor_set(&file_descriptor_set)
.build_v1()
.unwrap(),
)
.serve(addr)
.await?;

Ok(())
}
33 changes: 29 additions & 4 deletions testing/demo/pkg/setup/initialise_groth16_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ package main

import (
"context"
"encoding/hex"
"fmt"
"math/big"
"slices"
"strings"
"time"

"github.com/celestiaorg/celestia-zkevm-ibc-demo/ibc/lightclients/groth16"
proverclient "github.com/celestiaorg/celestia-zkevm-ibc-demo/provers/client"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cosmos/cosmos-sdk/client"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

"github.com/celestiaorg/celestia-zkevm-ibc-demo/testing/demo/pkg/utils"
channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
Expand Down Expand Up @@ -59,10 +64,30 @@ func InitializeGroth16LightClientOnSimapp() error {
}

func createClientAndConsensusState(genesisBlock, latestBlock *ethtypes.Block) (*cdctypes.Any, *cdctypes.Any, error) {
// TODO: this clientState isn't created with a state transition verifier key or state inclusion verifier key.
// Query the EVM prover for the verifier keys
// See: https://github.com/celestiaorg/celestia-zkevm-ibc-demo/blob/main/proto/prover/v1/prover.proto#L16-L20
clientState := groth16.NewClientState(latestBlock.Number().Uint64(), []byte{}, []byte{}, []byte{}, genesisBlock.Root().Bytes())
// Query the info endpoint for the state transition verifier key
// Membership proofs are currently not supported
conn, err := grpc.NewClient("localhost:50052", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, nil, fmt.Errorf("failed to connect to prover: %w", err)
}
defer conn.Close()

fmt.Printf("Getting evm prover info...\n")
proverClient := proverclient.NewProverClient(conn)
info, err := proverClient.Info(context.Background(), &proverclient.InfoRequest{})
if err != nil {
return nil, nil, fmt.Errorf("failed to get evm prover info %w", err)
}
fmt.Printf("Got evm prover info. StateTransitionVerifierKey: %v", info.StateTransitionVerifierKey)
verifierKeyDecoded, err := hex.DecodeString(strings.TrimPrefix(info.StateTransitionVerifierKey, "0x"))
if err != nil {
return nil, nil, fmt.Errorf("failed to decode verifier key %w", err)
}
// Q: Do we still need the fixed size of 32 bytes considering the verifier key is of type []byte?
// var verifierKey [32]byte
// copy(verifierKey[:], verifierKeyDecoded)

clientState := groth16.NewClientState(latestBlock.Number().Uint64(), verifierKeyDecoded, []byte{}, []byte{}, genesisBlock.Root().Bytes())
clientStateAny, err := cdctypes.NewAnyWithValue(clientState)
if err != nil {
return nil, nil, fmt.Errorf("failed to create client state any: %v", err)
Expand Down

0 comments on commit 0070f43

Please sign in to comment.