diff --git a/crates/rpc/rpc-types/src/eth/block.rs b/crates/rpc/rpc-types/src/eth/block.rs index 6db49cb7d..6b478ae3a 100644 --- a/crates/rpc/rpc-types/src/eth/block.rs +++ b/crates/rpc/rpc-types/src/eth/block.rs @@ -257,22 +257,37 @@ impl Serialize for Rich { /// BlockOverrides is a set of header fields to override. #[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)] #[serde(default, rename_all = "camelCase", deny_unknown_fields)] -#[allow(missing_docs)] pub struct BlockOverrides { - #[serde(default, skip_serializing_if = "Option::is_none")] + /// Overrides the block number. + /// + /// For `eth_callMany` this will be the block number of the first simulated block. Each + /// following block increments its block number by 1 + // Note: geth uses `number`, erigon uses `blockNumber` + #[serde(default, skip_serializing_if = "Option::is_none", alias = "blockNumber")] pub number: Option, + /// Overrides the difficulty of the block. #[serde(default, skip_serializing_if = "Option::is_none")] pub difficulty: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] + /// Overrides the timestamp of the block. + // Note: geth uses `time`, erigon uses `timestamp` + #[serde(default, skip_serializing_if = "Option::is_none", alias = "timestamp")] pub time: Option, + /// Overrides the gas limit of the block. #[serde(default, skip_serializing_if = "Option::is_none")] pub gas_limit: Option, + /// Overrides the coinbase address of the block. #[serde(default, skip_serializing_if = "Option::is_none")] pub coinbase: Option
, + /// Overrides the prevrandao of the block. #[serde(default, skip_serializing_if = "Option::is_none")] pub random: Option, + /// Overrides the basefee of the block. #[serde(default, skip_serializing_if = "Option::is_none")] pub base_fee: Option, + /// A dictionary that maps blockNumber to a user-defined hash. It could be queried from the + /// solidity opcode BLOCKHASH. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub block_hash: Option>, } #[cfg(test)] @@ -380,4 +395,10 @@ mod tests { let deserialized: Block = serde_json::from_str(&serialized).unwrap(); assert_eq!(block, deserialized); } + + #[test] + fn block_overrides() { + let s = r#"{"blockNumber": "0xe39dd0"}"#; + let _overrides = serde_json::from_str::(s).unwrap(); + } } diff --git a/crates/rpc/rpc/src/eth/revm_utils.rs b/crates/rpc/rpc/src/eth/revm_utils.rs index b4356e5f9..eda2f1e2c 100644 --- a/crates/rpc/rpc/src/eth/revm_utils.rs +++ b/crates/rpc/rpc/src/eth/revm_utils.rs @@ -217,7 +217,12 @@ where } // apply block overrides - if let Some(block_overrides) = overrides.block { + if let Some(mut block_overrides) = overrides.block { + if let Some(block_hashes) = block_overrides.block_hash.take() { + // override block hashes + db.block_hashes + .extend(block_hashes.into_iter().map(|(num, hash)| (U256::from(num), hash))) + } apply_block_overrides(*block_overrides, &mut env.block); } @@ -400,8 +405,16 @@ impl CallFees { /// Applies the given block overrides to the env fn apply_block_overrides(overrides: BlockOverrides, env: &mut BlockEnv) { - let BlockOverrides { number, difficulty, time, gas_limit, coinbase, random, base_fee } = - overrides; + let BlockOverrides { + number, + difficulty, + time, + gas_limit, + coinbase, + random, + base_fee, + block_hash: _, + } = overrides; if let Some(number) = number { env.number = number;