diff --git a/CHANGELOG.md b/CHANGELOG.md index c022899b6..474a41e3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,94 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.6.0] - 2024-07-15 + +### Changed +- Implement EIP-4788 for Cancun ([#40](https://github.com/0xPolygonZero/zk_evm/pull/40)) +- Implement Blob transactions (type-3) and BLOBHASH opcode ([#50](https://github.com/0xPolygonZero/zk_evm/pull/50)) +- Fix beacons root contract bytecode ([#70](https://github.com/0xPolygonZero/zk_evm/pull/70)) +- LxLy exit roots ([#90](https://github.com/0xPolygonZero/zk_evm/pull/90)) +- Eip 1153 (TLOAD/TSTORE) ([#59](https://github.com/0xPolygonZero/zk_evm/pull/59)) +- Remove blobbasefee from block header ([#100](https://github.com/0xPolygonZero/zk_evm/pull/100)) +- Fix MCOPY from rebasing ([#103](https://github.com/0xPolygonZero/zk_evm/pull/103)) +- Fix storage write for beacons root contract ([#102](https://github.com/0xPolygonZero/zk_evm/pull/102)) +- EIP-4844 part 2: Point evaluation precompile ([#133](https://github.com/0xPolygonZero/zk_evm/pull/133)) +- Some fixes to Cancun ([#187](https://github.com/0xPolygonZero/zk_evm/pull/187)) +- Insert blob versioned hashes in signature payload for hashing ([#209](https://github.com/0xPolygonZero/zk_evm/pull/209)) +- Fix KZG precompile context setup ([#210](https://github.com/0xPolygonZero/zk_evm/pull/210)) +- Fix txn type encoding for receipts ([#214](https://github.com/0xPolygonZero/zk_evm/pull/214)) +- Add blob gas fee burn for type-3 txns ([#219](https://github.com/0xPolygonZero/zk_evm/pull/219)) +- Update decoder processing for cancun ([#207](https://github.com/0xPolygonZero/zk_evm/pull/207)) +- cancun: Add a full block test ([#223](https://github.com/0xPolygonZero/zk_evm/pull/223)) +- Fix KZG precompile I/O ([#213](https://github.com/0xPolygonZero/zk_evm/pull/213)) +- Fix selfdestruct address listing ([#225](https://github.com/0xPolygonZero/zk_evm/pull/225)) +- Fix withdrawals without txns and add test for empty block ([#228](https://github.com/0xPolygonZero/zk_evm/pull/228)) +- doc: update README ([#242](https://github.com/0xPolygonZero/zk_evm/pull/242)) +- Cleanup and bring back deadcode lint ([#232](https://github.com/0xPolygonZero/zk_evm/pull/232)) +- fix(cancun): dummy payloads and public input retrieval ([#249](https://github.com/0xPolygonZero/zk_evm/pull/249)) +- fix: encode calldata for EIP-4780 as U256 ([#253](https://github.com/0xPolygonZero/zk_evm/pull/253)) +- fix: handle KZG precompile errors properly ([#251](https://github.com/0xPolygonZero/zk_evm/pull/251)) +- fix(cancun): `mcopy` check offsets and overwrites ([#252](https://github.com/0xPolygonZero/zk_evm/pull/252)) +- fix(cancun): correct search loop in transient storage ([#257](https://github.com/0xPolygonZero/zk_evm/pull/257)) +- perf: Charge gas before tload search ([#272](https://github.com/0xPolygonZero/zk_evm/pull/272)) +- fix: add check on decoded versioned hashes ([#278](https://github.com/0xPolygonZero/zk_evm/pull/278)) +- fix: Add beacon roots touched slots into `state_access` with native tracer ([#353](https://github.com/0xPolygonZero/zk_evm/pull/353)) +- feat(cancun): update test blocks ([#365](https://github.com/0xPolygonZero/zk_evm/pull/365)) +- fix: failed to send proof ([#366](https://github.com/0xPolygonZero/zk_evm/pull/366)) +- feat: cancun jerigon test network ([#367](https://github.com/0xPolygonZero/zk_evm/pull/367)) +- fix(cancun): properly update accumulator in fake_exponential() ([#376](https://github.com/0xPolygonZero/zk_evm/pull/376)) +- fix(cancun): tweak ranges in integration tests ([#377](https://github.com/0xPolygonZero/zk_evm/pull/377)) +- `cancun`: cleanup pre-release ([#392](https://github.com/0xPolygonZero/zk_evm/pull/392)) + +## [0.5.0] - 2024-07-15 + +### Changed +- fix: docker images ([#108](https://github.com/0xPolygonZero/zk_evm/pull/108)) +- feat: add transaction hash to zero trace ([#103](https://github.com/0xPolygonZero/zk_evm/pull/103)) +- perf: add benchmarks for different components ([#273](https://github.com/0xPolygonZero/zk_evm/pull/273)) +- fix: add check on decoded versioned hashes ([#278](https://github.com/0xPolygonZero/zk_evm/pull/278)) +- fix: discard intermediate proofs ([#106](https://github.com/0xPolygonZero/zk_evm/pull/106)) +- feat: stdio parallel proving ([#109](https://github.com/0xPolygonZero/zk_evm/pull/109)) +- Fixes related to nightly and alloy ([#101](https://github.com/0xPolygonZero/zk_evm/pull/101)) +- Introduce native tracer support ([#81](https://github.com/0xPolygonZero/zk_evm/pull/81)) +- chore: bump alloy to v0.1.1 ([#111](https://github.com/0xPolygonZero/zk_evm/pull/111)) +- Migrate `zero-bin` into `zk-evm` +- fix: Bring back Cargo.lock ([#280](https://github.com/0xPolygonZero/zk_evm/pull/280)) +- ci: add labeler flag for new `zero-bin` crate + update `CODEOWNERS` ([#281](https://github.com/0xPolygonZero/zk_evm/pull/281)) +- fix: only executables should choose a global allocator ([#301](https://github.com/0xPolygonZero/zk_evm/pull/301)) +- doc: fix typos ([#298](https://github.com/0xPolygonZero/zk_evm/pull/298)) +- misc: fix logging filename ([#305](https://github.com/0xPolygonZero/zk_evm/pull/305)) +- refactor zero_bin leader cli ([#317](https://github.com/0xPolygonZero/zk_evm/pull/317)) +- Removed non-existing dep public `__compat_primitive_types` ([#321](https://github.com/0xPolygonZero/zk_evm/pull/321)) +- perf: Check for zero amount early in 'add_eth' ([#322](https://github.com/0xPolygonZero/zk_evm/pull/322)) +- fix: interval ([#324](https://github.com/0xPolygonZero/zk_evm/pull/324)) +- fix: optimize previous hashes retrieval ([#316](https://github.com/0xPolygonZero/zk_evm/pull/316)) +- feat: add jerigon test workflow ([#303](https://github.com/0xPolygonZero/zk_evm/pull/303)) +- fix: do not add selfdestruct journal entry for empty accounts ([#328](https://github.com/0xPolygonZero/zk_evm/pull/328)) +- ci: add PR check job ([#332](https://github.com/0xPolygonZero/zk_evm/pull/332)) +- Constrain FP254 operations and SUBMOD to be kernel-only ([#333](https://github.com/0xPolygonZero/zk_evm/pull/333)) +- fix: add recipient to touched_addresses even when skipping empty transfer ([#336](https://github.com/0xPolygonZero/zk_evm/pull/336)) +- Fixed leader crashing when `.env` not present ([#335](https://github.com/0xPolygonZero/zk_evm/pull/335)) +- perf: reduce overhead in final iteration of memset ([#339](https://github.com/0xPolygonZero/zk_evm/pull/339)) +- Make leader work no matter what the CWD is ([#307](https://github.com/0xPolygonZero/zk_evm/pull/307)) +- Cleanup/clippy and update pass ([#341](https://github.com/0xPolygonZero/zk_evm/pull/341)) +- Add `Columns` and `DerefColumns` derive macros ([#315](https://github.com/0xPolygonZero/zk_evm/pull/315)) +- migrate compat to micro crate ([#308](https://github.com/0xPolygonZero/zk_evm/pull/308)) +- fix: docker build for worker and leader ([#329](https://github.com/0xPolygonZero/zk_evm/pull/329)) +- parse embedded short nodes ([#345](https://github.com/0xPolygonZero/zk_evm/pull/345)) +- Add `LogicColumnsView` struct for `LogicStark` ([#347](https://github.com/0xPolygonZero/zk_evm/pull/347)) +- fix: properly log final result when due ([#352](https://github.com/0xPolygonZero/zk_evm/pull/352)) +- fix: Check valid range for s and add test ([#363](https://github.com/0xPolygonZero/zk_evm/pull/363)) +- feat: add caching for `get_block` ([#346](https://github.com/0xPolygonZero/zk_evm/pull/346)) +- refactor!: docker builds ([#357](https://github.com/0xPolygonZero/zk_evm/pull/357)) +- fix: tweak fetching of previous block hashes ([#370](https://github.com/0xPolygonZero/zk_evm/pull/370)) +- fix(evm_arithmetization): Adjust layout of `CpuGeneralColumnsView` ([#355](https://github.com/0xPolygonZero/zk_evm/pull/355)) +- feat: skip range-checking `PUSH` operations in `KERNEL` mode ([#373](https://github.com/0xPolygonZero/zk_evm/pull/373)) +- Fix iterator length when fetching block hashes ([#374](https://github.com/0xPolygonZero/zk_evm/pull/374)) +- fix: scale withdrawals amount to gwei ([#371](https://github.com/0xPolygonZero/zk_evm/pull/371)) +- refactor: frontend of `trace_decoder` ([#309](https://github.com/0xPolygonZero/zk_evm/pull/309)) + + ## [0.4.0] - 2024-06-12 ### Changed diff --git a/Cargo.lock b/Cargo.lock index c490540e0..ba4b79bdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1903,7 +1903,7 @@ dependencies = [ [[package]] name = "evm_arithmetization" -version = "0.2.0" +version = "0.4.0" dependencies = [ "anyhow", "bytes", @@ -1916,7 +1916,7 @@ dependencies = [ "itertools 0.13.0", "keccak-hash 0.10.0", "log", - "mpt_trie 0.3.0", + "mpt_trie 0.4.1", "num", "num-bigint", "once_cell", @@ -1933,7 +1933,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "smt_trie 0.1.0", + "smt_trie 0.1.1", "starky", "static_assertions", "tiny-keccak", @@ -1942,8 +1942,8 @@ dependencies = [ [[package]] name = "evm_arithmetization" -version = "0.2.0" -source = "git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun#ddca6be9a40a7d0492312ecaf9d966e2124dbc91" +version = "0.4.0" +source = "git+https://github.com/0xPolygonZero/zk_evm?branch=develop#33360556b0945272883c3f742c3fb404cd4c7fb0" dependencies = [ "anyhow", "bytes", @@ -1954,7 +1954,7 @@ dependencies = [ "itertools 0.13.0", "keccak-hash 0.10.0", "log", - "mpt_trie 0.3.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "mpt_trie 0.4.1 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "num", "num-bigint", "once_cell", @@ -1973,7 +1973,7 @@ dependencies = [ "starky", "static_assertions", "tiny-keccak", - "zk_evm_proc_macro 0.1.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "zk_evm_proc_macro 0.1.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", ] [[package]] @@ -2782,7 +2782,7 @@ dependencies = [ "futures", "ops", "paladin-core", - "proof_gen 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "proof_gen 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "prover", "rpc", "serde", @@ -2936,7 +2936,7 @@ checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" [[package]] name = "mpt_trie" -version = "0.3.0" +version = "0.4.1" dependencies = [ "bytes", "enum-as-inner", @@ -2963,8 +2963,8 @@ dependencies = [ [[package]] name = "mpt_trie" -version = "0.3.0" -source = "git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun#ddca6be9a40a7d0492312ecaf9d966e2124dbc91" +version = "0.4.1" +source = "git+https://github.com/0xPolygonZero/zk_evm?branch=develop#33360556b0945272883c3f742c3fb404cd4c7fb0" dependencies = [ "bytes", "enum-as-inner", @@ -3220,10 +3220,10 @@ dependencies = [ name = "ops" version = "0.1.0" dependencies = [ - "evm_arithmetization 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "evm_arithmetization 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "keccak-hash 0.10.0", "paladin-core", - "proof_gen 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "proof_gen 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "serde", "tracing", "zero_bin_common", @@ -3758,9 +3758,9 @@ dependencies = [ [[package]] name = "proof_gen" -version = "0.2.0" +version = "0.4.0" dependencies = [ - "evm_arithmetization 0.2.0", + "evm_arithmetization 0.4.0", "log", "paste", "plonky2", @@ -3769,10 +3769,10 @@ dependencies = [ [[package]] name = "proof_gen" -version = "0.2.0" -source = "git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun#ddca6be9a40a7d0492312ecaf9d966e2124dbc91" +version = "0.4.0" +source = "git+https://github.com/0xPolygonZero/zk_evm?branch=develop#33360556b0945272883c3f742c3fb404cd4c7fb0" dependencies = [ - "evm_arithmetization 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "evm_arithmetization 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "log", "paste", "plonky2", @@ -3809,12 +3809,12 @@ dependencies = [ "num-traits", "ops", "paladin-core", - "proof_gen 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "proof_gen 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "ruint", "serde", "serde_json", "tokio", - "trace_decoder 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "trace_decoder 0.6.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "tracing", "zero_bin_common", ] @@ -4074,18 +4074,18 @@ dependencies = [ "anyhow", "clap", "compat", - "evm_arithmetization 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "evm_arithmetization 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "futures", "hex", "lru", - "mpt_trie 0.3.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "mpt_trie 0.4.1 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "primitive-types 0.12.2", "prover", "serde", "serde_json", "tokio", "tower", - "trace_decoder 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "trace_decoder 0.6.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "tracing-subscriber", "url", "zero_bin_common", @@ -4539,7 +4539,7 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smt_trie" -version = "0.1.0" +version = "0.1.1" dependencies = [ "ethereum-types", "hex-literal", @@ -4550,8 +4550,8 @@ dependencies = [ [[package]] name = "smt_trie" -version = "0.1.0" -source = "git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun#ddca6be9a40a7d0492312ecaf9d966e2124dbc91" +version = "0.1.1" +source = "git+https://github.com/0xPolygonZero/zk_evm?branch=develop#33360556b0945272883c3f742c3fb404cd4c7fb0" dependencies = [ "ethereum-types", "hex-literal", @@ -5027,7 +5027,7 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "trace_decoder" -version = "0.4.0" +version = "0.6.0" dependencies = [ "anyhow", "bitflags 2.5.0", @@ -5039,20 +5039,20 @@ dependencies = [ "either", "enum-as-inner", "ethereum-types", - "evm_arithmetization 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "evm_arithmetization 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "hex", "hex-literal", "itertools 0.13.0", "keccak-hash 0.10.0", "log", - "mpt_trie 0.3.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "mpt_trie 0.4.1 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "nunny", "plonky2", "pretty_env_logger", "rlp", "serde", "serde_json", - "smt_trie 0.1.0", + "smt_trie 0.1.1", "thiserror", "u4", "winnow 0.6.13", @@ -5060,8 +5060,8 @@ dependencies = [ [[package]] name = "trace_decoder" -version = "0.4.0" -source = "git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun#ddca6be9a40a7d0492312ecaf9d966e2124dbc91" +version = "0.6.0" +source = "git+https://github.com/0xPolygonZero/zk_evm?branch=develop#33360556b0945272883c3f742c3fb404cd4c7fb0" dependencies = [ "anyhow", "bitflags 2.5.0", @@ -5072,18 +5072,18 @@ dependencies = [ "either", "enum-as-inner", "ethereum-types", - "evm_arithmetization 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "evm_arithmetization 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "hex", "hex-literal", "itertools 0.13.0", "keccak-hash 0.10.0", "log", - "mpt_trie 0.3.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "mpt_trie 0.4.1 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "nunny", "plonky2", "rlp", "serde", - "smt_trie 0.1.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "smt_trie 0.1.1 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "thiserror", "u4", "winnow 0.6.13", @@ -5295,7 +5295,7 @@ dependencies = [ "anyhow", "clap", "dotenvy", - "proof_gen 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "proof_gen 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "serde_json", "serde_path_to_error", "tracing", @@ -5705,10 +5705,10 @@ dependencies = [ "anyhow", "async-stream", "clap", - "evm_arithmetization 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "evm_arithmetization 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "futures", "plonky2", - "proof_gen 0.2.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun)", + "proof_gen 0.4.0 (git+https://github.com/0xPolygonZero/zk_evm?branch=develop)", "serde", "serde_json", "thiserror", @@ -5769,7 +5769,7 @@ dependencies = [ [[package]] name = "zk_evm_proc_macro" version = "0.1.0" -source = "git+https://github.com/0xPolygonZero/zk_evm?branch=feat/cancun#ddca6be9a40a7d0492312ecaf9d966e2124dbc91" +source = "git+https://github.com/0xPolygonZero/zk_evm?branch=develop#33360556b0945272883c3f742c3fb404cd4c7fb0" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 3d9a44604..22c913324 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,19 @@ [workspace] members = [ - "compat", - "evm_arithmetization", - "mpt_trie", - "proc_macro", - "proof_gen", - "smt_trie", - "trace_decoder", - "zero_bin/common", - "zero_bin/leader", - "zero_bin/ops", - "zero_bin/prover", - "zero_bin/rpc", - "zero_bin/verifier", - "zero_bin/worker", + "compat", + "evm_arithmetization", + "mpt_trie", + "proc_macro", + "proof_gen", + "smt_trie", + "trace_decoder", + "zero_bin/common", + "zero_bin/leader", + "zero_bin/ops", + "zero_bin/prover", + "zero_bin/rpc", + "zero_bin/verifier", + "zero_bin/worker", ] resolver = "2" @@ -28,18 +28,18 @@ categories = ["cryptography::cryptocurrencies"] [workspace.dependencies] __compat_primitive_types = { version = "0.12.2", package = "primitive-types" } alloy = { git = "https://github.com/alloy-rs/alloy", tag = 'v0.1.1', default-features = false, features = [ - "consensus", - "reqwest", - "json-rpc", - "rlp", - "rpc", - "rpc-client", - "rpc-types-eth", - "rpc-types-trace", - "providers", - "transports", - "transport-http", - "rpc-types-debug", + "consensus", + "reqwest", + "json-rpc", + "rlp", + "rpc", + "rpc-client", + "rpc-types-eth", + "rpc-types-trace", + "providers", + "transports", + "transport-http", + "rpc-types-debug", ] } anyhow = "1.0.86" async-stream = "0.3.5" @@ -59,7 +59,6 @@ enumn = "0.1.13" env_logger = "0.11.3" eth_trie = "0.4.0" ethereum-types = "0.14.1" -evm_arithmetization = { path = "evm_arithmetization", version = "0.2.0" } futures = "0.3.30" hashbrown = "0.14.5" hex = "0.4.3" @@ -72,7 +71,6 @@ itertools = "0.13.0" keccak-hash = "0.10.0" log = "0.4.21" lru = "0.12.3" -mpt_trie = { path = "mpt_trie", version = "0.3.0" } num = "0.4.3" num-bigint = "0.4.5" num-traits = "0.2.19" @@ -84,7 +82,6 @@ paste = "1.0.15" pest = "2.7.10" pest_derive = "2.7.10" pretty_env_logger = "0.5.0" -proof_gen = { path = "proof_gen", version = "0.2.0" } rand = "0.8.5" rand_chacha = "0.3.1" ripemd = "0.1.3" @@ -96,14 +93,12 @@ serde_json = "1.0.118" serde_path_to_error = "0.1.16" serde_with = "3.8.1" sha2 = "0.10.8" -smt_trie = { path = "smt_trie", version = "0.1.0" } static_assertions = "1.1.0" thiserror = "1.0.61" tiny-keccak = "2.0.2" tokio = { version = "1.38.0", features = ["full"] } toml = "0.8.14" tower = "0.4" -trace_decoder = { path = "trace_decoder", version = "0.4.0" } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } u4 = "0.1.0" @@ -111,6 +106,14 @@ uint = "0.9.5" url = "2.5.2" winnow = "0.6.13" +# local dependencies +evm_arithmetization = { path = "evm_arithmetization", version = "0.4.0" } +mpt_trie = { path = "mpt_trie", version = "0.4.1" } +proof_gen = { path = "proof_gen", version = "0.4.0" } +smt_trie = { path = "smt_trie", version = "0.1.1" } +trace_decoder = { path = "trace_decoder", version = "0.6.0" } +zk_evm_proc_macro = { path = "proc_macro", version = "0.1.0" } + # zero-bin related dependencies ops = { path = "zero_bin/ops" } prover = { path = "zero_bin/prover" } @@ -128,4 +131,3 @@ proc-macro2 = "1.0" quote = "1.0" syn = "2.0" trybuild = "1.0" -zk_evm_proc_macro = { path = "proc_macro" } diff --git a/README.md b/README.md index 7e05e69d3..67a3364a7 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,9 @@ This repository contains the following Rust crates: * [mpt_trie](./mpt_trie/README.md): A collection of types and functions to work with Ethereum Merkle Patricie Tries. -* [trace_decoder](./trace_decoder/README.md): Flexible protocol designed to process Ethereum clients trace payloads into an IR format that can be +* [smt_trie](./smt_trie/README.md): A collection of types and functions to work with Polygon Hermez Sparse Merkle Trees (SMT). + +* [trace_decoder](./trace_decoder/Cargo.toml): Flexible protocol designed to process Ethereum clients trace payloads into an IR format that can be understood by the zkEVM prover. * [evm_arithmetization](./evm_arithmetization/README.md): Defines all the STARK constraints and recursive circuits to generate succinct proofs of EVM execution. @@ -18,37 +20,42 @@ It uses starky and plonky2 as proving backend: https://github.com/0xPolygonZero/ * [proof_gen](./proof_gen/README.md): A convenience library for generating proofs from inputs already in Intermediate Representation (IR) format. +* [zero_bin](./zero_bin/README.md): A composition of [`paladin`](https://github.com/0xPolygonZero/paladin) and [`proof_gen`](./proof_gen/README.md) to generate +EVM block proofs. + ## Dependency graph -Below is a simplified view of the dependency graph, including the proving systems backend and the application layer defined within [zero-bin](https://github.com/0xPolygonZero/zero-bin). +Below is a simplified view of the dependency graph, including the proving system backends and the application layer defined within [zero-bin](https://github.com/0xPolygonZero/zero-bin). + ```mermaid -flowchart TD +flowchart LR subgraph ps [proving systems] A1{{plonky2}} A2{{starky}} end + ps --> zk_evm + subgraph zk_evm [zk_evm] B[mpt_trie] C[evm_arithmetization] D[trace_decoder] E[proof_gen] - A1 --> C - A1 --> E - A2 --> C + B --> C B ---> D C ---> D C --> E D --> E - end F{zero-bin} - A1 --> F C --> F D --> F E --> F + end ``` ## Documentation diff --git a/compat/Cargo.toml b/compat/Cargo.toml index 69ff77eb7..f52e57c45 100644 --- a/compat/Cargo.toml +++ b/compat/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "compat" version = "0.1.0" -publish = false # TODO(): https://github.com/0xPolygonZero/zk_evm/issues/314 find a better place for this +publish = false # TODO(): https://github.com/0xPolygonZero/zk_evm/issues/314 find a better place for this edition.workspace = true license.workspace = true repository.workspace = true @@ -10,5 +10,5 @@ keywords.workspace = true categories.workspace = true [dependencies] -alloy = {workspace = true } +alloy = { workspace = true } __compat_primitive_types = { workspace = true } diff --git a/evm_arithmetization/Cargo.toml b/evm_arithmetization/Cargo.toml index 667afcb2f..a70e1d5cb 100644 --- a/evm_arithmetization/Cargo.toml +++ b/evm_arithmetization/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "evm_arithmetization" description = "Implementation of STARKs for the Ethereum Virtual Machine" -version = "0.2.0" +version = "0.4.0" authors = [ - "Daniel Lubarov ", - "William Borgeaud ", + "Daniel Lubarov ", + "William Borgeaud ", ] readme = "README.md" categories = ["cryptography"] @@ -59,9 +59,9 @@ default = ["parallel"] asmtools = ["hex"] disable_jemalloc = [] parallel = [ - "plonky2/parallel", - "plonky2_maybe_rayon/parallel", - "starky/parallel", + "plonky2/parallel", + "plonky2_maybe_rayon/parallel", + "starky/parallel", ] [[bin]] diff --git a/evm_arithmetization/src/cpu/columns/general.rs b/evm_arithmetization/src/cpu/columns/general.rs index 125e7e18f..9ce620078 100644 --- a/evm_arithmetization/src/cpu/columns/general.rs +++ b/evm_arithmetization/src/cpu/columns/general.rs @@ -21,7 +21,7 @@ impl CpuGeneralColumnsView { /// View of the columns used for exceptions: they are the exception code /// bits. SAFETY: Each view is a valid interpretation of the underlying /// array. - pub(crate) fn exception(&self) -> &CpuExceptionView { + pub(crate) const fn exception(&self) -> &CpuExceptionView { unsafe { &self.exception } } @@ -34,7 +34,7 @@ impl CpuGeneralColumnsView { /// View of the columns required for logic operations. /// SAFETY: Each view is a valid interpretation of the underlying array. - pub(crate) fn logic(&self) -> &CpuLogicView { + pub(crate) const fn logic(&self) -> &CpuLogicView { unsafe { &self.logic } } @@ -46,7 +46,7 @@ impl CpuGeneralColumnsView { /// View of the columns required for jump operations. /// SAFETY: Each view is a valid interpretation of the underlying array. - pub(crate) fn jumps(&self) -> &CpuJumpsView { + pub(crate) const fn jumps(&self) -> &CpuJumpsView { unsafe { &self.jumps } } @@ -58,7 +58,7 @@ impl CpuGeneralColumnsView { /// View of the columns required for shift operations. /// SAFETY: Each view is a valid interpretation of the underlying array. - pub(crate) fn shift(&self) -> &CpuShiftView { + pub(crate) const fn shift(&self) -> &CpuShiftView { unsafe { &self.shift } } @@ -70,7 +70,7 @@ impl CpuGeneralColumnsView { /// View of the columns required for the stack top. /// SAFETY: Each view is a valid interpretation of the underlying array. - pub(crate) fn stack(&self) -> &CpuStackView { + pub(crate) const fn stack(&self) -> &CpuStackView { unsafe { &self.stack } } @@ -82,7 +82,7 @@ impl CpuGeneralColumnsView { /// View of the columns required for the push operation. /// SAFETY: Each view is a valid interpretation of the underlying array. - pub(crate) fn push(&self) -> &CpuPushView { + pub(crate) const fn push(&self) -> &CpuPushView { unsafe { &self.push } } diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/create_receipt.asm b/evm_arithmetization/src/cpu/kernel/asm/core/create_receipt.asm index fc3632cc6..742c4784c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/create_receipt.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/create_receipt.asm @@ -129,7 +129,7 @@ process_receipt_logs_loop: MLOAD_GENERAL %append_to_trie_data // stack: addr_ptr, i, num_logs, receipt_ptr, txn_nb, new_cum_gas, txn_nb, num_nibbles, retdest - //Write num_topics. + // Write num_topics. %increment // stack: num_topics_ptr, i, num_logs, receipt_ptr, txn_nb, new_cum_gas, txn_nb, num_nibbles, retdest DUP1 diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/jumpdest_analysis.asm b/evm_arithmetization/src/cpu/kernel/asm/core/jumpdest_analysis.asm index 49b59fe63..2d7c53ee2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/jumpdest_analysis.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/jumpdest_analysis.asm @@ -134,7 +134,7 @@ global write_table_if_jumpdest: %jump_neq_const(0x5b, return) - //stack: jumpdest, ctx, proof_prefix_addr, retdest + // stack: jumpdest, ctx, proof_prefix_addr, retdest SWAP2 DUP1 // stack: proof_prefix_addr, proof_prefix_addr, ctx, jumpdest ISZERO diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/msm.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/msm.asm index d5b97312b..af350dd8f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/msm.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/msm.asm @@ -10,7 +10,7 @@ global bn_msm_loop: DUP1 %jumpi(bn_msm_loop_add_a_nonzero) POP msm_loop_add_b: - //stack: accx, accy, i, retdest + // stack: accx, accy, i, retdest DUP3 %bn_mload_wnaf_b // stack: w, accx, accy, i, retdest DUP1 %jumpi(bn_msm_loop_add_b_nonzero) @@ -20,7 +20,7 @@ msm_loop_contd: // TODO: the GLV scalars for the BN curve are 127-bit, so could use 127 here. But this would require modifying `wnaf.asm`. Not sure it's worth it... %eq_const(129) %jumpi(msm_end) %increment - //stack: i+1, accx, accy, retdest + // stack: i+1, accx, accy, retdest %stack (i, accx, accy, retdest) -> (accx, accy, bn_msm_loop, i, retdest) %jump(bn_double) @@ -54,9 +54,9 @@ bn_msm_loop_add_b_nonzero: // stack: w DUP1 %mload_current(@SEGMENT_BN_TABLE_Q) - //stack: Gy, w + // stack: Gy, w SWAP1 %decrement %mload_current(@SEGMENT_BN_TABLE_Q) - //stack: Gx, Gy + // stack: Gx, Gy %endmacro %macro bn_mload_point_b @@ -67,7 +67,7 @@ bn_msm_loop_add_b_nonzero: %stack (bneg, Gy, w) -> (@BN_BASE, Gy, bneg, bneg, Gy, w) SUB SWAP1 ISZERO MUL SWAP2 MUL ADD SWAP1 %decrement %mload_current(@SEGMENT_BN_TABLE_Q) - //stack: Gx, Gy + // stack: Gx, Gy PUSH @BN_GLV_BETA MULFP254 %endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert.asm index 33eadd755..83a12b4b0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert.asm @@ -42,7 +42,7 @@ global mpt_insert_branch: // stack: node_type, node_payload_ptr, num_nibbles, key, value_ptr, retdest POP - //stack: node_payload_ptr, num_nibbles, key, value_ptr, retdest + // stack: node_payload_ptr, num_nibbles, key, value_ptr, retdest // At this point, we branch based on whether the key terminates with this branch node. // stack: node_payload_ptr, num_nibbles, key, value_ptr, retdest diff --git a/evm_arithmetization/src/fixed_recursive_verifier.rs b/evm_arithmetization/src/fixed_recursive_verifier.rs index a040165a2..acbd56c4f 100644 --- a/evm_arithmetization/src/fixed_recursive_verifier.rs +++ b/evm_arithmetization/src/fixed_recursive_verifier.rs @@ -12,7 +12,7 @@ use plonky2::field::extension::Extendable; use plonky2::fri::FriParams; use plonky2::gates::constant::ConstantGate; use plonky2::gates::noop::NoopGate; -use plonky2::hash::hash_types::RichField; +use plonky2::hash::hash_types::{RichField, NUM_HASH_OUT_ELTS}; use plonky2::iop::challenger::RecursiveChallenger; use plonky2::iop::target::{BoolTarget, Target}; use plonky2::iop::witness::{PartialWitness, WitnessWrite}; @@ -20,7 +20,7 @@ use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::{ CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitData, VerifierCircuitTarget, }; -use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, GenericHashOut}; use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; use plonky2::recursion::cyclic_recursion::check_cyclic_proof_verifier_data; use plonky2::recursion::dummy_circuit::cyclic_base_proof; @@ -75,6 +75,9 @@ where /// The block circuit, which verifies an aggregation root proof and an /// optional previous block proof. pub block: BlockCircuitData, + /// The two-to-one block aggregation circuit, which verifies two unrelated + /// block proofs. + pub two_to_one_block: TwoToOneBlockCircuitData, /// Holds chains of circuits for each table and for each initial /// `degree_bits`. pub by_table: [RecursiveCircuitsForTable; NUM_TABLES], @@ -211,25 +214,25 @@ where struct AggregationChildTarget { is_agg: BoolTarget, agg_proof: ProofWithPublicInputsTarget, - evm_proof: ProofWithPublicInputsTarget, + base_proof: ProofWithPublicInputsTarget, } impl AggregationChildTarget { fn to_buffer(&self, buffer: &mut Vec) -> IoResult<()> { buffer.write_target_bool(self.is_agg)?; buffer.write_target_proof_with_public_inputs(&self.agg_proof)?; - buffer.write_target_proof_with_public_inputs(&self.evm_proof)?; + buffer.write_target_proof_with_public_inputs(&self.base_proof)?; Ok(()) } fn from_buffer(buffer: &mut Buffer) -> IoResult { let is_agg = buffer.read_target_bool()?; let agg_proof = buffer.read_target_proof_with_public_inputs()?; - let evm_proof = buffer.read_target_proof_with_public_inputs()?; + let base_proof = buffer.read_target_proof_with_public_inputs()?; Ok(Self { is_agg, agg_proof, - evm_proof, + base_proof, }) } @@ -238,8 +241,20 @@ impl AggregationChildTarget { builder: &mut CircuitBuilder, ) -> PublicValuesTarget { let agg_pv = PublicValuesTarget::from_public_inputs(&self.agg_proof.public_inputs); - let evm_pv = PublicValuesTarget::from_public_inputs(&self.evm_proof.public_inputs); - PublicValuesTarget::select(builder, self.is_agg, agg_pv, evm_pv) + let base_pv = PublicValuesTarget::from_public_inputs(&self.base_proof.public_inputs); + PublicValuesTarget::select(builder, self.is_agg, agg_pv, base_pv) + } + + fn public_inputs>( + &self, + builder: &mut CircuitBuilder, + ) -> Vec { + zip_eq( + &self.agg_proof.public_inputs, + &self.base_proof.public_inputs, + ) + .map(|(&agg_pv, &base_pv)| builder.select(self.is_agg, agg_pv, base_pv)) + .collect() } } @@ -301,6 +316,56 @@ where } } +/// Data for the two-to-one block circuit, which is used to generate a +/// proof of two unrelated proofs. +#[derive(Eq, PartialEq, Debug)] +pub struct TwoToOneBlockCircuitData +where + F: RichField + Extendable, + C: GenericConfig, +{ + pub circuit: CircuitData, + lhs: AggregationChildTarget, + rhs: AggregationChildTarget, + cyclic_vk: VerifierCircuitTarget, +} + +impl TwoToOneBlockCircuitData +where + F: RichField + Extendable, + C: GenericConfig, +{ + fn to_buffer( + &self, + buffer: &mut Vec, + gate_serializer: &dyn GateSerializer, + generator_serializer: &dyn WitnessGeneratorSerializer, + ) -> IoResult<()> { + buffer.write_circuit_data(&self.circuit, gate_serializer, generator_serializer)?; + self.lhs.to_buffer(buffer)?; + self.rhs.to_buffer(buffer)?; + buffer.write_target_verifier_circuit(&self.cyclic_vk)?; + Ok(()) + } + + fn from_buffer( + buffer: &mut Buffer, + gate_serializer: &dyn GateSerializer, + generator_serializer: &dyn WitnessGeneratorSerializer, + ) -> IoResult { + let circuit = buffer.read_circuit_data(gate_serializer, generator_serializer)?; + let lhs = AggregationChildTarget::from_buffer(buffer)?; + let rhs = AggregationChildTarget::from_buffer(buffer)?; + let cyclic_vk = buffer.read_target_verifier_circuit()?; + Ok(Self { + circuit, + lhs, + rhs, + cyclic_vk, + }) + } +} + impl AllRecursiveCircuits where F: RichField + Extendable, @@ -333,6 +398,8 @@ where .to_buffer(&mut buffer, gate_serializer, generator_serializer)?; self.block .to_buffer(&mut buffer, gate_serializer, generator_serializer)?; + self.two_to_one_block + .to_buffer(&mut buffer, gate_serializer, generator_serializer)?; if !skip_tables { for table in &self.by_table { table.to_buffer(&mut buffer, gate_serializer, generator_serializer)?; @@ -370,6 +437,11 @@ where )?; let block = BlockCircuitData::from_buffer(&mut buffer, gate_serializer, generator_serializer)?; + let two_to_one_block = TwoToOneBlockCircuitData::from_buffer( + &mut buffer, + gate_serializer, + generator_serializer, + )?; let by_table = match skip_tables { true => (0..NUM_TABLES) @@ -405,6 +477,7 @@ where root, aggregation, block, + two_to_one_block, by_table, }) } @@ -502,10 +575,13 @@ where let root = Self::create_root_circuit(&by_table, stark_config); let aggregation = Self::create_aggregation_circuit(&root); let block = Self::create_block_circuit(&aggregation); + let two_to_one_block = Self::create_two_to_one_block_circuit(&block); + Self { root, aggregation, block, + two_to_one_block, by_table, } } @@ -670,8 +746,9 @@ where let mut builder = CircuitBuilder::::new(root.circuit.common.config.clone()); let public_values = add_virtual_public_values(&mut builder); let cyclic_vk = builder.add_verifier_data_public_inputs(); - let lhs = Self::add_agg_child(&mut builder, root); - let rhs = Self::add_agg_child(&mut builder, root); + + let lhs = Self::add_agg_child(&mut builder, &root.circuit); + let rhs = Self::add_agg_child(&mut builder, &root.circuit); let lhs_public_values = lhs.public_values(&mut builder); let rhs_public_values = rhs.public_values(&mut builder); @@ -776,24 +853,38 @@ where builder.connect(lhs.gas_used_after, rhs.gas_used_before); } + /// Extend a circuit to verify one of two proofs. + /// + /// # Arguments + /// + /// - `builder`: The circuit builder object. + /// - `base_circuit`: Circuit data describing the circuit of the base proof. + /// + /// # Outputs + /// + /// Returns a [`TwoToOneBlockChildTarget`] object. fn add_agg_child( builder: &mut CircuitBuilder, - root: &RootCircuitData, + base_circuit: &CircuitData, ) -> AggregationChildTarget { - let common = &root.circuit.common; - let root_vk = builder.constant_verifier_data(&root.circuit.verifier_only); + let common = &base_circuit.common; + let base_vk = builder.constant_verifier_data(&base_circuit.verifier_only); let is_agg = builder.add_virtual_bool_target_safe(); let agg_proof = builder.add_virtual_proof_with_pis(common); - let evm_proof = builder.add_virtual_proof_with_pis(common); + let base_proof = builder.add_virtual_proof_with_pis(common); builder .conditionally_verify_cyclic_proof::( - is_agg, &agg_proof, &evm_proof, &root_vk, common, + is_agg, + &agg_proof, + &base_proof, + &base_vk, + common, ) .expect("Failed to build cyclic recursion circuit"); AggregationChildTarget { is_agg, agg_proof, - evm_proof, + base_proof, } } @@ -876,6 +967,87 @@ where } } + /// Create two-to-one block aggregation circuit. + /// + /// # Arguments + /// + /// - `block_circuit`: circuit data for the block circuit, that constitutes + /// the base case for aggregation. + /// + /// # Outputs + /// + /// Returns a [`TwoToOneBlockCircuitData`]. + fn create_two_to_one_block_circuit( + block_circuit: &BlockCircuitData, + ) -> TwoToOneBlockCircuitData + where + F: RichField + Extendable, + C: GenericConfig, + C::Hasher: AlgebraicHasher, + { + let mut builder = CircuitBuilder::::new(block_circuit.circuit.common.config.clone()); + + let mix_hash = builder.add_virtual_hash_public_input(); + + // We need to pad by PIS to match the count of PIS of the `base_proof`. + let mut padding = block_circuit.circuit.common.num_public_inputs; + // The number of PIS that will be added *after* padding by + // [`add_verifier_data_public_inputs()`]. + padding -= verification_key_len(&block_circuit.circuit); + // Account for `mix_pv_hash`. + padding -= builder.num_public_inputs(); + + let zero = builder.zero(); + for _ in 0..padding { + builder.register_public_input(zero); + } + + let cyclic_vk = builder.add_verifier_data_public_inputs(); + + let lhs = Self::add_agg_child(&mut builder, &block_circuit.circuit); + let rhs = Self::add_agg_child(&mut builder, &block_circuit.circuit); + + let lhs_public_inputs = lhs.public_inputs(&mut builder); + let rhs_public_inputs = rhs.public_inputs(&mut builder); + + let lhs_public_values = extract_block_public_values(&lhs_public_inputs); + let rhs_public_values = extract_block_public_values(&rhs_public_inputs); + + let lhs_agg_pv_hash = extract_two_to_one_block_hash(&lhs_public_inputs); + let rhs_agg_pv_hash = extract_two_to_one_block_hash(&rhs_public_inputs); + + let lhs_base_pv_hash = builder + .hash_n_to_hash_no_pad::(lhs_public_values.to_vec()) + .elements; + let rhs_base_pv_hash = builder + .hash_n_to_hash_no_pad::(rhs_public_values.to_vec()) + .elements; + + let lhs_hash: Vec = zip_eq(lhs_agg_pv_hash, lhs_base_pv_hash) + .map(|(&agg_target, base_target)| builder.select(lhs.is_agg, agg_target, base_target)) + .collect(); + + let rhs_hash: Vec = zip_eq(rhs_agg_pv_hash, rhs_base_pv_hash) + .map(|(&agg_target, base_target)| builder.select(rhs.is_agg, agg_target, base_target)) + .collect(); + + let mut mix_vec = vec![]; + mix_vec.extend(&lhs_hash); + mix_vec.extend(&rhs_hash); + + let mix_hash_virtual = builder.hash_n_to_hash_no_pad::(mix_vec); + + builder.connect_hashes(mix_hash, mix_hash_virtual); + + let circuit = builder.build::(); + TwoToOneBlockCircuitData { + circuit, + lhs, + rhs, + cyclic_vk, + } + } + /// Connect the 256 block hashes between two blocks fn connect_block_hashes( builder: &mut CircuitBuilder, @@ -1226,11 +1398,11 @@ where agg_inputs.set_bool_target(self.aggregation.lhs.is_agg, lhs_is_agg); agg_inputs.set_proof_with_pis_target(&self.aggregation.lhs.agg_proof, lhs_proof); - agg_inputs.set_proof_with_pis_target(&self.aggregation.lhs.evm_proof, lhs_proof); + agg_inputs.set_proof_with_pis_target(&self.aggregation.lhs.base_proof, lhs_proof); agg_inputs.set_bool_target(self.aggregation.rhs.is_agg, rhs_is_agg); agg_inputs.set_proof_with_pis_target(&self.aggregation.rhs.agg_proof, rhs_proof); - agg_inputs.set_proof_with_pis_target(&self.aggregation.rhs.evm_proof, rhs_proof); + agg_inputs.set_proof_with_pis_target(&self.aggregation.rhs.base_proof, rhs_proof); agg_inputs.set_verifier_data_target( &self.aggregation.cyclic_vk, @@ -1448,8 +1620,134 @@ where &self.block.circuit.common, ) } -} + /// Aggregates two proofs in manner similar to [`prove_aggregation`]. + /// + /// # Arguments + /// + /// - `lhs`: a proof of either a block or previous aggregation. + /// - `lhs_is_agg`: specify which case `lhs` was. + /// - `rhs`: a proof of either a block or previous aggregation. + /// - `rhs_is_agg`: specify which case `rhs` was. + /// + /// # Outputs + /// + /// Returns a [`ProofWithPublicInputs`]. + pub fn prove_two_to_one_block( + &self, + lhs: &ProofWithPublicInputs, + lhs_is_agg: bool, + rhs: &ProofWithPublicInputs, + rhs_is_agg: bool, + ) -> anyhow::Result> { + let mut witness = PartialWitness::new(); + + Self::set_dummy_if_necessary( + &self.two_to_one_block.lhs, + lhs_is_agg, + &self.two_to_one_block.circuit, + &mut witness, + lhs, + ); + + Self::set_dummy_if_necessary( + &self.two_to_one_block.rhs, + rhs_is_agg, + &self.two_to_one_block.circuit, + &mut witness, + rhs, + ); + + witness.set_verifier_data_target( + &self.two_to_one_block.cyclic_vk, + &self.two_to_one_block.circuit.verifier_only, + ); + + let proof = self.two_to_one_block.circuit.prove(witness)?; + Ok(proof) + } + + /// Verifies an existing block aggregation proof. + /// + /// # Arguments + /// + /// - `proof`: The proof generated with `prove_two_to_one_block`. + /// + /// # Outputs + /// + /// Returns whether the proof was valid or not. + pub fn verify_two_to_one_block( + &self, + proof: &ProofWithPublicInputs, + ) -> anyhow::Result<()> { + self.two_to_one_block.circuit.verify(proof.clone())?; + let verifier_data = &self.two_to_one_block.circuit.verifier_data(); + check_cyclic_proof_verifier_data(proof, &verifier_data.verifier_only, &verifier_data.common) + } + + /// Creates dummy public inputs with correct verifier key at the end. Used + /// by [`set_dummy_if_necessary`]. It cyclic vk to the aggregation circuit + /// values, so that both aggregation and non-aggregation parts of the child + /// share the same vk. This is possible because only the aggregation inner + /// circuit is checked against its vk. + fn set_dummy_proof_with_cyclic_vk_pis( + circuit_agg: &CircuitData, + witness: &mut PartialWitness, + agg_proof_with_pis: &ProofWithPublicInputsTarget, + base_proof_with_pis: &ProofWithPublicInputs, + ) { + let ProofWithPublicInputs { + proof: base_proof, + public_inputs: _, + } = base_proof_with_pis; + let ProofWithPublicInputsTarget { + proof: agg_proof_targets, + public_inputs: agg_pi_targets, + } = agg_proof_with_pis; + + // The proof remains the same. + witness.set_proof_target(agg_proof_targets, base_proof); + + let cyclic_verifying_data = &circuit_agg.verifier_only; + let mut cyclic_vk = cyclic_verifying_data.circuit_digest.to_vec(); + cyclic_vk.append(&mut cyclic_verifying_data.constants_sigmas_cap.flatten()); + + let mut dummy_pis = vec![F::ZERO; circuit_agg.common.num_public_inputs - cyclic_vk.len()]; + dummy_pis.append(&mut cyclic_vk); + + // Set dummy public inputs. + for (&pi_t, pi) in agg_pi_targets.iter().zip_eq(dummy_pis) { + witness.set_target(pi_t, pi); + } + } + + /// If the [`AggregationChild`] is a base proof and not an aggregation + /// proof, we need to manually set the public inputs vector of the otherwise + /// inert `agg_proof`, so that they correspond to the `cyclic_vk` of the + /// aggregation circuit. The cyclic prover expects to find the `cyclic_vk` + /// targets in the very end of the public inputs vector, and so it does not + /// matter what the preceding values are. + fn set_dummy_if_necessary( + agg_child: &AggregationChildTarget, + is_agg: bool, + circuit: &CircuitData, + agg_inputs: &mut PartialWitness, + proof: &ProofWithPublicInputs, + ) { + agg_inputs.set_bool_target(agg_child.is_agg, is_agg); + if is_agg { + agg_inputs.set_proof_with_pis_target(&agg_child.agg_proof, proof); + } else { + Self::set_dummy_proof_with_cyclic_vk_pis( + circuit, + agg_inputs, + &agg_child.agg_proof, + proof, + ); + } + agg_inputs.set_proof_with_pis_target(&agg_child.base_proof, proof); + } +} /// A map between initial degree sizes and their associated shrinking recursion /// circuits. #[derive(Eq, PartialEq, Debug)] @@ -1706,3 +2004,59 @@ fn shrinking_config() -> CircuitConfig { ..CircuitConfig::standard_recursion_config() } } + +/// Extracts the two-to-one block aggregation hash from a public inputs slice. +/// +/// # Arguments +/// +/// - `public_inputs`: A slice of public inputs originating from the aggregation +/// case of a two-to-one block proof. This slice must consist of a hash, +/// either of public values, or of two concatenated hashes. The hash must +/// start at offset zero of the slice and is typically followed by padding and +/// then a verifier key. It is an error to call this on a slice for a base +/// proof. +/// +/// # Outputs +/// +/// - A slice containing exactly the hash. +pub fn extract_two_to_one_block_hash(public_inputs: &[T]) -> &[T; NUM_HASH_OUT_ELTS] { + const PV_HASH_INDEX_START: usize = 0; + const PV_HASH_INDEX_END: usize = PV_HASH_INDEX_START + NUM_HASH_OUT_ELTS; + public_inputs[PV_HASH_INDEX_START..PV_HASH_INDEX_END] + .try_into() + .expect("Public inputs vector was malformed.") +} + +/// Extracts the two-to-one block aggregation public values of the block from +/// a public inputs slice. +/// +/// # Arguments +/// +/// - `public_inputs`: A slice of public inputs originating from the base case +/// of a two-to-one block proof. This slice must consist exactly of public +/// values starting at offset zero and is typically followed by a verifier +/// key. It is an error to call this function on a slice for an aggregation +/// proof. +/// +/// # Outputs +/// +/// - A slice containing exactly the public values. +pub fn extract_block_public_values(public_inputs: &[T]) -> &[T; PublicValuesTarget::SIZE] { + const PV_INDEX_START: usize = 0; + const PV_INDEX_END: usize = PV_INDEX_START + PublicValuesTarget::SIZE; + public_inputs[PV_INDEX_START..PV_INDEX_END] + .try_into() + .expect("Public inputs vector was malformed.") +} + +/// Computes the length added to the public inputs vector by +/// [`CircuitBuilder::add_verifier_data_public_inputs`]. +pub const fn verification_key_len(circuit: &CircuitData) -> usize +where + F: RichField + Extendable, + C: GenericConfig, + C::Hasher: AlgebraicHasher, +{ + circuit.verifier_only.circuit_digest.elements.len() + + (1 << circuit.common.config.fri_config.cap_height) * NUM_HASH_OUT_ELTS +} diff --git a/evm_arithmetization/src/proof.rs b/evm_arithmetization/src/proof.rs index 80c401b24..442e1a455 100644 --- a/evm_arithmetization/src/proof.rs +++ b/evm_arithmetization/src/proof.rs @@ -59,14 +59,7 @@ impl PublicValues { /// Public values are always the first public inputs added to the circuit, /// so we can start extracting at index 0. pub fn from_public_inputs(pis: &[F]) -> Self { - assert!( - pis.len() - > TrieRootsTarget::SIZE * 2 - + BlockMetadataTarget::SIZE - + BlockHashesTarget::SIZE - + ExtraBlockDataTarget::SIZE - - 1 - ); + assert!(PublicValuesTarget::SIZE <= pis.len()); let trie_roots_before = TrieRoots::from_public_inputs(&pis[0..TrieRootsTarget::SIZE]); let trie_roots_after = @@ -294,6 +287,10 @@ pub struct PublicValuesTarget { } impl PublicValuesTarget { + pub(crate) const SIZE: usize = TrieRootsTarget::SIZE * 2 + + BlockMetadataTarget::SIZE + + BlockHashesTarget::SIZE + + ExtraBlockDataTarget::SIZE; /// Serializes public value targets. pub(crate) fn to_buffer(&self, buffer: &mut Vec) -> IoResult<()> { let TrieRootsTarget { @@ -827,7 +824,7 @@ pub struct ExtraBlockDataTarget { impl ExtraBlockDataTarget { /// Number of `Target`s required for the extra block data. - const SIZE: usize = 12; + pub(crate) const SIZE: usize = 12; /// Extracts the extra block data `Target`s from the public input `Target`s. /// The provided `pis` should start with the extra vblock data. diff --git a/evm_arithmetization/src/witness/traces.rs b/evm_arithmetization/src/witness/traces.rs index 66224c2bb..b538e185b 100644 --- a/evm_arithmetization/src/witness/traces.rs +++ b/evm_arithmetization/src/witness/traces.rs @@ -41,7 +41,7 @@ pub(crate) struct Traces { } impl Traces { - pub(crate) fn new() -> Self { + pub(crate) const fn new() -> Self { Traces { arithmetic_ops: vec![], byte_packing_ops: vec![], diff --git a/evm_arithmetization/tests/basic_smart_contract.rs b/evm_arithmetization/tests/basic_smart_contract.rs deleted file mode 100644 index 468d78f36..000000000 --- a/evm_arithmetization/tests/basic_smart_contract.rs +++ /dev/null @@ -1,192 +0,0 @@ -use std::collections::HashMap; -use std::str::FromStr; -use std::time::Duration; - -use ethereum_types::{Address, BigEndianHash, H160, H256, U256}; -use evm_arithmetization::cpu::kernel::opcodes::{get_opcode, get_push_opcode}; -use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; -use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; -use evm_arithmetization::proof::{BlockHashes, BlockMetadata, TrieRoots}; -use evm_arithmetization::prover::prove; -use evm_arithmetization::testing_utils::{ - eth_to_wei, init_logger, preinitialized_state, preinitialized_state_with_updated_storage, - set_account, -}; -use evm_arithmetization::verifier::verify_proof; -use evm_arithmetization::{AllStark, Node, StarkConfig}; -use hex_literal::hex; -use mpt_trie::nibbles::Nibbles; -use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; -use plonky2::field::goldilocks_field::GoldilocksField; -use plonky2::plonk::config::KeccakGoldilocksConfig; -use plonky2::util::timing::TimingTree; -use smt_trie::code::hash_bytecode_u256; -use smt_trie::utils::hashout2u; - -type F = GoldilocksField; -const D: usize = 2; -type C = KeccakGoldilocksConfig; - -/// Test a simple token transfer to a new address. -#[test] -#[ignore] // Too slow to run on CI. -fn test_basic_smart_contract() -> anyhow::Result<()> { - init_logger(); - - let all_stark = AllStark::::default(); - let config = StarkConfig::standard_fast_config(); - - let beneficiary = hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); - let sender = hex!("2c7536e3605d9c16a7a3d7b1898e529396a65c23"); - let to = hex!("a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0"); - - let push1 = get_push_opcode(1); - let add = get_opcode("ADD"); - let stop = get_opcode("STOP"); - let code = [push1, 3, push1, 4, add, stop]; - let code_gas = 3 + 3 + 3; - let code_hash = hash_bytecode_u256(code.to_vec()); - - let beneficiary_account_before = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - let sender_account_before = AccountRlp { - nonce: 5.into(), - balance: eth_to_wei(100_000.into()), - ..AccountRlp::default() - }; - let to_account_before = AccountRlp { - code_hash, - ..AccountRlp::default() - }; - - let mut state_smt_before = preinitialized_state(); - set_account( - &mut state_smt_before, - H160(beneficiary), - &beneficiary_account_before, - &HashMap::new(), - ); - set_account( - &mut state_smt_before, - H160(sender), - &sender_account_before, - &HashMap::new(), - ); - set_account( - &mut state_smt_before, - H160(to), - &to_account_before, - &HashMap::new(), - ); - - let tries_before = TrieInputs { - state_smt: state_smt_before.serialize(), - transactions_trie: Node::Empty.into(), - receipts_trie: Node::Empty.into(), - }; - - let txdata_gas = 2 * 16; - let gas_used = 21_000 + code_gas + txdata_gas; - - // Generated using a little py-evm script. - let txn = hex!("f861050a8255f094a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0648242421ba02c89eb757d9deeb1f5b3859a9d4d679951ef610ac47ad4608dc142beb1b7e313a05af7e9fbab825455d36c36c7f4cfcafbeafa9a77bdff936b52afb36d4fe4bcdd"); - let value = U256::from(100u32); - - let block_metadata = BlockMetadata { - block_beneficiary: Address::from(beneficiary), - block_difficulty: 0x20000.into(), - block_number: 1.into(), - block_chain_id: 1.into(), - block_timestamp: 0x03e8.into(), - block_gaslimit: 0xff112233u32.into(), - block_gas_used: gas_used.into(), - block_base_fee: 0xa.into(), - ..Default::default() - }; - - let mut contract_code = HashMap::new(); - contract_code.insert(hash_bytecode_u256(vec![]), vec![]); - contract_code.insert(code_hash, code.to_vec()); - - let expected_state_smt_after = { - let mut smt = preinitialized_state_with_updated_storage(&block_metadata, &[]); - - let beneficiary_account_after = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - let sender_account_after = AccountRlp { - balance: sender_account_before.balance - value - gas_used * 10, - nonce: sender_account_before.nonce + 1, - ..sender_account_before - }; - let to_account_after = AccountRlp { - balance: to_account_before.balance + value, - ..to_account_before - }; - - set_account( - &mut smt, - H160(beneficiary), - &beneficiary_account_after, - &HashMap::new(), - ); - set_account( - &mut smt, - H160(sender), - &sender_account_after, - &HashMap::new(), - ); - set_account(&mut smt, H160(to), &to_account_after, &HashMap::new()); - - smt - }; - - let receipt_0 = LegacyReceiptRlp { - status: true, - cum_gas_used: gas_used.into(), - bloom: vec![0; 256].into(), - logs: vec![], - }; - let mut receipts_trie = HashedPartialTrie::from(Node::Empty); - receipts_trie.insert( - Nibbles::from_str("0x80").unwrap(), - rlp::encode(&receipt_0).to_vec(), - )?; - let transactions_trie: HashedPartialTrie = Node::Leaf { - nibbles: Nibbles::from_str("0x80").unwrap(), - value: txn.to_vec(), - } - .into(); - - let trie_roots_after = TrieRoots { - state_root: H256::from_uint(&hashout2u(expected_state_smt_after.root)), - transactions_root: transactions_trie.hash(), - receipts_root: receipts_trie.hash(), - }; - let inputs = GenerationInputs { - signed_txn: Some(txn.to_vec()), - withdrawals: vec![], - global_exit_roots: vec![], - tries: tries_before, - trie_roots_after, - contract_code, - checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(), - block_metadata, - txn_number_before: 0.into(), - gas_used_before: 0.into(), - gas_used_after: gas_used.into(), - block_hashes: BlockHashes { - prev_hashes: vec![H256::default(); 256], - cur_hash: H256::default(), - }, - }; - - let mut timing = TimingTree::new("prove", log::Level::Debug); - let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; - timing.filter(Duration::from_millis(100)).print(); - - verify_proof(&all_stark, proof, &config) -} diff --git a/evm_arithmetization/tests/empty_txn_list.rs b/evm_arithmetization/tests/empty_txn_list.rs deleted file mode 100644 index 966f9b704..000000000 --- a/evm_arithmetization/tests/empty_txn_list.rs +++ /dev/null @@ -1,187 +0,0 @@ -use core::marker::PhantomData; -use std::collections::HashMap; -use std::time::Duration; - -use ethereum_types::{BigEndianHash, H256}; -use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; -use evm_arithmetization::proof::{BlockHashes, BlockMetadata, PublicValues, TrieRoots}; -use evm_arithmetization::testing_utils::{ - init_logger, preinitialized_state, preinitialized_state_with_updated_storage, -}; -use evm_arithmetization::{AllRecursiveCircuits, AllStark, Node, StarkConfig}; -use hex_literal::hex; -use log::info; -use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; -use plonky2::field::goldilocks_field::GoldilocksField; -use plonky2::plonk::config::PoseidonGoldilocksConfig; -use plonky2::util::serialization::{DefaultGateSerializer, DefaultGeneratorSerializer}; -use plonky2::util::timing::TimingTree; -use smt_trie::code::hash_bytecode_u256; -use smt_trie::utils::hashout2u; - -type F = GoldilocksField; -const D: usize = 2; -type C = PoseidonGoldilocksConfig; - -/// Execute the empty list of transactions, i.e. a no-op. -#[test] -#[ignore] // Too slow to run on CI. -fn test_empty_txn_list() -> anyhow::Result<()> { - init_logger(); - - let all_stark = AllStark::::default(); - let config = StarkConfig::standard_fast_config(); - - let block_metadata = BlockMetadata { - block_number: 1.into(), - block_timestamp: 1.into(), - parent_beacon_block_root: H256(hex!( - "44e2566c06c03b132e0ede3e90af477ebca74393b89dd6cb29f9c79cbcb6e963" - )), - ..Default::default() - }; - - let state_smt = preinitialized_state(); - let transactions_trie = HashedPartialTrie::from(Node::Empty); - let receipts_trie = HashedPartialTrie::from(Node::Empty); - - let mut contract_code = HashMap::new(); - contract_code.insert(hash_bytecode_u256(vec![]), vec![]); - - let state_smt_after = preinitialized_state_with_updated_storage(&block_metadata, &[]); - - // No transactions, but the beacon roots contract has been updated. - let trie_roots_after = TrieRoots { - state_root: H256::from_uint(&hashout2u(state_smt_after.root)), - transactions_root: transactions_trie.hash(), - receipts_root: receipts_trie.hash(), - }; - let mut initial_block_hashes = vec![H256::default(); 256]; - initial_block_hashes[255] = H256::from_uint(&hashout2u(state_smt.root)); - let inputs1 = GenerationInputs { - signed_txn: None, - withdrawals: vec![], - global_exit_roots: vec![], - tries: TrieInputs { - state_smt: state_smt.serialize(), - transactions_trie: transactions_trie.clone(), - receipts_trie: receipts_trie.clone(), - }, - trie_roots_after: trie_roots_after.clone(), - contract_code: contract_code.clone(), - checkpoint_state_trie_root: H256::from_uint(&hashout2u(state_smt.root)), - block_metadata: block_metadata.clone(), - txn_number_before: 0.into(), - gas_used_before: 0.into(), - gas_used_after: 0.into(), - block_hashes: BlockHashes { - prev_hashes: initial_block_hashes.clone(), - cur_hash: H256::default(), - }, - }; - - // Initialize the preprocessed circuits for the zkEVM. - let all_circuits = AllRecursiveCircuits::::new( - &all_stark, - // Minimal ranges to prove an empty list - &[16..17, 11..12, 13..14, 14..15, 9..11, 12..13, 17..18, 6..7], - &config, - ); - - { - let gate_serializer = DefaultGateSerializer; - let generator_serializer = DefaultGeneratorSerializer:: { - _phantom: PhantomData::, - }; - - let timing = TimingTree::new("serialize AllRecursiveCircuits", log::Level::Info); - let all_circuits_bytes = all_circuits - .to_bytes(false, &gate_serializer, &generator_serializer) - .map_err(|_| anyhow::Error::msg("AllRecursiveCircuits serialization failed."))?; - timing.filter(Duration::from_millis(100)).print(); - info!( - "AllRecursiveCircuits length: {} bytes", - all_circuits_bytes.len() - ); - - let timing = TimingTree::new("deserialize AllRecursiveCircuits", log::Level::Info); - let all_circuits_from_bytes = AllRecursiveCircuits::::from_bytes( - &all_circuits_bytes, - false, - &gate_serializer, - &generator_serializer, - ) - .map_err(|_| anyhow::Error::msg("AllRecursiveCircuits deserialization failed."))?; - timing.filter(Duration::from_millis(100)).print(); - - assert_eq!(all_circuits, all_circuits_from_bytes); - } - - let mut timing = TimingTree::new("prove first dummy", log::Level::Info); - let (root_proof, public_values) = - all_circuits.prove_root(&all_stark, &config, inputs1, &mut timing, None)?; - timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_root(root_proof.clone())?; - - // Test retrieved public values from the proof public inputs. - let retrieved_public_values = PublicValues::from_public_inputs(&root_proof.public_inputs); - assert_eq!(retrieved_public_values, public_values); - - // We cannot duplicate the proof here because even though there weren't any - // transactions, the state has mutated when updating the beacon roots contract. - - let inputs2 = GenerationInputs { - signed_txn: None, - withdrawals: vec![], - global_exit_roots: vec![], - tries: TrieInputs { - state_smt: state_smt_after.serialize(), - transactions_trie, - receipts_trie, - }, - trie_roots_after, - contract_code, - checkpoint_state_trie_root: H256::from_uint(&hashout2u(state_smt.root)), - block_metadata, - txn_number_before: 0.into(), - gas_used_before: 0.into(), - gas_used_after: 0.into(), - block_hashes: BlockHashes { - prev_hashes: initial_block_hashes, - cur_hash: H256::default(), - }, - }; - - let mut timing = TimingTree::new("prove second dummy", log::Level::Info); - let (root_proof2, public_values2) = - all_circuits.prove_root(&all_stark, &config, inputs2, &mut timing, None)?; - timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_root(root_proof2.clone())?; - - let (agg_proof, agg_public_values) = all_circuits.prove_aggregation( - false, - &root_proof, - public_values.clone(), - false, - &root_proof2, - public_values2, - )?; - all_circuits.verify_aggregation(&agg_proof)?; - - // Test retrieved public values from the proof public inputs. - let retrieved_public_values = PublicValues::from_public_inputs(&agg_proof.public_inputs); - assert_eq!(retrieved_public_values, agg_public_values); - - let (block_proof, block_public_values) = - all_circuits.prove_block(None, &agg_proof, agg_public_values)?; - all_circuits.verify_block(&block_proof)?; - - // Test retrieved public values from the proof public inputs. - let retrieved_public_values = PublicValues::from_public_inputs(&block_proof.public_inputs); - assert_eq!(retrieved_public_values, block_public_values); - - // Get the verifier associated to these preprocessed circuits, and have it - // verify the block_proof. - let verifier = all_circuits.final_verifier_data(); - verifier.verify(block_proof) -} diff --git a/evm_arithmetization/tests/log_opcode.rs b/evm_arithmetization/tests/log_opcode.rs index 5965b2a5b..4975fdee5 100644 --- a/evm_arithmetization/tests/log_opcode.rs +++ b/evm_arithmetization/tests/log_opcode.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use std::time::Duration; use bytes::Bytes; -use ethereum_types::{Address, BigEndianHash, H160, H256, U256}; +use ethereum_types::{Address, BigEndianHash, H160, H256}; use evm_arithmetization::generation::mpt::transaction_testing::{ AddressOption, LegacyTransactionRlp, }; @@ -13,10 +13,9 @@ use evm_arithmetization::proof::{BlockHashes, BlockMetadata, TrieRoots}; use evm_arithmetization::prover::prove; use evm_arithmetization::testing_utils::{ init_logger, preinitialized_state, preinitialized_state_with_updated_storage, set_account, - update_beacon_roots_account_storage, }; use evm_arithmetization::verifier::verify_proof; -use evm_arithmetization::{AllRecursiveCircuits, AllStark, Node, StarkConfig}; +use evm_arithmetization::{AllStark, Node, StarkConfig}; use hex_literal::hex; use mpt_trie::nibbles::Nibbles; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; @@ -32,7 +31,6 @@ type C = PoseidonGoldilocksConfig; /// Variation of `add11_yml` testing LOG opcodes. #[test] -#[ignore] // Too slow to run on CI. fn test_log_opcodes() -> anyhow::Result<()> { init_logger(); @@ -254,462 +252,6 @@ fn test_log_opcodes() -> anyhow::Result<()> { verify_proof(&all_stark, proof, &config) } -// Tests proving two transactions, one of which with logs, and aggregating them. -#[test] -#[ignore] // Too slow to run on CI. -fn test_log_with_aggreg() -> anyhow::Result<()> { - init_logger(); - - let code = [ - 0x64, 0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0x60, 0x0, 0x52, // MSTORE(0x0, 0xA1B2C3D4E5) - 0x60, 0x0, 0x60, 0x0, 0xA0, // LOG0(0x0, 0x0) - 0x60, 99, 0x60, 98, 0x60, 5, 0x60, 27, 0xA2, // LOG2(27, 5, 98, 99) - 0x00, - ]; - - let code_gas = 3 + 3 + 3 // PUSHs and MSTORE - + 3 + 3 + 375 // PUSHs and LOG0 - + 3 + 3 + 3 + 3 + 375 + 375*2 + 8*5 // PUSHs and LOG2 - + 3 // Memory expansion - ; - let gas_used = 21_000 + code_gas; - let code_hash = hash_bytecode_u256(code.to_vec()); - - // First transaction. - let all_stark = AllStark::::default(); - let config = StarkConfig::standard_fast_config(); - - let beneficiary = hex!("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"); - let sender_first = hex!("af1276cbb260bb13deddb4209ae99ae6e497f446"); - let to_first = hex!("095e7baea6a6c7c4c2dfeb977efac326af552d87"); - let to = hex!("095e7baea6a6c7c4c2dfeb977efac326af552e89"); - - let beneficiary_account_before = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - let sender_balance_before = 1000000000000000000u64.into(); - let sender_account_before = AccountRlp { - balance: sender_balance_before, - ..AccountRlp::default() - }; - let to_account_before = AccountRlp { - ..AccountRlp::default() - }; - let to_account_second_before = AccountRlp { - code_hash, - ..AccountRlp::default() - }; - - // In the first transaction, the sender account sends `txn_value` to - // `to_account`. - let gas_price = 10; - let txn_value = 0xau64; - let mut state_smt_before = preinitialized_state(); - set_account( - &mut state_smt_before, - H160(beneficiary), - &beneficiary_account_before, - &HashMap::new(), - ); - set_account( - &mut state_smt_before, - H160(sender_first), - &sender_account_before, - &HashMap::new(), - ); - set_account( - &mut state_smt_before, - H160(to_first), - &to_account_before, - &HashMap::new(), - ); - set_account( - &mut state_smt_before, - H160(to), - &to_account_second_before, - &HashMap::new(), - ); - - let checkpoint_state_trie_root = H256::from_uint(&hashout2u(state_smt_before.root)); - - let tries_before = TrieInputs { - state_smt: state_smt_before.serialize(), - transactions_trie: Node::Empty.into(), - receipts_trie: Node::Empty.into(), - }; - - let txn = hex!("f85f800a82520894095e7baea6a6c7c4c2dfeb977efac326af552d870a8026a0122f370ed4023a6c253350c6bfb87d7d7eb2cd86447befee99e0a26b70baec20a07100ab1b3977f2b4571202b9f4b68850858caf5469222794600b5ce1cfb348ad"); - - let block_1_metadata = BlockMetadata { - block_beneficiary: Address::from(beneficiary), - block_timestamp: 0x03e8.into(), - block_number: 1.into(), - block_difficulty: 0x020000.into(), - block_gaslimit: 0x445566u32.into(), - block_chain_id: 1.into(), - block_base_fee: 0xa.into(), - block_gas_used: (22570 + 21000).into(), - block_bloom: [ - 0.into(), - 0.into(), - U256::from_dec_str( - "55213970774324510299479508399853534522527075462195808724319849722937344", - ) - .unwrap(), - U256::from_dec_str("1361129467683753853853498429727072845824").unwrap(), - 33554432.into(), - U256::from_dec_str("9223372036854775808").unwrap(), - U256::from_dec_str( - "3618502788666131106986593281521497120414687020801267626233049500247285563392", - ) - .unwrap(), - U256::from_dec_str("2722259584404615024560450425766186844160").unwrap(), - ], - ..Default::default() - }; - - let beneficiary_account_after = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - - let sender_balance_after = sender_balance_before - gas_price * 21000 - txn_value; - let sender_account_after = AccountRlp { - balance: sender_balance_after, - nonce: 1.into(), - ..AccountRlp::default() - }; - let to_account_after = AccountRlp { - balance: txn_value.into(), - ..AccountRlp::default() - }; - - let mut contract_code = HashMap::new(); - contract_code.insert(hash_bytecode_u256(vec![]), vec![]); - contract_code.insert(code_hash, code.to_vec()); - - let expected_state_smt_after = { - let mut smt = preinitialized_state_with_updated_storage(&block_1_metadata, &[]); - - set_account( - &mut smt, - H160(beneficiary), - &beneficiary_account_after, - &HashMap::new(), - ); - set_account( - &mut smt, - H160(sender_first), - &sender_account_after, - &HashMap::new(), - ); - set_account(&mut smt, H160(to_first), &to_account_after, &HashMap::new()); - set_account( - &mut smt, - H160(to), - &to_account_second_before, - &HashMap::new(), - ); - - smt - }; - - // Compute new receipt trie. - let mut receipts_trie = HashedPartialTrie::from(Node::Empty); - let receipt_0 = LegacyReceiptRlp { - status: true, - cum_gas_used: 21000u64.into(), - bloom: [0x00; 256].to_vec().into(), - logs: vec![], - }; - receipts_trie.insert( - Nibbles::from_str("0x80").unwrap(), - rlp::encode(&receipt_0).to_vec(), - )?; - - let mut transactions_trie: HashedPartialTrie = Node::Leaf { - nibbles: Nibbles::from_str("0x80").unwrap(), - value: txn.to_vec(), - } - .into(); - - let tries_after = TrieRoots { - state_root: H256::from_uint(&hashout2u(expected_state_smt_after.root)), - transactions_root: transactions_trie.hash(), - receipts_root: receipts_trie.clone().hash(), - }; - - let block_1_hash = - H256::from_str("0x0101010101010101010101010101010101010101010101010101010101010101")?; - let mut block_hashes = vec![H256::default(); 256]; - - let inputs_first = GenerationInputs { - signed_txn: Some(txn.to_vec()), - withdrawals: vec![], - global_exit_roots: vec![], - tries: tries_before, - trie_roots_after: tries_after, - contract_code, - checkpoint_state_trie_root, - block_metadata: block_1_metadata.clone(), - txn_number_before: 0.into(), - gas_used_before: 0.into(), - gas_used_after: 21000u64.into(), - block_hashes: BlockHashes { - prev_hashes: block_hashes.clone(), - cur_hash: block_1_hash, - }, - }; - - // Preprocess all circuits. - let all_circuits = AllRecursiveCircuits::::new( - &all_stark, - &[16..17, 12..15, 14..17, 14..15, 10..11, 12..13, 17..20, 7..8], - &config, - ); - - let mut timing = TimingTree::new("prove root first", log::Level::Info); - let (root_proof_first, public_values_first) = - all_circuits.prove_root(&all_stark, &config, inputs_first, &mut timing, None)?; - - timing.filter(Duration::from_millis(100)).print(); - all_circuits.verify_root(root_proof_first.clone())?; - - // The gas used and transaction number are fed to the next transaction, so the - // two proofs can be correctly aggregated. - let gas_used_second = public_values_first.extra_block_data.gas_used_after; - - // Prove second transaction. In this second transaction, the code with logs is - // executed. - - let state_smt_before = expected_state_smt_after; - - let tries_before = TrieInputs { - state_smt: state_smt_before.serialize(), - transactions_trie: transactions_trie.clone(), - receipts_trie: receipts_trie.clone(), - }; - - // Prove a transaction which carries out two LOG opcodes. - let txn_gas_price = 10; - let txn_2 = hex!("f860010a830186a094095e7baea6a6c7c4c2dfeb977efac326af552e89808025a04a223955b0bd3827e3740a9a427d0ea43beb5bafa44a0204bf0a3306c8219f7ba0502c32d78f233e9e7ce9f5df3b576556d5d49731e0678fd5a068cdf359557b5b"); - - let mut contract_code = HashMap::new(); - contract_code.insert(hash_bytecode_u256(vec![]), vec![]); - contract_code.insert(code_hash, code.to_vec()); - - // Update the state and receipt tries after the transaction, so that we have the - // correct expected tries: Update accounts. - let beneficiary_account_after = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - - let sender_balance_after = sender_balance_after - gas_used * txn_gas_price; - let sender_account_after = AccountRlp { - balance: sender_balance_after, - nonce: 2.into(), - ..AccountRlp::default() - }; - let balance_after = to_account_after.balance; - let to_account_after = AccountRlp { - balance: balance_after, - ..AccountRlp::default() - }; - let to_account_second_after = AccountRlp { - balance: to_account_second_before.balance, - code_hash, - ..AccountRlp::default() - }; - - // Update the receipt trie. - let first_log = LogRlp { - address: to.into(), - topics: vec![], - data: Bytes::new(), - }; - - let second_log = LogRlp { - address: to.into(), - topics: vec![ - hex!("0000000000000000000000000000000000000000000000000000000000000062").into(), /* dec: 98 */ - hex!("0000000000000000000000000000000000000000000000000000000000000063").into(), /* dec: 99 */ - ], - data: hex!("a1b2c3d4e5").to_vec().into(), - }; - - let receipt = LegacyReceiptRlp { - status: true, - cum_gas_used: (22570 + 21000).into(), - bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000800000000000000008000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000800002000000000000000000000000000").to_vec().into(), - logs: vec![first_log, second_log], - }; - - let receipt_nibbles = Nibbles::from_str("0x01").unwrap(); // RLP(1) = 0x1 - receipts_trie.insert(receipt_nibbles, rlp::encode(&receipt).to_vec())?; - - // Update the state trie. - let expected_state_smt_after = { - let mut smt = preinitialized_state_with_updated_storage(&block_1_metadata, &[]); - set_account( - &mut smt, - H160(beneficiary), - &beneficiary_account_after, - &HashMap::new(), - ); - set_account( - &mut smt, - H160(sender_first), - &sender_account_after, - &HashMap::new(), - ); - set_account(&mut smt, H160(to_first), &to_account_after, &HashMap::new()); - set_account( - &mut smt, - H160(to), - &to_account_second_after, - &HashMap::new(), - ); - - smt - }; - - let mut state_smt_after_block2 = expected_state_smt_after.clone(); - - transactions_trie.insert(Nibbles::from_str("0x01").unwrap(), txn_2.to_vec())?; - - let block_1_state_root = H256::from_uint(&hashout2u(expected_state_smt_after.root)); - println!("{:x}", block_1_state_root); - - let trie_roots_after = TrieRoots { - state_root: block_1_state_root, - transactions_root: transactions_trie.hash(), - receipts_root: receipts_trie.hash(), - }; - - let inputs = GenerationInputs { - signed_txn: Some(txn_2.to_vec()), - withdrawals: vec![], - global_exit_roots: vec![], - tries: tries_before, - trie_roots_after: trie_roots_after.clone(), - contract_code, - checkpoint_state_trie_root, - block_metadata: block_1_metadata, - txn_number_before: 1.into(), - gas_used_before: gas_used_second, - gas_used_after: receipt.cum_gas_used, - block_hashes: BlockHashes { - prev_hashes: block_hashes.clone(), - cur_hash: block_1_hash, - }, - }; - - let mut timing = TimingTree::new("prove root second", log::Level::Info); - let (root_proof_second, public_values_second) = - all_circuits.prove_root(&all_stark, &config, inputs, &mut timing, None.clone())?; - timing.filter(Duration::from_millis(100)).print(); - - all_circuits.verify_root(root_proof_second.clone())?; - - let (agg_proof, updated_agg_public_values) = all_circuits.prove_aggregation( - false, - &root_proof_first, - public_values_first, - false, - &root_proof_second, - public_values_second, - )?; - all_circuits.verify_aggregation(&agg_proof)?; - let (first_block_proof, _block_public_values) = - all_circuits.prove_block(None, &agg_proof, updated_agg_public_values)?; - all_circuits.verify_block(&first_block_proof)?; - - // Prove the next, empty block. - - let block_2_hash = - H256::from_str("0x0123456789101112131415161718192021222324252627282930313233343536")?; - block_hashes[255] = block_1_hash; - - let block_2_metadata = BlockMetadata { - block_beneficiary: Address::from(beneficiary), - block_timestamp: 0x03e9.into(), - block_number: 2.into(), - block_difficulty: 0x020000.into(), - block_gaslimit: 0x445566u32.into(), - block_chain_id: 1.into(), - block_base_fee: 0xa.into(), - ..Default::default() - }; - - update_beacon_roots_account_storage( - &mut state_smt_after_block2, - block_2_metadata.block_timestamp, - block_2_metadata.parent_beacon_block_root, - ); - - let mut contract_code = HashMap::new(); - contract_code.insert(hash_bytecode_u256(vec![]), vec![]); - - let inputs = GenerationInputs { - signed_txn: None, - withdrawals: vec![], - global_exit_roots: vec![], - tries: TrieInputs { - state_smt: expected_state_smt_after.serialize(), - transactions_trie: Node::Empty.into(), - receipts_trie: Node::Empty.into(), - }, - trie_roots_after: TrieRoots { - state_root: H256::from_uint(&hashout2u(state_smt_after_block2.root)), - transactions_root: HashedPartialTrie::from(Node::Empty).hash(), - receipts_root: HashedPartialTrie::from(Node::Empty).hash(), - }, - contract_code, - checkpoint_state_trie_root: block_1_state_root, // We use block 1 as new checkpoint. - block_metadata: block_2_metadata, - txn_number_before: 0.into(), - gas_used_before: 0.into(), - gas_used_after: 0.into(), - block_hashes: BlockHashes { - prev_hashes: block_hashes, - cur_hash: block_2_hash, - }, - }; - let mut inputs2 = inputs.clone(); - - let (root_proof, public_values) = - all_circuits.prove_root(&all_stark, &config, inputs, &mut timing, None)?; - all_circuits.verify_root(root_proof.clone())?; - - // We cannot duplicate the proof here because even though there weren't any - // transactions, the state has mutated when updating the beacon roots contract. - - inputs2.tries.state_smt = state_smt_after_block2.serialize(); - - let (root_proof2, public_values2) = - all_circuits.prove_root(&all_stark, &config, inputs2, &mut timing, None)?; - all_circuits.verify_root(root_proof2.clone())?; - - let (agg_proof, updated_agg_public_values) = all_circuits.prove_aggregation( - false, - &root_proof, - public_values.clone(), - false, - &root_proof2, - public_values2, - )?; - all_circuits.verify_aggregation(&agg_proof)?; - - let (second_block_proof, _block_public_values) = all_circuits.prove_block( - None, // We don't specify a previous proof, considering block 1 as the new checkpoint. - &agg_proof, - updated_agg_public_values, - )?; - all_circuits.verify_block(&second_block_proof) -} - /// Values taken from the block 1000000 of Goerli: https://goerli.etherscan.io/txs?block=1000000 #[test] fn test_txn_and_receipt_trie_hash() -> anyhow::Result<()> { diff --git a/evm_arithmetization/tests/self_balance_gas_cost.rs b/evm_arithmetization/tests/self_balance_gas_cost.rs deleted file mode 100644 index f9c5e98c0..000000000 --- a/evm_arithmetization/tests/self_balance_gas_cost.rs +++ /dev/null @@ -1,200 +0,0 @@ -use std::collections::HashMap; -use std::str::FromStr; -use std::time::Duration; - -use ethereum_types::{Address, BigEndianHash, H160, H256, U256}; -use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; -use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; -use evm_arithmetization::proof::{BlockHashes, BlockMetadata, TrieRoots}; -use evm_arithmetization::prover::prove; -use evm_arithmetization::testing_utils::{ - init_logger, preinitialized_state, preinitialized_state_with_updated_storage, set_account, -}; -use evm_arithmetization::verifier::verify_proof; -use evm_arithmetization::{AllStark, Node, StarkConfig}; -use hex_literal::hex; -use mpt_trie::nibbles::Nibbles; -use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; -use plonky2::field::goldilocks_field::GoldilocksField; -use plonky2::plonk::config::KeccakGoldilocksConfig; -use plonky2::util::timing::TimingTree; -use smt_trie::code::hash_bytecode_u256; -use smt_trie::utils::hashout2u; - -type F = GoldilocksField; -const D: usize = 2; -type C = KeccakGoldilocksConfig; - -/// The `selfBalanceGasCost` test case from https://github.com/ethereum/tests -#[test] -#[ignore] // Too slow to run on CI. -fn self_balance_gas_cost() -> anyhow::Result<()> { - init_logger(); - - let all_stark = AllStark::::default(); - let config = StarkConfig::standard_fast_config(); - - let beneficiary = hex!("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"); - let sender = hex!("a94f5374fce5edbc8e2a8697c15331677e6ebf0b"); - let to = hex!("1000000000000000000000000000000000000000"); - - let code = [ - 0x5a, 0x47, 0x5a, 0x90, 0x50, 0x90, 0x03, 0x60, 0x02, 0x90, 0x03, 0x60, 0x01, 0x55, 0x00, - ]; - let code_gas = 2 // GAS - + 5 // SELFBALANCE - + 2 // GAS - + 3 // SWAP1 - + 2 // POP - + 3 // SWAP1 - + 3 // SUB - + 3 // PUSH1 - + 3 // SWAP1 - + 3 // SUB - + 3 // PUSH1 - + 22100; // SSTORE - let code_hash = hash_bytecode_u256(code.to_vec()); - - let beneficiary_account_before = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - let sender_account_before = AccountRlp { - balance: 0x3635c9adc5dea00000u128.into(), - ..AccountRlp::default() - }; - let to_account_before = AccountRlp { - code_hash, - ..AccountRlp::default() - }; - - let mut state_smt_before = preinitialized_state(); - set_account( - &mut state_smt_before, - H160(beneficiary), - &beneficiary_account_before, - &HashMap::new(), - ); - set_account( - &mut state_smt_before, - H160(sender), - &sender_account_before, - &HashMap::new(), - ); - set_account( - &mut state_smt_before, - H160(to), - &to_account_before, - &HashMap::new(), - ); - - let tries_before = TrieInputs { - state_smt: state_smt_before.serialize(), - transactions_trie: Node::Empty.into(), - receipts_trie: Node::Empty.into(), - }; - - let txn = hex!("f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509b"); - - let gas_used = 21_000 + code_gas; - - let block_metadata = BlockMetadata { - block_beneficiary: Address::from(beneficiary), - block_difficulty: 0x20000.into(), - block_number: 1.into(), - block_chain_id: 1.into(), - block_timestamp: 0x03e8.into(), - block_gaslimit: 0xff112233u32.into(), - block_gas_used: gas_used.into(), - block_base_fee: 0xa.into(), - ..Default::default() - }; - - let mut contract_code = HashMap::new(); - contract_code.insert(hash_bytecode_u256(vec![]), vec![]); - contract_code.insert(code_hash, code.to_vec()); - - let expected_state_smt_after = { - let mut smt = preinitialized_state_with_updated_storage(&block_metadata, &[]); - let beneficiary_account_after = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - let sender_account_after = AccountRlp { - balance: sender_account_before.balance - U256::from(gas_used) * U256::from(10), - nonce: 1.into(), - ..AccountRlp::default() - }; - let to_account_after = AccountRlp { - code_hash, - ..AccountRlp::default() - }; - - set_account( - &mut smt, - H160(beneficiary), - &beneficiary_account_after, - &HashMap::new(), - ); - set_account( - &mut smt, - H160(sender), - &sender_account_after, - &HashMap::new(), - ); - set_account( - &mut smt, - H160(to), - &to_account_after, - &HashMap::from([(1.into(), 5.into())]), // Storage map: { 1 => 5 } - ); - - smt - }; - - let receipt_0 = LegacyReceiptRlp { - status: true, - cum_gas_used: gas_used.into(), - bloom: vec![0; 256].into(), - logs: vec![], - }; - let mut receipts_trie = HashedPartialTrie::from(Node::Empty); - receipts_trie.insert( - Nibbles::from_str("0x80").unwrap(), - rlp::encode(&receipt_0).to_vec(), - )?; - let transactions_trie: HashedPartialTrie = Node::Leaf { - nibbles: Nibbles::from_str("0x80").unwrap(), - value: txn.to_vec(), - } - .into(); - - let trie_roots_after = TrieRoots { - state_root: H256::from_uint(&hashout2u(expected_state_smt_after.root)), - transactions_root: transactions_trie.hash(), - receipts_root: receipts_trie.hash(), - }; - let inputs = GenerationInputs { - signed_txn: Some(txn.to_vec()), - withdrawals: vec![], - global_exit_roots: vec![], - tries: tries_before, - trie_roots_after, - contract_code, - checkpoint_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(), - block_metadata, - txn_number_before: 0.into(), - gas_used_before: 0.into(), - gas_used_after: gas_used.into(), - block_hashes: BlockHashes { - prev_hashes: vec![H256::default(); 256], - cur_hash: H256::default(), - }, - }; - - let mut timing = TimingTree::new("prove", log::Level::Debug); - let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; - timing.filter(Duration::from_millis(100)).print(); - - verify_proof(&all_stark, proof, &config) -} diff --git a/evm_arithmetization/tests/two_to_one_block.rs b/evm_arithmetization/tests/two_to_one_block.rs new file mode 100644 index 000000000..8ff790006 --- /dev/null +++ b/evm_arithmetization/tests/two_to_one_block.rs @@ -0,0 +1,268 @@ +use std::collections::HashMap; + +use ethereum_types::{Address, BigEndianHash, H256}; +use evm_arithmetization::fixed_recursive_verifier::{ + extract_block_public_values, extract_two_to_one_block_hash, +}; +use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; +use evm_arithmetization::proof::{BlockMetadata, PublicValues, TrieRoots}; +use evm_arithmetization::testing_utils::{ + init_logger, preinitialized_state, preinitialized_state_with_updated_storage, +}; +use evm_arithmetization::{AllRecursiveCircuits, AllStark, Node, StarkConfig}; +use hex_literal::hex; +use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; +use plonky2::field::goldilocks_field::GoldilocksField; +use plonky2::hash::poseidon::PoseidonHash; +use plonky2::plonk::config::{Hasher, PoseidonGoldilocksConfig}; +use plonky2::plonk::proof::ProofWithPublicInputs; +use plonky2::util::timing::TimingTree; +use smt_trie::db::MemoryDb; +use smt_trie::smt::Smt; +use smt_trie::utils::hashout2u; + +type F = GoldilocksField; +const D: usize = 2; +type C = PoseidonGoldilocksConfig; + +/// Get `GenerationInputs` for an empty block with the given timestamp. +fn empty_transfer(timestamp: u64) -> anyhow::Result<(GenerationInputs, Smt)> { + init_logger(); + + let beneficiary = hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + + let state_smt_before = preinitialized_state(); + let checkpoint_state_trie_root = H256::from_uint(&hashout2u(state_smt_before.root)); + + let tries_before = TrieInputs { + state_smt: state_smt_before.serialize(), + transactions_trie: HashedPartialTrie::from(Node::Empty), + receipts_trie: HashedPartialTrie::from(Node::Empty), + }; + + let block_metadata = BlockMetadata { + block_beneficiary: Address::from(beneficiary), + block_timestamp: timestamp.into(), + block_number: 1.into(), + block_difficulty: 0x020000.into(), + block_random: H256::from_uint(&0x020000.into()), + block_gaslimit: 0xff112233u32.into(), + block_chain_id: 1.into(), + block_base_fee: 0xa.into(), + ..Default::default() + }; + + let contract_code = HashMap::new(); + + let expected_smt_after = preinitialized_state_with_updated_storage(&block_metadata, &[]); + + let trie_roots_after = TrieRoots { + state_root: H256::from_uint(&hashout2u(expected_smt_after.root)), + transactions_root: HashedPartialTrie::from(Node::Empty).hash(), + receipts_root: HashedPartialTrie::from(Node::Empty).hash(), + }; + + let inputs = GenerationInputs { + tries: tries_before, + trie_roots_after, + contract_code, + checkpoint_state_trie_root, + block_metadata, + ..Default::default() + }; + + Ok((inputs, expected_smt_after)) +} + +fn get_test_block_proof( + timestamp: u64, + all_circuits: &AllRecursiveCircuits, + all_stark: &AllStark, + config: &StarkConfig, +) -> anyhow::Result> { + let (inputs0, state_smt) = empty_transfer(timestamp)?; + let inputs = inputs0.clone(); + let dummy0 = GenerationInputs { + txn_number_before: inputs.txn_number_before, + gas_used_before: inputs.gas_used_after, + gas_used_after: inputs.gas_used_after, + signed_txn: None, + global_exit_roots: vec![], + withdrawals: vec![], + tries: TrieInputs { + state_smt: state_smt.serialize(), + transactions_trie: HashedPartialTrie::from(Node::Hash( + inputs.trie_roots_after.transactions_root, + )), + receipts_trie: HashedPartialTrie::from(Node::Hash( + inputs.trie_roots_after.receipts_root, + )), + }, + trie_roots_after: inputs.trie_roots_after, + checkpoint_state_trie_root: inputs.checkpoint_state_trie_root, + contract_code: Default::default(), + block_metadata: inputs.block_metadata.clone(), + block_hashes: inputs.block_hashes.clone(), + }; + + let timing = &mut TimingTree::new(&format!("Blockproof {timestamp}"), log::Level::Info); + let (root_proof0, pv0) = all_circuits.prove_root(all_stark, config, inputs0, timing, None)?; + all_circuits.verify_root(root_proof0.clone())?; + let (dummy_proof0, dummy_pv0) = + all_circuits.prove_root(all_stark, config, dummy0, timing, None)?; + all_circuits.verify_root(dummy_proof0.clone())?; + + let (agg_proof0, pv0) = all_circuits.prove_aggregation( + false, + &root_proof0, + pv0, + false, + &dummy_proof0, + dummy_pv0, + )?; + + all_circuits.verify_aggregation(&agg_proof0)?; + + // Test retrieved public values from the proof public inputs. + let retrieved_public_values0 = PublicValues::from_public_inputs(&agg_proof0.public_inputs); + assert_eq!(retrieved_public_values0, pv0); + assert_eq!( + pv0.trie_roots_before.state_root, + pv0.extra_block_data.checkpoint_state_trie_root + ); + + let (block_proof0, block_public_values) = all_circuits.prove_block( + None, // We don't specify a previous proof, considering block 1 as the new checkpoint. + &agg_proof0, + pv0.clone(), + )?; + + let pv_block = PublicValues::from_public_inputs(&block_proof0.public_inputs); + assert_eq!(block_public_values, pv_block); + + Ok(block_proof0) +} + +#[ignore] +#[test] +fn test_two_to_one_block_aggregation() -> anyhow::Result<()> { + init_logger(); + let some_timestamps = [127, 42, 65, 43]; + + let all_stark = AllStark::::default(); + let config = StarkConfig::standard_fast_config(); + let all_circuits = AllRecursiveCircuits::::new( + &all_stark, + &[16..17, 8..9, 13..14, 14..15, 10..11, 12..13, 17..18, 6..7], + &config, + ); + + let unrelated_block_proofs = some_timestamps + .iter() + .map(|&ts| get_test_block_proof(ts, &all_circuits, &all_stark, &config)) + .collect::>>>()?; + + unrelated_block_proofs + .iter() + .try_for_each(|bp| all_circuits.verify_block(bp))?; + + let bp = unrelated_block_proofs; + + { + // Aggregate the same proof twice + let aggproof_42_42 = all_circuits.prove_two_to_one_block(&bp[0], false, &bp[0], false)?; + all_circuits.verify_two_to_one_block(&aggproof_42_42)?; + } + + { + // Binary tree reduction + // + // A B C D Blockproofs (base case) + // \ / \ / + // (A, B) (C, D) Two-to-one block aggregation proofs + // \ / + // ((A,B), (C,D)) Two-to-one block aggregation proofs + + let aggproof01 = all_circuits.prove_two_to_one_block(&bp[0], false, &bp[1], false)?; + all_circuits.verify_two_to_one_block(&aggproof01)?; + + let aggproof23 = all_circuits.prove_two_to_one_block(&bp[2], false, &bp[3], false)?; + all_circuits.verify_two_to_one_block(&aggproof23)?; + + let aggproof0123 = + all_circuits.prove_two_to_one_block(&aggproof01, true, &aggproof23, true)?; + all_circuits.verify_two_to_one_block(&aggproof0123)?; + + { + // Compute Merkle root from public inputs of block proofs. + // Leaves + let mut hashes: Vec<_> = bp + .iter() + .map(|block_proof| { + let public_values = extract_block_public_values(&block_proof.public_inputs); + PoseidonHash::hash_no_pad(public_values) + }) + .collect(); + + // Inner nodes + hashes.extend_from_within(0..hashes.len()); + let half = hashes.len() / 2; + for i in 0..half - 1 { + hashes[half + i] = PoseidonHash::two_to_one(hashes[2 * i], hashes[2 * i + 1]); + } + let merkle_root = hashes[hashes.len() - 2].elements; + + assert_eq!( + extract_two_to_one_block_hash(&aggproof0123.public_inputs), + &merkle_root, + "Merkle root of verifier's verification tree did not match merkle root in public inputs." + ); + } + } + + { + // Foldleft + // + // A B C D Blockproofs (base case) + // \ / / / + // (A, B) / / Two-to-one block aggregation proofs + // \ / / + // ((A,B), C) / Two-to-one block aggregation proofs + // \ / + // (((A,B),C),D) Two-to-one block aggregation proofs + + let aggproof01 = all_circuits.prove_two_to_one_block(&bp[0], false, &bp[1], false)?; + all_circuits.verify_two_to_one_block(&aggproof01)?; + + let aggproof012 = all_circuits.prove_two_to_one_block(&aggproof01, true, &bp[2], false)?; + all_circuits.verify_two_to_one_block(&aggproof012)?; + + let aggproof0123 = + all_circuits.prove_two_to_one_block(&aggproof012, true, &bp[3], false)?; + all_circuits.verify_two_to_one_block(&aggproof0123)?; + } + + { + // Foldright + // + // A B C D Blockproofs (base case) + // \ \ \ / + // \ \ (C,D) Two-to-one block aggregation proofs + // \ \ / + // \ (B,(C, D)) Two-to-one block aggregation proofs + // \ / + // (A,(B,(C,D))) Two-to-one block aggregation proofs + + let aggproof23 = all_circuits.prove_two_to_one_block(&bp[2], false, &bp[3], false)?; + all_circuits.verify_two_to_one_block(&aggproof23)?; + + let aggproof123 = all_circuits.prove_two_to_one_block(&bp[1], false, &aggproof23, true)?; + all_circuits.verify_two_to_one_block(&aggproof123)?; + + let aggproof0123 = + all_circuits.prove_two_to_one_block(&bp[0], false, &aggproof123, true)?; + all_circuits.verify_two_to_one_block(&aggproof0123)?; + } + + Ok(()) +} diff --git a/mpt_trie/Cargo.toml b/mpt_trie/Cargo.toml index 46a14df26..0d64fafa6 100644 --- a/mpt_trie/Cargo.toml +++ b/mpt_trie/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "mpt_trie" description = "Types and utility functions for building/working with partial Ethereum tries." -version = "0.3.0" +version = "0.4.1" authors = ["Polygon Zero "] readme = "README.md" edition.workspace = true @@ -9,9 +9,7 @@ license.workspace = true repository.workspace = true homepage.workspace = true -exclude = [ - "test_data/*" -] +exclude = ["test_data/*"] [dependencies] bytes = { workspace = true } diff --git a/mpt_trie/src/builder.rs b/mpt_trie/src/builder.rs index 1e0e06bd3..48475f4d2 100644 --- a/mpt_trie/src/builder.rs +++ b/mpt_trie/src/builder.rs @@ -28,7 +28,7 @@ pub struct PartialTrieBuilder { impl PartialTrieBuilder { /// Creates a new `PartialTrieBuilder` with the given root and nodes. - pub fn new(root: H256, nodes: HashMap>) -> Self { + pub const fn new(root: H256, nodes: HashMap>) -> Self { PartialTrieBuilder { root, nodes, diff --git a/mpt_trie/src/nibbles.rs b/mpt_trie/src/nibbles.rs index a417dca4e..1079aa6d2 100644 --- a/mpt_trie/src/nibbles.rs +++ b/mpt_trie/src/nibbles.rs @@ -912,7 +912,7 @@ impl Nibbles { /// Returns a slice of the internal bytes of packed nibbles. /// Only the relevant bytes (up to `count` nibbles) are considered valid. - pub fn as_byte_slice(&self) -> &[u8] { + pub const fn as_byte_slice(&self) -> &[u8] { // Calculate the number of full bytes needed to cover 'count' nibbles let bytes_needed = (self.count + 1) / 2; // each nibble is half a byte diff --git a/proc_macro/Cargo.toml b/proc_macro/Cargo.toml index d2deca37f..c3ee894e4 100644 --- a/proc_macro/Cargo.toml +++ b/proc_macro/Cargo.toml @@ -1,10 +1,13 @@ [package] name = "zk_evm_proc_macro" +description = "Procedural Macros for Polygon Zero zkEVM" +authors = ["Polygon Zero"] version = "0.1.0" -publish = false edition.workspace = true license.workspace = true repository.workspace = true +homepage.workspace = true +keywords.workspace = true [lib] proc-macro = true diff --git a/proof_gen/Cargo.toml b/proof_gen/Cargo.toml index 67987fec6..fc380fba1 100644 --- a/proof_gen/Cargo.toml +++ b/proof_gen/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "proof_gen" description = "Generates block proofs from zero proof IR." -version = "0.2.0" +version = "0.4.0" authors = ["Polygon Zero "] edition.workspace = true license.workspace = true diff --git a/proof_gen/src/proof_gen.rs b/proof_gen/src/proof_gen.rs index 2546106cc..2b1dbda1f 100644 --- a/proof_gen/src/proof_gen.rs +++ b/proof_gen/src/proof_gen.rs @@ -14,7 +14,10 @@ use plonky2::{ // TODO: bring back import from trace_decoder once SMT logic is implemented // use trace_decoder::types::TxnProofGenIR; use crate::{ - proof_types::{AggregatableProof, GeneratedAggProof, GeneratedBlockProof, GeneratedTxnProof}, + proof_types::{ + AggregatableBlockProof, AggregatableProof, GeneratedAggBlockProof, GeneratedAggProof, + GeneratedBlockProof, GeneratedTxnProof, + }, prover_state::ProverState, types::{Config, Field, PlonkyProofIntern, EXTENSION_DEGREE}, }; @@ -116,6 +119,27 @@ pub fn generate_block_proof( }) } +/// Generates an aggregation block proof from two child proofs. +/// +/// Note that the child proofs may be either block or aggregation proofs. +pub fn generate_agg_block_proof( + p_state: &ProverState, + lhs_child: &AggregatableBlockProof, + rhs_child: &AggregatableBlockProof, +) -> ProofGenResult { + let intern = p_state + .state + .prove_two_to_one_block( + lhs_child.intern(), + lhs_child.is_agg(), + rhs_child.intern(), + rhs_child.is_agg(), + ) + .map_err(|err| err.to_string())?; + + Ok(GeneratedAggBlockProof { intern }) +} + /// Generates a dummy proof for a dummy circuit doing nothing. /// This is useful for testing purposes only. pub fn dummy_proof() -> ProofGenResult { diff --git a/proof_gen/src/proof_types.rs b/proof_gen/src/proof_types.rs index f707030df..037daa1c1 100644 --- a/proof_gen/src/proof_types.rs +++ b/proof_gen/src/proof_types.rs @@ -1,11 +1,15 @@ //! This module defines the various proof types used throughout the block proof //! generation process. -use evm_arithmetization::proof::PublicValues; +use evm_arithmetization::{ + fixed_recursive_verifier::{extract_block_public_values, extract_two_to_one_block_hash}, + proof::PublicValues, + BlockHeight, +}; +use plonky2::plonk::config::Hasher as _; use serde::{Deserialize, Serialize}; -// use trace_decoder::types::BlockHeight; -use crate::types::PlonkyProofIntern; +use crate::types::{Hash, Hasher, PlonkyProofIntern}; /// A transaction proof along with its public values, for proper connection with /// contiguous proofs. @@ -35,7 +39,18 @@ pub struct GeneratedAggProof { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct GeneratedBlockProof { /// Associated block height. - pub b_height: u64, // TODO: replace by BlockHeight once trace_decoder is updated + pub b_height: BlockHeight, + /// Underlying plonky2 proof. + pub intern: PlonkyProofIntern, +} + +/// An aggregation block proof along with its hashed public values, for proper +/// connection with other proofs. +/// +/// Aggregation block proofs can represent any aggregation of independent +/// blocks. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct GeneratedAggBlockProof { /// Underlying plonky2 proof. pub intern: PlonkyProofIntern, } @@ -85,3 +100,52 @@ impl From for AggregatableProof { Self::Agg(v) } } + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum AggregatableBlockProof { + /// The underlying proof is a single block proof. + Block(GeneratedBlockProof), + /// The underlying proof is an aggregated proof. + Agg(GeneratedAggBlockProof), +} + +impl AggregatableBlockProof { + pub fn pv_hash(&self) -> Hash { + match self { + AggregatableBlockProof::Block(info) => { + let pv = extract_block_public_values(&info.intern.public_inputs); + Hasher::hash_no_pad(pv) + } + AggregatableBlockProof::Agg(info) => { + let hash = extract_two_to_one_block_hash(&info.intern.public_inputs); + Hash::from_partial(hash) + } + } + } + + pub(crate) const fn is_agg(&self) -> bool { + match self { + AggregatableBlockProof::Block(_) => false, + AggregatableBlockProof::Agg(_) => true, + } + } + + pub(crate) const fn intern(&self) -> &PlonkyProofIntern { + match self { + AggregatableBlockProof::Block(info) => &info.intern, + AggregatableBlockProof::Agg(info) => &info.intern, + } + } +} + +impl From for AggregatableBlockProof { + fn from(v: GeneratedBlockProof) -> Self { + Self::Block(v) + } +} + +impl From for AggregatableBlockProof { + fn from(v: GeneratedAggBlockProof) -> Self { + Self::Agg(v) + } +} diff --git a/proof_gen/src/types.rs b/proof_gen/src/types.rs index e3238e00b..bf1b4185c 100644 --- a/proof_gen/src/types.rs +++ b/proof_gen/src/types.rs @@ -3,7 +3,8 @@ use plonky2::{ field::goldilocks_field::GoldilocksField, - plonk::{config::PoseidonGoldilocksConfig, proof::ProofWithPublicInputs}, + hash::poseidon::PoseidonHash, + plonk::{self, config::PoseidonGoldilocksConfig, proof::ProofWithPublicInputs}, }; /// The base field on which statements are being proven. @@ -17,6 +18,10 @@ pub const EXTENSION_DEGREE: usize = 2; /// A type alias for proofs generated by the zkEVM. pub type PlonkyProofIntern = ProofWithPublicInputs; +pub type Hasher = PoseidonHash; + +pub type Hash = >::Hash; + /// A type alias for the set of preprocessed circuits necessary to generate /// succinct block proofs. pub type AllRecursiveCircuits = evm_arithmetization::fixed_recursive_verifier::AllRecursiveCircuits< diff --git a/smt_trie/Cargo.toml b/smt_trie/Cargo.toml index f3008c5f7..d87658c3d 100644 --- a/smt_trie/Cargo.toml +++ b/smt_trie/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "smt_trie" description = "Types and utility functions for building/working with Polygon Hermez Sparse Merkle Trees." -version = "0.1.0" +version = "0.1.1" authors = ["William Borgeaud "] readme = "README.md" categories = ["cryptography"] diff --git a/smt_trie/src/bits.rs b/smt_trie/src/bits.rs index 4d2d2ed91..0fbcac0e1 100644 --- a/smt_trie/src/bits.rs +++ b/smt_trie/src/bits.rs @@ -44,14 +44,14 @@ impl Add for Bits { } impl Bits { - pub fn empty() -> Self { + pub const fn empty() -> Self { Bits { count: 0, packed: U256::zero(), } } - pub fn is_empty(&self) -> bool { + pub const fn is_empty(&self) -> bool { self.count == 0 } diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 703230b25..cc63ad44c 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -2,7 +2,7 @@ name = "trace_decoder" description = "Ethereum node witness -> Prover input" authors = ["Polygon Zero"] -version = "0.4.0" +version = "0.6.0" edition.workspace = true license.workspace = true repository.workspace = true @@ -35,8 +35,8 @@ winnow = { workspace = true } # Local dependencies smt_trie = { workspace = true } # TODO: update decoder to take local versions again -mpt_trie = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } -evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } +mpt_trie = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } +evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } [dev-dependencies] criterion = { workspace = true } diff --git a/trace_decoder/src/decoding.rs b/trace_decoder/src/decoding.rs index 29b439dc1..98a0d8857 100644 --- a/trace_decoder/src/decoding.rs +++ b/trace_decoder/src/decoding.rs @@ -89,7 +89,7 @@ impl std::error::Error for TraceParsingError {} impl TraceParsingError { /// Function to create a new TraceParsingError with mandatory fields - fn new(reason: TraceParsingErrorReason) -> Self { + const fn new(reason: TraceParsingErrorReason) -> Self { Self { block_num: None, block_chain_id: None, diff --git a/zero_bin/README.md b/zero_bin/README.md index aecba5dee..8f2ef3dfa 100644 --- a/zero_bin/README.md +++ b/zero_bin/README.md @@ -1,6 +1,8 @@ # Zero Bin -A composition of [`paladin`](https://github.com/0xPolygonZero/paladin) and [`plonky-block-proof-gen`](https://github.com/0xPolygonZero/plonky-block-proof-gen). Given the [proof generation protocol](/prover/src/lib.rs) as input, generate a proof. The project is instrumented with [`paladin`](https://github.com/0xPolygonZero/paladin), and as such can distribute proof generation across multiple worker machines. +A composition of [`paladin`](https://github.com/0xPolygonZero/paladin) and [`proof_gen`](../proof_gen/README.md). +Given the [proof generation protocol](./prover/src/lib.rs) as input, generate a proof. +The project is instrumented with [`paladin`](https://github.com/0xPolygonZero/paladin), and as such can distribute proof generation across multiple worker machines. - [Zero Bin](#zero-bin) - [Project layout](#project-layout) @@ -433,6 +435,7 @@ A few other notes: - Proving blocks is very resource intensive in terms of both CPU and memory. You can also only generate the witness for a block instead (see [Generating Witnesses Only](#generating-witnesses-only)) to significantly reduce the CPU and memory requirements. - Because incorporating the previous block proof requires a chain of proofs back to the last checkpoint height, you can also disable this requirement by passing `true` for `` (which internally just sets the current checkpoint height to the previous block height). +- When proving multiple blocks concurrently, one may need to increase the system resource usage limit because of the number of RPC connections opened simultaneously, in particular when running a native tracer. For Linux systems, it is recommended to set `ulimit` to 8192. ### Generating Witnesses Only diff --git a/zero_bin/common/Cargo.toml b/zero_bin/common/Cargo.toml index ee1c6702d..01e32b96f 100644 --- a/zero_bin/common/Cargo.toml +++ b/zero_bin/common/Cargo.toml @@ -23,5 +23,5 @@ async-stream = { workspace = true } # Local dependencies # TODO: update deps to take local versions again -proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } -evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } \ No newline at end of file +proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } +evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } \ No newline at end of file diff --git a/zero_bin/common/src/prover_state/circuit.rs b/zero_bin/common/src/prover_state/circuit.rs index 5eaf2da7a..f23d6ebe9 100644 --- a/zero_bin/common/src/prover_state/circuit.rs +++ b/zero_bin/common/src/prover_state/circuit.rs @@ -200,7 +200,7 @@ impl CircuitConfig { } /// Get all circuits specified in the config. - pub fn as_degree_bits_ranges(&self) -> &[Range; NUM_TABLES] { + pub const fn as_degree_bits_ranges(&self) -> &[Range; NUM_TABLES] { &self.circuits } diff --git a/zero_bin/common/src/prover_state/cli.rs b/zero_bin/common/src/prover_state/cli.rs index 5a78a1863..5355d7f4e 100644 --- a/zero_bin/common/src/prover_state/cli.rs +++ b/zero_bin/common/src/prover_state/cli.rs @@ -33,7 +33,10 @@ pub enum CircuitPersistence { } impl CircuitPersistence { - pub fn with_load_strategy(self, load_strategy: TableLoadStrategy) -> super::CircuitPersistence { + pub const fn with_load_strategy( + self, + load_strategy: TableLoadStrategy, + ) -> super::CircuitPersistence { match self { CircuitPersistence::None => super::CircuitPersistence::None, CircuitPersistence::Disk => super::CircuitPersistence::Disk(load_strategy), diff --git a/zero_bin/common/src/prover_state/mod.rs b/zero_bin/common/src/prover_state/mod.rs index 44463b53d..aacd7c12e 100644 --- a/zero_bin/common/src/prover_state/mod.rs +++ b/zero_bin/common/src/prover_state/mod.rs @@ -125,7 +125,7 @@ pub struct ProverStateManager { } impl ProverStateManager { - pub fn with_load_strategy(self, load_strategy: TableLoadStrategy) -> Self { + pub const fn with_load_strategy(self, load_strategy: TableLoadStrategy) -> Self { match self.persistence { CircuitPersistence::None => self, CircuitPersistence::Disk(_) => Self { diff --git a/zero_bin/leader/Cargo.toml b/zero_bin/leader/Cargo.toml index ab29fba74..3c442ccca 100644 --- a/zero_bin/leader/Cargo.toml +++ b/zero_bin/leader/Cargo.toml @@ -30,7 +30,7 @@ prover = { workspace = true } rpc = { workspace = true } zero_bin_common ={ workspace = true } # TODO: update deps to take local versions again -proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } +proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } [features] default = [] diff --git a/zero_bin/ops/Cargo.toml b/zero_bin/ops/Cargo.toml index 66f2da1f7..85a253609 100644 --- a/zero_bin/ops/Cargo.toml +++ b/zero_bin/ops/Cargo.toml @@ -16,8 +16,8 @@ keccak-hash = { workspace = true } # Local dependencies # TODO: update deps to take local versions again -proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } -evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } +proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } +evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } zero_bin_common = { workspace = true } [features] diff --git a/zero_bin/prover/Cargo.toml b/zero_bin/prover/Cargo.toml index 745cc94e2..ba216daab 100644 --- a/zero_bin/prover/Cargo.toml +++ b/zero_bin/prover/Cargo.toml @@ -15,16 +15,16 @@ paladin-core = { workspace = true } anyhow = { workspace = true } futures = { workspace = true } alloy.workspace = true -tokio = {workspace = true} -serde_json = {workspace = true} +tokio = { workspace = true } +serde_json = { workspace = true } ruint = { workspace = true, features = ["num-traits", "primitive-types"] } ops = { workspace = true } num-traits = { workspace = true } # Local dependencies # TODO: update deps to take local versions again -proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } -trace_decoder = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } +proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } +trace_decoder = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } zero_bin_common ={ workspace = true } [features] diff --git a/zero_bin/rpc/Cargo.toml b/zero_bin/rpc/Cargo.toml index b2bc00875..fe6970d96 100644 --- a/zero_bin/rpc/Cargo.toml +++ b/zero_bin/rpc/Cargo.toml @@ -28,6 +28,6 @@ compat = { workspace = true } zero_bin_common = { workspace = true } prover = { workspace = true } # TODO: update deps to take local versions again -mpt_trie = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } -evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } -trace_decoder = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } +mpt_trie = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } +evm_arithmetization = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } +trace_decoder = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } diff --git a/zero_bin/rpc/src/native/txn.rs b/zero_bin/rpc/src/native/txn.rs index 61bcf5f4a..94d280968 100644 --- a/zero_bin/rpc/src/native/txn.rs +++ b/zero_bin/rpc/src/native/txn.rs @@ -278,7 +278,7 @@ async fn process_code( } /// Processes the self destruct for the given account state. -fn process_self_destruct( +const fn process_self_destruct( post_state: Option<&AccountState>, pre_state: Option<&AccountState>, ) -> Option { diff --git a/zero_bin/rpc/src/provider.rs b/zero_bin/rpc/src/provider.rs index fc782ff43..f0c6a2691 100644 --- a/zero_bin/rpc/src/provider.rs +++ b/zero_bin/rpc/src/provider.rs @@ -39,7 +39,7 @@ where &mut self.provider } - pub fn as_provider(&self) -> &ProviderT { + pub const fn as_provider(&self) -> &ProviderT { &self.provider } diff --git a/zero_bin/rpc/src/retry.rs b/zero_bin/rpc/src/retry.rs index 0c6db2291..2fe81cb60 100644 --- a/zero_bin/rpc/src/retry.rs +++ b/zero_bin/rpc/src/retry.rs @@ -32,7 +32,7 @@ impl Clone for RetryPolicy { } impl RetryPolicy { - pub fn new(backoff: tokio::time::Duration, max_retries: u32) -> Self { + pub const fn new(backoff: tokio::time::Duration, max_retries: u32) -> Self { Self { backoff, retries: 0, diff --git a/zero_bin/verifier/Cargo.toml b/zero_bin/verifier/Cargo.toml index 891d51e5c..b9f15ae4a 100644 --- a/zero_bin/verifier/Cargo.toml +++ b/zero_bin/verifier/Cargo.toml @@ -14,6 +14,6 @@ serde_json = { workspace = true } serde_path_to_error = { workspace = true } # Local dependencies -zero_bin_common ={ path = "../common" } # TODO: update deps to take local versions again -proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "feat/cancun" } +proof_gen = { git = "https://github.com/0xPolygonZero/zk_evm", branch = "develop" } +zero_bin_common ={ path = "../common" }