Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 4bb91a4

Browse files
authored
BREAKING: StateReader::get_storage_at return zero by default (#1011)
* update InMemoryStateReader & CachedState * Add comments * Apply changes to State implementation too * Fix behaviour * Add test
1 parent 3d55d62 commit 4bb91a4

File tree

3 files changed

+32
-41
lines changed

3 files changed

+32
-41
lines changed

src/state/cached_state.rs

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -105,28 +105,12 @@ impl<T: StateReader> StateReader for CachedState<T> {
105105
}
106106

107107
/// Returns storage data for a given storage entry.
108+
/// Returns zero as default value if missing
108109
fn get_storage_at(&self, storage_entry: &StorageEntry) -> Result<Felt252, StateError> {
109-
if self.cache.get_storage(storage_entry).is_none() {
110-
match self.state_reader.get_storage_at(storage_entry) {
111-
Ok(storage) => {
112-
return Ok(storage);
113-
}
114-
Err(
115-
StateError::EmptyKeyInStorage
116-
| StateError::NoneStoragLeaf(_)
117-
| StateError::NoneStorage(_)
118-
| StateError::NoneContractState(_),
119-
) => return Ok(Felt252::zero()),
120-
Err(e) => {
121-
return Err(e);
122-
}
123-
}
124-
}
125-
126110
self.cache
127111
.get_storage(storage_entry)
128-
.ok_or_else(|| StateError::NoneStorage(storage_entry.clone()))
129-
.cloned()
112+
.map(|v| Ok(v.clone()))
113+
.unwrap_or_else(|| self.state_reader.get_storage_at(storage_entry))
130114
}
131115

132116
// TODO: check if that the proper way to store it (converting hash to address)
@@ -353,27 +337,20 @@ impl<T: StateReader> State for CachedState<T> {
353337
.clone())
354338
}
355339

340+
/// Returns storage data for a given storage entry.
341+
/// Returns zero as default value if missing
342+
/// Adds the value to the cache's inital_values if not present
356343
fn get_storage_at(&mut self, storage_entry: &StorageEntry) -> Result<Felt252, StateError> {
357-
if self.cache.get_storage(storage_entry).is_none() {
358-
let value = match self.state_reader.get_storage_at(storage_entry) {
359-
Ok(value) => value,
360-
Err(
361-
StateError::EmptyKeyInStorage
362-
| StateError::NoneStoragLeaf(_)
363-
| StateError::NoneStorage(_)
364-
| StateError::NoneContractState(_),
365-
) => Felt252::zero(),
366-
Err(e) => return Err(e),
367-
};
368-
self.cache
369-
.storage_initial_values
370-
.insert(storage_entry.clone(), value);
344+
match self.cache.get_storage(storage_entry) {
345+
Some(value) => Ok(value.clone()),
346+
None => {
347+
let value = self.state_reader.get_storage_at(storage_entry)?;
348+
self.cache
349+
.storage_initial_values
350+
.insert(storage_entry.clone(), value.clone());
351+
Ok(value)
352+
}
371353
}
372-
373-
self.cache
374-
.get_storage(storage_entry)
375-
.ok_or_else(|| StateError::NoneStorage(storage_entry.clone()))
376-
.cloned()
377354
}
378355

379356
// TODO: check if that the proper way to store it (converting hash to address)

src/state/in_memory_state_reader.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ impl StateReader for InMemoryStateReader {
9797
}
9898

9999
fn get_storage_at(&self, storage_entry: &StorageEntry) -> Result<Felt252, StateError> {
100-
let storage = self
100+
Ok(self
101101
.address_to_storage
102102
.get(storage_entry)
103-
.ok_or_else(|| StateError::NoneStorage(storage_entry.clone()));
104-
storage.cloned()
103+
.cloned()
104+
.unwrap_or_default())
105105
}
106106

107107
fn get_compiled_class_hash(
@@ -132,10 +132,21 @@ impl StateReader for InMemoryStateReader {
132132

133133
#[cfg(test)]
134134
mod tests {
135+
use num_traits::One;
136+
135137
use super::*;
136138
use crate::services::api::contract_classes::deprecated_contract_class::ContractClass;
137139
use std::sync::Arc;
138140

141+
#[test]
142+
fn get_storage_returns_zero_if_missing() {
143+
let state_reader = InMemoryStateReader::default();
144+
assert!(state_reader
145+
.get_storage_at(&(Address(Felt252::one()), Felt252::one().to_be_bytes()))
146+
.unwrap()
147+
.is_zero())
148+
}
149+
139150
#[test]
140151
fn get_contract_state_test() {
141152
let mut state_reader = InMemoryStateReader::new(

src/state/state_api.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub trait StateReader {
1616
/// Returns the nonce of the given contract instance.
1717
fn get_nonce_at(&self, contract_address: &Address) -> Result<Felt252, StateError>;
1818
/// Returns the storage value under the given key in the given contract instance.
19+
/// Returns zero by default if the value is not present
1920
fn get_storage_at(&self, storage_entry: &StorageEntry) -> Result<Felt252, StateError>;
2021
/// Return the class hash of the given casm contract class
2122
fn get_compiled_class_hash(
@@ -65,6 +66,8 @@ pub trait State {
6566
/// Default: 0 for an uninitialized contract address.
6667
fn get_nonce_at(&mut self, contract_address: &Address) -> Result<Felt252, StateError>;
6768

69+
/// Returns storage data for a given storage entry.
70+
/// Returns zero as default value if missing
6871
fn get_storage_at(&mut self, storage_entry: &StorageEntry) -> Result<Felt252, StateError>;
6972

7073
fn get_compiled_class_hash(&mut self, class_hash: &ClassHash) -> Result<ClassHash, StateError>;

0 commit comments

Comments
 (0)