-
Notifications
You must be signed in to change notification settings - Fork 0
/
cast.rs
120 lines (112 loc) · 4.27 KB
/
cast.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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 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_bytes_be_slice(&entry.key)),
ClassHash(Felt::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_bytes_be_slice(&entry.key)),
Nonce(Felt::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_bytes_be_slice(&entry.key)),
ClassHash(Felt::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_bytes_be_slice(&entry.address)),
ContractState {
nonce: Nonce(Felt::from_bytes_be_slice(&entry.nonce)),
class_hash: ClassHash(Felt::from_bytes_be_slice(&entry.class_hash)),
storage_root_hash: HashOutput(Felt::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_bytes_be_slice(&inner_entry.key)),
StarknetStorageValue(Felt::from_bytes_be_slice(&inner_entry.value)),
)
})
.collect();
add_unique(
&mut storage_updates,
"starknet storage updates",
ContractAddress(Felt::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(())
}