Skip to content

Commit cbb6ed9

Browse files
starknet_patricia: from merkle node to preimage (#10889)
1 parent acb235c commit cbb6ed9

File tree

5 files changed

+127
-1
lines changed

5 files changed

+127
-1
lines changed

Cargo.lock

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ simple_logger = "4.0.0"
350350
socket2 = "0.5.8"
351351
starknet-core = "0.16.0"
352352
starknet-crypto = "0.8.1"
353+
starknet-rust-core = "0.16.0"
353354
starknet-types-core = "0.2.4"
354355
starknet_api = { path = "crates/starknet_api", version = "0.0.0" }
355356
starknet_committer.path = "crates/starknet_committer"

crates/starknet_patricia/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ serde_json.workspace = true
3030
starknet-types-core.workspace = true
3131
starknet_api.workspace = true
3232
starknet_patricia_storage.workspace = true
33+
starknet-rust-core.workspace = true
3334
strum.workspace = true
3435
strum_macros.workspace = true
3536
thiserror.workspace = true

crates/starknet_patricia/src/patricia_merkle_tree/node_data/inner_node.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::HashMap;
22

33
use ethnum::U256;
44
use starknet_api::hash::HashOutput;
5+
use starknet_rust_core::types::MerkleNode;
56
use starknet_types_core::felt::Felt;
67

78
use crate::patricia_merkle_tree::node_data::errors::{
@@ -240,6 +241,39 @@ impl Preimage {
240241
}
241242
}
242243

244+
impl From<&MerkleNode> for Preimage {
245+
fn from(node: &MerkleNode) -> Self {
246+
match node {
247+
MerkleNode::BinaryNode(binary_node) => Preimage::Binary(BinaryData {
248+
left_data: HashOutput(binary_node.left),
249+
right_data: HashOutput(binary_node.right),
250+
}),
251+
MerkleNode::EdgeNode(edge_node) => {
252+
let length = u8::try_from(edge_node.length).unwrap_or_else(|_| {
253+
panic!(
254+
"EdgeNode length {} exceeds u8::MAX when converting to Preimage",
255+
edge_node.length
256+
)
257+
});
258+
Preimage::Edge(EdgeData {
259+
bottom_data: HashOutput(edge_node.child),
260+
path_to_bottom: PathToBottom::new(
261+
EdgePath(U256::from_be_bytes(edge_node.path.to_bytes_be())),
262+
EdgePathLength(length),
263+
)
264+
.unwrap_or_else(|_| {
265+
panic!(
266+
"Failed to create PathToBottom from MerkleNode edge: path={:?}, \
267+
length={}",
268+
edge_node.path, edge_node.length
269+
)
270+
}),
271+
})
272+
}
273+
}
274+
}
275+
}
276+
243277
impl TryFrom<&Vec<Felt>> for Preimage {
244278
type Error = PreimageError;
245279

crates/starknet_patricia/src/patricia_merkle_tree/node_data/inner_node_tests.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use ethnum::U256;
22
use rstest::rstest;
3+
use starknet_rust_core::types::{EdgeNode, MerkleNode};
4+
use starknet_types_core::felt::Felt;
35

4-
use crate::patricia_merkle_tree::node_data::inner_node::{EdgePathLength, PathToBottom};
6+
use crate::patricia_merkle_tree::node_data::inner_node::{EdgePathLength, PathToBottom, Preimage};
57

68
#[rstest]
79
#[case(PathToBottom::from("1011"), 1, PathToBottom::from("011"))]
@@ -20,3 +22,25 @@ fn test_remove_first_edges(
2022
expected
2123
);
2224
}
25+
26+
#[test]
27+
#[should_panic(expected = "EdgeNode length 256 exceeds u8::MAX")]
28+
fn test_preimage_from_edge_merkle_node_length_exceeds_u8() {
29+
let merkle_node =
30+
MerkleNode::EdgeNode(EdgeNode { child: Felt::ONE, path: Felt::ZERO, length: 256 });
31+
32+
let _ = Preimage::from(&merkle_node);
33+
}
34+
35+
#[test]
36+
#[should_panic(expected = "Failed to create PathToBottom from MerkleNode edge")]
37+
fn test_preimage_from_edge_merkle_node_path_mismatch() {
38+
// Path 0b1111 (4 bits) with length 2 should fail - path is too long for the stated length.
39+
let merkle_node = MerkleNode::EdgeNode(EdgeNode {
40+
child: Felt::ONE,
41+
path: Felt::from(0b1111_u128),
42+
length: 2,
43+
});
44+
45+
let _ = Preimage::from(&merkle_node);
46+
}

0 commit comments

Comments
 (0)