@@ -22,7 +22,7 @@ use std::{
2222 collections:: HashSet ,
2323 path:: Path ,
2424 sync:: {
25- Arc , Mutex ,
25+ Arc , Mutex , RwLock ,
2626 mpsc:: { SyncSender , sync_channel} ,
2727 } ,
2828} ;
@@ -139,7 +139,7 @@ enum FKVGeneratorControlMessage {
139139#[ derive( Debug , Clone ) ]
140140pub struct Store {
141141 db : Arc < DBWithThreadMode < MultiThreaded > > ,
142- trie_cache : Arc < Mutex < Arc < TrieLayerCache > > > ,
142+ trie_cache : Arc < RwLock < TrieLayerCache > > ,
143143 flatkeyvalue_control_tx : std:: sync:: mpsc:: SyncSender < FKVGeneratorControlMessage > ,
144144 trie_update_worker_tx : TriedUpdateWorkerTx ,
145145 last_computed_flatkeyvalue : Arc < Mutex < Vec < u8 > > > ,
@@ -706,7 +706,6 @@ impl Store {
706706 ) -> Result < ( ) , StoreError > {
707707 let db = & * self . db ;
708708 let fkv_ctl = & self . flatkeyvalue_control_tx ;
709- let trie_cache = & self . trie_cache ;
710709
711710 // Phase 1: update the in-memory diff-layers only, then notify block production.
712711 let new_layer = storage_updates
@@ -718,36 +717,40 @@ impl Store {
718717 } )
719718 . chain ( account_updates)
720719 . collect ( ) ;
721- // Read-Copy- Update the trie cache with a new layer.
722- let trie = trie_cache
723- . lock ( )
720+ // Update trie cache with a new layer under write lock .
721+ self . trie_cache
722+ . write ( )
724723 . map_err ( |_| StoreError :: LockError ) ?
725- . clone ( ) ;
726- let mut trie_mut = ( * trie) . clone ( ) ;
727- trie_mut. put_batch ( parent_state_root, child_state_root, new_layer) ;
728- let trie = Arc :: new ( trie_mut) ;
729- * trie_cache. lock ( ) . map_err ( |_| StoreError :: LockError ) ? = trie. clone ( ) ;
724+ . put_batch ( parent_state_root, child_state_root, new_layer) ;
730725 // Update finished, signal block processing.
731726 notify. send ( Ok ( ( ) ) ) . map_err ( |_| StoreError :: LockError ) ?;
732727
733728 // Phase 2: update disk layer.
734- let Some ( root) = trie. get_commitable ( parent_state_root, COMMIT_THRESHOLD ) else {
729+ let Some ( root) = self
730+ . trie_cache
731+ . read ( )
732+ . map_err ( |_| StoreError :: LockError ) ?
733+ . get_commitable ( parent_state_root, COMMIT_THRESHOLD )
734+ else {
735735 // Nothing to commit to disk, move on.
736736 return Ok ( ( ) ) ;
737737 } ;
738738 // Stop the flat-key-value generator thread, as the underlying trie is about to change.
739739 // Ignore the error, if the channel is closed it means there is no worker to notify.
740740 let _ = fkv_ctl. send ( FKVGeneratorControlMessage :: Stop ) ;
741741
742- // RCU to remove the bottom layer: update step needs to happen after disk layer is updated.
743- let mut trie_mut = ( * trie) . clone ( ) ;
744742 let mut batch = WriteBatch :: default ( ) ;
745743 let [ cf_trie_nodes, cf_flatkeyvalue, cf_misc] =
746744 open_cfs ( db, [ CF_TRIE_NODES , CF_FLATKEYVALUE , CF_MISC_VALUES ] ) ?;
747745
748746 let last_written = db. get_cf ( & cf_misc, "last_written" ) ?. unwrap_or_default ( ) ;
749747 // Commit removes the bottom layer and returns it, this is the mutation step.
750- let nodes = trie_mut. commit ( root) . unwrap_or_default ( ) ;
748+ let nodes = self
749+ . trie_cache
750+ . write ( )
751+ . map_err ( |_| StoreError :: LockError ) ?
752+ . commit ( root)
753+ . unwrap_or_default ( ) ;
751754 for ( key, value) in nodes {
752755 let is_leaf = key. len ( ) == 65 || key. len ( ) == 131 ;
753756
@@ -769,8 +772,7 @@ impl Store {
769772 // We want to send this message even if there was an error during the batch write
770773 let _ = fkv_ctl. send ( FKVGeneratorControlMessage :: Continue ) ;
771774 result?;
772- // Phase 3: update diff layers with the removal of bottom layer.
773- * trie_cache. lock ( ) . map_err ( |_| StoreError :: LockError ) ? = Arc :: new ( trie_mut) ;
775+ // Phase 3: diff layers already updated by commit mutation.
774776 Ok ( ( ) )
775777 }
776778
@@ -1478,11 +1480,7 @@ impl StoreEngine for Store {
14781480 ) ?) ;
14791481 let wrap_db = Box :: new ( TrieWrapper {
14801482 state_root,
1481- inner : self
1482- . trie_cache
1483- . lock ( )
1484- . map_err ( |_| StoreError :: LockError ) ?
1485- . clone ( ) ,
1483+ inner : self . trie_cache . clone ( ) ,
14861484 db,
14871485 prefix : Some ( hashed_address) ,
14881486 } ) ;
@@ -1499,11 +1497,7 @@ impl StoreEngine for Store {
14991497 ) ?) ;
15001498 let wrap_db = Box :: new ( TrieWrapper {
15011499 state_root,
1502- inner : self
1503- . trie_cache
1504- . lock ( )
1505- . map_err ( |_| StoreError :: LockError ) ?
1506- . clone ( ) ,
1500+ inner : self . trie_cache . clone ( ) ,
15071501 db,
15081502 prefix : None ,
15091503 } ) ;
@@ -1543,11 +1537,7 @@ impl StoreEngine for Store {
15431537 ) ?) ;
15441538 let wrap_db = Box :: new ( TrieWrapper {
15451539 state_root,
1546- inner : self
1547- . trie_cache
1548- . lock ( )
1549- . map_err ( |_| StoreError :: LockError ) ?
1550- . clone ( ) ,
1540+ inner : self . trie_cache . clone ( ) ,
15511541 db,
15521542 prefix : None ,
15531543 } ) ;
@@ -1568,11 +1558,7 @@ impl StoreEngine for Store {
15681558 ) ?) ;
15691559 let wrap_db = Box :: new ( TrieWrapper {
15701560 state_root,
1571- inner : self
1572- . trie_cache
1573- . lock ( )
1574- . map_err ( |_| StoreError :: LockError ) ?
1575- . clone ( ) ,
1561+ inner : self . trie_cache . clone ( ) ,
15761562 db,
15771563 prefix : Some ( hashed_address) ,
15781564 } ) ;
0 commit comments