Skip to content

Commit

Permalink
refactor(hermes): wrap hex::serde for deserializing
Browse files Browse the repository at this point in the history
  • Loading branch information
Reisen committed Sep 25, 2023
1 parent 26b8dcd commit 80fe023
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 52 deletions.
2 changes: 1 addition & 1 deletion hermes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dashmap = { version = "5.4.0" }
derive_more = { version = "0.99.17" }
env_logger = { version = "0.10.0" }
futures = { version = "0.3.28" }
hex = { version = "0.4.3" }
hex = { version = "0.4.3", features = ["serde"] }
humantime = { version = "2.1.0" }
lazy_static = { version = "1.4.0" }
libc = { version = "0.2.140" }
Expand Down
10 changes: 6 additions & 4 deletions hermes/src/api/rest/get_vaa_ccip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use {
UnixTimestamp,
},
api::rest::RestError,
impl_deserialize_for_hex_string_wrapper,
},
anyhow::Result,
axum::{
Expand All @@ -17,16 +16,19 @@ use {
DerefMut,
},
pyth_sdk::PriceIdentifier,
serde::{
Deserialize,
Serialize,
},
serde_qs::axum::QsQuery,
utoipa::{
IntoParams,
ToSchema,
},
};

#[derive(Debug, Clone, Deref, DerefMut, ToSchema)]
pub struct GetVaaCcipInput([u8; 40]);
impl_deserialize_for_hex_string_wrapper!(GetVaaCcipInput, 40);
#[derive(Clone, Debug, Deref, DerefMut, Deserialize, Serialize, ToSchema)]
pub struct GetVaaCcipInput(#[serde(with = "crate::serde::hex")] [u8; 40]);

#[derive(Debug, serde::Deserialize, IntoParams)]
#[into_params(parameter_in=Query)]
Expand Down
11 changes: 6 additions & 5 deletions hermes/src/api/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use {
UnixTimestamp,
},
doc_examples,
impl_deserialize_for_hex_string_wrapper,
},
base64::{
engine::general_purpose::STANDARD as base64_standard_engine,
Expand All @@ -21,6 +20,10 @@ use {
DerefMut,
},
pyth_sdk::PriceIdentifier,
serde::{
Deserialize,
Serialize,
},
utoipa::ToSchema,
wormhole_sdk::Chain,
};
Expand All @@ -33,11 +36,9 @@ use {
/// * e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43
///
/// See https://pyth.network/developers/price-feed-ids for a list of all price feed ids.
#[derive(Debug, Clone, Deref, DerefMut, ToSchema)]
#[derive(Clone, Debug, Deref, DerefMut, Deserialize, Serialize, ToSchema)]
#[schema(value_type=String, example=doc_examples::price_feed_id_example)]
pub struct PriceIdInput([u8; 32]);
// TODO: Use const generics instead of macro.
impl_deserialize_for_hex_string_wrapper!(PriceIdInput, 32);
pub struct PriceIdInput(#[serde(with = "crate::serde::hex")] [u8; 32]);

impl From<PriceIdInput> for PriceIdentifier {
fn from(id: PriceIdInput) -> Self {
Expand Down
41 changes: 0 additions & 41 deletions hermes/src/macros.rs

This file was deleted.

2 changes: 1 addition & 1 deletion hermes/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ mod aggregate;
mod api;
mod config;
mod doc_examples;
mod macros;
mod network;
mod serde;
mod state;
mod wormhole;

Expand Down
83 changes: 83 additions & 0 deletions hermes/src/serde.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
pub mod hex {
use {
hex::FromHex,
serde::{
de::IntoDeserializer,
Deserialize,
Deserializer,
Serializer,
},
};

pub fn serialize<S, const N: usize>(b: &[u8; N], s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
s.serialize_str(hex::encode(b).as_str())
}

pub fn deserialize<'de, D, R>(d: D) -> Result<R, D::Error>
where
D: Deserializer<'de>,
R: FromHex,
<R as hex::FromHex>::Error: std::fmt::Display,
{
let s: String = Deserialize::deserialize(d)?;
let p = s.starts_with("0x") || s.starts_with("0X");
let s = if p { &s[2..] } else { &s[..] };
hex::serde::deserialize(s.into_deserializer())
}

#[cfg(test)]
mod tests {
use serde::Deserialize;

#[derive(Debug, Deserialize, PartialEq)]
struct H(#[serde(with = "super")] [u8; 32]);

#[test]
fn test_deserialize() {
let e = H([
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67,
0x89, 0xab, 0xcd, 0xef,
]);

let l = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"";
let u = "\"0x0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"";
assert_eq!(serde_json::from_str::<H>(l).unwrap(), e);
assert_eq!(serde_json::from_str::<H>(u).unwrap(), e);

let l = "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"";
let u = "\"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"";
assert_eq!(serde_json::from_str::<H>(l).unwrap(), e);
assert_eq!(serde_json::from_str::<H>(u).unwrap(), e);
}

#[test]
fn test_deserialize_invalid_length() {
let l = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde\"";
let u = "\"0X0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE\"";
assert!(serde_json::from_str::<H>(l).is_err());
assert!(serde_json::from_str::<H>(u).is_err());

let l = "\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde\"";
let u = "\"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE\"";
assert!(serde_json::from_str::<H>(l).is_err());
assert!(serde_json::from_str::<H>(u).is_err());
}

#[test]
fn test_deserialize_invalid_hex() {
let l = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg\"";
let u = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg\"";
assert!(serde_json::from_str::<H>(l).is_err());
assert!(serde_json::from_str::<H>(u).is_err());

let l = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg\"";
let u = "\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdeg\"";
assert!(serde_json::from_str::<H>(l).is_err());
assert!(serde_json::from_str::<H>(u).is_err());
}
}
}

0 comments on commit 80fe023

Please sign in to comment.