From 27f6bdc43922128884c1c3c0ccbaa3e300ce6df6 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Fri, 18 Sep 2020 11:00:43 +1000 Subject: [PATCH] Remove serde_utils duplication --- common/eth2/src/types.rs | 2 +- consensus/serde_utils/src/bytes_4_hex.rs | 40 +++ consensus/serde_utils/src/lib.rs | 3 + consensus/serde_utils/src/u32_hex.rs | 28 ++ consensus/serde_utils/src/u8_hex.rs | 25 ++ consensus/types/src/beacon_block_header.rs | 2 +- consensus/types/src/beacon_state.rs | 4 +- consensus/types/src/chain_spec.rs | 24 +- consensus/types/src/enr_fork_id.rs | 4 +- consensus/types/src/fork.rs | 4 +- consensus/types/src/fork_data.rs | 2 +- consensus/types/src/utils/serde_utils.rs | 364 --------------------- 12 files changed, 117 insertions(+), 385 deletions(-) create mode 100644 consensus/serde_utils/src/bytes_4_hex.rs create mode 100644 consensus/serde_utils/src/u32_hex.rs create mode 100644 consensus/serde_utils/src/u8_hex.rs delete mode 100644 consensus/types/src/utils/serde_utils.rs diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index b94f988fd58..679b9258434 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -29,7 +29,7 @@ pub struct GenesisData { #[serde(with = "serde_utils::quoted_u64")] pub genesis_time: u64, pub genesis_validators_root: Hash256, - #[serde(with = "serde_utils::fork_bytes_4")] + #[serde(with = "serde_utils::bytes_4_hex")] pub genesis_fork_version: [u8; 4], } diff --git a/consensus/serde_utils/src/bytes_4_hex.rs b/consensus/serde_utils/src/bytes_4_hex.rs new file mode 100644 index 00000000000..03da1c80c15 --- /dev/null +++ b/consensus/serde_utils/src/bytes_4_hex.rs @@ -0,0 +1,40 @@ +use serde::de::Error; +use serde::{Deserialize, Deserializer, Serializer}; + +const BYTES_LEN: usize = 4; + +pub fn serialize(bytes: &[u8; BYTES_LEN], serializer: S) -> Result +where + S: Serializer, +{ + let mut hex_string: String = "0x".to_string(); + hex_string.push_str(&hex::encode(&bytes)); + + serializer.serialize_str(&hex_string) +} + +pub fn deserialize<'de, D>(deserializer: D) -> Result<[u8; BYTES_LEN], D::Error> +where + D: Deserializer<'de>, +{ + let s: String = Deserialize::deserialize(deserializer)?; + let mut array = [0 as u8; BYTES_LEN]; + + let start = s + .as_str() + .get(2..) + .ok_or_else(|| D::Error::custom("string length too small"))?; + let decoded: Vec = hex::decode(&start).map_err(D::Error::custom)?; + + if decoded.len() != BYTES_LEN { + return Err(D::Error::custom("Fork length too long")); + } + + for (i, item) in array.iter_mut().enumerate() { + if i > decoded.len() { + break; + } + *item = decoded[i]; + } + Ok(array) +} diff --git a/consensus/serde_utils/src/lib.rs b/consensus/serde_utils/src/lib.rs index 2d76869327a..b74071cb786 100644 --- a/consensus/serde_utils/src/lib.rs +++ b/consensus/serde_utils/src/lib.rs @@ -1,3 +1,6 @@ +pub mod bytes_4_hex; pub mod hex; pub mod quoted_u64; pub mod quoted_u64_vec; +pub mod u32_hex; +pub mod u8_hex; diff --git a/consensus/serde_utils/src/u32_hex.rs b/consensus/serde_utils/src/u32_hex.rs new file mode 100644 index 00000000000..c5305c5e8cd --- /dev/null +++ b/consensus/serde_utils/src/u32_hex.rs @@ -0,0 +1,28 @@ +use serde::de::Error; +use serde::{Deserialize, Deserializer, Serializer}; + +pub fn serialize(num: &u32, serializer: S) -> Result +where + S: Serializer, +{ + let mut hex: String = "0x".to_string(); + let bytes = num.to_le_bytes(); + hex.push_str(&hex::encode(&bytes)); + + serializer.serialize_str(&hex) +} + +pub fn deserialize<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let s: String = Deserialize::deserialize(deserializer)?; + let start = s + .as_str() + .get(2..) + .ok_or_else(|| D::Error::custom("string length too small"))?; + + u32::from_str_radix(&start, 16) + .map_err(D::Error::custom) + .map(u32::from_be) +} diff --git a/consensus/serde_utils/src/u8_hex.rs b/consensus/serde_utils/src/u8_hex.rs new file mode 100644 index 00000000000..aadb8a89c6f --- /dev/null +++ b/consensus/serde_utils/src/u8_hex.rs @@ -0,0 +1,25 @@ +use serde::de::Error; +use serde::{Deserialize, Deserializer, Serializer}; + +pub fn serialize(byte: &u8, serializer: S) -> Result +where + S: Serializer, +{ + let mut hex: String = "0x".to_string(); + hex.push_str(&hex::encode(&[*byte])); + + serializer.serialize_str(&hex) +} + +pub fn deserialize<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let s: String = Deserialize::deserialize(deserializer)?; + + let start = match s.as_str().get(2..) { + Some(start) => start, + None => return Err(D::Error::custom("string length too small")), + }; + u8::from_str_radix(&start, 16).map_err(D::Error::custom) +} diff --git a/consensus/types/src/beacon_block_header.rs b/consensus/types/src/beacon_block_header.rs index b815d6ce4ef..708c0e16fe7 100644 --- a/consensus/types/src/beacon_block_header.rs +++ b/consensus/types/src/beacon_block_header.rs @@ -14,7 +14,7 @@ use tree_hash_derive::TreeHash; #[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)] pub struct BeaconBlockHeader { pub slot: Slot, - #[serde(with = "crate::serde_utils::quoted_u64")] + #[serde(with = "serde_utils::quoted_u64")] pub proposer_index: u64, pub parent_root: Hash256, pub state_root: Hash256, diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index a89922fcf61..29528324b98 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -157,7 +157,7 @@ where T: EthSpec, { // Versioning - #[serde(with = "crate::serde_utils::quoted_u64")] + #[serde(with = "serde_utils::quoted_u64")] pub genesis_time: u64, pub genesis_validators_root: Hash256, pub slot: Slot, @@ -174,7 +174,7 @@ where // Ethereum 1.0 chain data pub eth1_data: Eth1Data, pub eth1_data_votes: VariableList, - #[serde(with = "crate::serde_utils::quoted_u64")] + #[serde(with = "serde_utils::quoted_u64")] pub eth1_deposit_index: u64, // Registry diff --git a/consensus/types/src/chain_spec.rs b/consensus/types/src/chain_spec.rs index dfedc860387..f9c1ac6d723 100644 --- a/consensus/types/src/chain_spec.rs +++ b/consensus/types/src/chain_spec.rs @@ -60,9 +60,9 @@ pub struct ChainSpec { /* * Initial Values */ - #[serde(with = "crate::serde_utils::fork_bytes_4")] + #[serde(with = "serde_utils::bytes_4_hex")] pub genesis_fork_version: [u8; 4], - #[serde(with = "crate::serde_utils::u8_hex")] + #[serde(with = "serde_utils::u8_hex")] pub bls_withdrawal_prefix_byte: u8, /* @@ -465,9 +465,9 @@ pub struct YamlConfig { hysteresis_downward_multiplier: u64, hysteresis_upward_multiplier: u64, genesis_slot: u64, - #[serde(with = "crate::serde_utils::fork_bytes_4")] + #[serde(with = "serde_utils::bytes_4_hex")] genesis_fork_version: [u8; 4], - #[serde(with = "crate::serde_utils::u8_hex")] + #[serde(with = "serde_utils::u8_hex")] bls_withdrawal_prefix: u8, seconds_per_slot: u64, min_attestation_inclusion_delay: u64, @@ -483,21 +483,21 @@ pub struct YamlConfig { min_slashing_penalty_quotient: u64, safe_slots_to_update_justified: u64, - #[serde(with = "crate::serde_utils::u32_hex")] + #[serde(with = "serde_utils::u32_hex")] domain_beacon_proposer: u32, - #[serde(with = "crate::serde_utils::u32_hex")] + #[serde(with = "serde_utils::u32_hex")] domain_beacon_attester: u32, - #[serde(with = "crate::serde_utils::u32_hex")] + #[serde(with = "serde_utils::u32_hex")] domain_randao: u32, - #[serde(with = "crate::serde_utils::u32_hex")] + #[serde(with = "serde_utils::u32_hex")] domain_deposit: u32, - #[serde(with = "crate::serde_utils::u32_hex")] + #[serde(with = "serde_utils::u32_hex")] domain_voluntary_exit: u32, - #[serde(with = "crate::serde_utils::u32_hex")] + #[serde(with = "serde_utils::u32_hex")] domain_selection_proof: u32, - #[serde(with = "crate::serde_utils::u32_hex")] + #[serde(with = "serde_utils::u32_hex")] domain_aggregate_and_proof: u32, - #[serde(with = "crate::serde_utils::u32_hex")] + #[serde(with = "serde_utils::u32_hex")] // EthSpec justification_bits_length: u32, max_validators_per_committee: u32, diff --git a/consensus/types/src/enr_fork_id.rs b/consensus/types/src/enr_fork_id.rs index 40a6bbdfee7..008b7933fff 100644 --- a/consensus/types/src/enr_fork_id.rs +++ b/consensus/types/src/enr_fork_id.rs @@ -15,9 +15,9 @@ use tree_hash_derive::TreeHash; Debug, Clone, PartialEq, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, )] pub struct EnrForkId { - #[serde(with = "crate::serde_utils::fork_bytes_4")] + #[serde(with = "serde_utils::bytes_4_hex")] pub fork_digest: [u8; 4], - #[serde(with = "crate::serde_utils::fork_bytes_4")] + #[serde(with = "serde_utils::bytes_4_hex")] pub next_fork_version: [u8; 4], pub next_fork_epoch: Epoch, } diff --git a/consensus/types/src/fork.rs b/consensus/types/src/fork.rs index 2d3b86a45aa..b129271ba0f 100644 --- a/consensus/types/src/fork.rs +++ b/consensus/types/src/fork.rs @@ -24,9 +24,9 @@ use tree_hash_derive::TreeHash; TestRandom, )] pub struct Fork { - #[serde(with = "crate::serde_utils::fork_bytes_4")] + #[serde(with = "serde_utils::bytes_4_hex")] pub previous_version: [u8; 4], - #[serde(with = "crate::serde_utils::fork_bytes_4")] + #[serde(with = "serde_utils::bytes_4_hex")] pub current_version: [u8; 4], pub epoch: Epoch, } diff --git a/consensus/types/src/fork_data.rs b/consensus/types/src/fork_data.rs index 0d02ea22a73..092102f779e 100644 --- a/consensus/types/src/fork_data.rs +++ b/consensus/types/src/fork_data.rs @@ -14,7 +14,7 @@ use tree_hash_derive::TreeHash; Debug, Clone, PartialEq, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, )] pub struct ForkData { - #[serde(with = "crate::serde_utils::fork_bytes_4")] + #[serde(with = "serde_utils::bytes_4_hex")] pub current_version: [u8; 4], pub genesis_validators_root: Hash256, } diff --git a/consensus/types/src/utils/serde_utils.rs b/consensus/types/src/utils/serde_utils.rs deleted file mode 100644 index 24d45a42b9e..00000000000 --- a/consensus/types/src/utils/serde_utils.rs +++ /dev/null @@ -1,364 +0,0 @@ -use serde::de::Error; -use serde::{Deserialize, Deserializer, Serializer}; - -pub const FORK_BYTES_LEN: usize = 4; -pub const GRAFFITI_BYTES_LEN: usize = 32; - -/// Type for a slice of `GRAFFITI_BYTES_LEN` bytes. -/// -/// Gets included inside each `BeaconBlockBody`. -pub type Graffiti = [u8; GRAFFITI_BYTES_LEN]; - -pub fn u8_from_hex_str<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let s: String = Deserialize::deserialize(deserializer)?; - - let start = match s.as_str().get(2..) { - Some(start) => start, - None => return Err(D::Error::custom("string length too small")), - }; - u8::from_str_radix(&start, 16).map_err(D::Error::custom) -} - -#[allow(clippy::trivially_copy_pass_by_ref)] // Serde requires the `byte` to be a ref. -pub fn u8_to_hex_str(byte: &u8, serializer: S) -> Result -where - S: Serializer, -{ - let mut hex: String = "0x".to_string(); - hex.push_str(&hex::encode(&[*byte])); - - serializer.serialize_str(&hex) -} - -pub fn u32_from_hex_str<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let s: String = Deserialize::deserialize(deserializer)?; - let start = s - .as_str() - .get(2..) - .ok_or_else(|| D::Error::custom("string length too small"))?; - - u32::from_str_radix(&start, 16) - .map_err(D::Error::custom) - .map(u32::from_be) -} - -#[allow(clippy::trivially_copy_pass_by_ref)] // Serde requires the `num` to be a ref. -pub fn u32_to_hex_str(num: &u32, serializer: S) -> Result -where - S: Serializer, -{ - let mut hex: String = "0x".to_string(); - let bytes = num.to_le_bytes(); - hex.push_str(&hex::encode(&bytes)); - - serializer.serialize_str(&hex) -} - -pub fn fork_from_hex_str<'de, D>(deserializer: D) -> Result<[u8; FORK_BYTES_LEN], D::Error> -where - D: Deserializer<'de>, -{ - let s: String = Deserialize::deserialize(deserializer)?; - let mut array = [0 as u8; FORK_BYTES_LEN]; - - let start = s - .as_str() - .get(2..) - .ok_or_else(|| D::Error::custom("string length too small"))?; - let decoded: Vec = hex::decode(&start).map_err(D::Error::custom)?; - - if decoded.len() != FORK_BYTES_LEN { - return Err(D::Error::custom("Fork length too long")); - } - - for (i, item) in array.iter_mut().enumerate() { - if i > decoded.len() { - break; - } - *item = decoded[i]; - } - Ok(array) -} - -#[allow(clippy::trivially_copy_pass_by_ref)] -pub fn fork_to_hex_str(bytes: &[u8; FORK_BYTES_LEN], serializer: S) -> Result -where - S: Serializer, -{ - let mut hex_string: String = "0x".to_string(); - hex_string.push_str(&hex::encode(&bytes)); - - serializer.serialize_str(&hex_string) -} - -pub fn graffiti_to_hex_str(bytes: &Graffiti, serializer: S) -> Result -where - S: Serializer, -{ - let mut hex_string: String = "0x".to_string(); - hex_string.push_str(&hex::encode(&bytes)); - - serializer.serialize_str(&hex_string) -} - -pub fn graffiti_from_hex_str<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let s: String = Deserialize::deserialize(deserializer)?; - let mut array = Graffiti::default(); - - let start = s - .as_str() - .get(2..) - .ok_or_else(|| D::Error::custom("string length too small"))?; - let decoded: Vec = hex::decode(&start).map_err(D::Error::custom)?; - - if decoded.len() > GRAFFITI_BYTES_LEN { - return Err(D::Error::custom("Fork length too long")); - } - - for (i, item) in array.iter_mut().enumerate() { - if i > decoded.len() { - break; - } - *item = decoded[i]; - } - Ok(array) -} - -pub mod u32_hex { - use super::*; - - pub fn serialize(num: &u32, serializer: S) -> Result - where - S: Serializer, - { - let mut hex: String = "0x".to_string(); - let bytes = num.to_le_bytes(); - hex.push_str(&hex::encode(&bytes)); - - serializer.serialize_str(&hex) - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s: String = Deserialize::deserialize(deserializer)?; - let start = s - .as_str() - .get(2..) - .ok_or_else(|| D::Error::custom("string length too small"))?; - - u32::from_str_radix(&start, 16) - .map_err(D::Error::custom) - .map(u32::from_be) - } -} - -pub mod u8_hex { - use super::*; - - pub fn serialize(byte: &u8, serializer: S) -> Result - where - S: Serializer, - { - let mut hex: String = "0x".to_string(); - hex.push_str(&hex::encode(&[*byte])); - - serializer.serialize_str(&hex) - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s: String = Deserialize::deserialize(deserializer)?; - - let start = match s.as_str().get(2..) { - Some(start) => start, - None => return Err(D::Error::custom("string length too small")), - }; - u8::from_str_radix(&start, 16).map_err(D::Error::custom) - } -} - -pub mod fork_bytes_4 { - use super::*; - - pub fn serialize(bytes: &[u8; FORK_BYTES_LEN], serializer: S) -> Result - where - S: Serializer, - { - let mut hex_string: String = "0x".to_string(); - hex_string.push_str(&hex::encode(&bytes)); - - serializer.serialize_str(&hex_string) - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result<[u8; FORK_BYTES_LEN], D::Error> - where - D: Deserializer<'de>, - { - let s: String = Deserialize::deserialize(deserializer)?; - let mut array = [0 as u8; FORK_BYTES_LEN]; - - let start = s - .as_str() - .get(2..) - .ok_or_else(|| D::Error::custom("string length too small"))?; - let decoded: Vec = hex::decode(&start).map_err(D::Error::custom)?; - - if decoded.len() != FORK_BYTES_LEN { - return Err(D::Error::custom("Fork length too long")); - } - - for (i, item) in array.iter_mut().enumerate() { - if i > decoded.len() { - break; - } - *item = decoded[i]; - } - Ok(array) - } -} - -pub mod graffiti { - use super::*; - - pub fn serialize(bytes: &Graffiti, serializer: S) -> Result - where - S: Serializer, - { - let mut hex_string: String = "0x".to_string(); - hex_string.push_str(&hex::encode(&bytes)); - - serializer.serialize_str(&hex_string) - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s: String = Deserialize::deserialize(deserializer)?; - let mut array = Graffiti::default(); - - let start = s - .as_str() - .get(2..) - .ok_or_else(|| D::Error::custom("string length too small"))?; - let decoded: Vec = hex::decode(&start).map_err(D::Error::custom)?; - - if decoded.len() > GRAFFITI_BYTES_LEN { - return Err(D::Error::custom("Fork length too long")); - } - - for (i, item) in array.iter_mut().enumerate() { - if i > decoded.len() { - break; - } - *item = decoded[i]; - } - Ok(array) - } -} - -pub mod quoted { - use super::*; - - pub struct QuotedIntVisitor; - impl<'a> serde::de::Visitor<'a> for QuotedIntVisitor { - type Value = u64; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(formatter, "a quoted or unquoted integer") - } - - fn visit_str(self, s: &str) -> Result - where - E: serde::de::Error, - { - let s = if s.len() > 2 && s.starts_with("\"") && s.ends_with("\"") { - &s[1..s.len() - 1] - } else { - s - }; - s.parse().map_err(serde::de::Error::custom) - } - } - - pub fn serialize(value: &u64, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&format!("{}", value)) - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_any(QuotedIntVisitor) - } -} - -pub mod quoted_u64_vec { - use super::*; - use serde::ser::SerializeSeq; - use serde_derive::{Deserialize, Serialize}; - - #[derive(Serialize, Deserialize)] - #[serde(transparent)] - pub struct QuotedIntWrapper { - #[serde(with = "super::quoted")] - int: u64, - } - - pub struct QuotedIntVecVisitor; - impl<'a> serde::de::Visitor<'a> for QuotedIntVecVisitor { - type Value = Vec; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(formatter, "a list of quoted or unquoted integers") - } - - fn visit_seq(self, mut seq: A) -> Result - where - A: serde::de::SeqAccess<'a>, - { - let mut vec = vec![]; - - while let Some(val) = seq.next_element()? { - let val: QuotedIntWrapper = val; - vec.push(val.int); - } - - Ok(vec) - } - } - - pub fn serialize(value: &Vec, serializer: S) -> Result - where - S: Serializer, - { - let mut seq = serializer.serialize_seq(Some(value.len()))?; - for &int in value { - seq.serialize_element(&QuotedIntWrapper { int })?; - } - seq.end() - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - deserializer.deserialize_any(QuotedIntVecVisitor) - } -}