Skip to content

Commit 1855d49

Browse files
committed
create evm prover
1 parent bb7f418 commit 1855d49

File tree

6 files changed

+188
-1
lines changed

6 files changed

+188
-1
lines changed

Cargo.lock

+23
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[workspace]
22
members = [
33
"provers/celestia-prover",
4+
"provers/evm-prover",
45
]
56
resolver = "2"
67

@@ -26,4 +27,4 @@ ibc-core-commitment-types = "0.56"
2627

2728
ibc-eureka-solidity-types = { git = "https://github.com/cosmos/solidity-ibc-eureka.git", branch = "main", subdir = "packages/solidity", features = ["rpc"]}
2829
sp1-ics07-tendermint-prover = { git = "https://github.com/cosmos/solidity-ibc-eureka.git", branch = "main", subdir = "packages/prover"}
29-
sp1-ics07-tendermint-utils = { git = "https://github.com/cosmos/solidity-ibc-eureka.git", branch = "main", subdir = "packages/utils"}
30+
sp1-ics07-tendermint-utils = { git = "https://github.com/cosmos/solidity-ibc-eureka.git", branch = "main", subdir = "packages/utils"}

provers/evm-prover/Cargo.toml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "evm-prover"
3+
version = "0.1.0"
4+
edition = { workspace = true }
5+
6+
[dependencies]
7+
tonic.workspace = true
8+
prost.workspace = true
9+
tokio = { workspace = true, features = ["full"] }
10+
futures = "0.3"
11+
tonic-reflection.workspace = true
12+
tendermint-rpc = { workspace = true, features = ["http-client"] }
13+
ibc-client-tendermint-types.workspace = true
14+
reqwest.workspace = true
15+
alloy = { workspace = true, features = ["providers"] }
16+
alloy-provider = { workspace = true }
17+
ibc-eureka-solidity-types.workspace = true
18+
sp1-ics07-tendermint-prover.workspace = true
19+
sp1-ics07-tendermint-utils.workspace = true
20+
ibc-core-commitment-types = { workspace = true }
21+
dotenv = "0.15.0"
22+
anyhow = "1.0.94"
23+
24+
[build-dependencies]
25+
tonic-build.workspace = true

provers/evm-prover/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# EVM Prover
2+
3+
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.
4+
5+
## Usage
6+
7+
> [!WARNING]
8+
> This gRPC service is still under development and may not work as described
9+
10+
To run the server you will need to clone the repo and install rust and cargo. To run the node you also need to set the following environment variables:
11+
12+
- `TENDERMINT_RPC_URL` - the url of the tendermint chain you are proving.
13+
- `RPC_URL` the json rpc url of the evm chain you are generating the proofs for.
14+
- `CONTRACT_ADDRESS` - the evm address of the tendermint sp1 ics07 contract.
15+
16+
To then run the server (on port `:50051`):
17+
18+
```
19+
cargo run
20+
```
21+
22+
To use the SP1 Prover Network you should also populate the `SP1_PROVER` and `SP1_PRIVATE_KEY` environment variables. You can also use a `.env` file for all environment variables
23+
24+
25+
## Protobuf
26+
27+
gRPC depends on proto defined types. These are stored in `proto/prover/v1` from the root directory.

provers/evm-prover/build.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() -> Result<(), Box<dyn std::error::Error>> {
2+
tonic_build::configure()
3+
.build_server(true)
4+
.file_descriptor_set_path("proto_descriptor.bin")
5+
.compile_protos(&["../../proto/prover/v1/prover.proto"], &["../../proto"])?;
6+
Ok(())
7+
}

provers/evm-prover/src/main.rs

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
use std::env;
2+
use std::fs;
3+
use tonic::{transport::Server, Request, Response, Status};
4+
// Import the generated proto rust code
5+
pub mod prover {
6+
tonic::include_proto!("celestia.prover.v1");
7+
}
8+
9+
use alloy::primitives::Address;
10+
use prover::prover_server::{Prover, ProverServer};
11+
use prover::{
12+
ProveMembershipRequest, ProveMembershipResponse, ProveStateTransitionRequest,
13+
ProveStateTransitionResponse,
14+
};
15+
use reqwest::Url;
16+
use sp1_ics07_tendermint_prover::{
17+
programs::UpdateClientProgram,
18+
prover::{SP1ICS07TendermintProver, SupportedProofType},
19+
};
20+
use sp1_ics07_tendermint_utils::rpc::TendermintRpcExt;
21+
use tendermint_rpc::HttpClient;
22+
23+
// TODO: swap tendermint prover for blevm sp1 prover
24+
pub struct ProverService {
25+
tendermint_prover: SP1ICS07TendermintProver<UpdateClientProgram>,
26+
tendermint_rpc_client: HttpClient,
27+
evm_rpc_url: Url,
28+
evm_contract_address: Address,
29+
}
30+
31+
impl ProverService {
32+
fn new() -> ProverService {
33+
let rpc_url = env::var("RPC_URL").expect("RPC_URL not set");
34+
let contract_address = env::var("CONTRACT_ADDRESS").expect("CONTRACT_ADDRESS not set");
35+
let url = Url::parse(rpc_url.as_str()).expect("Failed to parse RPC_URL");
36+
37+
ProverService {
38+
tendermint_prover: SP1ICS07TendermintProver::new(SupportedProofType::Groth16),
39+
tendermint_rpc_client: HttpClient::from_env(),
40+
evm_rpc_url: url,
41+
evm_contract_address: contract_address
42+
.parse()
43+
.expect("Failed to parse contract address"),
44+
}
45+
}
46+
}
47+
48+
#[tonic::async_trait]
49+
impl Prover for ProverService {
50+
async fn prove_state_transition(
51+
&self,
52+
request: Request<ProveStateTransitionRequest>,
53+
) -> Result<Response<ProveStateTransitionResponse>, Status> {
54+
println!("Got state transition request: {:?}", request);
55+
56+
// TODO: get blevm sp1 proof
57+
let response = ProveStateTransitionResponse {
58+
proof: vec![],
59+
public_values: vec![],
60+
};
61+
62+
Ok(Response::new(response))
63+
}
64+
65+
async fn prove_membership(
66+
&self,
67+
request: Request<ProveMembershipRequest>,
68+
) -> Result<Response<ProveMembershipResponse>, Status> {
69+
println!("Got membership request: {:?}", request);
70+
71+
// Implement your membership proof logic here
72+
let response = ProveMembershipResponse {
73+
proof: vec![],
74+
height: 0,
75+
};
76+
77+
Ok(Response::new(response))
78+
}
79+
}
80+
81+
#[tokio::main]
82+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
83+
dotenv::dotenv().ok();
84+
let addr = "[::1]:50051".parse()?;
85+
let prover = ProverService::new();
86+
87+
println!("Prover Server listening on {}", addr);
88+
89+
// Load the file descriptor set
90+
let file_descriptor_set = fs::read("proto_descriptor.bin")?;
91+
92+
Server::builder()
93+
.add_service(ProverServer::new(prover))
94+
.add_service(
95+
tonic_reflection::server::Builder::configure()
96+
.register_encoded_file_descriptor_set(&file_descriptor_set)
97+
.build_v1()
98+
.unwrap(),
99+
)
100+
.serve(addr)
101+
.await?;
102+
103+
Ok(())
104+
}

0 commit comments

Comments
 (0)