Skip to content

Commit

Permalink
chore: backwardscompat blockenv serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse committed Dec 6, 2023
1 parent 5a4daaf commit 3bf274e
Showing 1 changed file with 93 additions and 5 deletions.
98 changes: 93 additions & 5 deletions crates/evm/core/src/fork/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use std::{
path::PathBuf,
sync::Arc,
};

use url::Url;

pub type StorageInfo = Map<U256, U256>;
Expand Down Expand Up @@ -154,10 +153,10 @@ impl<'de> Deserialize<'de> for BlockchainDbMeta {
where
D: Deserializer<'de>,
{
/// A backwards compatible representation of [revm::CfgEnv]
/// A backwards compatible representation of [revm::primitives::CfgEnv]
///
/// This prevents deserialization errors of cache files caused by breaking changes to the
/// default [revm::CfgEnv], for example enabling an optional feature.
/// default [revm::primitives::CfgEnv], for example enabling an optional feature.
/// By hand rolling deserialize impl we can prevent cache file issues
struct CfgEnvBackwardsCompat {
inner: revm::primitives::CfgEnv,
Expand Down Expand Up @@ -202,11 +201,43 @@ impl<'de> Deserialize<'de> for BlockchainDbMeta {
}
}

/// A backwards compatible representation of [revm::primitives::BlockEnv]
///
/// This prevents deserialization errors of cache files caused by breaking changes to the
/// default [revm::primitives::BlockEnv], for example enabling an optional feature.
/// By hand rolling deserialize impl we can prevent cache file issues
struct BlockEnvBackwardsCompat {
inner: revm::primitives::BlockEnv,
}

impl<'de> Deserialize<'de> for BlockEnvBackwardsCompat {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let mut value = serde_json::Value::deserialize(deserializer)?;

// we check for breaking changes here
if let Some(obj) = value.as_object_mut() {
// additional EIP-4844 fields that are present by default
let key = "blob_excess_gas_and_price";
if !obj.contains_key(key) {
let value = revm::primitives::BlockEnv::default().blob_excess_gas_and_price;
obj.insert(key.to_string(), serde_json::to_value(value).unwrap());
}
}

let cfg_env: revm::primitives::BlockEnv =
serde_json::from_value(value).map_err(serde::de::Error::custom)?;
Ok(Self { inner: cfg_env })
}
}

// custom deserialize impl to not break existing cache files
#[derive(Deserialize)]
struct Meta {
cfg_env: CfgEnvBackwardsCompat,
block_env: revm::primitives::BlockEnv,
block_env: BlockEnvBackwardsCompat,
/// all the hosts used to connect to
#[serde(alias = "host")]
hosts: Hosts,
Expand All @@ -222,7 +253,7 @@ impl<'de> Deserialize<'de> for BlockchainDbMeta {
let Meta { cfg_env, block_env, hosts } = Meta::deserialize(deserializer)?;
Ok(Self {
cfg_env: cfg_env.inner,
block_env,
block_env: block_env.inner,
hosts: match hosts {
Hosts::Multi(hosts) => hosts,
Hosts::Single(host) => BTreeSet::from([host]),
Expand Down Expand Up @@ -533,4 +564,61 @@ mod tests {

let _s = serde_json::to_string(&cache).unwrap();
}

#[test]
fn can_deserialize_cache_post_4844() {
let s = r#"{
"meta": {
"cfg_env": {
"chain_id": 1,
"spec_id": "LATEST",
"perf_analyse_created_bytecodes": "Analyse",
"limit_contract_code_size": 18446744073709551615,
"memory_limit": 134217728,
"disable_block_gas_limit": false,
"disable_eip3607": true,
"disable_base_fee": false,
"optimism": false
},
"block_env": {
"number": "0x11c99bc",
"coinbase": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97",
"timestamp": "0x65627003",
"gas_limit": "0x1c9c380",
"basefee": "0x64288ff1f",
"difficulty": "0xc6b1a299886016dea3865689f8393b9bf4d8f4fe8c0ad25f0058b3569297c057",
"prevrandao": "0xc6b1a299886016dea3865689f8393b9bf4d8f4fe8c0ad25f0058b3569297c057",
"blob_excess_gas_and_price": {
"excess_blob_gas": 0,
"blob_gasprice": 1
}
},
"hosts": [
"eth-mainnet.alchemyapi.io"
]
},
"accounts": {
"0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97": {
"balance": "0x8e0c373cfcdfd0eb",
"nonce": 128912,
"code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
"code": {
"bytecode": "0x000000000000000000000000000000000000000000000000000000000000000000",
"state": {
"Checked": {
"len": 0
}
}
}
}
},
"storage": {},
"block_hashes": {}
}"#;

let cache: JsonBlockCacheData = serde_json::from_str(s).unwrap();
assert_eq!(cache.data.accounts.read().len(), 1);

let _s = serde_json::to_string(&cache).unwrap();
}
}

0 comments on commit 3bf274e

Please sign in to comment.