Skip to content

Commit

Permalink
chore: add deserialization types and basic casting implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
nimrod-starkware committed Apr 10, 2024
1 parent 1d5f5e0 commit c61ab82
Show file tree
Hide file tree
Showing 12 changed files with 314 additions and 22 deletions.
46 changes: 29 additions & 17 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Expand Up @@ -14,6 +14,11 @@ license-file = "LICENSE"

[workspace.dependencies]
pretty_assertions = "1.2.1"
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0"
starknet-types-core = "0.0.11"
starknet_api = "0.12.0-dev.0"
thiserror = "1.0.24"

[workspace.lints.rust]
warnings = "deny"
Expand Down
7 changes: 5 additions & 2 deletions crates/committer/Cargo.toml
Expand Up @@ -13,5 +13,8 @@ workspace = true
pretty_assertions.workspace = true

[dependencies]
starknet-types-core = "0.0.11"
starknet_api = "0.12.0-dev.0"
serde.workspace = true
serde_json.workspace = true
starknet-types-core.workspace = true
starknet_api.workspace = true
thiserror.workspace = true
3 changes: 3 additions & 0 deletions crates/committer/src/deserialization.rs
@@ -0,0 +1,3 @@
pub mod cast;
pub mod errors;
pub mod types;
146 changes: 146 additions & 0 deletions crates/committer/src/deserialization/cast.rs
@@ -0,0 +1,146 @@
use super::errors::DeserializationError;
use super::types::{Input, RawInput, StarknetStorageKey, StarknetStorageValue, StateDiff};
use crate::deserialization::types::{ContractAddress, ContractState};
use crate::hash::types::HashOutput;
use crate::patricia_merkle_tree::filled_node::{ClassHash, Nonce};
use crate::patricia_merkle_tree::types::TreeHeight;
use crate::storage::storage_trait::{StorageKey, StorageValue};
use crate::types::Felt;
use starknet_types_core::felt::Felt as StarknetTypesFelt;

use std::collections::HashMap;

impl TryFrom<RawInput> for Input {
type Error = DeserializationError;
fn try_from(raw_input: RawInput) -> Result<Self, Self::Error> {
let mut storage = HashMap::new();
for entry in raw_input.storage {
add_unique(
&mut storage,
"storage",
StorageKey(entry.key),
StorageValue(entry.value),
)?
}

let mut address_to_class_hash = HashMap::new();
for entry in raw_input.state_diff.address_to_class_hash {
add_unique(
&mut address_to_class_hash,
"address to class hash",
ContractAddress(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.key,
))),
ClassHash(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.value,
))),
)?
}

let mut address_to_nonce = HashMap::new();
for entry in raw_input.state_diff.address_to_nonce {
add_unique(
&mut address_to_nonce,
"address to nonce",
ContractAddress(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.key,
))),
Nonce(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.value,
))),
)?;
}

let mut class_hash_to_compiled_class_hash = HashMap::new();
for entry in raw_input.state_diff.class_hash_to_compiled_class_hash {
add_unique(
&mut class_hash_to_compiled_class_hash,
"class hash to compiled class hash",
ClassHash(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.key,
))),
ClassHash(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.value,
))),
)?;
}

let mut current_contract_state_leaves = HashMap::new();
for entry in raw_input.state_diff.current_contract_state_leaves {
add_unique(
&mut current_contract_state_leaves,
"current contract state leaves",
ContractAddress(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.address,
))),
ContractState {
nonce: Nonce(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.nonce,
))),
class_hash: ClassHash(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&entry.class_hash,
))),
storage_root_hash: HashOutput(Felt::from(
StarknetTypesFelt::from_bytes_be_slice(&entry.storage_root_hash),
)),
},
)?;
}

let mut storage_updates = HashMap::new();
for outer_entry in raw_input.state_diff.storage_updates {
let inner_map = outer_entry
.storage_updates
.iter()
.map(|inner_entry| {
(
StarknetStorageKey(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&inner_entry.key,
))),
StarknetStorageValue(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&inner_entry.value,
))),
)
})
.collect();
add_unique(
&mut storage_updates,
"starknet storage updates",
ContractAddress(Felt::from(StarknetTypesFelt::from_bytes_be_slice(
&outer_entry.address,
))),
inner_map,
)?;
}

Ok(Input {
storage,
state_diff: StateDiff {
address_to_class_hash,
address_to_nonce,
class_hash_to_compiled_class_hash,
current_contract_state_leaves,
storage_updates,
},
tree_height: TreeHeight(raw_input.tree_height),
})
}
}

pub(crate) fn add_unique<K, V>(
map: &mut HashMap<K, V>,
map_name: &str,
key: K,
value: V,
) -> Result<(), DeserializationError>
where
K: std::cmp::Eq + std::hash::Hash + std::fmt::Debug,
{
if map.contains_key(&key) {
return Err(DeserializationError::KeyDuplicate(format!(
"{map_name}: {key:?}"
)));
}
map.insert(key, value);
Ok(())
}
10 changes: 10 additions & 0 deletions crates/committer/src/deserialization/errors.rs
@@ -0,0 +1,10 @@
use std::fmt::Debug;

use thiserror::Error;

#[allow(dead_code)]
#[derive(Debug, Error)]
pub(crate) enum DeserializationError {
#[error("There is a key duplicate at {0} mapping.")]
KeyDuplicate(String),
}

0 comments on commit c61ab82

Please sign in to comment.