@@ -10,7 +10,7 @@ use foundry_cheatcodes::{
1010 Vm :: {
1111 chainIdCall, coinbaseCall, dealCall, etchCall, getNonce_0Call, loadCall, polkadotSkipCall,
1212 pvmCall, resetNonceCall, revertToStateAndDeleteCall, revertToStateCall, rollCall,
13- setNonceCall, setNonceUnsafeCall, snapshotStateCall, storeCall, warpCall,
13+ setBlockhashCall , setNonceCall, setNonceUnsafeCall, snapshotStateCall, storeCall, warpCall,
1414 } ,
1515 journaled_account, precompile_error,
1616} ;
@@ -380,6 +380,25 @@ impl CheatcodeInspectorStrategyRunner for PvmCheatcodeInspectorStrategyRunner {
380380
381381 cheatcode. dyn_apply ( ccx, executor)
382382 }
383+ t if is :: < setBlockhashCall > ( t) => {
384+ let & setBlockhashCall { blockNumber, blockHash } =
385+ cheatcode. as_any ( ) . downcast_ref ( ) . unwrap ( ) ;
386+
387+ tracing:: info!( cheatcode = ?cheatcode. as_debug( ) , using_pvm = ?using_pvm) ;
388+
389+ // Validate blockNumber is not in the future
390+ let current_block = ctx. externalities . get_block_number ( ) ;
391+ if blockNumber > current_block {
392+ return Err ( foundry_cheatcodes:: Error :: from (
393+ "block number must be less than or equal to the current block number" ,
394+ ) ) ;
395+ }
396+
397+ let block_num_u64 = blockNumber. to :: < u64 > ( ) ;
398+ ctx. externalities . set_blockhash ( block_num_u64, blockHash) ;
399+
400+ cheatcode. dyn_apply ( ccx, executor)
401+ }
383402 t if using_pvm && is :: < etchCall > ( t) => {
384403 let etchCall { target, newRuntimeBytecode } =
385404 cheatcode. as_any ( ) . downcast_ref ( ) . unwrap ( ) ;
0 commit comments