Skip to content

Commit

Permalink
Add test-batch-prove (#234)
Browse files Browse the repository at this point in the history
* Add `test-batch-prove`.

* Add enum `LayerId`, and test functions `gen_and_verify_batch_proofs` and `gen_and_verify_chunk_proofs`.

* Add `verify_chunk_proof`.

* Dump chunk-procotol in `batch_tests`.
  • Loading branch information
silathdiir authored Aug 23, 2023
1 parent a29cbaa commit 132b2a7
Show file tree
Hide file tree
Showing 11 changed files with 290 additions and 157 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ test-chunk-prove:
test-agg-prove:
@cargo test --features prove_verify --release test_agg_prove_verify

test-batch-prove:
@cargo test --features prove_verify --release test_batch_prove_verify

test-ccc:
@cargo test --release test_capacity_checker

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ make download-setup -e degree=DEGREE params_dir=PARAMS_DIR

`make test-chunk-prove` and `make test-agg-prove` are the main testing entries for multi-level circuit constraint system of scroll-prover. Developers could understand how the system works by reading the codes of these tests.

Besides it, `make test-inner-prove` could be used to test the first-level circuit.
Besides it, `make test-inner-prove` could be used to test the first-level circuit, and `make test-batch-prove` could be used to test the final two levels.

### Binaries

Expand Down
48 changes: 47 additions & 1 deletion prover/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::utils::read_env_var;
use aggregator::ConfigParams;
use once_cell::sync::Lazy;
use std::{collections::HashSet, fs::File, path::Path};
use std::{collections::HashSet, fmt, fs::File, path::Path};

pub static INNER_DEGREE: Lazy<u32> = Lazy::new(|| read_env_var("SCROLL_PROVER_INNER_DEGREE", 20));

Expand Down Expand Up @@ -29,6 +29,52 @@ pub static ZKEVM_DEGREES: Lazy<Vec<u32>> = Lazy::new(|| {
pub static AGG_DEGREES: Lazy<Vec<u32>> =
Lazy::new(|| Vec::from_iter(HashSet::from([*LAYER3_DEGREE, *LAYER4_DEGREE])));

pub enum LayerId {
/// Compression wide layer
Layer1,
/// Compression thin layer (to generate chunk-proof)
Layer2,
/// Aggregation layer
Layer3,
/// Compression thin layer (to generate batch-proof)
Layer4,
}

impl fmt::Display for LayerId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.id())
}
}

impl LayerId {
pub fn id(&self) -> &str {
match self {
Self::Layer1 => "layer1",
Self::Layer2 => "layer2",
Self::Layer3 => "layer3",
Self::Layer4 => "layer4",
}
}

pub fn degree(&self) -> u32 {
match self {
Self::Layer1 => *LAYER1_DEGREE,
Self::Layer2 => *LAYER2_DEGREE,
Self::Layer3 => *LAYER3_DEGREE,
Self::Layer4 => *LAYER4_DEGREE,
}
}

pub fn config_path(&self) -> &str {
match self {
Self::Layer1 => &LAYER1_CONFIG_PATH,
Self::Layer2 => &LAYER2_CONFIG_PATH,
Self::Layer3 => &LAYER3_CONFIG_PATH,
Self::Layer4 => &LAYER4_CONFIG_PATH,
}
}
}

pub fn layer_config_path(id: &str) -> &str {
match id {
"layer1" => &LAYER1_CONFIG_PATH,
Expand Down
2 changes: 1 addition & 1 deletion prover/src/proof/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use snark_verifier::Protocol;
use snark_verifier_sdk::Snark;
use types::{base64, eth::StorageTrace};

#[derive(Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ChunkProof {
#[serde(with = "base64")]
pub storage_trace: Vec<u8>,
Expand Down
2 changes: 1 addition & 1 deletion prover/src/proof/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use halo2_proofs::{
};
use serde_derive::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct EvmProof {
pub proof: Proof,
pub num_instance: Vec<usize>,
Expand Down
3 changes: 3 additions & 0 deletions prover/src/test_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use glob::glob;
use types::eth::BlockTrace;

pub mod mock_plonk;
mod proof;

pub use proof::{gen_and_verify_batch_proofs, gen_and_verify_chunk_proofs};

pub const PARAMS_DIR: &str = "./test_params";

Expand Down
149 changes: 149 additions & 0 deletions prover/src/test_util/proof.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use crate::{
aggregator::{Prover, Verifier},
common,
config::LayerId,
test_util::PARAMS_DIR,
zkevm, BatchProof, ChunkProof, EvmProof,
};
use aggregator::CompressionCircuit;
use snark_verifier_sdk::Snark;
use std::env;
use types::eth::StorageTrace;

pub fn gen_and_verify_batch_proofs(agg_prover: &mut Prover, layer3_snark: Snark, output_dir: &str) {
let normal_proof = gen_normal_proof(
&mut agg_prover.inner,
LayerId::Layer4,
layer3_snark.clone(),
output_dir,
);
let evm_proof = gen_evm_proof(
&mut agg_prover.inner,
LayerId::Layer4,
layer3_snark,
output_dir,
);
verify_normal_and_evm_proofs(
&mut agg_prover.inner,
LayerId::Layer4,
normal_proof,
&evm_proof,
output_dir,
);
verify_batch_proof(evm_proof, output_dir);
}

pub fn gen_and_verify_chunk_proofs(
zkevm_prover: &mut zkevm::Prover,
layer1_snark: Snark,
output_dir: &str,
) {
let normal_proof = gen_normal_proof(
&mut zkevm_prover.inner,
LayerId::Layer2,
layer1_snark.clone(),
output_dir,
);
let evm_proof = gen_evm_proof(
&mut zkevm_prover.inner,
LayerId::Layer2,
layer1_snark,
output_dir,
);
verify_normal_and_evm_proofs(
&mut zkevm_prover.inner,
LayerId::Layer2,
normal_proof.clone(),
&evm_proof,
output_dir,
);
verify_chunk_proof(&zkevm_prover.inner, normal_proof, output_dir);
}

fn gen_evm_proof(
prover: &mut common::Prover,
layer_id: LayerId,
previous_snark: Snark,
output_dir: &str,
) -> EvmProof {
let id = layer_id.id();
let degree = layer_id.degree();

// Load or generate compression EVM proof.
let evm_proof = prover
.load_or_gen_comp_evm_proof("evm", id, true, degree, previous_snark, Some(output_dir))
.unwrap();
log::info!("Generated EVM proof: {id}");

evm_proof
}

fn gen_normal_proof(
prover: &mut common::Prover,
layer_id: LayerId,
previous_snark: Snark,
output_dir: &str,
) -> Snark {
let id = layer_id.id();
let degree = layer_id.degree();

// Load or generate compression snark.
let snark = prover
.load_or_gen_comp_snark("normal", id, true, degree, previous_snark, Some(output_dir))
.unwrap();
log::info!("Generated compression snark: {id}");

snark
}

fn verify_batch_proof(evm_proof: EvmProof, output_dir: &str) {
let batch_proof = BatchProof::from(evm_proof.proof);
batch_proof.dump(output_dir, "agg").unwrap();
batch_proof.clone().assert_calldata();

env::set_var("AGG_VK_FILENAME", "vk_evm_layer4_evm.vkey");
let verifier = Verifier::from_dirs(PARAMS_DIR, output_dir);
log::info!("Constructed aggregator verifier");

assert!(verifier.verify_agg_evm_proof(batch_proof));
log::info!("Verified batch proof");
}

fn verify_chunk_proof(prover: &common::Prover, normal_proof: Snark, output_dir: &str) {
let pk = prover.pk(LayerId::Layer2.id()).unwrap();
let chunk_proof =
ChunkProof::new(normal_proof, StorageTrace::default(), Some(pk), None).unwrap();
chunk_proof.dump(output_dir, "0").unwrap();

env::set_var("CHUNK_VK_FILENAME", "vk_chunk_0.vkey");
let verifier = zkevm::Verifier::from_dirs(PARAMS_DIR, output_dir);
log::info!("Constructed zkevm verifier");

assert!(verifier.verify_chunk_proof(chunk_proof));
log::info!("Verified chunk proof");
}

fn verify_normal_and_evm_proofs(
prover: &mut common::Prover,
layer_id: LayerId,
normal_proof: Snark,
evm_proof: &EvmProof,
output_dir: &str,
) {
let id = layer_id.id();
let degree = layer_id.degree();
let config_path = layer_id.config_path();

env::set_var("COMPRESSION_CONFIG", config_path);
let vk = evm_proof.proof.vk::<CompressionCircuit>();

let params = prover.params(degree).clone();
let verifier = common::Verifier::<CompressionCircuit>::new(params, vk);
log::info!("Constructed common verifier");

assert!(verifier.verify_snark(normal_proof));
log::info!("Verified normal proof: {id}");

verifier.evm_verify(evm_proof, output_dir);
log::info!("Verified EVM proof: {id}");
}
90 changes: 4 additions & 86 deletions prover/tests/aggregation_tests.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
use aggregator::CompressionCircuit;
use prover::{
aggregator::{Prover, Verifier},
common,
config::{LAYER4_CONFIG_PATH, LAYER4_DEGREE},
test_util::{load_block_traces_for_test, PARAMS_DIR},
aggregator::Prover,
test_util::{gen_and_verify_batch_proofs, load_block_traces_for_test, PARAMS_DIR},
utils::{chunk_trace_to_witness_block, init_env_and_log},
zkevm, BatchProof, ChunkHash, ChunkProof, EvmProof, Proof,
zkevm, ChunkHash, ChunkProof,
};
use snark_verifier_sdk::Snark;
use std::env;

#[cfg(feature = "prove_verify")]
Expand All @@ -33,85 +29,7 @@ fn test_agg_prove_verify() {
.load_or_gen_last_agg_snark("agg", chunk_hashes_proofs, Some(&output_dir))
.unwrap();

let (evm_proof, agg_verifier) =
gen_and_verify_evm_proof(&output_dir, &mut agg_prover, layer3_snark.clone());

gen_and_verify_normal_proof(
&output_dir,
&mut agg_prover,
&agg_verifier,
evm_proof.proof.raw_vk().to_vec(),
layer3_snark,
);
}

fn gen_and_verify_evm_proof(
output_dir: &str,
prover: &mut Prover,
layer3_snark: Snark,
) -> (EvmProof, Verifier) {
// Load or generate compression EVM proof (layer-4).
let evm_proof = prover
.inner
.load_or_gen_comp_evm_proof(
"evm",
"layer4",
true,
*LAYER4_DEGREE,
layer3_snark,
Some(&output_dir),
)
.unwrap();
log::info!("Got compression-EVM-proof (layer-4)");

env::set_var("COMPRESSION_CONFIG", &*LAYER4_CONFIG_PATH);
let vk = evm_proof.proof.vk::<CompressionCircuit>();

let params = prover.inner.params(*LAYER4_DEGREE).clone();
common::Verifier::<CompressionCircuit>::new(params, vk).evm_verify(&evm_proof, &output_dir);
log::info!("Generated deployment bytecode");

env::set_var("AGG_VK_FILENAME", "vk_evm_layer4_evm.vkey");
let verifier = Verifier::from_dirs(PARAMS_DIR, output_dir);
log::info!("Constructed aggregator verifier");

let batch_proof = BatchProof::from(evm_proof.proof.clone());
batch_proof.dump(output_dir, "agg").unwrap();
batch_proof.clone().assert_calldata();

let success = verifier.verify_agg_evm_proof(batch_proof);
assert!(success);
log::info!("Finished EVM verification");

(evm_proof, verifier)
}

fn gen_and_verify_normal_proof(
output_dir: &str,
prover: &mut Prover,
verifier: &Verifier,
raw_vk: Vec<u8>,
layer3_snark: Snark,
) {
// Load or generate compression thin snark (layer-4).
let layer4_snark = prover
.inner
.load_or_gen_comp_snark(
"layer4",
"layer4",
true,
*LAYER4_DEGREE,
layer3_snark,
Some(&output_dir),
)
.unwrap();
log::info!("Got compression thin snark (layer-4)");

let proof = Proof::from_snark(layer4_snark, raw_vk);
log::info!("Got normal proof");

assert!(verifier.inner.verify_proof(proof));
log::info!("Finished normal verification");
gen_and_verify_batch_proofs(&mut agg_prover, layer3_snark, &output_dir);
}

fn gen_chunk_hashes_and_proofs(
Expand Down
Loading

0 comments on commit 132b2a7

Please sign in to comment.