@@ -79,20 +79,18 @@ impl StateManager {
7979 Ok ( manager)
8080 }
8181
82- /// Get account
82+ /// Get account (returns reference to cached value)
83+ ///
84+ /// Note: This only checks the in-memory cache. For guaranteed up-to-date values
85+ /// that may exist only in storage, use get_account_owned() instead.
8386 pub fn get_account ( & self , pubkey : & [ u8 ; 33 ] ) -> Option < & Account > {
84- // Check in-memory cache first
85- if let Some ( account) = self . accounts . get ( pubkey) {
86- return Some ( account) ;
87- }
88-
89- // If we have storage, try loading from disk
90- // Note: This returns None because we can't return a reference to a temporary
91- // In production, we'd need to update the cache or use a different pattern
92- None
87+ self . accounts . get ( pubkey)
9388 }
9489
95- /// Get account (with storage fallback, returns owned value)
90+ /// Get account with storage fallback (returns owned value)
91+ ///
92+ /// This method checks both the in-memory cache and storage backend,
93+ /// ensuring that persisted state is accessible even if not yet cached.
9694 pub fn get_account_owned ( & self , pubkey : & [ u8 ; 33 ] ) -> Option < Account > {
9795 // Check in-memory cache first
9896 if let Some ( account) = self . accounts . get ( pubkey) {
@@ -102,6 +100,10 @@ impl StateManager {
102100 // Fallback to storage if available
103101 if let Some ( storage) = & self . storage {
104102 if let Ok ( Some ( account) ) = storage. get_account ( pubkey) {
103+ tracing:: trace!(
104+ pubkey = %hex:: encode( & pubkey) ,
105+ "Loaded account from storage (cache miss)"
106+ ) ;
105107 return Some ( account) ;
106108 }
107109 }
@@ -132,12 +134,18 @@ impl StateManager {
132134 self . recompute_root ( ) ;
133135 }
134136
135- /// Get bond state
137+ /// Get bond state (returns reference to cached value)
138+ ///
139+ /// Note: This only checks the in-memory cache. For guaranteed up-to-date values
140+ /// that may exist only in storage, use get_bond_owned() instead.
136141 pub fn get_bond ( & self , pubkey : & [ u8 ; 33 ] ) -> Option < & BondState > {
137142 self . bonds . get ( pubkey)
138143 }
139144
140- /// Get bond state (with storage fallback, returns owned value)
145+ /// Get bond state with storage fallback (returns owned value)
146+ ///
147+ /// This method checks both the in-memory cache and storage backend,
148+ /// ensuring that persisted state is accessible even if not yet cached.
141149 pub fn get_bond_owned ( & self , pubkey : & [ u8 ; 33 ] ) -> Option < BondState > {
142150 // Check in-memory cache first
143151 if let Some ( bond) = self . bonds . get ( pubkey) {
@@ -147,6 +155,10 @@ impl StateManager {
147155 // Fallback to storage if available
148156 if let Some ( storage) = & self . storage {
149157 if let Ok ( Some ( bond) ) = storage. get_bond ( pubkey) {
158+ tracing:: trace!(
159+ pubkey = %hex:: encode( & pubkey) ,
160+ "Loaded bond from storage (cache miss)"
161+ ) ;
150162 return Some ( bond) ;
151163 }
152164 }
@@ -276,6 +288,7 @@ impl Default for StateManager {
276288#[ cfg( test) ]
277289mod tests {
278290 use super :: * ;
291+ use tempfile:: TempDir ;
279292
280293 #[ test]
281294 fn test_state_manager ( ) {
@@ -292,4 +305,77 @@ mod tests {
292305 let retrieved = sm. get_account ( & pubkey) . unwrap ( ) ;
293306 assert_eq ! ( retrieved. balance, 1000 ) ;
294307 }
308+
309+ #[ test]
310+ fn test_state_manager_with_storage ( ) {
311+ let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
312+ let storage = Arc :: new ( StorageManager :: new ( temp_dir. path ( ) ) . unwrap ( ) ) ;
313+ let pubkey = [ 1u8 ; 33 ] ;
314+
315+ // Create state manager with storage and add an account
316+ {
317+ let mut sm = StateManager :: with_storage ( storage. clone ( ) ) . unwrap ( ) ;
318+ let account = Account {
319+ balance : 1000 ,
320+ nonce : 5 ,
321+ } ;
322+ sm. update_account ( pubkey, account) ;
323+ }
324+
325+ // Create new state manager with same storage and verify persistence
326+ {
327+ let sm = StateManager :: with_storage ( storage) . unwrap ( ) ;
328+ let retrieved = sm. get_account_owned ( & pubkey) . unwrap ( ) ;
329+ assert_eq ! ( retrieved. balance, 1000 ) ;
330+ assert_eq ! ( retrieved. nonce, 5 ) ;
331+ }
332+ }
333+
334+ #[ test]
335+ fn test_bond_persistence_with_storage ( ) {
336+ let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
337+ let storage = Arc :: new ( StorageManager :: new ( temp_dir. path ( ) ) . unwrap ( ) ) ;
338+ let miner_id = [ 42u8 ; 33 ] ;
339+
340+ // Create state manager with storage and add a bond
341+ {
342+ let mut sm = StateManager :: with_storage ( storage. clone ( ) ) . unwrap ( ) ;
343+ let bond = BondState {
344+ amount : 5000 ,
345+ status : BondStatus :: Active ,
346+ locked_epoch : 10 ,
347+ } ;
348+ sm. update_bond ( miner_id, bond) ;
349+ }
350+
351+ // Create new state manager with same storage and verify persistence
352+ {
353+ let sm = StateManager :: with_storage ( storage) . unwrap ( ) ;
354+ let retrieved = sm. get_bond_owned ( & miner_id) . unwrap ( ) ;
355+ assert_eq ! ( retrieved. amount, 5000 ) ;
356+ assert_eq ! ( retrieved. locked_epoch, 10 ) ;
357+ assert ! ( retrieved. is_active( ) ) ;
358+ }
359+ }
360+
361+ #[ test]
362+ fn test_state_manager_get_or_create_account ( ) {
363+ let mut sm = StateManager :: new ( ) ;
364+ let pubkey = [ 3u8 ; 33 ] ;
365+
366+ // Account doesn't exist yet
367+ assert ! ( sm. get_account( & pubkey) . is_none( ) ) ;
368+ assert ! ( sm. get_account_owned( & pubkey) . is_none( ) ) ;
369+
370+ // Create account
371+ let account = Account {
372+ balance : 500 ,
373+ nonce : 0 ,
374+ } ;
375+ sm. update_account ( pubkey, account) ;
376+
377+ // Now it exists
378+ assert ! ( sm. get_account( & pubkey) . is_some( ) ) ;
379+ assert_eq ! ( sm. get_account_owned( & pubkey) . unwrap( ) . balance, 500 ) ;
380+ }
295381}
0 commit comments