@@ -146,17 +146,26 @@ impl<S: StateProvider> StateProvider for CachedStateProvider<S> {
146146 storage_key : StorageKey ,
147147 ) -> ProviderResult < Option < StorageValue > > {
148148 match self . caches . get_storage ( & account, & storage_key) {
149- SlotStatus :: NotCached => {
150- self . metrics . storage_cache_misses . increment ( 1 ) ;
149+ ( SlotStatus :: NotCached , maybe_cache) => {
151150 let final_res = self . state_provider . storage ( account, storage_key) ?;
152- self . caches . insert_storage ( account, storage_key, final_res) ;
151+ let account_cache = maybe_cache. unwrap_or_default ( ) ;
152+ account_cache. insert_storage ( storage_key, final_res) ;
153+ // we always need to insert the value to update the weights.
154+ // Note: there exists a race when the storage cache did not exist yet and two
155+ // consumers looking up the a storage value for this account for the first time,
156+ // however we can assume that this will only happen for the very first (mostlikely
157+ // the same) value, and don't expect that this will accidentally
158+ // replace an account storage cache with additional values.
159+ self . caches . insert_storage_cache ( account, account_cache) ;
160+
161+ self . metrics . storage_cache_misses . increment ( 1 ) ;
153162 Ok ( final_res)
154163 }
155- SlotStatus :: Empty => {
164+ ( SlotStatus :: Empty , _ ) => {
156165 self . metrics . storage_cache_hits . increment ( 1 ) ;
157166 Ok ( None )
158167 }
159- SlotStatus :: Value ( value) => {
168+ ( SlotStatus :: Value ( value) , _ ) => {
160169 self . metrics . storage_cache_hits . increment ( 1 ) ;
161170 Ok ( Some ( value) )
162171 }
@@ -311,18 +320,28 @@ pub(crate) struct ExecutionCache {
311320impl ExecutionCache {
312321 /// Get storage value from hierarchical cache.
313322 ///
314- /// Returns a `SlotStatus` indicating whether:
315- /// - `NotCached`: The account's storage cache doesn't exist
316- /// - `Empty`: The slot exists in the account's cache but is empty
317- /// - `Value`: The slot exists and has a specific value
318- pub ( crate ) fn get_storage ( & self , address : & Address , key : & StorageKey ) -> SlotStatus {
323+ /// Returns a tuple of:
324+ /// - `SlotStatus` indicating whether:
325+ /// - `NotCached`: The account's storage cache doesn't exist
326+ /// - `Empty`: The slot exists in the account's cache but is empty
327+ /// - `Value`: The slot exists and has a specific value
328+ /// - `Option<Arc<AccountStorageCache>>`: The account's storage cache if it exists
329+ pub ( crate ) fn get_storage (
330+ & self ,
331+ address : & Address ,
332+ key : & StorageKey ,
333+ ) -> ( SlotStatus , Option < Arc < AccountStorageCache > > ) {
319334 match self . storage_cache . get ( address) {
320- None => SlotStatus :: NotCached ,
321- Some ( account_cache) => account_cache. get_storage ( key) ,
335+ None => ( SlotStatus :: NotCached , None ) ,
336+ Some ( account_cache) => {
337+ let status = account_cache. get_storage ( key) ;
338+ ( status, Some ( account_cache) )
339+ }
322340 }
323341 }
324342
325343 /// Insert storage value into hierarchical cache
344+ #[ cfg( test) ]
326345 pub ( crate ) fn insert_storage (
327346 & self ,
328347 address : Address ,
@@ -351,6 +370,15 @@ impl ExecutionCache {
351370 self . storage_cache . insert ( address, account_cache) ;
352371 }
353372
373+ /// Inserts the [`AccountStorageCache`].
374+ pub ( crate ) fn insert_storage_cache (
375+ & self ,
376+ address : Address ,
377+ storage_cache : Arc < AccountStorageCache > ,
378+ ) {
379+ self . storage_cache . insert ( address, storage_cache) ;
380+ }
381+
354382 /// Invalidate storage for specific account
355383 pub ( crate ) fn invalidate_account_storage ( & self , address : & Address ) {
356384 self . storage_cache . invalidate ( address) ;
@@ -800,7 +828,7 @@ mod tests {
800828 caches. insert_storage ( address, storage_key, Some ( storage_value) ) ;
801829
802830 // check that the storage returns the cached value
803- let slot_status = caches. get_storage ( & address, & storage_key) ;
831+ let ( slot_status, _ ) = caches. get_storage ( & address, & storage_key) ;
804832 assert_eq ! ( slot_status, SlotStatus :: Value ( storage_value) ) ;
805833 }
806834
@@ -814,7 +842,7 @@ mod tests {
814842 let caches = ExecutionCacheBuilder :: default ( ) . build_caches ( 1000 ) ;
815843
816844 // check that the storage is not cached
817- let slot_status = caches. get_storage ( & address, & storage_key) ;
845+ let ( slot_status, _ ) = caches. get_storage ( & address, & storage_key) ;
818846 assert_eq ! ( slot_status, SlotStatus :: NotCached ) ;
819847 }
820848
@@ -830,7 +858,7 @@ mod tests {
830858 caches. insert_storage ( address, storage_key, None ) ;
831859
832860 // check that the storage is empty
833- let slot_status = caches. get_storage ( & address, & storage_key) ;
861+ let ( slot_status, _ ) = caches. get_storage ( & address, & storage_key) ;
834862 assert_eq ! ( slot_status, SlotStatus :: Empty ) ;
835863 }
836864
0 commit comments