├── .github └── workflows │ └── ci.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── LICENSE-APACHE ├── LICENSE-MIT ├── Makefile ├── README.md ├── benches ├── parallel_assignment.rs └── traces.json ├── integration-tests ├── .gitignore ├── contracts │ └── Greeter.sol ├── scripts │ ├── deploy.js │ └── tx_multigreeter.js └── src │ └── main.rs ├── rust-toolchain ├── spec └── mpt-proof.md └── src ├── circuit.rs ├── constraint_builder.rs ├── constraint_builder ├── binary_column.rs ├── binary_query.rs ├── column.rs └── query.rs ├── gadgets.rs ├── gadgets ├── byte_bit.rs ├── byte_representation.rs ├── canonical_representation.rs ├── is_zero.rs ├── key_bit.rs ├── mpt_update.rs ├── mpt_update │ ├── nonexistence_proof.rs │ ├── path.rs │ ├── segment.rs │ └── word_rlc.rs ├── one_hot.rs ├── poseidon.rs └── rlc_randomness.rs ├── lib.rs ├── mpt.rs ├── mpt_table.rs ├── serde.rs ├── tests.rs ├── traces ├── createNameRegistratorPerTxsNotEnoughGas_d0_g0_v0.json ├── depth_1_type_1_storage.json ├── empty_account_type_1.json ├── empty_account_type_1_balance_update.json ├── empty_account_type_1_nonce_update.json ├── empty_account_type_2.json ├── empty_account_type_2_balance_update.json ├── empty_account_type_2_nonce_update.json ├── empty_storage_type_1_update_a.json ├── empty_storage_type_1_update_b.json ├── empty_storage_type_1_update_c.json ├── empty_storage_type_2_update_a.json ├── empty_storage_type_2_update_b.json ├── existing_account_balance_update.json ├── existing_account_code_size_update.json ├── existing_account_keccak_codehash_update.json ├── existing_account_nonce_update.json ├── existing_account_poseidon_codehash_update.json ├── existing_storage_update.json └── insert_into_singleton_storage_trie.json ├── types.rs ├── types ├── storage.rs └── trie.rs └── util.rs /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: checks 2 | on: push 3 | 4 | jobs: 5 | fmt: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v3 9 | - uses: actions-rs/toolchain@v1 10 | with: 11 | profile: minimal 12 | components: rustfmt 13 | - run: make fmt 14 | clippy: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | - uses: actions-rs/toolchain@v1 19 | with: 20 | profile: minimal 21 | components: clippy 22 | - run: make clippy 23 | test: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v3 27 | - uses: actions-rs/toolchain@v1 28 | with: 29 | profile: minimal 30 | - run: make test 31 | par-test: 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/checkout@v3 35 | - uses: actions-rs/toolchain@v1 36 | with: 37 | profile: minimal 38 | - run: make test_par 39 | bench: 40 | runs-on: ubuntu-latest 41 | steps: 42 | - uses: actions/checkout@v3 43 | - uses: actions-rs/toolchain@v1 44 | with: 45 | profile: minimal 46 | - run: make bench 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /layouts 3 | .vscode 4 | .cargo 5 | *.png 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "halo2-mpt-circuits" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | ethers-core = "=2.0.7" 10 | itertools = "0.10.5" 11 | hash-circuit = { package = "poseidon-circuit", git = "https://github.com/scroll-tech/poseidon-circuit.git", branch = "main" } 12 | halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v2022_09_10" } 13 | rand = "0.8" 14 | lazy_static = "1.4.0" 15 | num-traits = "0.2.15" 16 | serde = { version = "1.0", features = ["derive"] } 17 | serde_json = "1.0" 18 | strum = "0.24" 19 | strum_macros = "0.24" 20 | num-bigint = "0.4" 21 | hex = "0.4" 22 | thiserror = "1.0" 23 | log = "0.4" 24 | # mpt-zktrie = { git = "https://github.com/scroll-tech/zkevm-circuits.git", rev = "7d9bc181953cfc6e7baf82ff0ce651281fd70a8a" } 25 | rand_chacha = "0.3.0" 26 | criterion = { version = "0.4", optional = true} 27 | 28 | [patch."https://github.com/privacy-scaling-explorations/halo2.git"] 29 | halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "v1.0" } 30 | [patch.crates-io] 31 | ethers-core = { git = "https://github.com/scroll-tech/ethers-rs.git", branch = "v2.0.7", features = ["scroll"] } 32 | ethers-providers = { git = "https://github.com/scroll-tech/ethers-rs.git", branch = "v2.0.7" } 33 | ethers = { git = "https://github.com/scroll-tech/ethers-rs.git", branch = "v2.0.7" } 34 | ethers-etherscan = { git = "https://github.com/scroll-tech/ethers-rs.git", branch = "v2.0.7" } 35 | 36 | [features] 37 | # printout the layout of circuits for demo and some unittests 38 | print_layout = ["halo2_proofs/dev-graph"] 39 | default = ["halo2_proofs/mock-batch-inv", "parallel_syn"] 40 | parallel_syn = ["halo2_proofs/parallel_syn"] 41 | bench = ["dep:criterion"] 42 | 43 | [dev-dependencies] 44 | mpt-zktrie = { git = "https://github.com/scroll-tech/zkevm-circuits.git", rev = "d14464379107ca80b6280d4b9238eeb60e1fbf15" } 45 | # mpt-zktrie = { path = "../zkevm-circuits/zktrie" } 46 | plotters = "0.3" 47 | bencher = "0.1" 48 | env_logger = "0.10" 49 | subtle = "2" 50 | 51 | [[bin]] 52 | name = "integration-test" 53 | path = "integration-tests/src/main.rs" 54 | 55 | [profile.test] 56 | opt-level = 3 57 | debug-assertions = true 58 | 59 | [[bench]] 60 | name = "parallel_assignment" 61 | harness = false 62 | required-features = ["bench"] 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Scroll 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 The Scroll Foundation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | @cargo test 3 | 4 | test_par: 5 | PARALLEL_SYN=true cargo test -- --nocapture 6 | 7 | fmt: 8 | @cargo fmt 9 | 10 | clippy: 11 | @cargo clippy --all-features 12 | 13 | bench: 14 | @cargo bench --features bench 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scroll's MPT Circuit 2 | 3 | Integration tests: https://github.com/scroll-tech/mpt-circuit/tree/master/integration-tests 4 | 5 | ## License 6 | 7 | Licensed under either of 8 | 9 | - Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 10 | - MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 11 | 12 | at your option. 13 | -------------------------------------------------------------------------------- /benches/parallel_assignment.rs: -------------------------------------------------------------------------------- 1 | use criterion::{criterion_group, criterion_main, Criterion}; 2 | use halo2_mpt_circuits::TestCircuit; 3 | use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr}; 4 | 5 | fn bench(criterion: &mut Criterion) { 6 | let json = include_str!("traces.json"); 7 | let circuit = TestCircuit::new(10_000, serde_json::from_str(&json).unwrap()); 8 | 9 | criterion.bench_function("assign trace", |bencher| { 10 | bencher.iter(|| MockProver::::run(14, &circuit, vec![])) 11 | }); 12 | } 13 | 14 | criterion_group! { 15 | name = benches; 16 | config = Criterion::default().sample_size(10); 17 | targets = bench 18 | } 19 | 20 | criterion_main!(benches); 21 | -------------------------------------------------------------------------------- /integration-tests/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | trace.json 6 | witness.json 7 | typechain 8 | *.exe 9 | 10 | #Hardhat files 11 | cache 12 | artifacts 13 | hardhat.config.js 14 | 15 | scripts/*.json 16 | -------------------------------------------------------------------------------- /integration-tests/contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity >=0.7.0 <0.9.0; 4 | 5 | /** 6 | * @title Greeter 7 | * @dev Store & retrieve value in a variable 8 | */ 9 | contract Greeter { 10 | 11 | uint256 number; 12 | 13 | constructor(uint256 num) { 14 | number = num; 15 | } 16 | 17 | function retrieve() public view returns (uint256){ 18 | return number; 19 | } 20 | 21 | function retrieve_failing() public view returns (uint256){ 22 | require(false); 23 | return number; 24 | } 25 | 26 | function set_value(uint256 num) public{ 27 | number = num; 28 | } 29 | 30 | function set_value_failing(uint256 num) public{ 31 | number = num; 32 | require(false); 33 | } 34 | 35 | function set_value_and_receive(uint256 num) public payable { 36 | number = num; 37 | } 38 | 39 | function set_value_and_receive_failing(uint256 num) public payable { 40 | number = num; 41 | revert("deliberately"); 42 | } 43 | } 44 | 45 | /** 46 | * @title MultiGreeter 47 | * @dev Store & retrieve value in a variable, has 2 slots 48 | */ 49 | contract MutipleGreeter { 50 | mapping(uint => uint256) public values; 51 | 52 | constructor() { 53 | } 54 | 55 | function retrieve(uint which) public view returns (uint256){ 56 | return values[which]; 57 | } 58 | 59 | function set_multiple(uint num, uint256 val) public { 60 | for (uint i = 0; i < num; i++){ 61 | values[i] = val; 62 | } 63 | } 64 | 65 | function set_one(uint which, uint256 val) public{ 66 | values[which] = val; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /integration-tests/scripts/deploy.js: -------------------------------------------------------------------------------- 1 | // We require the Hardhat Runtime Environment explicitly here. This is optional 2 | // but useful for running the script in a standalone fashion through `node