Skip to content

Commit

Permalink
chore: remove redundant code from ethers (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
prestwich authored Apr 2, 2024
1 parent 14d7dc0 commit bfd0fda
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 142 deletions.
4 changes: 1 addition & 3 deletions crates/genesis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ use alloc::collections::BTreeMap;

use alloy_primitives::{Address, Bytes, B256, U256};
use alloy_serde::{
json_u256::{deserialize_json_ttd_opt, deserialize_json_u256},
num::{u64_hex_or_decimal, u64_hex_or_decimal_opt},
storage::deserialize_storage_map,
ttd::deserialize_json_ttd_opt,
};
use serde::{Deserialize, Serialize};

Expand All @@ -49,7 +49,6 @@ pub struct Genesis {
#[serde(with = "u64_hex_or_decimal")]
pub gas_limit: u64,
/// The genesis header difficulty.
#[serde(deserialize_with = "deserialize_json_u256")]
pub difficulty: U256,
/// The genesis header mix hash.
pub mix_hash: B256,
Expand Down Expand Up @@ -219,7 +218,6 @@ pub struct GenesisAccount {
#[serde(skip_serializing_if = "Option::is_none", with = "u64_hex_or_decimal_opt", default)]
pub nonce: Option<u64>,
/// The balance of the account at genesis.
#[serde(deserialize_with = "deserialize_json_u256")]
pub balance: U256,
/// The account's bytecode at genesis.
#[serde(default, skip_serializing_if = "Option::is_none")]
Expand Down
3 changes: 0 additions & 3 deletions crates/rpc-types/src/eth/admin.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Types for the admin api
use alloy_genesis::ChainConfig;
use alloy_primitives::{B256, U256};
use alloy_serde::json_u256::deserialize_json_u256;
use serde::{Deserialize, Serialize};
use std::net::{IpAddr, SocketAddr};

Expand Down Expand Up @@ -60,7 +59,6 @@ pub struct EthProtocolInfo {
/// The eth network version.
pub network: u64,
/// The total difficulty of the host's blockchain.
#[serde(deserialize_with = "deserialize_json_u256")]
pub difficulty: U256,
/// The Keccak hash of the host's genesis block.
pub genesis: B256,
Expand Down Expand Up @@ -115,7 +113,6 @@ pub struct EthInfo {
#[serde(default)]
pub version: u64,
/// The total difficulty of the peer's blockchain.
#[serde(default, deserialize_with = "deserialize_json_u256")]
pub difficulty: U256,
/// The hash of the peer's best known block.
#[serde(default)]
Expand Down
16 changes: 8 additions & 8 deletions crates/serde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@

extern crate alloc;

use alloc::format;

use alloy_primitives::B256;
use serde::Serializer;

pub mod json_u256;
pub use self::json_u256::JsonU256;

/// Helpers for dealing with booleans.
mod bool;
pub use self::bool::*;
Expand All @@ -40,6 +32,14 @@ pub use self::num::*;
pub mod storage;
pub use self::storage::JsonStorageKey;

pub mod ttd;
pub use self::ttd::*;

use alloc::format;
use serde::Serializer;

use alloy_primitives::B256;

/// Serialize a byte vec as a hex string _without_ the "0x" prefix.
///
/// This behaves the same as [`hex::encode`](alloy_primitives::hex::encode).
Expand Down
138 changes: 10 additions & 128 deletions crates/serde/src/json_u256.rs → crates/serde/src/ttd.rs
Original file line number Diff line number Diff line change
@@ -1,126 +1,9 @@
//! Json U256 serde helpers.

#[cfg(not(feature = "std"))]
use alloc::string::String;
use alloc::{fmt, format};
use core::str::FromStr;

use alloy_primitives::U256;
use serde::{
de::{Error, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use serde::{de::Error, Deserialize, Deserializer};
use serde_json::Value;

/// Wrapper around primitive U256 type that also supports deserializing numbers
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
pub struct JsonU256(pub U256);

impl From<JsonU256> for U256 {
fn from(value: JsonU256) -> Self {
value.0
}
}

impl From<U256> for JsonU256 {
fn from(value: U256) -> Self {
JsonU256(value)
}
}

impl fmt::Display for JsonU256 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}

impl Serialize for JsonU256 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(serializer)
}
}

impl<'a> Deserialize<'a> for JsonU256 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'a>,
{
deserializer.deserialize_any(JsonU256Visitor)
}
}

/// Visitor pattern for `JsonU256` deserialization.
struct JsonU256Visitor;

impl<'a> Visitor<'a> for JsonU256Visitor {
type Value = JsonU256;

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a hex encoding or decimal number")
}

fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: Error,
{
Ok(JsonU256(U256::from(value)))
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
let value = u256_from_str(value)?;
Ok(JsonU256(value))
}

fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_str(value.as_ref())
}
}

/// Supports parsing `U256` numbers as strings via [JsonU256]
pub fn deserialize_json_u256<'de, D>(deserializer: D) -> Result<U256, D::Error>
where
D: Deserializer<'de>,
{
let num = JsonU256::deserialize(deserializer)?;
Ok(num.into())
}

/// Supports parsing `U256` numbers as strings via [JsonU256]
pub fn deserialize_json_u256_opt<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
where
D: Deserializer<'de>,
{
let num = Option::<JsonU256>::deserialize(deserializer)?;
Ok(num.map(Into::into))
}

/// Supports deserializing a [U256] from a [String].
pub fn u256_from_str<E>(raw: &str) -> Result<U256, E>
where
E: Error,
{
let value = match raw.len() {
0 => U256::ZERO,
2 if raw.starts_with("0x") => U256::ZERO,
_ if raw.starts_with("0x") => U256::from_str(raw)
.map_err(|e| Error::custom(format!("Parsing JsonU256 as hex failed {raw}: {e}")))?,
_ => U256::from_str_radix(raw, 10).map_err(|e| {
Error::custom(format!("Parsing JsonU256 as decimal failed {raw}: {e:?}"))
})?,
};

Ok(value)
}

/// Supports parsing the TTD as an `Option<u64>`, or `Option<f64>` specifically for the mainnet TTD
/// (5.875e22).
pub fn deserialize_json_ttd_opt<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
Expand All @@ -138,7 +21,7 @@ where
{
let val = match val {
Value::Number(num) => num,
Value::String(raw) => return u256_from_str(&raw),
Value::String(raw) => return raw.parse().map_err(D::Error::custom),
_ => return Err(Error::custom("TTD must be a number or string")),
};

Expand Down Expand Up @@ -179,32 +62,31 @@ where

#[cfg(test)]
mod test {
use super::JsonU256;
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use alloy_primitives::U256;
use serde::{Deserialize, Serialize};

#[test]
fn jsonu256_deserialize() {
let deserialized: Vec<JsonU256> =
let deserialized: Vec<U256> =
serde_json::from_str(r#"["","0", "0x","10",10,"0x10"]"#).unwrap();
assert_eq!(
deserialized,
vec![
JsonU256(U256::ZERO),
JsonU256(U256::ZERO),
JsonU256(U256::ZERO),
JsonU256(U256::from(10)),
JsonU256(U256::from(10)),
JsonU256(U256::from(16)),
U256::ZERO,
U256::ZERO,
U256::ZERO,
U256::from(10),
U256::from(10),
U256::from(16),
]
);
}

#[test]
fn jsonu256_serialize() {
let data = JsonU256(U256::from(16));
let data = U256::from(16);
let serialized = serde_json::to_string(&data).unwrap();

assert_eq!(serialized, r#""0x10""#);
Expand Down

0 comments on commit bfd0fda

Please sign in to comment.