diff --git a/crates/eips/src/eip2930.rs b/crates/eips/src/eip2930.rs index a53715a963a..2dd78fc3ecc 100644 --- a/crates/eips/src/eip2930.rs +++ b/crates/eips/src/eip2930.rs @@ -30,6 +30,8 @@ pub struct AccessListItem { strategy = "proptest::collection::vec(proptest::arbitrary::any::(), 0..=20)" ) )] + // In JSON, we have to accept `null` for storage key, which is interpreted as an empty array. + #[cfg_attr(feature = "serde", serde(deserialize_with = "alloy_serde::null_as_default"))] pub storage_keys: Vec, } @@ -166,8 +168,24 @@ pub struct AccessListWithGasUsed { #[cfg(all(test, feature = "serde"))] mod tests { + use serde_json::json; + use super::*; + #[test] + fn access_list_null_storage_keys() { + let json = json!([ + { + "address": "0x81b7bdd5b89c90b63f604fc7cdd17035cb939707", + "storageKeys": null, + } + ]); + + let access_list = serde_json::from_value::(json).unwrap(); + assert_eq!(access_list.len(), 1); + assert_eq!(access_list[0].storage_keys, Vec::::default()); + } + #[test] fn access_list_serde() { let list = AccessList(vec![ diff --git a/crates/serde/src/lib.rs b/crates/serde/src/lib.rs index ee8bb06fd15..633216fc8b8 100644 --- a/crates/serde/src/lib.rs +++ b/crates/serde/src/lib.rs @@ -18,6 +18,9 @@ use serde::Serializer; mod bool; pub use self::bool::*; +mod optional; +pub use self::optional::*; + #[cfg_attr(not(test), deprecated = "use `quantity::{self, opt, vec}` instead")] pub mod num; #[allow(deprecated)] diff --git a/crates/serde/src/optional.rs b/crates/serde/src/optional.rs new file mode 100644 index 00000000000..5ef3288461c --- /dev/null +++ b/crates/serde/src/optional.rs @@ -0,0 +1,13 @@ +//! Serde functions for encoding optional values. +use serde::{Deserialize, Deserializer}; + +/// For use with serde's `deserialize_with` on a sequence that must be +/// deserialized as a single but optional (i.e. possibly `null`) value. +pub fn null_as_default<'de, T, D>(deserializer: D) -> Result +where + T: Deserialize<'de> + Default, + D: Deserializer<'de>, +{ + let s: Option = Deserialize::deserialize(deserializer)?; + Ok(s.unwrap_or_default()) +}