From 4219feb6778a8e7266a42fac34b43eddd42af30e Mon Sep 17 00:00:00 2001 From: noelwei Date: Wed, 11 Sep 2024 00:29:43 +0900 Subject: [PATCH 1/2] induce soft prove Signed-off-by: noelwei --- rs_zktrie/src/raw.rs | 54 +++++++++++++++++++++++++++++++++++++++++++ rs_zktrie/src/trie.rs | 5 ++-- src/lib.rs | 2 +- src/rs_lib.rs | 4 ++-- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/rs_zktrie/src/raw.rs b/rs_zktrie/src/raw.rs index 6034a33..2191da8 100644 --- a/rs_zktrie/src/raw.rs +++ b/rs_zktrie/src/raw.rs @@ -536,6 +536,60 @@ impl ZkTrieImpl Result>, ImplError> { + let path = Self::get_path(node_key); + let mut next_hash = self.root_hash.clone(); + let mut nodes = Vec::with_capacity(MAX_LEVELS); + for p in path.iter() { + let n = self.get_node(&next_hash)?; + let finished = match n.node_type { + NodeTypeEmptyNew | NodeTypeLeafNew => { + // the only possible to encounter this node + return Ok(Vec::new()) + }, + // both terminal + NodeTypeBranch0 => true, + // left (*p == 0) is terminal + NodeTypeBranch1 => if *p { + next_hash = n.child_right.clone().expect("node should has this child"); + false + } else { + true + } + // right (*p == 1) is terminal + NodeTypeBranch2 => if *p { + true + } else { + next_hash = n.child_left.clone().expect("node should has this child"); + false + } + // both are not terminal + NodeTypeBranch3 => { + if *p { + next_hash = n.child_right.clone().expect("node should has this child"); + } else { + next_hash = n.child_left.clone().expect("node should has this child"); + }; + false + } + NodeTypeEmpty | NodeTypeLeaf | NodeTypeParent => { + unreachable!("encounter deprecated node types") + } + _ => unreachable!(), + }; + + nodes.push(n); + if finished { + break; + } + } + + Ok(nodes) + } + // prove constructs a merkle proof for SMT, it respect the protocol used by the ethereum-trie // but save the node data with a compact form pub fn prove(&self, node_key: &H) -> Result>, ImplError> { diff --git a/rs_zktrie/src/trie.rs b/rs_zktrie/src/trie.rs index 855c3a9..5f1b7b9 100644 --- a/rs_zktrie/src/trie.rs +++ b/rs_zktrie/src/trie.rs @@ -112,9 +112,10 @@ impl> ZkTrie { // tuple is false // // If the trie contain a non-empty leaf for key, the `bool` in returned tuple is true - pub fn prove(&self, key_hash_byte: &[u8]) -> Result<(Vec>, bool), ImplError> { + pub fn prove(&self, key_hash_byte: &[u8], is_soft: bool) -> Result<(Vec>, bool), ImplError> { let key_hash = H::from_bytes(key_hash_byte)?; - let proof = self.tree.prove(&key_hash)?; + let proof = if is_soft {self.tree.prove_soft(&key_hash)} + else {self.tree.prove(&key_hash)}?; let mut hit = false; for n in &proof { diff --git a/src/lib.rs b/src/lib.rs index ecbc430..cbfee24 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -250,7 +250,7 @@ mod tests { Rc::get_mut(&mut db).expect("no reference").update(trie_db); let trie = db.new_ref_trie(&root).unwrap(); - let proof = trie.prove(&acc_buf).unwrap(); + let proof = trie.prove(&acc_buf, false).unwrap(); assert_eq!(proof.len(), 8); assert_eq!(proof[7], hex::decode("5448495320495320534f4d45204d4147494320425954455320464f5220534d54206d3172525867503278704449").unwrap()); diff --git a/src/rs_lib.rs b/src/rs_lib.rs index 98945bb..c7e121a 100644 --- a/src/rs_lib.rs +++ b/src/rs_lib.rs @@ -307,12 +307,12 @@ impl> ZkTrie { } // build prove array for mpt path - pub fn prove(&self, key: &[u8]) -> Result>, ErrString> { + pub fn prove(&self, key: &[u8], is_soft: bool) -> Result>, ErrString> { use types::Node; let s_key = Node::::hash_bytes(key).map_err(|e| e.to_string())?; - let (proof, _) = self.0.prove(s_key.as_ref()).map_err(|e| e.to_string())?; + let (proof, _) = self.0.prove(s_key.as_ref(), is_soft).map_err(|e| e.to_string())?; Ok(proof .into_iter() From 959b84aa33de7c7fbc53f9d8bea2dd8513fccb78 Mon Sep 17 00:00:00 2001 From: noelwei Date: Wed, 11 Sep 2024 10:29:14 +0900 Subject: [PATCH 2/2] complete soft proof with dummy terminal Signed-off-by: noelwei --- rs_zktrie/src/trie.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rs_zktrie/src/trie.rs b/rs_zktrie/src/trie.rs index 5f1b7b9..090d71b 100644 --- a/rs_zktrie/src/trie.rs +++ b/rs_zktrie/src/trie.rs @@ -114,8 +114,16 @@ impl> ZkTrie { // If the trie contain a non-empty leaf for key, the `bool` in returned tuple is true pub fn prove(&self, key_hash_byte: &[u8], is_soft: bool) -> Result<(Vec>, bool), ImplError> { let key_hash = H::from_bytes(key_hash_byte)?; - let proof = if is_soft {self.tree.prove_soft(&key_hash)} - else {self.tree.prove(&key_hash)}?; + let proof = if is_soft { + self.tree.prove_soft(&key_hash) + .map(|mut proof|{ + // add a dummy leaf node to keep the consistent of format + proof.push(Node::new_empty_node()); + proof + }) + } else { + self.tree.prove(&key_hash) + }?; let mut hit = false; for n in &proof {