Skip to content

Commit 17427df

Browse files
chore: add deserialization types and basic casting implementation
1 parent 707a58d commit 17427df

File tree

10 files changed

+431
-1752
lines changed

10 files changed

+431
-1752
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ license-file = "LICENSE"
1414

1515
[workspace.dependencies]
1616
pretty_assertions = "1.2.1"
17+
serde = { version = "1.0.197", features = ["derive"] }
18+
serde_json = "1.0"
19+
starknet-types-core = "0.0.11"
20+
thiserror = "1.0.24"
21+
1722

1823
[workspace.lints.rust]
1924
warnings = "deny"

crates/committer/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ workspace = true
1313
pretty_assertions.workspace = true
1414

1515
[dependencies]
16-
starknet-types-core = "0.0.11"
17-
starknet_api = "0.12.0-dev.0"
16+
serde.workspace = true
17+
serde_json.workspace = true
18+
starknet-types-core.workspace = true
19+
thiserror.workspace = true
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod cast;
2+
pub mod errors;
3+
pub mod types;
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
use super::errors::DeserializationError;
2+
use super::types::{Input, RawInput, StarknetStorageKey, StarknetStorageValue, StateDiff};
3+
use crate::deserialization::types::{ContractAddress, ContractState, StorageKey, StorageValue};
4+
use crate::hash::types::HashOutput;
5+
use crate::patricia_merkle_tree::filled_node::{ClassHash, Nonce};
6+
use crate::types::Felt;
7+
use std::collections::HashMap;
8+
9+
impl TryFrom<RawInput> for Input {
10+
type Error = DeserializationError;
11+
fn try_from(raw_input: RawInput) -> Result<Self, Self::Error> {
12+
let mut storage = HashMap::new();
13+
for entry in raw_input.storage {
14+
if storage
15+
.insert(StorageKey(entry.key), StorageValue(entry.value))
16+
.is_some()
17+
{
18+
return Err(DeserializationError::Duplicate("storage".to_string()));
19+
}
20+
}
21+
22+
let mut address_to_class_hash = HashMap::new();
23+
for entry in raw_input.state_diff.address_to_class_hash {
24+
if address_to_class_hash
25+
.insert(
26+
ContractAddress(Felt::from_bytes_be_slice(&entry.key)),
27+
ClassHash(Felt::from_bytes_be_slice(&entry.value)),
28+
)
29+
.is_some()
30+
{
31+
return Err(DeserializationError::Duplicate(
32+
"address to class hash".to_string(),
33+
));
34+
}
35+
}
36+
37+
let mut address_to_nonce = HashMap::new();
38+
for entry in raw_input.state_diff.address_to_nonce {
39+
if address_to_nonce
40+
.insert(
41+
ContractAddress(Felt::from_bytes_be_slice(&entry.key)),
42+
Nonce(Felt::from_bytes_be_slice(&entry.value)),
43+
)
44+
.is_some()
45+
{
46+
return Err(DeserializationError::Duplicate(
47+
"address to nonce".to_string(),
48+
));
49+
}
50+
}
51+
52+
let mut class_hash_to_compiled_class_hash = HashMap::new();
53+
for entry in raw_input.state_diff.class_hash_to_compiled_class_hash {
54+
if class_hash_to_compiled_class_hash
55+
.insert(
56+
ClassHash(Felt::from_bytes_be_slice(&entry.key)),
57+
ClassHash(Felt::from_bytes_be_slice(&entry.value)),
58+
)
59+
.is_some()
60+
{
61+
return Err(DeserializationError::Duplicate(
62+
"class hash to compiled class hash".to_string(),
63+
));
64+
}
65+
}
66+
67+
let mut current_contract_state_leaves = HashMap::new();
68+
for entry in raw_input.state_diff.current_contract_state_leaves {
69+
if current_contract_state_leaves
70+
.insert(
71+
ContractAddress(Felt::from_bytes_be_slice(&entry.address)),
72+
ContractState {
73+
nonce: Nonce(Felt::from_bytes_be_slice(&entry.nonce)),
74+
class_hash: ClassHash(Felt::from_bytes_be_slice(&entry.class_hash)),
75+
storage_root_hash: HashOutput(Felt::from_bytes_be_slice(
76+
&entry.storage_root_hash,
77+
)),
78+
},
79+
)
80+
.is_some()
81+
{
82+
return Err(DeserializationError::Duplicate(
83+
"current contract state leaves".to_string(),
84+
));
85+
}
86+
}
87+
88+
let mut storage_updates = HashMap::new();
89+
for outer_entry in raw_input.state_diff.storage_updates {
90+
let inner_map = outer_entry
91+
.storage_updates
92+
.iter()
93+
.map(|inner_entry| {
94+
(
95+
StarknetStorageKey(Felt::from_bytes_be_slice(&inner_entry.key)),
96+
StarknetStorageValue(Felt::from_bytes_be_slice(&inner_entry.value)),
97+
)
98+
})
99+
.collect();
100+
if storage_updates
101+
.insert(
102+
ContractAddress(Felt::from_bytes_be_slice(&outer_entry.address)),
103+
inner_map,
104+
)
105+
.is_some()
106+
{
107+
return Err(DeserializationError::Duplicate(
108+
"starknet storage updates".to_string(),
109+
));
110+
}
111+
}
112+
113+
Ok(Input {
114+
storage,
115+
state_diff: StateDiff {
116+
address_to_class_hash,
117+
address_to_nonce,
118+
class_hash_to_compiled_class_hash,
119+
current_contract_state_leaves,
120+
storage_updates,
121+
},
122+
tree_height: raw_input.tree_height,
123+
})
124+
}
125+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use thiserror::Error;
2+
3+
#[allow(dead_code)]
4+
#[derive(Debug, Error)]
5+
pub(crate) enum DeserializationError {
6+
#[error("There is a key duplication at {0} mapping.")]
7+
Duplicate(String),
8+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use crate::{
2+
hash::types::HashOutput,
3+
patricia_merkle_tree::filled_node::{ClassHash, Nonce},
4+
types::Felt,
5+
};
6+
use serde::Deserialize;
7+
use std::collections::HashMap;
8+
9+
type RawFelt = [u8; 32];
10+
#[derive(PartialEq, Eq, Hash)]
11+
pub(crate) struct StorageKey(pub Vec<u8>);
12+
#[allow(dead_code)]
13+
pub(crate) struct StorageValue(pub Vec<u8>);
14+
#[derive(PartialEq, Eq, Hash)]
15+
// TODO(Nimrod, 1/6/2024): Swap to starknet-types-core types once implemented.
16+
pub(crate) struct ContractAddress(pub Felt);
17+
#[derive(PartialEq, Eq, Hash)]
18+
// TODO(Nimrod, 1/6/2024): Swap to starknet-types-core types once implemented.
19+
pub(crate) struct StarknetStorageKey(pub Felt);
20+
#[allow(dead_code)]
21+
pub(crate) struct StarknetStorageValue(pub Felt);
22+
23+
#[derive(Deserialize, Debug)]
24+
#[allow(dead_code)]
25+
/// Input to the committer.
26+
pub(crate) struct RawInput {
27+
/// Storage. Will be casted to HashMap<Bytes, Bytes> to simulate DB access.
28+
pub storage: Vec<RawStorageEntry>,
29+
/// All relevant information for the state diff commitment.
30+
pub state_diff: RawStateDiff,
31+
/// The height of the patricia tree.
32+
// TODO(Nimrod,20/4/2024): Strong assumption - all trees have same height. How can I get
33+
// rid of it?
34+
pub tree_height: u8,
35+
}
36+
37+
#[allow(dead_code)]
38+
pub(crate) struct Input {
39+
pub storage: HashMap<StorageKey, StorageValue>,
40+
pub state_diff: StateDiff,
41+
pub tree_height: u8,
42+
}
43+
44+
#[derive(Deserialize, Debug)]
45+
#[allow(dead_code)]
46+
/// Fact storage entry.
47+
pub(crate) struct RawStorageEntry {
48+
pub key: Vec<u8>,
49+
pub value: Vec<u8>,
50+
}
51+
52+
#[derive(Deserialize, Debug)]
53+
#[allow(dead_code)]
54+
pub(crate) struct RawFeltMapEntry {
55+
pub key: RawFelt,
56+
pub value: RawFelt,
57+
}
58+
59+
#[derive(Deserialize, Debug)]
60+
#[allow(dead_code)]
61+
/// Represents storage updates. Later will be casted to HashMap<Felt, HashMap<Felt,Felt>> entry.
62+
pub(crate) struct RawStorageUpdates {
63+
pub address: RawFelt,
64+
pub storage_updates: Vec<RawFeltMapEntry>,
65+
}
66+
67+
#[derive(Deserialize, Debug)]
68+
#[allow(dead_code)]
69+
/// Represents current state leaf at the contract state tree. Later will be casted to
70+
/// HashMap<Felt, (nonce, class_hash, storage_root_hash)> entry.
71+
pub(crate) struct RawContractStateLeaf {
72+
pub address: RawFelt,
73+
pub nonce: RawFelt,
74+
pub storage_root_hash: RawFelt,
75+
pub class_hash: RawFelt,
76+
}
77+
78+
#[derive(Deserialize, Debug)]
79+
#[allow(dead_code)]
80+
/// Represents state diff.
81+
pub(crate) struct RawStateDiff {
82+
/// Will be casted to HashMap<Felt,Felt>.
83+
pub address_to_class_hash: Vec<RawFeltMapEntry>,
84+
/// Will be casted to HashMap<Felt,Felt>.
85+
pub address_to_nonce: Vec<RawFeltMapEntry>,
86+
/// Will be casted to HashMap<Felt,Felt>.
87+
pub class_hash_to_compiled_class_hash: Vec<RawFeltMapEntry>,
88+
/// Will be casted to HashMap<Felt,HashMap<Felt,Felt>>.
89+
pub storage_updates: Vec<RawStorageUpdates>,
90+
/// Will be casted to HashMap<Felt,ContractState>.
91+
pub current_contract_state_leaves: Vec<RawContractStateLeaf>,
92+
}
93+
94+
#[allow(dead_code)]
95+
pub(crate) struct StateDiff {
96+
pub address_to_class_hash: HashMap<ContractAddress, ClassHash>,
97+
pub address_to_nonce: HashMap<ContractAddress, Nonce>,
98+
pub class_hash_to_compiled_class_hash: HashMap<ClassHash, ClassHash>,
99+
pub current_contract_state_leaves: HashMap<ContractAddress, ContractState>,
100+
pub storage_updates:
101+
HashMap<ContractAddress, HashMap<StarknetStorageKey, StarknetStorageValue>>,
102+
}
103+
104+
#[allow(dead_code)]
105+
pub(crate) struct ContractState {
106+
pub nonce: Nonce,
107+
pub class_hash: ClassHash,
108+
pub storage_root_hash: HashOutput,
109+
}

crates/committer/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod deserialization;
12
pub mod hash;
23
pub mod patricia_merkle_tree;
34
pub mod types;

crates/committer/src/patricia_merkle_tree/filled_node.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::patricia_merkle_tree::types::{EdgeData, LeafDataTrait};
22
use crate::{hash::types::HashOutput, types::Felt};
33
// TODO(Nimrod, 1/6/2024): Swap to starknet-types-core types once implemented.
44
#[allow(dead_code)]
5+
#[derive(Eq, PartialEq, Hash)]
56
pub(crate) struct ClassHash(pub Felt);
67
#[allow(dead_code)]
78
pub(crate) struct Nonce(pub Felt);

crates/committer/src/patricia_merkle_tree/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub(crate) trait TreeHashFunction<L: LeafDataTrait, H: HashFunction> {
99

1010
// TODO(Amos, 01/05/2024): Implement types for NodeIndex, EdgePath, EdgePathLength
1111
#[allow(dead_code)]
12+
#[derive(Eq, PartialEq, Hash)]
1213
pub(crate) struct NodeIndex(pub Felt);
1314

1415
#[allow(dead_code)]

0 commit comments

Comments
 (0)