diff --git a/Cargo.lock b/Cargo.lock index 1430cbc430..473f84dde1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5530,7 +5530,7 @@ dependencies = [ [[package]] name = "zktrie" version = "0.3.0" -source = "git+https://github.com/scroll-tech/zktrie.git?branch=v0.9#460b8c22af65b7809164548cba1e0253b6db5a70" +source = "git+https://github.com/scroll-tech/zktrie.git?branch=feat/soft_prove#959b84aa33de7c7fbc53f9d8bea2dd8513fccb78" dependencies = [ "gobuild", "zktrie_rust", @@ -5539,7 +5539,7 @@ dependencies = [ [[package]] name = "zktrie_rust" version = "0.3.0" -source = "git+https://github.com/scroll-tech/zktrie.git?branch=v0.9#460b8c22af65b7809164548cba1e0253b6db5a70" +source = "git+https://github.com/scroll-tech/zktrie.git?branch=feat/soft_prove#959b84aa33de7c7fbc53f9d8bea2dd8513fccb78" dependencies = [ "hex", "lazy_static", diff --git a/prover/src/zkevm/capacity_checker.rs b/prover/src/zkevm/capacity_checker.rs index 4536f1b7f9..9c68f6c40f 100644 --- a/prover/src/zkevm/capacity_checker.rs +++ b/prover/src/zkevm/capacity_checker.rs @@ -181,7 +181,7 @@ impl CircuitCapacityChecker { None, ) }; - let witness_block = finalize_builder(&mut estimate_builder)?; + let witness_block = finalize_builder(&mut estimate_builder, true)?; let mut rows = calculate_row_usage_of_witness_block(&witness_block)?; let mut code_db = codedb_prev.unwrap_or_else(CodeDB::new); diff --git a/prover/src/zkevm/circuit/builder.rs b/prover/src/zkevm/circuit/builder.rs index 69add86a83..4ec5572eb1 100644 --- a/prover/src/zkevm/circuit/builder.rs +++ b/prover/src/zkevm/circuit/builder.rs @@ -146,14 +146,14 @@ pub fn block_traces_to_witness_block(block_traces: Vec) -> Result Result { +pub fn finalize_builder(builder: &mut CircuitInputBuilder, ccc_mode: bool) -> Result { builder.finalize_building()?; log::debug!("converting builder.block to witness block"); @@ -163,6 +163,8 @@ pub fn finalize_builder(builder: &mut CircuitInputBuilder) -> Result { "witness_block built with circuits_params {:?}", witness_block.circuits_params ); + println!("finalize builder {}", ccc_mode); + witness_block.mpt_updates.ccc_mode = ccc_mode; if let Some(state) = &mut builder.mpt_init_state { if *state.root() != [0u8; 32] { diff --git a/zkevm-circuits/src/witness/mpt.rs b/zkevm-circuits/src/witness/mpt.rs index 0f242e7444..137568efdd 100644 --- a/zkevm-circuits/src/witness/mpt.rs +++ b/zkevm-circuits/src/witness/mpt.rs @@ -104,6 +104,8 @@ pub struct MptUpdates { /// The detailed mpt witness pub smt_traces: Vec, pub(crate) proof_types: Vec, + /// set update used in ccc mode + pub ccc_mode: bool, } /// The field element encoding of an MPT update, which is used by the MptTable @@ -176,9 +178,10 @@ impl MptUpdates { pub(crate) fn fill_state_roots(&mut self, init_trie: &ZktrieState) -> WitnessGenerator { let root_pair = (self.old_root, self.new_root); self.old_root = init_trie.root().into(); - log::trace!("fill_state_roots init {:?}", self.old_root); + log::trace!("fill_state_roots init {:?}, ccc_mode {}", self.old_root, self.ccc_mode); let wit_gen = WitnessGenerator::from(init_trie); + let wit_gen = if self.ccc_mode {wit_gen.set_ccc_mode()} else {wit_gen}; let wit_gen = self.fill_state_roots_from_generator(wit_gen); let root_pair2 = (self.old_root, self.new_root); @@ -206,7 +209,8 @@ impl MptUpdates { } let gen_withdraw_proof = false; - if gen_withdraw_proof { + // in ccc mode some full proof is not avaliable + if !self.ccc_mode && gen_withdraw_proof { // generate withdraw proof let address = *bus_mapping::l2_predeployed::message_queue::ADDRESS; let key = bus_mapping::l2_predeployed::message_queue::WITHDRAW_TRIE_ROOT_SLOT; diff --git a/zkevm-circuits/src/witness/mpt/witness.rs b/zkevm-circuits/src/witness/mpt/witness.rs index 7054997c6e..ea53caa9c4 100644 --- a/zkevm-circuits/src/witness/mpt/witness.rs +++ b/zkevm-circuits/src/witness/mpt/witness.rs @@ -41,6 +41,7 @@ pub struct WitnessGenerator { trie: ZkTrie, storages_cache: HashMap, ref_db: Rc, + ccc_mode: bool, } impl From<&ZktrieState> for WitnessGenerator { @@ -49,11 +50,20 @@ impl From<&ZktrieState> for WitnessGenerator { trie: state.zk_db.new_trie(&state.trie_root).unwrap(), storages_cache: HashMap::new(), ref_db: state.zk_db.clone(), + ccc_mode: false, } } } impl WitnessGenerator { + + /// set to ccc mode, would built SMTTrace without terminal node, + /// but do not require deletion proof + pub fn set_ccc_mode(mut self) -> Self { + self.ccc_mode = true; + self + } + /// output all updated ZkTrie pub fn into_updated_trie(self) -> impl Iterator { std::iter::once(self.trie).chain(self.storages_cache.into_values()) @@ -71,7 +81,7 @@ impl WitnessGenerator { } /// get account proof pub fn account_proof(&self, address: Address) -> Vec> { - self.trie.prove(address.as_bytes()).unwrap() + self.trie.prove(address.as_bytes(), false).unwrap() } /// get storage proof pub fn storage_proof(&self, address: Address, key: Word) -> Vec> { @@ -83,14 +93,14 @@ impl WitnessGenerator { if let Some(trie) = self.storages_cache.get(&address) { // trie is under updating - trie.prove(key.as_ref()).ok() + trie.prove(key.as_ref(), false).ok() } else { // create a temporary trie and prove it self.trie .get_account(address.as_bytes()) .map(AccountData::from) .and_then(|account| self.ref_db.new_trie(&account.storage_root.0)) - .and_then(|trie| trie.prove(key.as_ref()).ok()) + .and_then(|trie| trie.prove(key.as_ref(), false).ok()) } .unwrap_or_default() } @@ -118,6 +128,7 @@ impl WitnessGenerator { new_value: Word, old_value: Word, ) -> SMTTrace { + let ccc_mode = self.ccc_mode; let (storage_key, key) = { let mut word_buf = [0u8; 32]; key.to_big_endian(word_buf.as_mut_slice()); @@ -145,7 +156,7 @@ impl WitnessGenerator { value: HexBytes(word_buf), } }; - let storage_before_proofs = trie.prove(key.as_ref()).unwrap(); + let storage_before_proofs = trie.prove(key.as_ref(), false).unwrap(); let storage_before = decode_proof_for_mpt_path(storage_key, storage_before_proofs); let store_before = { @@ -178,17 +189,20 @@ impl WitnessGenerator { } // notice if the value is both zero we never touch the trie layer let storage_root_after = H256(trie.root()); - let storage_after_proofs = trie.prove(key.as_ref()).unwrap(); + let storage_after_proofs = trie.prove(key.as_ref(), ccc_mode).unwrap(); let storage_after = decode_proof_for_mpt_path(storage_key, storage_after_proofs); // sanity check - assert_eq!( - smt_hash_from_bytes(storage_root_after.as_bytes()), - storage_after - .as_ref() - .map(|(p, _)| p.root) - .unwrap_or(HexBytes([0; 32])) - ); + if !ccc_mode { + assert_eq!( + smt_hash_from_bytes(storage_root_after.as_bytes()), + storage_after + .as_ref() + .map(|(p, _)| p.root) + .unwrap_or(HexBytes([0; 32])) + ); + } + let mut out = self.trace_account_update(address, |acc| { if let Some(acc) = acc { @@ -225,7 +239,7 @@ impl WitnessGenerator { where U: FnOnce(Option<&AccountData>) -> Option, { - let proofs = match self.trie.prove(address.as_bytes()) { + let proofs = match self.trie.prove(address.as_bytes(), false) { Ok(proofs) => proofs, Err(e) => { panic!("cannot prove, addr {address:?}, err{e:?}"); @@ -281,7 +295,7 @@ impl WitnessGenerator { // self.accounts_cache.remove(&address); } // no touch for non-exist proof - let proofs = self.trie.prove(address.as_bytes()).unwrap(); + let proofs = self.trie.prove(address.as_bytes(), self.ccc_mode).unwrap(); let (account_path_after, _) = decode_proof_for_mpt_path(address_key, proofs).unwrap(); SMTTrace { diff --git a/zktrie/Cargo.toml b/zktrie/Cargo.toml index 33cc999f4c..129a154c08 100644 --- a/zktrie/Cargo.toml +++ b/zktrie/Cargo.toml @@ -8,7 +8,7 @@ license.workspace = true [dependencies] halo2curves.workspace = true -zktrie = { git = "https://github.com/scroll-tech/zktrie.git", branch = "v0.9", features= ["rs_zktrie"] } +zktrie = { git = "https://github.com/scroll-tech/zktrie.git", branch = "feat/soft_prove", features= ["rs_zktrie"] } poseidon-base.workspace = true eth-types = { path = "../eth-types" } num-bigint.workspace = true