新注册的用户请输入邮箱并保存,随后登录邮箱激活账号。后续可直接使用邮箱登录!

Merge branch 'fix_test' into 'develop' (merge request !426)
geruiwang authored
fix: fix init_params test --story=1
c367d2f7

印客·Inker zkevm-circuits

印客·Inker zkevm-circuits 是一个实现零知识以太坊虚拟机电路的项目,用于验证以太坊智能合约的执行。

项目结构

.
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── NOTICE
├── aggregate-zkevm # 用于聚合证明
├── csv2html # 用于csv转化为html的库
   └── src
├── eth-types #以太坊相关的数据类型
   └── src
├── evmutil # 用于生成测试数据
├── gadgets # 一些小工具
   └── src
├── keccak256 # keccak256 相关工具
   └── src
├── poseidon # poseidon 相关工具
├── prover # 使用zkevm封装的验证器
   └── src
├── README.md
├── scripts # 用于benchmark测试/代码注释覆盖率/单元测试覆盖率统计脚本
├── trace-parser # 用于解析evm的trace的库
   └── src
└── zkevm-circuits # zkevm电路代码
    ├── benches # bench测试
    ├── Cargo.toml
    ├── examples # 用于生成新gadget电路模板的工具类
       └── gen_code.rs
    ├── src # 电路源码
       ├── arithmetic_circuit # 各算术子电路
       ├── arithmetic_circuit.rs # 算术电路
       ├── bitwise_circuit.rs # 位运算电路
       ├── bytecode_circuit.rs # 字节码电路
       ├── constant.rs # 常量
       ├── copy_circuit.rs # copy电路
       ├── core_circuit.rs # core电路
       ├── execution # 各种指令执行电路
       ├── execution.rs # 执行中用到的一些公共代码
       ├── exp_circuit.rs # exp计算电路
       ├── fixed_circuit.rs # fixed电路
       ├── keccak_circuit # keccak256电路相关
       ├── keccak_circuit.rs # keccak256电路
       ├── lib.rs
    │   ├── poseidon_circuit.rs # poseidon电路
       ├── public_circuit_no_hash.rs 
       ├── public_circuit.rs # public电路
       ├── state_circuit # state电路相关
       ├── state_circuit.rs # state电路
       ├── super_circuit.rs # super电路
       ├── table.rs # 各电路互相查用到的table
       ├── util.rs # 一些工具函数
       ├── witness # witness相关代码
       └── witness.rs # witness相关代码
    ├── test_data # 测试数据
    └── tests # 测试相关
        ├── fuzz # mutate篡改测试
        └── opcode_tests # 用于单个opcode的测试

如何运行单元测试

无需evm的单元测试

主要用于验证zkevm-circuits中的各种电路工作逻辑的正确性。

  • 运行指定单测
cargo test -p zkevm-circuits super_circuit::tests::test_super_circuit
  • 运行项目下所有测试
cargo test -p zkevm-circuits

含有evm的单元测试

运行含有EVM的测试,在使用测试命令的时候需要加上对应的feature "evm"。这类测试用于运行通过evm可执行文件加载测试中的solidity汇编指令产生trace,继而进行证明的测试。

准备 evm可执行文件

  • 可以从go-ethereum下载源码,使用命令go run build/ci.go install ./cmd/evm安装。

  • 可以在官网下载相应版本的"Geth & Tools"工具,然后将evm可执行文件拷贝到zkevm-circuits目录下。

运行项目下所有单元测试(含有EVM的测试)

cargo test -p zkevm-circuits --features "default,evm"

查看生成的witness

运行电路的单测时,会生成相应的witness;如果想查看witness的具体值,可以以html文件的形式进行输出。其关键代码片段如下:

    let file_name = std::path::Path::new("./witness.html"); // 生成的html文件路径
    let mut buf = std::io::BufWriter::new(std::fs::File::create(file_name).unwrap());
    witness.write_html(&mut buf); // 将witness以html文件形式输出

运行benchmark测试

快速验证fast_test (small k,机器内存一般需要16G以上)

生成验证参数

预生成验证所需参数,将其写入到文件

cargo test -p zkevm-circuits --profile bench --bench benchmark_list -- init_proof_params  --nocapture

运行电路

  • 使用生成的验证参数运行电路
USEFILE=true cargo test -p zkevm-circuits --profile bench --bench benchmark_list -- super_circuit  --nocapture
  • 运行电路不使用验证参数(每次运行重新生成)
cargo test -p zkevm-circuits --profile bench --bench benchmark_list -- super_circuit  --nocapture

标准测试 (k=19,机器内存一般需要256G以上)

生成验证参数

预生成验证所需参数,将其写入到文件

cargo test -p zkevm-circuits --profile bench --no-default-features --bench benchmark_list -- init_proof_params  --nocapture

运行电路

  • 使用生成的验证参数运行电路
USEFILE=true cargo test -p zkevm-circuits --profile bench --no-default-features --bench benchmark_list -- super_circuit  --nocapture
  • 运行电路不使用验证参数(每次运行重新生成)
cargo test -p zkevm-circuits --profile bench --no-default-features --bench benchmark_list -- super_circuit  --nocapture

运行电路时可以指通过环境变量指定轮次

# round is 10
ROUND=10 cargo test -p zkevm-circuits --profile bench --no-default-features --bench benchmark_list -- super_circuit  --nocapture

参数说明:

--profile bench:使用[profile.bench]

--no-default-features:关闭 "fast_test"特性

--features "benches":打开这个feature会运行多轮

--bench benchmark_list -- super_circuit:运行super_circuit电路的 benchmark

benchmark运行结果在Grafana中展示

在运行benchmark测试的时候,可以使用这里的脚本。如果仅运行测试,那么系统上仅需安装sysstat即可。若需要将测试结果做可视化,可以借助grafana。还需要确认以下依赖项目都已安装

Dependencies

  1. 依赖sysstat

  2. 依赖python:python3, pandas, sqlalchemy, pymysql

  3. 依赖mysql:mysql(5.7+), 提前准备好数据库,数据库的连接帐号,密码 将其写入到scripts/report_system_data/env.json文件

  4. 依赖 grafana(10.3.3)

    • 在grafana的web页面上,首先增加data source;选择mysql模板,用env.json中的mysql信息填充该模板;需要注意的是data source name必须与文件 grafana-bench-config.json中的一致,默认值为bench_test

    • 在grafana的web页面上,使用scripts/report_system_data/grafana-bench-config.json来导入Dashboard面板

Bench scripts

  1. 运行benchmark测试:
cd scripts && ./bench_test.sh $benchmark_list $sample_seconds
  • $benchmark_list:指定运行哪个电路的bench,可以设置为super_circuit

  • $sample_seconds:为cpu/mem的取样间隔,可以设置为3(意味着3s取样一次)

    这一步会运行指定电路的bench测试,并按照设置的采样间隔,记录cpu/mem数据

  1. benchmark测试结果写入到mysql数据库:
cd scripts && ./record_bench_result_to_db.sh $test_id $log_file $cpu_file $mem_file [$delete_file]
  • $test_id:如下文件log_file,cpu_file,mem_file的前缀

  • $log_file:log文件

  • $cpu_file:cpu采样文件

  • $mem_file memory采样文件

  • $delete_file:可选参数,若为y则删除 log_file,cpu_file,mem_file;

    这个命令用于处理 log file, cpu file, mem file文件,将处理结果写入到mysql数据库;若指定了删除文件参数为y,则处理后会删除这三个文件

  1. 也提供了将步骤1和步骤2合为一步的命令:
cd scripts && ./bench_for_grafana.sh $benchmark_list $sample_seconds [$delete_file]
  • $benchmark_list:指定运行哪个电路的bench,可以设置为super_circuit

  • $sample_seconds:为cpu/mem的取样间隔,可以设置为3(意味着3s取样一次)

  • $delete_file:可选参数,若为y则删除 log_file,cpu_file,mem_file;

    这个命令一次完成了步骤1和步骤2的工作

代码审计

本项目代码尚未经第三方审计,仅供学习研究。如需应用于生产环境,请谨慎使用。

参考资料

详细设计内容参考本项目Wiki。

许可

本项目基于Apache-2.0协议开源, 请根据LICENSE文件进行相关的操作。

致谢

感谢privacy-scaling-explorations项目的卓越工作,本项目从中受益匪浅。