@@ -30,7 +30,7 @@ use crate::{
3030 storage:: { BlockchainStorage , InMemoryBlockStates , MinedBlockOutcome } ,
3131 } ,
3232 revm:: { db:: DatabaseRef , primitives:: AccountInfo } ,
33- NodeConfig , PrecompileFactory ,
33+ ForkChoice , NodeConfig , PrecompileFactory ,
3434} ;
3535use alloy_consensus:: { Account , Header , Receipt , ReceiptWithBloom } ;
3636use alloy_eips:: eip4844:: MAX_BLOBS_PER_BLOCK ;
@@ -427,37 +427,51 @@ impl Backend {
427427 . ok_or ( BlockchainError :: BlockNotFound ) ?;
428428 // update all settings related to the forked block
429429 {
430- let mut env = self . env . write ( ) ;
431- env. cfg . chain_id = fork. chain_id ( ) ;
432-
433- env. block = BlockEnv {
434- number : U256 :: from ( fork_block_number) ,
435- timestamp : U256 :: from ( fork_block. header . timestamp ) ,
436- gas_limit : U256 :: from ( fork_block. header . gas_limit ) ,
437- difficulty : fork_block. header . difficulty ,
438- prevrandao : Some ( fork_block. header . mix_hash . unwrap_or_default ( ) ) ,
439- // Keep previous `coinbase` and `basefee` value
440- coinbase : env. block . coinbase ,
441- basefee : env. block . basefee ,
442- ..env. block . clone ( )
443- } ;
430+ if let Some ( fork_url) = forking. json_rpc_url {
431+ // Set the fork block number
432+ let mut node_config = self . node_config . write ( ) . await ;
433+ node_config. fork_choice = Some ( ForkChoice :: Block ( fork_block_number) ) ;
444434
445- self . time . reset ( env. block . timestamp . to :: < u64 > ( ) ) ;
435+ let mut env = self . env . read ( ) . clone ( ) ;
436+ let ( forked_db, client_fork_config) =
437+ node_config. setup_fork_db_config ( fork_url, & mut env, & self . fees ) . await ;
446438
447- // this is the base fee of the current block, but we need the base fee of
448- // the next block
449- let next_block_base_fee = self . fees . get_next_block_base_fee_per_gas (
450- fork_block. header . gas_used ,
451- fork_block. header . gas_limit ,
452- fork_block. header . base_fee_per_gas . unwrap_or_default ( ) ,
453- ) ;
439+ * self . db . write ( ) . await = Box :: new ( forked_db) ;
440+ let fork = ClientFork :: new ( client_fork_config, Arc :: clone ( & self . db ) ) ;
441+ * self . fork . write ( ) = Some ( fork) ;
442+ * self . env . write ( ) = env;
443+ } else {
444+ let mut env = self . env . write ( ) ;
445+ env. cfg . chain_id = fork. chain_id ( ) ;
446+ env. block = BlockEnv {
447+ number : U256 :: from ( fork_block_number) ,
448+ timestamp : U256 :: from ( fork_block. header . timestamp ) ,
449+ gas_limit : U256 :: from ( fork_block. header . gas_limit ) ,
450+ difficulty : fork_block. header . difficulty ,
451+ prevrandao : Some ( fork_block. header . mix_hash . unwrap_or_default ( ) ) ,
452+ // Keep previous `coinbase` and `basefee` value
453+ coinbase : env. block . coinbase ,
454+ basefee : env. block . basefee ,
455+ ..env. block . clone ( )
456+ } ;
454457
455- self . fees . set_base_fee ( next_block_base_fee) ;
458+ // this is the base fee of the current block, but we need the base fee of
459+ // the next block
460+ let next_block_base_fee = self . fees . get_next_block_base_fee_per_gas (
461+ fork_block. header . gas_used ,
462+ fork_block. header . gas_limit ,
463+ fork_block. header . base_fee_per_gas . unwrap_or_default ( ) ,
464+ ) ;
465+
466+ self . fees . set_base_fee ( next_block_base_fee) ;
467+ }
468+
469+ // reset the time to the timestamp of the forked block
470+ self . time . reset ( fork_block. header . timestamp ) ;
456471
457472 // also reset the total difficulty
458473 self . blockchain . storage . write ( ) . total_difficulty = fork. total_difficulty ( ) ;
459474 }
460-
461475 // reset storage
462476 * self . blockchain . storage . write ( ) = BlockchainStorage :: forked (
463477 fork. block_number ( ) ,
0 commit comments