Skip to content

Commit

Permalink
Merge pull request #424 from dusk-network/neotamandua/hex_serde
Browse files Browse the repository at this point in the history
uplink: change event data to hex serialization instead of base64
  • Loading branch information
Neotamandua authored Feb 20, 2025
2 parents 2e21be3 + b9018f3 commit 3cca439
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 92 deletions.
5 changes: 5 additions & 0 deletions piecrust-uplink/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Add `TryFrom<String>` trait impl for `ContractId` [#420]

### Changed

- Change serialization of event data field from base64 to hex [#425]

## [0.17.3] - 2024-12-19

## [0.17.2] - 2024-12-17
Expand Down Expand Up @@ -230,6 +234,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- First `piecrust-uplink` release

<!-- ISSUES -->
[#425]: https://github.com/dusk-network/piecrust/issues/425
[#420]: https://github.com/dusk-network/piecrust/issues/420
[#414]: https://github.com/dusk-network/piecrust/issues/414
[#375]: https://github.com/dusk-network/piecrust/issues/375
Expand Down
3 changes: 1 addition & 2 deletions piecrust-uplink/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ bytecheck = { version = "0.6", default-features = false }
dlmalloc = { version = "0.2", optional = true, features = ["global"] }
serde = { version = "1.0", optional = true }
hex = { version = "0.4", default-features = false, features = ["alloc"]}
base64 = { version = "0.22", optional = true }
serde_json = { version = "1.0", optional = true }

[dev-dependencies]
Expand All @@ -27,7 +26,7 @@ rand = "0.8"
[features]
abi = []
debug = []
serde = ["dep:serde", "serde_json", "base64"]
serde = ["dep:serde", "serde_json", "hex/serde"]

[package.metadata.docs.rs]
all-features = true
Expand Down
107 changes: 17 additions & 90 deletions piecrust-uplink/src/serde_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use alloc::format;
use alloc::string::String;

use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
use base64::Engine;
use serde::de::{Error as SerdeError, MapAccess, Visitor};
use serde::ser::SerializeStruct;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

Expand All @@ -20,26 +16,16 @@ impl Serialize for ContractId {
&self,
serializer: S,
) -> Result<S::Ok, S::Error> {
let s = hex::encode(self.to_bytes());
serializer.serialize_str(&s)
hex::serde::serialize(&self.to_bytes(), serializer)
}
}

impl<'de> Deserialize<'de> for ContractId {
fn deserialize<D: Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
let s = String::deserialize(deserializer)?;
let decoded = hex::decode(&s).map_err(SerdeError::custom)?;
let decoded_len = decoded.len();
let byte_length_str = format!("{CONTRACT_ID_BYTES}");
let bytes: [u8; CONTRACT_ID_BYTES] =
decoded.try_into().map_err(|_| {
SerdeError::invalid_length(
decoded_len,
&byte_length_str.as_str(),
)
})?;
hex::serde::deserialize(deserializer)?;
Ok(bytes.into())
}
}
Expand All @@ -52,8 +38,7 @@ impl Serialize for Event {
let mut struct_ser = serializer.serialize_struct("Event", 3)?;
struct_ser.serialize_field("source", &self.source)?;
struct_ser.serialize_field("topic", &self.topic)?;
struct_ser
.serialize_field("data", &BASE64_STANDARD.encode(&self.data))?;
struct_ser.serialize_field("data", &hex::encode(&self.data))?;
struct_ser.end()
}
}
Expand All @@ -62,79 +47,21 @@ impl<'de> Deserialize<'de> for Event {
fn deserialize<D: Deserializer<'de>>(
deserializer: D,
) -> Result<Self, D::Error> {
struct StructVisitor;

impl<'de> Visitor<'de> for StructVisitor {
type Value = Event;

fn expecting(
&self,
formatter: &mut alloc::fmt::Formatter,
) -> alloc::fmt::Result {
formatter
.write_str("a struct with fields: source, topic, and data")
}

fn visit_map<A: MapAccess<'de>>(
self,
mut map: A,
) -> Result<Self::Value, A::Error> {
let (mut source, mut topic, mut data) = (None, None, None);
while let Some(key) = map.next_key()? {
match key {
"source" => {
if source.is_some() {
return Err(SerdeError::duplicate_field(
"source",
));
}
source = Some(map.next_value()?);
}
"topic" => {
if topic.is_some() {
return Err(SerdeError::duplicate_field(
"topic",
));
}
topic = Some(map.next_value()?);
}
"data" => {
if data.is_some() {
return Err(SerdeError::duplicate_field(
"data",
));
}
data = Some(map.next_value()?);
}
field => {
return Err(SerdeError::unknown_field(
field,
&["source", "topic", "data"],
))
}
};
}
let data: String =
data.ok_or_else(|| SerdeError::missing_field("data"))?;
let data = BASE64_STANDARD.decode(data).map_err(|e| {
SerdeError::custom(format!(
"failed to base64 decode Event data: {e}"
))
})?;
Ok(Event {
source: source
.ok_or_else(|| SerdeError::missing_field("source"))?,
topic: topic
.ok_or_else(|| SerdeError::missing_field("topic"))?,
data,
})
}
#[derive(Deserialize)]
struct IntermediateEvent {
source: ContractId,
topic: String,
data: String,
}

deserializer.deserialize_struct(
"Event",
&["source", "topic", "data"],
StructVisitor,
)
let intermediate: IntermediateEvent =
Deserialize::deserialize(deserializer)?;
let data = hex::decode(&intermediate.data)
.map_err(serde::de::Error::custom)?;
Ok(Event {
source: intermediate.source,
topic: intermediate.topic,
data,
})
}
}

0 comments on commit 3cca439

Please sign in to comment.