Skip to content

Commit

Permalink
Switch to alloy (#8)
Browse files Browse the repository at this point in the history
* chore(deps): change ethereum-types to alloy-primitives (#7)

f

f

* Add additional utils (#9)

* add bytes_20_hex

* add bytes_20_hex

* add bytes_20_hex

* add address utils

* add address utils

* add b256 utils

* remove ssz feature flag

* Add tests for B256

---------

Co-authored-by: Kolby Moroz Liebl <31669092+KolbyML@users.noreply.github.com>
Co-authored-by: Eitan Seri-Levi <eserilev@gmail.com>
  • Loading branch information
3 people authored Aug 15, 2024
1 parent 9dbafae commit c74ceb5
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ categories = ["cryptography::cryptocurrencies"]
name = "serde_utils"

[dependencies]
alloy-primitives = { version = "0.7.7", features = ["serde"] }
serde = { version = "1.0.0", features = ["derive"] }
serde_derive = "1.0.0"
serde_json = "1.0.0"
hex = "0.4.3"
ethereum-types = "0.14.1"
34 changes: 34 additions & 0 deletions src/address_hex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use alloy_primitives::Address;
use serde::de::Error;
use serde::{Deserializer, Serializer};

use crate::hex::PrefixedHexVisitor;

pub fn serialize<S>(address: &Address, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut hex_string: String = "0x".to_string();
hex_string.push_str(&hex::encode(&address));

serializer.serialize_str(&hex_string)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<Address, D::Error>
where
D: Deserializer<'de>,
{
let decoded = deserializer.deserialize_str(PrefixedHexVisitor)?;

if decoded.len() != 20 {
return Err(D::Error::custom(format!(
"expected {} bytes for array, got {}",
20,
decoded.len()
)));
}

let mut array = [0; 20];
array.copy_from_slice(&decoded);
Ok(array.into())
}
100 changes: 100 additions & 0 deletions src/b256_hex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use alloy_primitives::B256;
use serde::de::Error;
use serde::{Deserializer, Serializer};

use crate::hex::PrefixedHexVisitor;

pub fn serialize<S>(hash: &B256, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut hex_string: String = "0x".to_string();
hex_string.push_str(&hex::encode(&hash));

serializer.serialize_str(&hex_string)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<B256, D::Error>
where
D: Deserializer<'de>,
{
let decoded = deserializer.deserialize_str(PrefixedHexVisitor)?;

if decoded.len() != 32 {
return Err(D::Error::custom(format!(
"expected {} bytes for array, got {}",
32,
decoded.len()
)));
}

let mut array = [0; 32];
array.copy_from_slice(&decoded);
Ok(array.into())
}

#[cfg(test)]
mod test {
use super::*;
use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
struct Wrapper {
#[serde(with = "super")]
val: B256,
}

#[test]
fn encoding() {
assert_eq!(
&serde_json::to_string(&Wrapper { val: B256::ZERO }).unwrap(),
"\"0x0000000000000000000000000000000000000000000000000000000000000000\""
);
assert_eq!(
&serde_json::to_string(&Wrapper {
val: B256::with_last_byte(0x03)
})
.unwrap(),
"\"0x0000000000000000000000000000000000000000000000000000000000000003\""
);
assert_eq!(
&serde_json::to_string(&Wrapper {
val: B256::repeat_byte(0x03)
})
.unwrap(),
"\"0x0303030303030303030303030303030303030303030303030303030303030303\""
);
}

#[test]
fn decoding() {
assert_eq!(
serde_json::from_str::<Wrapper>(
"\"0x0000000000000000000000000000000000000000000000000000000000000000\""
)
.unwrap(),
Wrapper { val: B256::ZERO },
);
assert_eq!(
serde_json::from_str::<Wrapper>(
"\"0x0000000000000000000000000000000000000000000000000000000000000003\""
)
.unwrap(),
Wrapper {
val: B256::with_last_byte(0x03)
},
);

// Require 0x.
serde_json::from_str::<Wrapper>(
"\"0000000000000000000000000000000000000000000000000000000000000000\"",
)
.unwrap_err();
// Wrong length.
serde_json::from_str::<Wrapper>(
"\"0x00000000000000000000000000000000000000000000000000000000000000\"",
)
.unwrap_err();
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod quoted_int;

pub mod address_hex;
pub mod b256_hex;
pub mod fixed_bytes_hex;
pub mod hex;
pub mod hex_vec;
Expand Down
8 changes: 4 additions & 4 deletions src/quoted_int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//!
//! Quotes can be optional during decoding.
use ethereum_types::U256;
use alloy_primitives::U256;
use serde::{Deserializer, Serializer};
use serde_derive::{Deserialize, Serialize};
use std::convert::TryFrom;
Expand Down Expand Up @@ -177,7 +177,7 @@ pub mod quoted_u256 {
where
E: serde::de::Error,
{
U256::from_dec_str(v).map_err(serde::de::Error::custom)
U256::from_str_radix(v, 10).map_err(serde::de::Error::custom)
}
}

Expand Down Expand Up @@ -209,12 +209,12 @@ mod test {
#[test]
fn u256_with_quotes() {
assert_eq!(
&serde_json::to_string(&WrappedU256(U256::one())).unwrap(),
&serde_json::to_string(&WrappedU256(U256::from(1))).unwrap(),
"\"1\""
);
assert_eq!(
serde_json::from_str::<WrappedU256>("\"1\"").unwrap(),
WrappedU256(U256::one())
WrappedU256(U256::from(1))
);
}

Expand Down
46 changes: 28 additions & 18 deletions src/u256_dec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ethereum_types::U256;
use alloy_primitives::U256;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

pub fn serialize<S>(num: &U256, serializer: S) -> Result<S::Ok, S::Error>
Expand All @@ -13,12 +13,12 @@ where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
U256::from_dec_str(&s).map_err(|e| de::Error::custom(format!("Invalid U256 string: {e}")))
U256::from_str_radix(&s, 10).map_err(|e| de::Error::custom(format!("Invalid U256 string: {e}")))
}

#[cfg(test)]
mod test {
use ethereum_types::U256;
use alloy_primitives::U256;
use serde::{Deserialize, Serialize};
use serde_json;

Expand All @@ -32,37 +32,43 @@ mod test {
#[test]
fn encoding() {
assert_eq!(
&serde_json::to_string(&Wrapper { val: 0.into() }).unwrap(),
&serde_json::to_string(&Wrapper { val: U256::from(0) }).unwrap(),
"\"0\""
);
assert_eq!(
&serde_json::to_string(&Wrapper { val: 1.into() }).unwrap(),
&serde_json::to_string(&Wrapper { val: U256::from(1) }).unwrap(),
"\"1\""
);
assert_eq!(
&serde_json::to_string(&Wrapper { val: 256.into() }).unwrap(),
&serde_json::to_string(&Wrapper {
val: U256::from(256)
})
.unwrap(),
"\"256\""
);
assert_eq!(
&serde_json::to_string(&Wrapper { val: 65.into() }).unwrap(),
&serde_json::to_string(&Wrapper {
val: U256::from(65)
})
.unwrap(),
"\"65\""
);
assert_eq!(
&serde_json::to_string(&Wrapper { val: 1024.into() }).unwrap(),
&serde_json::to_string(&Wrapper {
val: U256::from(1024)
})
.unwrap(),
"\"1024\""
);
assert_eq!(
&serde_json::to_string(&Wrapper {
val: U256::max_value() - 1
val: U256::MAX - U256::from(1)
})
.unwrap(),
"\"115792089237316195423570985008687907853269984665640564039457584007913129639934\""
);
assert_eq!(
&serde_json::to_string(&Wrapper {
val: U256::max_value()
})
.unwrap(),
&serde_json::to_string(&Wrapper { val: U256::MAX }).unwrap(),
"\"115792089237316195423570985008687907853269984665640564039457584007913129639935\""
);
}
Expand All @@ -71,23 +77,27 @@ mod test {
fn decoding() {
assert_eq!(
serde_json::from_str::<Wrapper>("\"0\"").unwrap(),
Wrapper { val: 0.into() },
Wrapper { val: U256::from(0) },
);
assert_eq!(
serde_json::from_str::<Wrapper>("\"65\"").unwrap(),
Wrapper { val: 65.into() },
Wrapper {
val: U256::from(65)
},
);
assert_eq!(
serde_json::from_str::<Wrapper>("\"1024\"").unwrap(),
Wrapper { val: 1024.into() },
Wrapper {
val: U256::from(1024)
},
);
assert_eq!(
serde_json::from_str::<Wrapper>(
"\"115792089237316195423570985008687907853269984665640564039457584007913129639934\""
)
.unwrap(),
Wrapper {
val: U256::max_value() - 1
val: U256::MAX - U256::from(1)
},
);
assert_eq!(
Expand All @@ -96,7 +106,7 @@ mod test {
)
.unwrap(),
Wrapper {
val: U256::max_value()
val: U256::MAX
},
);
serde_json::from_str::<Wrapper>("\"0x0\"").unwrap_err();
Expand Down
Loading

0 comments on commit c74ceb5

Please sign in to comment.