use mega_evm::{revm::primitives::U256, BucketHasher, TestExternalEnvs};
use serde::{Deserialize, Serialize};
use std::convert::Infallible;
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MegaEnv {
#[serde(default)]
pub bucket_capacities: Vec<(u32, u64)>,
#[serde(default)]
pub oracle_storage: Vec<(U256, U256)>,
}
impl MegaEnv {
pub fn validate(&self) -> Result<(), String> {
for &(bucket_id, capacity) in &self.bucket_capacities {
if capacity < mega_evm::MIN_BUCKET_SIZE as u64 {
return Err(format!(
"megaEnv bucket {bucket_id} capacity {capacity} is below \
MIN_BUCKET_SIZE ({})",
mega_evm::MIN_BUCKET_SIZE
));
}
}
Ok(())
}
pub fn to_external_envs<H: BucketHasher>(&self) -> TestExternalEnvs<Infallible, H> {
let mut envs = TestExternalEnvs::new();
for &(bucket_id, capacity) in &self.bucket_capacities {
envs = envs.with_bucket_capacity(bucket_id, capacity);
}
for &(slot, value) in &self.oracle_storage {
envs = envs.with_oracle_storage(slot, value);
}
envs
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mega_env_json_roundtrip() {
let env = MegaEnv {
bucket_capacities: vec![(1, 100), (42, 2_000_000)],
oracle_storage: vec![(U256::from(0), U256::from(7)), (U256::from(9), U256::MAX)],
};
let json = serde_json::to_string(&env).expect("serialize");
let back: MegaEnv = serde_json::from_str(&json).expect("deserialize");
assert_eq!(env, back);
}
#[test]
fn test_mega_env_camel_case_field_names() {
let env = MegaEnv {
bucket_capacities: vec![(1, 100)],
oracle_storage: vec![(U256::from(0), U256::from(7))],
};
let value = serde_json::to_value(&env).expect("serialize");
assert!(value.get("bucketCapacities").is_some(), "expected camelCase bucketCapacities");
assert!(value.get("oracleStorage").is_some(), "expected camelCase oracleStorage");
}
#[test]
fn test_mega_env_empty_fields_default() {
let env: MegaEnv = serde_json::from_str("{}").expect("deserialize empty");
assert!(env.bucket_capacities.is_empty());
assert!(env.oracle_storage.is_empty());
}
}