libzkp and coordinator updates (preparation for Upgrade4) (#1419)

Co-authored-by: georgehao <haohongfan@gmail.com>
This commit is contained in:
Rohit Narurkar
2024-07-11 12:47:02 +01:00
committed by GitHub
parent 3567f5b62a
commit a2e8b6a644
14 changed files with 477 additions and 101 deletions

View File

@@ -39,9 +39,9 @@ dependencies = [
"ctor",
"encoder",
"env_logger 0.10.0",
"eth-types",
"eth-types 0.11.0",
"ethers-core",
"gadgets",
"gadgets 0.11.0",
"halo2-base",
"halo2-ecc",
"halo2_proofs",
@@ -59,7 +59,41 @@ dependencies = [
"snark-verifier-sdk",
"strum 0.25.0",
"strum_macros 0.25.3",
"zkevm-circuits",
"zkevm-circuits 0.11.0",
]
[[package]]
name = "aggregator"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"ark-std 0.3.0",
"bitstream-io",
"c-kzg",
"ctor",
"encoder",
"env_logger 0.10.0",
"eth-types 0.12.0",
"ethers-core",
"gadgets 0.12.0",
"halo2-base",
"halo2-ecc",
"halo2_proofs",
"hex",
"itertools 0.11.0",
"log",
"num-bigint",
"once_cell",
"rand",
"revm-precompile",
"revm-primitives",
"serde",
"serde_json",
"snark-verifier",
"snark-verifier-sdk",
"strum 0.25.0",
"strum_macros 0.25.3",
"zkevm-circuits 0.12.0",
]
[[package]]
@@ -539,18 +573,18 @@ name = "bus-mapping"
version = "0.11.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453"
dependencies = [
"eth-types",
"eth-types 0.11.0",
"ethers-core",
"ethers-providers",
"ethers-signers",
"external-tracer",
"gadgets",
"external-tracer 0.11.0",
"gadgets 0.11.0",
"halo2_proofs",
"hex",
"itertools 0.11.0",
"log",
"mock",
"mpt-zktrie",
"mock 0.11.0",
"mpt-zktrie 0.11.0",
"num",
"poseidon-circuit",
"rand",
@@ -561,6 +595,31 @@ dependencies = [
"strum_macros 0.25.3",
]
[[package]]
name = "bus-mapping"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"eth-types 0.12.0",
"ethers-core",
"ethers-providers",
"ethers-signers",
"gadgets 0.12.0",
"halo2_proofs",
"hex",
"itertools 0.11.0",
"log",
"mock 0.12.0",
"mpt-zktrie 0.12.0",
"num",
"poseidon-circuit",
"revm-precompile",
"serde",
"serde_json",
"strum 0.25.0",
"strum_macros 0.25.3",
]
[[package]]
name = "byte-slice-cast"
version = "1.2.2"
@@ -1152,6 +1211,34 @@ dependencies = [
"uint",
]
[[package]]
name = "eth-types"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"base64 0.13.1",
"ethers-core",
"ethers-signers",
"halo2curves",
"hex",
"itertools 0.11.0",
"log",
"num",
"num-bigint",
"poseidon-base",
"regex",
"revm-precompile",
"revm-primitives",
"serde",
"serde_json",
"serde_with",
"sha3 0.10.8",
"strum 0.25.0",
"strum_macros 0.25.3",
"subtle",
"uint",
]
[[package]]
name = "ethabi"
version = "18.0.0"
@@ -1285,8 +1372,21 @@ name = "external-tracer"
version = "0.11.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453"
dependencies = [
"eth-types",
"geth-utils",
"eth-types 0.11.0",
"geth-utils 0.11.0",
"log",
"serde",
"serde_json",
"serde_stacker",
]
[[package]]
name = "external-tracer"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"eth-types 0.12.0",
"geth-utils 0.12.0",
"log",
"serde",
"serde_json",
@@ -1467,7 +1567,19 @@ name = "gadgets"
version = "0.11.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453"
dependencies = [
"eth-types",
"eth-types 0.11.0",
"halo2_proofs",
"poseidon-base",
"sha3 0.10.8",
"strum 0.25.0",
]
[[package]]
name = "gadgets"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"eth-types 0.12.0",
"halo2_proofs",
"poseidon-base",
"sha3 0.10.8",
@@ -1495,6 +1607,16 @@ dependencies = [
"log",
]
[[package]]
name = "geth-utils"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"env_logger 0.10.0",
"gobuild",
"log",
]
[[package]]
name = "getrandom"
version = "0.2.10"
@@ -2239,10 +2361,25 @@ name = "mock"
version = "0.11.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453"
dependencies = [
"eth-types",
"eth-types 0.11.0",
"ethers-core",
"ethers-signers",
"external-tracer",
"external-tracer 0.11.0",
"itertools 0.11.0",
"log",
"rand",
"rand_chacha",
]
[[package]]
name = "mock"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"eth-types 0.12.0",
"ethers-core",
"ethers-signers",
"external-tracer 0.12.0",
"itertools 0.11.0",
"log",
"rand",
@@ -2254,7 +2391,21 @@ name = "mpt-zktrie"
version = "0.11.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453"
dependencies = [
"eth-types",
"eth-types 0.11.0",
"halo2curves",
"hex",
"log",
"num-bigint",
"poseidon-base",
"zktrie",
]
[[package]]
name = "mpt-zktrie"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"eth-types 0.12.0",
"halo2curves",
"hex",
"log",
@@ -2726,14 +2877,14 @@ name = "prover"
version = "0.11.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453"
dependencies = [
"aggregator",
"aggregator 0.11.0",
"anyhow",
"base64 0.13.1",
"blake2",
"bus-mapping",
"bus-mapping 0.11.0",
"chrono",
"dotenvy",
"eth-types",
"eth-types 0.11.0",
"ethers-core",
"git-version",
"halo2_proofs",
@@ -2741,7 +2892,7 @@ dependencies = [
"itertools 0.11.0",
"log",
"log4rs",
"mpt-zktrie",
"mpt-zktrie 0.11.0",
"num-bigint",
"rand",
"rand_xorshift",
@@ -2752,7 +2903,41 @@ dependencies = [
"sha2",
"snark-verifier",
"snark-verifier-sdk",
"zkevm-circuits",
"zkevm-circuits 0.11.0",
]
[[package]]
name = "prover"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"aggregator 0.12.0",
"anyhow",
"base64 0.13.1",
"blake2",
"bus-mapping 0.12.0",
"chrono",
"dotenvy",
"eth-types 0.12.0",
"ethers-core",
"git-version",
"halo2_proofs",
"hex",
"itertools 0.11.0",
"log",
"log4rs",
"mpt-zktrie 0.12.0",
"num-bigint",
"rand",
"rand_xorshift",
"serde",
"serde_derive",
"serde_json",
"serde_stacker",
"sha2",
"snark-verifier",
"snark-verifier-sdk",
"zkevm-circuits 0.12.0",
]
[[package]]
@@ -2958,7 +3143,7 @@ dependencies = [
[[package]]
name = "revm-precompile"
version = "7.0.0"
source = "git+https://github.com/scroll-tech/revm?branch=scroll-evm-executor/v36#8543dd627348907773d8057807b6a310b276bb30"
source = "git+https://github.com/scroll-tech/revm?branch=scroll-evm-executor/v36#36c304d9e9ba4e4b2d5468d91a6bd27210133b6a"
dependencies = [
"aurora-engine-modexp",
"c-kzg",
@@ -2974,7 +3159,7 @@ dependencies = [
[[package]]
name = "revm-primitives"
version = "4.0.0"
source = "git+https://github.com/scroll-tech/revm?branch=scroll-evm-executor/v36#8543dd627348907773d8057807b6a310b276bb30"
source = "git+https://github.com/scroll-tech/revm?branch=scroll-evm-executor/v36#36c304d9e9ba4e4b2d5468d91a6bd27210133b6a"
dependencies = [
"alloy-primitives",
"auto_impl",
@@ -3525,7 +3710,7 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "snark-verifier"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/snark-verifier?branch=develop#fe1f8906041ad323034881fbd808908250d44829"
source = "git+https://github.com/scroll-tech/snark-verifier?branch=develop#58c46b74c73156b9e09dc27617369d2acfb4461b"
dependencies = [
"bytes",
"ethereum-types",
@@ -3548,7 +3733,7 @@ dependencies = [
[[package]]
name = "snark-verifier-sdk"
version = "0.0.1"
source = "git+https://github.com/scroll-tech/snark-verifier?branch=develop#fe1f8906041ad323034881fbd808908250d44829"
source = "git+https://github.com/scroll-tech/snark-verifier?branch=develop#58c46b74c73156b9e09dc27617369d2acfb4461b"
dependencies = [
"bincode",
"ethereum-types",
@@ -4364,14 +4549,14 @@ version = "0.11.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.11.4#38a68e22d3d8449bd39a50c22da55b9e741de453"
dependencies = [
"array-init",
"bus-mapping",
"bus-mapping 0.11.0",
"either",
"env_logger 0.10.0",
"eth-types",
"eth-types 0.11.0",
"ethers-core",
"ethers-signers",
"ff",
"gadgets",
"gadgets 0.11.0",
"halo2-base",
"halo2-ecc",
"halo2-mpt-circuits",
@@ -4381,8 +4566,50 @@ dependencies = [
"itertools 0.11.0",
"log",
"misc-precompiled-circuit",
"mock",
"mpt-zktrie",
"mock 0.11.0",
"mpt-zktrie 0.11.0",
"num",
"num-bigint",
"poseidon-circuit",
"rand",
"rand_chacha",
"rand_xorshift",
"rayon",
"serde",
"serde_json",
"sha3 0.10.8",
"snark-verifier",
"snark-verifier-sdk",
"strum 0.25.0",
"strum_macros 0.25.3",
"subtle",
]
[[package]]
name = "zkevm-circuits"
version = "0.12.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?branch=feat/agg_recursion#86158b58907aac1c4c8f43ce9d5b29170d309401"
dependencies = [
"array-init",
"bus-mapping 0.12.0",
"either",
"env_logger 0.10.0",
"eth-types 0.12.0",
"ethers-core",
"ethers-signers",
"ff",
"gadgets 0.12.0",
"halo2-base",
"halo2-ecc",
"halo2-mpt-circuits",
"halo2_gadgets",
"halo2_proofs",
"hex",
"itertools 0.11.0",
"log",
"misc-precompiled-circuit",
"mock 0.12.0",
"mpt-zktrie 0.12.0",
"num",
"num-bigint",
"poseidon-circuit",
@@ -4410,7 +4637,8 @@ dependencies = [
"libc",
"log",
"once_cell",
"prover",
"prover 0.11.0",
"prover 0.12.0",
"serde",
"serde_derive",
"serde_json",

View File

@@ -25,7 +25,11 @@ bls12_381 = { git = "https://github.com/scroll-tech/bls12_381", branch = "feat/i
[dependencies]
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "v1.1" }
snark-verifier-sdk = { git = "https://github.com/scroll-tech/snark-verifier", branch = "develop", default-features = false, features = ["loader_halo2", "loader_evm", "halo2-pse"] }
prover = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.11.4", default-features = false, features = ["parallel_syn", "scroll"] }
# curie
prover_v3 = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.11.4", package = "prover", default-features = false, features = ["parallel_syn", "scroll"] }
# darwin
prover_v4 = { git = "https://github.com/scroll-tech/zkevm-circuits.git", branch = "feat/agg_recursion", package = "prover", default-features = false, features = ["parallel_syn", "scroll"] }
base64 = "0.13.0"
env_logger = "0.9.0"

View File

@@ -6,17 +6,20 @@ use crate::{
},
};
use libc::c_char;
use prover::{
aggregator::{Prover, Verifier},
use prover_v3::BatchProof as BatchProofV3;
use prover_v4::{
aggregator::{Prover, Verifier as VerifierV4},
check_chunk_hashes,
consts::AGG_VK_FILENAME,
consts::BATCH_VK_FILENAME,
utils::{chunk_trace_to_witness_block, init_env_and_log},
BatchProof, BatchProvingTask, BlockTrace, ChunkInfo, ChunkProof,
BatchHeader, BatchProof as BatchProofV4, BatchProvingTask, BlockTrace, BundleProof,
BundleProvingTask, ChunkInfo, ChunkProof, MAX_AGG_SNARKS,
};
use snark_verifier_sdk::verify_evm_calldata;
use std::{cell::OnceCell, env, ptr::null};
static mut PROVER: OnceCell<Prover> = OnceCell::new();
static mut VERIFIER: OnceCell<Verifier> = OnceCell::new();
static mut VERIFIER_V4: OnceCell<VerifierV4> = OnceCell::new();
/// # Safety
#[no_mangle]
@@ -30,8 +33,8 @@ pub unsafe extern "C" fn init_batch_prover(params_dir: *const c_char, assets_dir
env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir);
// VK file must exist, it is optional and logged as a warning in prover.
if !file_exists(assets_dir, &AGG_VK_FILENAME) {
panic!("{} must exist in folder {}", *AGG_VK_FILENAME, assets_dir);
if !file_exists(assets_dir, &BATCH_VK_FILENAME) {
panic!("{} must exist in folder {}", *BATCH_VK_FILENAME, assets_dir);
}
let prover = Prover::from_dirs(params_dir, assets_dir);
@@ -49,15 +52,26 @@ pub unsafe extern "C" fn init_batch_verifier(params_dir: *const c_char, assets_d
// TODO: add a settings in scroll-prover.
env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir);
let verifier = Verifier::from_dirs(params_dir, assets_dir);
let verifier_v4 = VerifierV4::from_dirs(params_dir, assets_dir);
VERIFIER.set(verifier).unwrap();
VERIFIER_V4.set(verifier_v4).unwrap();
}
/// # Safety
#[no_mangle]
pub unsafe extern "C" fn get_batch_vk() -> *const c_char {
let vk_result = panic_catch(|| PROVER.get_mut().unwrap().get_vk());
let vk_result = panic_catch(|| PROVER.get_mut().unwrap().get_batch_vk());
vk_result
.ok()
.flatten()
.map_or(null(), |vk| string_to_c_char(base64::encode(vk)))
}
/// # Safety
#[no_mangle]
pub unsafe extern "C" fn get_bundle_vk() -> *const c_char {
let vk_result = panic_catch(|| PROVER.get_mut().unwrap().get_bundle_vk());
vk_result
.ok()
@@ -103,15 +117,19 @@ pub unsafe extern "C" fn check_chunk_proofs(chunk_proofs: *const c_char) -> *con
pub unsafe extern "C" fn gen_batch_proof(
chunk_hashes: *const c_char,
chunk_proofs: *const c_char,
batch_header: *const c_char,
) -> *const c_char {
let proof_result: Result<Vec<u8>, String> = panic_catch(|| {
let chunk_hashes = c_char_to_vec(chunk_hashes);
let chunk_proofs = c_char_to_vec(chunk_proofs);
let batch_header = c_char_to_vec(batch_header);
let chunk_hashes = serde_json::from_slice::<Vec<ChunkInfo>>(&chunk_hashes)
.map_err(|e| format!("failed to deserialize chunk hashes: {e:?}"))?;
let chunk_proofs = serde_json::from_slice::<Vec<ChunkProof>>(&chunk_proofs)
.map_err(|e| format!("failed to deserialize chunk proofs: {e:?}"))?;
let batch_header = serde_json::from_slice::<BatchHeader<MAX_AGG_SNARKS>>(&batch_header)
.map_err(|e| format!("failed to deserialize batch header: {e:?}"))?;
if chunk_hashes.len() != chunk_proofs.len() {
return Err(format!("chunk hashes and chunk proofs lengths mismatch: chunk_hashes.len() = {}, chunk_proofs.len() = {}",
@@ -125,12 +143,13 @@ pub unsafe extern "C" fn gen_batch_proof(
check_chunk_hashes("", &chunk_hashes_proofs).map_err(|e| format!("failed to check chunk info: {e:?}"))?;
let batch = BatchProvingTask {
chunk_proofs
chunk_proofs,
batch_header,
};
let proof = PROVER
.get_mut()
.expect("failed to get mutable reference to PROVER.")
.gen_agg_evm_proof(batch, None, OUTPUT_DIR.as_deref())
.gen_batch_proof(batch, None, OUTPUT_DIR.as_deref())
.map_err(|e| format!("failed to generate proof: {e:?}"))?;
serde_json::to_vec(&proof).map_err(|e| format!("failed to serialize the proof: {e:?}"))
@@ -153,10 +172,78 @@ pub unsafe extern "C" fn gen_batch_proof(
/// # Safety
#[no_mangle]
pub unsafe extern "C" fn verify_batch_proof(proof: *const c_char) -> c_char {
pub unsafe extern "C" fn verify_batch_proof(
proof: *const c_char,
fork_name: *const c_char,
) -> c_char {
let proof = c_char_to_vec(proof);
let proof = serde_json::from_slice::<BatchProof>(proof.as_slice()).unwrap();
let verified = panic_catch(|| VERIFIER.get().unwrap().verify_agg_evm_proof(proof));
let fork_name_str = c_char_to_str(fork_name);
let fork_id = match fork_name_str {
"curie" => 3,
"darwin" => 4,
_ => {
log::warn!("unexpected fork_name {fork_name_str}, treated as darwin");
4
}
};
let verified = panic_catch(|| {
if fork_id == 3 {
// As of upgrade #3 (Curie), we verify batch proofs on-chain (EVM).
let proof = serde_json::from_slice::<BatchProofV3>(proof.as_slice()).unwrap();
verify_evm_calldata(
include_bytes!("plonk_verifier_0.11.4.bin").to_vec(),
proof.calldata(),
)
} else {
// Post upgrade #4 (Darwin), batch proofs are not EVM-verifiable. Instead they are
// halo2 proofs meant to be bundled recursively.
let proof = serde_json::from_slice::<BatchProofV4>(proof.as_slice()).unwrap();
VERIFIER_V4.get().unwrap().verify_batch_proof(proof)
}
});
verified.unwrap_or(false) as c_char
}
/// # Safety
#[no_mangle]
pub unsafe extern "C" fn gen_bundle_proof(batch_proofs: *const c_char) -> *const c_char {
let proof_result: Result<Vec<u8>, String> = panic_catch(|| {
let batch_proofs = c_char_to_vec(batch_proofs);
let batch_proofs = serde_json::from_slice::<Vec<BatchProofV4>>(&batch_proofs)
.map_err(|e| format!("failed to deserialize batch proofs: {e:?}"))?;
let bundle = BundleProvingTask { batch_proofs };
let proof = PROVER
.get_mut()
.expect("failed to get mutable reference to PROVER.")
.gen_bundle_proof(bundle, None, OUTPUT_DIR.as_deref())
.map_err(|e| format!("failed to generate bundle proof: {e:?}"))?;
serde_json::to_vec(&proof)
.map_err(|e| format!("failed to serialize the bundle proof: {e:?}"))
})
.unwrap_or_else(|e| Err(format!("unwind error: {e:?}")));
let r = match proof_result {
Ok(proof_bytes) => ProofResult {
message: Some(proof_bytes),
error: None,
},
Err(err) => ProofResult {
message: None,
error: Some(err),
},
};
serde_json::to_vec(&r).map_or(null(), vec_to_c_char)
}
/// # Safety
#[no_mangle]
pub unsafe extern "C" fn verify_bundle_proof(proof: *const c_char) -> c_char {
let proof = c_char_to_vec(proof);
let proof = serde_json::from_slice::<BundleProof>(proof.as_slice()).unwrap();
let verified = panic_catch(|| VERIFIER_V4.get().unwrap().verify_bundle_proof(proof));
verified.unwrap_or(false) as c_char
}

View File

@@ -6,16 +6,18 @@ use crate::{
},
};
use libc::c_char;
use prover::{
use prover_v3::{zkevm::Verifier as VerifierV3, ChunkProof as ChunkProofV3};
use prover_v4::{
consts::CHUNK_VK_FILENAME,
utils::init_env_and_log,
zkevm::{Prover, Verifier},
BlockTrace, ChunkProof, ChunkProvingTask,
zkevm::{Prover, Verifier as VerifierV4},
BlockTrace, ChunkProof as ChunkProofV4, ChunkProvingTask,
};
use std::{cell::OnceCell, env, ptr::null};
static mut PROVER: OnceCell<Prover> = OnceCell::new();
static mut VERIFIER: OnceCell<Verifier> = OnceCell::new();
static mut VERIFIER_V3: OnceCell<VerifierV3> = OnceCell::new();
static mut VERIFIER_V4: OnceCell<VerifierV4> = OnceCell::new();
/// # Safety
#[no_mangle]
@@ -48,9 +50,11 @@ pub unsafe extern "C" fn init_chunk_verifier(params_dir: *const c_char, assets_d
// TODO: add a settings in scroll-prover.
env::set_var("SCROLL_PROVER_ASSETS_DIR", assets_dir);
let verifier = Verifier::from_dirs(params_dir, assets_dir);
let verifier_v3 = VerifierV3::from_dirs(params_dir, assets_dir);
let verifier_v4 = VerifierV4::from_dirs(params_dir, assets_dir);
VERIFIER.set(verifier).unwrap();
VERIFIER_V3.set(verifier_v3).unwrap();
VERIFIER_V4.set(verifier_v4).unwrap();
}
/// # Safety
@@ -99,10 +103,29 @@ pub unsafe extern "C" fn gen_chunk_proof(block_traces: *const c_char) -> *const
/// # Safety
#[no_mangle]
pub unsafe extern "C" fn verify_chunk_proof(proof: *const c_char) -> c_char {
pub unsafe extern "C" fn verify_chunk_proof(
proof: *const c_char,
fork_name: *const c_char,
) -> c_char {
let proof = c_char_to_vec(proof);
let proof = serde_json::from_slice::<ChunkProof>(proof.as_slice()).unwrap();
let verified = panic_catch(|| VERIFIER.get().unwrap().verify_chunk_proof(proof));
let fork_name_str = c_char_to_str(fork_name);
let fork_id = match fork_name_str {
"curie" => 3,
"darwin" => 4,
_ => {
log::warn!("unexpected fork_name {fork_name_str}, treated as darwin");
4
}
};
let verified = panic_catch(|| {
if fork_id == 3 {
let proof = serde_json::from_slice::<ChunkProofV3>(proof.as_slice()).unwrap();
VERIFIER_V3.get().unwrap().verify_chunk_proof(proof)
} else {
let proof = serde_json::from_slice::<ChunkProofV4>(proof.as_slice()).unwrap();
VERIFIER_V4.get().unwrap().verify_chunk_proof(proof)
}
});
verified.unwrap_or(false) as c_char
}

Binary file not shown.

View File

@@ -1,15 +1,26 @@
// BatchProver is used to:
// - Batch a list of chunk proofs
// - Bundle a list of batch proofs
void init_batch_prover(char* params_dir, char* assets_dir);
// BatchVerifier is used to:
// - Verify a batch proof
// - Verify a bundle proof
void init_batch_verifier(char* params_dir, char* assets_dir);
char* get_batch_vk();
char* check_chunk_proofs(char* chunk_proofs);
char* gen_batch_proof(char* chunk_hashes, char* chunk_proofs);
char verify_batch_proof(char* proof);
char* gen_batch_proof(char* chunk_hashes, char* chunk_proofs, char* batch_header);
char verify_batch_proof(char* proof, char* fork_name);
char* get_bundle_vk();
char* gen_bundle_proof(char* batch_proofs);
char verify_bundle_proof(char* proof);
void init_chunk_prover(char* params_dir, char* assets_dir);
void init_chunk_verifier(char* params_dir, char* assets_dir);
char* get_chunk_vk();
char* gen_chunk_proof(char* block_traces);
char verify_chunk_proof(char* proof);
char verify_chunk_proof(char* proof, char* fork_name);
char* block_traces_to_chunk_info(char* block_traces);
void free_c_chars(char* ptr);

View File

@@ -52,22 +52,14 @@ type ChunkTaskDetail struct {
// BatchTaskDetail is a type containing BatchTask detail.
type BatchTaskDetail struct {
ChunkInfos []*ChunkInfo `json:"chunk_infos"`
ChunkProofs []*ChunkProof `json:"chunk_proofs"`
ParentStateRoot common.Hash `json:"parent_state_root"`
ParentBatchHash common.Hash `json:"parent_batch_hash"`
BatchHeader *codecv3.DABatch `json:"batch_header"`
ChunkInfos []*ChunkInfo `json:"chunk_infos"`
ChunkProofs []*ChunkProof `json:"chunk_proofs"`
BatchHeader *codecv3.DABatch `json:"batch_header"`
}
// BundleTaskDetail consists of all the information required to describe the task to generate a proof for a bundle of batches.
type BundleTaskDetail struct {
ChainID uint64 `json:"chain_id"`
FinalizedBatchHash common.Hash `json:"finalized_batch_hash"`
FinalizedStateRoot common.Hash `json:"finalized_state_root"`
PendingBatchHash common.Hash `json:"pending_batch_hash"`
PendingStateRoot common.Hash `json:"pending_state_root"`
PendingWithdrawRoot common.Hash `json:"pending_withdraw_root"`
BatchProofs []*BatchProof `json:"batch_proofs"`
BatchProofs []*BatchProof `json:"batch_proofs"`
}
// ChunkInfo is for calculating pi_hash for chunk

View File

@@ -214,8 +214,6 @@ func (bp *BatchProverTask) formatProverTask(ctx context.Context, task *orm.Prove
}
if hardForkName == "darwin" {
taskDetail.ParentStateRoot = common.HexToHash(chunks[0].ParentChunkStateRoot)
taskDetail.ParentBatchHash = common.HexToHash(batch.ParentBatchHash)
batchHeader, decodeErr := codecv3.NewDABatchFromBytes(batch.BatchHeader)
if decodeErr != nil {
return nil, fmt.Errorf("failed to decode batch header, taskID:%s err:%w", task.TaskID, decodeErr)

View File

@@ -9,7 +9,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/log"
"github.com/scroll-tech/go-ethereum/params"
"gorm.io/gorm"
@@ -209,15 +208,8 @@ func (bp *BundleProverTask) formatProverTask(ctx context.Context, task *orm.Prov
batchProofs = append(batchProofs, &proof)
}
lastPendingBatch := batches[len(batches)-1]
taskDetail := message.BundleTaskDetail{
ChainID: bp.cfg.L2.ChainID,
FinalizedBatchHash: common.HexToHash(latestFinalizedBatch.Hash),
FinalizedStateRoot: common.HexToHash(latestFinalizedBatch.StateRoot),
PendingBatchHash: common.HexToHash(lastPendingBatch.Hash),
PendingStateRoot: common.HexToHash(lastPendingBatch.StateRoot),
PendingWithdrawRoot: common.HexToHash(lastPendingBatch.WithdrawRoot),
BatchProofs: batchProofs,
BatchProofs: batchProofs,
}
batchProofsBytes, err := json.Marshal(taskDetail)

View File

@@ -169,7 +169,8 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor
if getHardForkErr != nil {
return ErrGetHardForkNameFailed
}
// only verify batch proof. chunk proof verifier have been disabled after Bernoulli
// Post-Bernoulli we do not verify chunk proofs.
// Verify batch proof
if message.ProofType(proofParameter.TaskType) == message.ProofTypeBatch {
var batchProof message.BatchProof
if unmarshalErr := json.Unmarshal([]byte(proofParameter.Proof), &batchProof); unmarshalErr != nil {
@@ -177,9 +178,13 @@ func (m *ProofReceiverLogic) HandleZkProof(ctx *gin.Context, proofParameter coor
}
success, verifyErr = m.verifier.VerifyBatchProof(&batchProof, hardForkName)
}
// Verify bundle proof
if message.ProofType(proofParameter.TaskType) == message.ProofTypeBundle {
// TODO add bundle check here
var bundleProof message.BundleProof
if unmarshalErr := json.Unmarshal([]byte(proofParameter.Proof), &bundleProof); unmarshalErr != nil {
return unmarshalErr
}
success, verifyErr = m.verifier.VerifyBundleProof(&bundleProof)
}
if verifyErr != nil || !success {

View File

@@ -30,3 +30,11 @@ func (v *Verifier) VerifyBatchProof(proof *message.BatchProof, forkName string)
}
return true, nil
}
// VerifyBundleProof return a mock verification result for a BundleProof.
func (v *Verifier) VerifyBundleProof(proof *message.BundleProof) (bool, error) {
if string(proof.Proof) == InvalidTestProof {
return false, nil
}
return true, nil
}

View File

@@ -22,7 +22,7 @@ import (
"github.com/scroll-tech/go-ethereum/log"
coordinatorType "scroll-tech/common/types/message"
"scroll-tech/common/types/message"
"scroll-tech/coordinator/internal/config"
)
@@ -30,9 +30,10 @@ import (
// NewVerifier Sets up a rust ffi to call verify.
func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
if cfg.MockMode {
batchVKMap := map[string]string{cfg.ForkName: "mock_vk"}
chunkVKMap := map[string]string{cfg.ForkName: "mock_vk"}
return &Verifier{cfg: cfg, ChunkVKMap: chunkVKMap, BatchVKMap: batchVKMap}, nil
batchVKMap := map[string]string{cfg.ForkName: "mock_vk"}
bundleVKMap := map[string]string{cfg.ForkName: "mock_vk"}
return &Verifier{cfg: cfg, ChunkVKMap: chunkVKMap, BatchVKMap: batchVKMap, BundleVkMap: bundleVKMap}, nil
}
paramsPathStr := C.CString(cfg.ParamsPath)
assetsPathStr := C.CString(cfg.AssetsPath)
@@ -50,15 +51,15 @@ func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
BatchVKMap: make(map[string]string),
}
bundleVK, err := v.readVK(path.Join(cfg.AssetsPath, "bundle_vk.vkey"))
bundleVK, err := v.readVK(path.Join(cfg.AssetsPath, "vk_bundle.vkey"))
if err != nil {
return nil, err
}
batchVK, err := v.readVK(path.Join(cfg.AssetsPath, "batch_vk.vkey"))
batchVK, err := v.readVK(path.Join(cfg.AssetsPath, "vk_batch.vkey"))
if err != nil {
return nil, err
}
chunkVK, err := v.readVK(path.Join(cfg.AssetsPath, "chunk_vk.vkey"))
chunkVK, err := v.readVK(path.Join(cfg.AssetsPath, "vk_chunk.vkey"))
if err != nil {
return nil, err
}
@@ -73,7 +74,7 @@ func NewVerifier(cfg *config.VerifierConfig) (*Verifier, error) {
}
// VerifyBatchProof Verify a ZkProof by marshaling it and sending it to the Halo2 Verifier.
func (v *Verifier) VerifyBatchProof(proof *coordinatorType.BatchProof, forkName string) (bool, error) {
func (v *Verifier) VerifyBatchProof(proof *message.BatchProof, forkName string) (bool, error) {
if v.cfg.MockMode {
log.Info("Mock mode, batch verifier disabled")
if string(proof.Proof) == InvalidTestProof {
@@ -95,12 +96,39 @@ func (v *Verifier) VerifyBatchProof(proof *coordinatorType.BatchProof, forkName
C.free(unsafe.Pointer(forkNameStr))
}()
verified := C.verify_batch_proof(proofStr)
verified := C.verify_batch_proof(proofStr, forkNameStr)
return verified != 0, nil
}
// VerifyChunkProof Verify a ZkProof by marshaling it and sending it to the Halo2 Verifier.
func (v *Verifier) VerifyChunkProof(proof *coordinatorType.ChunkProof) (bool, error) {
func (v *Verifier) VerifyChunkProof(proof *message.ChunkProof, forkName string) (bool, error) {
if v.cfg.MockMode {
log.Info("Mock mode, verifier disabled")
if string(proof.Proof) == InvalidTestProof {
return false, nil
}
return true, nil
}
buf, err := json.Marshal(proof)
if err != nil {
return false, err
}
log.Info("Start to verify chunk proof", "forkName", forkName)
proofStr := C.CString(string(buf))
forkNameStr := C.CString(forkName)
defer func() {
C.free(unsafe.Pointer(proofStr))
C.free(unsafe.Pointer(forkNameStr))
}()
verified := C.verify_chunk_proof(proofStr, forkNameStr)
return verified != 0, nil
}
// VerifyBundleProof Verify a ZkProof for a bundle of batches, by marshaling it and verifying it via the EVM verifier.
func (v *Verifier) VerifyBundleProof(proof *message.BundleProof) (bool, error) {
if v.cfg.MockMode {
log.Info("Mock mode, verifier disabled")
if string(proof.Proof) == InvalidTestProof {
@@ -119,8 +147,8 @@ func (v *Verifier) VerifyChunkProof(proof *coordinatorType.ChunkProof) (bool, er
C.free(unsafe.Pointer(proofStr))
}()
log.Info("Start to verify chunk proof ...")
verified := C.verify_chunk_proof(proofStr)
log.Info("Start to verify bundle proof ...")
verified := C.verify_bundle_proof(proofStr)
return verified != 0, nil
}

View File

@@ -11,7 +11,7 @@ import (
"gorm.io/gorm/clause"
"scroll-tech/common/types"
coordinatorType "scroll-tech/common/types/message"
"scroll-tech/common/types/message"
"scroll-tech/common/utils"
)
@@ -98,7 +98,7 @@ func (o *ProverTask) GetProverTasks(ctx context.Context, fields map[string]inter
// GetProverTasksByHashes retrieves the ProverTask records associated with the specified hashes.
// The returned prover task objects are sorted in ascending order by their ids.
func (o *ProverTask) GetProverTasksByHashes(ctx context.Context, taskType coordinatorType.ProofType, hashes []string) ([]*ProverTask, error) {
func (o *ProverTask) GetProverTasksByHashes(ctx context.Context, taskType message.ProofType, hashes []string) ([]*ProverTask, error) {
if len(hashes) == 0 {
return nil, nil
}
@@ -118,7 +118,7 @@ func (o *ProverTask) GetProverTasksByHashes(ctx context.Context, taskType coordi
// GetAssignedProverTaskByTaskIDAndProver get prover task taskID and public key
// TODO: when prover all upgrade need DEPRECATED this function
func (o *ProverTask) GetAssignedProverTaskByTaskIDAndProver(ctx context.Context, taskType coordinatorType.ProofType, taskID, proverPublicKey, proverVersion string) (*ProverTask, error) {
func (o *ProverTask) GetAssignedProverTaskByTaskIDAndProver(ctx context.Context, taskType message.ProofType, taskID, proverPublicKey, proverVersion string) (*ProverTask, error) {
db := o.db.WithContext(ctx)
db = db.Model(&ProverTask{})
db = db.Where("task_type", int(taskType))
@@ -151,7 +151,7 @@ func (o *ProverTask) GetProverTaskByUUIDAndPublicKey(ctx context.Context, uuid,
}
// GetAssignedTaskOfOtherProvers get the chunk/batch task assigned other provers
func (o *ProverTask) GetAssignedTaskOfOtherProvers(ctx context.Context, taskType coordinatorType.ProofType, taskID, proverPublicKey string) ([]ProverTask, error) {
func (o *ProverTask) GetAssignedTaskOfOtherProvers(ctx context.Context, taskType message.ProofType, taskID, proverPublicKey string) ([]ProverTask, error) {
db := o.db.WithContext(ctx)
db = db.Model(&ProverTask{})
db = db.Where("task_type", int(taskType))
@@ -167,7 +167,7 @@ func (o *ProverTask) GetAssignedTaskOfOtherProvers(ctx context.Context, taskType
}
// GetProvingStatusByTaskID retrieves the proving status of a prover task
func (o *ProverTask) GetProvingStatusByTaskID(ctx context.Context, taskType coordinatorType.ProofType, taskID string) (types.ProverProveStatus, error) {
func (o *ProverTask) GetProvingStatusByTaskID(ctx context.Context, taskType message.ProofType, taskID string) (types.ProverProveStatus, error) {
db := o.db.WithContext(ctx)
db = db.Model(&ProverTask{})
db = db.Select("proving_status")
@@ -182,7 +182,7 @@ func (o *ProverTask) GetProvingStatusByTaskID(ctx context.Context, taskType coor
}
// GetTimeoutAssignedProverTasks get the timeout and assigned proving_status prover task
func (o *ProverTask) GetTimeoutAssignedProverTasks(ctx context.Context, limit int, taskType coordinatorType.ProofType, timeout time.Duration) ([]ProverTask, error) {
func (o *ProverTask) GetTimeoutAssignedProverTasks(ctx context.Context, limit int, taskType message.ProofType, timeout time.Duration) ([]ProverTask, error) {
db := o.db.WithContext(ctx)
db = db.Model(&ProverTask{})
db = db.Where("proving_status", int(types.ProverAssigned))
@@ -199,7 +199,7 @@ func (o *ProverTask) GetTimeoutAssignedProverTasks(ctx context.Context, limit in
}
// TaskTimeoutMoreThanOnce get the timeout twice task. a temp design
func (o *ProverTask) TaskTimeoutMoreThanOnce(ctx context.Context, taskType coordinatorType.ProofType, taskID string) bool {
func (o *ProverTask) TaskTimeoutMoreThanOnce(ctx context.Context, taskType message.ProofType, taskID string) bool {
db := o.db.WithContext(ctx)
db = db.Model(&ProverTask{})
db = db.Where("task_type", int(taskType))