Skip to content

Commit

Permalink
Make sure class cache is not serving classes from the future
Browse files Browse the repository at this point in the history
  • Loading branch information
omerfirmak authored and wojciechos committed Nov 23, 2023
1 parent fe294c1 commit 9e3e580
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
28 changes: 21 additions & 7 deletions vm/rust/src/juno_state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,22 @@ extern "C" {
-> *const c_char;
}

static CLASS_CACHE: Lazy<Mutex<SizedCache<ClassHash, ContractClass>>> = Lazy::new(|| {
Mutex::new(SizedCache::with_size(128))
});
struct CachedContractClass {
pub definition: ContractClass,
pub cached_on_height: u64,
}

static CLASS_CACHE: Lazy<Mutex<SizedCache<ClassHash, CachedContractClass>>> =
Lazy::new(|| Mutex::new(SizedCache::with_size(128)));

pub struct JunoStateReader {
pub handle: usize, // uintptr_t equivalent
pub height: u64,
}

impl JunoStateReader {
pub fn new(handle: usize) -> Self {
Self { handle }
pub fn new(handle: usize, height: u64) -> Self {
Self { handle, height }
}
}

Expand Down Expand Up @@ -115,7 +119,11 @@ impl StateReader for JunoStateReader {
class_hash: &ClassHash,
) -> StateResult<ContractClass> {
if let Some(cached_class) = CLASS_CACHE.lock().unwrap().cache_get(class_hash) {
return Ok(cached_class.clone())
// skip the cache if it comes from a height higher than ours. Class might be undefined on the height
// that we are reading from right now.
if cached_class.cached_on_height <= self.height {
return Ok(cached_class.definition.clone());
}
}

let class_hash_bytes = felt_to_byte_array(&class_hash.0);
Expand All @@ -126,7 +134,13 @@ impl StateReader for JunoStateReader {
let json_str = unsafe { CStr::from_ptr(ptr) }.to_str().unwrap();
let contract_class = contract_class_from_json_str(json_str);
if let Ok(class) = &contract_class {
CLASS_CACHE.lock().unwrap().cache_set(*class_hash, class.clone());
CLASS_CACHE.lock().unwrap().cache_set(
*class_hash,
CachedContractClass {
definition: class.clone(),
cached_on_height: self.height,
},
);
}

unsafe { JunoFree(ptr as *const c_void) };
Expand Down
4 changes: 2 additions & 2 deletions vm/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub extern "C" fn cairoVMCall(
block_timestamp: c_ulonglong,
chain_id: *const c_char,
) {
let reader = JunoStateReader::new(reader_handle);
let reader = JunoStateReader::new(reader_handle, block_number);
let contract_addr_felt = ptr_to_felt(contract_address);
let class_hash = if class_hash.is_null() {
None
Expand Down Expand Up @@ -148,7 +148,7 @@ pub extern "C" fn cairoVMExecute(
gas_price: *const c_uchar,
legacy_json: c_uchar,
) {
let reader = JunoStateReader::new(reader_handle);
let reader = JunoStateReader::new(reader_handle, block_number);
let chain_id_str = unsafe { CStr::from_ptr(chain_id) }.to_str().unwrap();
let txn_json_str = unsafe { CStr::from_ptr(txns_json) }.to_str().unwrap();
let txns_and_query_bits: Result<Vec<TxnAndQueryBit>, serde_json::Error> =
Expand Down

0 comments on commit 9e3e580

Please sign in to comment.