@@ -100,6 +100,25 @@ pub trait Provider: Send + Sync {
100100 /// # Returns
101101 /// A BTreeMap of all storage slots (slot -> value) for the account.
102102 fn get_all_storage ( & self , address : Address ) -> Result < BTreeMap < U256 , U256 > > ;
103+
104+ /// Get the current block number (last executed block).
105+ ///
106+ /// This method retrieves the persisted block number for execution engine recovery.
107+ /// Returns `None` if no block has been executed yet (first startup).
108+ ///
109+ /// # Returns
110+ /// * `Ok(Some(block_number))` - The last executed block number
111+ /// * `Ok(None)` - No block has been executed yet
112+ fn get_current_block ( & self ) -> Result < Option < u64 > > ;
113+
114+ /// Set the current block number (last executed block).
115+ ///
116+ /// This method persists the block number after each block execution to enable
117+ /// proper recovery after node restart.
118+ ///
119+ /// # Arguments
120+ /// * `block_number` - The block number to persist
121+ fn set_current_block ( & self , block_number : u64 ) -> Result < ( ) > ;
103122}
104123
105124/// In-memory provider for testing and development.
@@ -112,6 +131,8 @@ pub struct InMemoryProvider {
112131 code : Arc < DashMap < B256 , Bytecode > > ,
113132 storage : Arc < DashMap < ( Address , U256 ) , U256 > > ,
114133 block_hashes : Arc < DashMap < u64 , B256 > > ,
134+ /// Current block number (last executed block). Uses RwLock for atomic u64 access.
135+ current_block : Arc < RwLock < Option < u64 > > > ,
115136}
116137
117138impl InMemoryProvider {
@@ -122,6 +143,7 @@ impl InMemoryProvider {
122143 code : Arc :: new ( DashMap :: new ( ) ) ,
123144 storage : Arc :: new ( DashMap :: new ( ) ) ,
124145 block_hashes : Arc :: new ( DashMap :: new ( ) ) ,
146+ current_block : Arc :: new ( RwLock :: new ( None ) ) ,
125147 }
126148 }
127149
@@ -204,6 +226,15 @@ impl Provider for InMemoryProvider {
204226 }
205227 Ok ( result)
206228 }
229+
230+ fn get_current_block ( & self ) -> Result < Option < u64 > > {
231+ Ok ( * self . current_block . read ( ) )
232+ }
233+
234+ fn set_current_block ( & self , block_number : u64 ) -> Result < ( ) > {
235+ * self . current_block . write ( ) = Some ( block_number) ;
236+ Ok ( ( ) )
237+ }
207238}
208239
209240/// Blanket implementation of Provider for Arc<P> where P: Provider.
@@ -254,6 +285,14 @@ impl<P: Provider> Provider for Arc<P> {
254285 fn get_all_storage ( & self , address : Address ) -> Result < BTreeMap < U256 , U256 > > {
255286 ( * * self ) . get_all_storage ( address)
256287 }
288+
289+ fn get_current_block ( & self ) -> Result < Option < u64 > > {
290+ ( * * self ) . get_current_block ( )
291+ }
292+
293+ fn set_current_block ( & self , block_number : u64 ) -> Result < ( ) > {
294+ ( * * self ) . set_current_block ( block_number)
295+ }
257296}
258297
259298/// CipherBFT database implementation that implements revm's Database trait.
@@ -779,6 +818,22 @@ mod tests {
779818 // Verify cache contains the entry
780819 assert ! ( db. cache_accounts. write( ) . contains( & addr) ) ;
781820 }
821+
822+ #[ test]
823+ fn test_in_memory_provider_current_block ( ) {
824+ let provider = InMemoryProvider :: new ( ) ;
825+
826+ // Initially no current block
827+ assert ! ( provider. get_current_block( ) . unwrap( ) . is_none( ) ) ;
828+
829+ // Set current block
830+ provider. set_current_block ( 100 ) . unwrap ( ) ;
831+ assert_eq ! ( provider. get_current_block( ) . unwrap( ) , Some ( 100 ) ) ;
832+
833+ // Update current block
834+ provider. set_current_block ( 200 ) . unwrap ( ) ;
835+ assert_eq ! ( provider. get_current_block( ) . unwrap( ) , Some ( 200 ) ) ;
836+ }
782837}
783838
784839// =============================================================================
@@ -798,6 +853,7 @@ pub mod mdbx_provider {
798853 ///
799854 /// This provider wraps `MdbxEvmStore` from the storage layer and implements
800855 /// the `Provider` trait to integrate with the execution layer.
856+ #[ derive( Clone ) ]
801857 pub struct MdbxProvider {
802858 store : MdbxEvmStore ,
803859 }
@@ -923,6 +979,18 @@ pub mod mdbx_provider {
923979 } )
924980 . map_err ( |e| DatabaseError :: mdbx ( e. to_string ( ) ) . into ( ) )
925981 }
982+
983+ fn get_current_block ( & self ) -> Result < Option < u64 > > {
984+ self . store
985+ . get_current_block ( )
986+ . map_err ( |e| DatabaseError :: mdbx ( e. to_string ( ) ) . into ( ) )
987+ }
988+
989+ fn set_current_block ( & self , block_number : u64 ) -> Result < ( ) > {
990+ self . store
991+ . set_current_block ( block_number)
992+ . map_err ( |e| DatabaseError :: mdbx ( e. to_string ( ) ) . into ( ) )
993+ }
926994 }
927995
928996 #[ cfg( test) ]
0 commit comments