Skip to content

Commit

Permalink
Circuit benchmarks addition to workspace (privacy-scaling-exploration…
Browse files Browse the repository at this point in the history
…s#226)

* Add bench profile to workspace Cargo.toml

* Add benchmark running rules to Makefile

* Change CI to test the benchmarks without run

* Add circuit-benchmarks crate

This crate is responsible for allowing to run the circuit
benchmarks on a more easy and clean way.

* Update visibility of Circuit structs to allow benchmarks

* Compile crate before checking rustfmt

* Fix rebase unused_imports

* Add state_circuit module during build.rs run

* Change to more descriptive env var error messages

Co-authored-by: Eduard S. <[email protected]>

* Fix Makefile and CI

* Fix ethers dep to pull grom git

While a new version is not published in crates.io, we need to pull from
git.

* Change state_circuit generation from build.rs

* Update evm_circuit to latest main version

Co-authored-by: Han <[email protected]>

* Fix contract deployment breaking change issues

`ethers-solc` had a breaking change within patch versions.
This solves it while we still depend on the git dep.

* Update solc version used in integration CI job to 0.8.10

Co-authored-by: Eduard S. <[email protected]>

Co-authored-by: Eduard S. <[email protected]>
Co-authored-by: Han <[email protected]>
  • Loading branch information
3 people authored Dec 16, 2021
1 parent 1f5c8aa commit 8fec0e5
Show file tree
Hide file tree
Showing 20 changed files with 401 additions and 106 deletions.
13 changes: 12 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --release --all --all-features --exclude integration-tests
args: --verbose --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks

build:
if: github.event.pull_request.draft == false
Expand All @@ -53,6 +53,12 @@ jobs:
with:
command: build
args: --all-features
# Make sure benchmarks compile.
- name: cargo build benchmarks no-run
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --release --all-features -p circuit-benchmarks --no-run

bitrot:
if: github.event.pull_request.draft == false
Expand Down Expand Up @@ -107,6 +113,11 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
override: false
- name: cargo check
uses: actions-rs/cargo@v1
with:
command: check
args: --all-features
- run: rustup component add rustfmt
- uses: actions-rs/cargo@v1
with:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ jobs:
run: echo "${HOME}/bin" >> $GITHUB_PATH
- name: Install Solc
run: |
mkdir -p "$HOME/bin"
wget -q https://github.com/ethereum/solidity/releases/download/v0.8.0/solc-static-linux -O $HOME/bin/solc
chmod u+x "$HOME/bin/solc"
solc --version
mkdir -p "$HOME/bin"
wget -q https://github.com/ethereum/solidity/releases/download/v0.8.10/solc-static-linux -O $HOME/bin/solc
chmod u+x "$HOME/bin/solc"
solc --version
# Run an initial build in a sepparate step to split the build time from execution time
- name: Build gendata bin
run: cargo build --bin gen_blockchain_data
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/lints.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

name: Lints

# We only run these lints on trial-merges of PRs to reduce noise.
Expand Down
16 changes: 16 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"keccak256",
"geth-utils",
"integration-tests",
"circuit-benchmarks"
]

[patch.crates-io]
Expand All @@ -14,3 +15,18 @@ halo2 = { git = "https://github.com/appliedzkp/halo2.git", rev = "b78c39cacc1c79
# and leads to a compilation error. This can be removed once the upstream PR
# is resolved: https://github.com/bitvecto-rs/bitvec/pull/141
bitvec = { git = "https://github.com/ed255/bitvec.git", rev = "5cfc5fa8496c66872d21905e677120fc3e79693c" }

ethers-providers = { git = "https://github.com/gakonst/ethers-rs.git", rev = "6cbdc891876851355c4f8d300d24d7dab5bb9af3" }
ethers-core = { git = "https://github.com/gakonst/ethers-rs.git", rev = "6cbdc891876851355c4f8d300d24d7dab5bb9af3" }
ethers = { git = "https://github.com/gakonst/ethers-rs.git", rev = "6cbdc891876851355c4f8d300d24d7dab5bb9af3" }

# Definition of benchmarks profile to use.
[profile.bench]
opt-level = 3
debug = false
debug-assertions = false
overflow-checks = false
rpath = false
lto = "thin"
incremental = false
codegen-units = 1
19 changes: 16 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,31 @@ help: ## Display this help screen
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

clippy: ## Run clippy checks over all workspace members
@cargo check --all-features
@cargo clippy --all-features --all-targets -- -D clippy::all

doc: ## Generate and tests docs including private items
@cargo doc --all --document-private-items

fmt: ## Check whether the code is formated correctly
@cargo check --all-features
@cargo fmt --all -- --check

test: ## Run tests for all the workspace members
@cargo test --release --all --all-features
@cargo test --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks

test-all: fmt doc clippy test ## Run all the CI checks locally (in your actual toolchain)
test_benches: ## Compiles the benchmarks
@cargo test --verbose --release --all-features -p circuit-benchmarks --no-run

test-all: fmt doc clippy test_benches test ## Run all the CI checks locally (in your actual toolchain)

.PHONY: clippy doc fmt test test-all help
evm_bench: ## Run Evm Circuit benchmarks
@cargo test --profile bench bench_evm_circuit_prover -p circuit-benchmarks --features benches -- --nocapture

state_bench: ## Run State Circuit benchmarks
@cargo test --profile bench bench_evm_circuit_prover -p circuit-benchmarks --features benches -- --nocapture

circuit_benches: evm_bench state_bench ## Run All Circuit benchmarks


.PHONY: clippy doc fmt test test_benches test-all evm_bench state_bench circuit_benches help
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,16 @@ Check out the work in progress [specification](https://github.com/appliedzkp/zke

## Getting started

`make test-all`
To run the same tests as the CI, please use: `make test-all`.

## Running benchmarks

There are currently two benchmarks to run in the workspace in regards to the circuits.
Both use the `DEGREE` env var to specify the degree of the `K` parameter that you want
to use for your circuit in the bench process.
- EVM Circuit prover benches. -> `DEGREE=18 make evm_bench`.
- State Circuit prover benches. -> `DEGREE=18, MEMORY_ADDRESS_MAX=3000, STACK_ADDRESS_MAX=1500 make state_bench`
For state circuit, `MEMORY_ADDRESS_MAX` and `STACK_ADDRESS_MAX` do not need to be specified.
By default will take values: 2000 and 1300.

You can also run both benchmarks by running: `make circuit_benches DEGREE=18`.
4 changes: 2 additions & 2 deletions bus-mapping/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ serde_json = "1.0.66"
hex = "0.4"
geth-utils = { path = "../geth-utils" }
uint = "0.9.1"
ethers-providers = "0.6.2"
ethers-core = "0.6.2"
ethers-providers = "0.6"
ethers-core = "0.6"
regex = "1.5.4"

[dev-dependencies]
Expand Down
20 changes: 20 additions & 0 deletions circuit-benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "circuit-benchmarks"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ff = "0.11"
halo2 = { git = "https://github.com/appliedzkp/halo2.git", rev = "b78c39cacc1c79d287032f1b5f94beb661b3fb42" }
pairing = { git = 'https://github.com/appliedzkp/pairing', package = "pairing_bn256" }
ark-std = { version = "0.3", features = ["print-trace"] }
zkevm-circuits = { path = "../zkevm-circuits" }
bus-mapping = { path = "../bus-mapping" }
rand_xorshift = "0.3"
rand = "0.8"

[features]
default = []
benches = []
36 changes: 36 additions & 0 deletions circuit-benchmarks/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! Generate the benchmark file for State Circuit fetching the bench parameters
//! from ENV.
use std::env::var;
use std::fs::*;
use std::io::Write;

fn main() {
let degree: usize = var("DEGREE")
.unwrap_or_else(|_| "11".to_string())
.parse()
.expect("Cannot parse DEGREE env var as usize");
let memory_address_max: usize = var("MEMORY_ADDRESS_MAX")
.unwrap_or_else(|_| "2000".to_string())
.parse()
.expect("Cannot parse MEMORY_ADDRESS_MAX env var as usize");
let stack_address_max: usize = var("STACK_ADDRESS_MAX")
.unwrap_or_else(|_| "1300".to_string())
.parse()
.expect("Cannot parse STACK_ADDRESS_MAX env var as usize");

// Add state_circuit module to `lib.rs`
let consts = format!(
"pub(crate) const DEGREE: usize = {};
pub(crate) const MEMORY_ADDRESS_MAX: usize = {};
pub(crate) const STACK_ADDRESS_MAX: usize = {};
",
degree, memory_address_max, stack_address_max
);

let mut state_file = File::create("src/bench_params.rs")
.expect("Error generating bench_params.rs file");
state_file
.write_all(consts.as_bytes())
.expect("Error writing to bench_params.rs file");
}
110 changes: 110 additions & 0 deletions circuit-benchmarks/src/evm_circuit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//! Evm circuit benchmarks
use halo2::{
arithmetic::FieldExt,
circuit::{Layouter, SimpleFloorPlanner},
plonk::{Circuit, ConstraintSystem, Error},
};
use zkevm_circuits::evm_circuit::{bus_mapping_tmp::Block, EvmCircuit};

#[derive(Debug, Default)]
pub struct TestCircuit<F> {
block: Block<F>,
}

impl<F: FieldExt> Circuit<F> for TestCircuit<F> {
type Config = EvmCircuit<F>;
type FloorPlanner = SimpleFloorPlanner;

fn without_witnesses(&self) -> Self {
Self::default()
}

fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
let tx_table = [(); 4].map(|_| meta.advice_column());
let rw_table = [(); 8].map(|_| meta.advice_column());
let bytecode_table = [(); 4].map(|_| meta.advice_column());
let randomness = meta.instance_column();

EvmCircuit::configure(
meta,
randomness,
tx_table,
rw_table,
bytecode_table,
)
}

fn synthesize(
&self,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
config.assign_block(&mut layouter, &self.block)
}
}

#[cfg(test)]
mod evm_circ_benches {
use super::*;
use ark_std::{end_timer, start_timer};
use halo2::plonk::{create_proof, keygen_pk, keygen_vk};
use halo2::{
plonk::verify_proof,
poly::commitment::Setup,
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
};
use pairing::bn256::Bn256;
use pairing::bn256::Fr;
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::env::var;

#[cfg_attr(not(feature = "benches"), ignore)]
#[test]
fn bench_evm_circuit_prover() {
let degree: u32 = var("DEGREE")
.expect("No DEGREE env var was provided")
.parse()
.expect("Cannot parse DEGREE env var as u32");

let circuit = TestCircuit::<Fr>::default();
let rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37,
0x32, 0x54, 0x06, 0xbc, 0xe5,
]);

// Bench setup generation
let setup_message =
format!("Setup generation with degree = {}", degree);
let start1 = start_timer!(|| setup_message);
let params = Setup::<Bn256>::new(degree, rng);
end_timer!(start1);

let vk = keygen_vk(&params, &circuit).unwrap();
let pk = keygen_pk(&params, vk, &circuit).unwrap();

// Prove
let mut transcript =
Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);

// Bench proof generation time
let proof_message =
format!("EVM Proof generation with {} rows", degree);
let start2 = start_timer!(|| proof_message);
create_proof(&params, &pk, &[circuit], &[&[&[]]], &mut transcript)
.unwrap();
let proof = transcript.finalize();
end_timer!(start2);

// Verify
let params = Setup::<Bn256>::verifier_params(&params, 0).unwrap();
let mut transcript =
Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);

// Bench verification time
let start3 = start_timer!(|| "EVM Proof verification");
verify_proof(&params, pk.get_vk(), &[&[&[]]], &mut transcript).unwrap();
end_timer!(start3);
}
}
9 changes: 9 additions & 0 deletions circuit-benchmarks/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[cfg(feature = "benches")]
pub mod evm_circuit;

#[cfg(feature = "benches")]
pub mod state_circuit;

#[cfg(test)]
#[cfg(feature = "benches")]
pub mod bench_params;
Loading

0 comments on commit 8fec0e5

Please sign in to comment.