Skip to content

Commit 3cca439

Browse files
authored
Merge pull request #424 from dusk-network/neotamandua/hex_serde
uplink: change event data to hex serialization instead of base64
2 parents 2e21be3 + b9018f3 commit 3cca439

File tree

3 files changed

+23
-92
lines changed

3 files changed

+23
-92
lines changed

piecrust-uplink/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

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

14+
### Changed
15+
16+
- Change serialization of event data field from base64 to hex [#425]
17+
1418
## [0.17.3] - 2024-12-19
1519

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

232236
<!-- ISSUES -->
237+
[#425]: https://github.com/dusk-network/piecrust/issues/425
233238
[#420]: https://github.com/dusk-network/piecrust/issues/420
234239
[#414]: https://github.com/dusk-network/piecrust/issues/414
235240
[#375]: https://github.com/dusk-network/piecrust/issues/375

piecrust-uplink/Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ bytecheck = { version = "0.6", default-features = false }
1818
dlmalloc = { version = "0.2", optional = true, features = ["global"] }
1919
serde = { version = "1.0", optional = true }
2020
hex = { version = "0.4", default-features = false, features = ["alloc"]}
21-
base64 = { version = "0.22", optional = true }
2221
serde_json = { version = "1.0", optional = true }
2322

2423
[dev-dependencies]
@@ -27,7 +26,7 @@ rand = "0.8"
2726
[features]
2827
abi = []
2928
debug = []
30-
serde = ["dep:serde", "serde_json", "base64"]
29+
serde = ["dep:serde", "serde_json", "hex/serde"]
3130

3231
[package.metadata.docs.rs]
3332
all-features = true

piecrust-uplink/src/serde_support.rs

+17-90
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@
44
//
55
// Copyright (c) DUSK NETWORK. All rights reserved.
66

7-
use alloc::format;
87
use alloc::string::String;
98

10-
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
11-
use base64::Engine;
12-
use serde::de::{Error as SerdeError, MapAccess, Visitor};
139
use serde::ser::SerializeStruct;
1410
use serde::{Deserialize, Deserializer, Serialize, Serializer};
1511

@@ -20,26 +16,16 @@ impl Serialize for ContractId {
2016
&self,
2117
serializer: S,
2218
) -> Result<S::Ok, S::Error> {
23-
let s = hex::encode(self.to_bytes());
24-
serializer.serialize_str(&s)
19+
hex::serde::serialize(&self.to_bytes(), serializer)
2520
}
2621
}
2722

2823
impl<'de> Deserialize<'de> for ContractId {
2924
fn deserialize<D: Deserializer<'de>>(
3025
deserializer: D,
3126
) -> Result<Self, D::Error> {
32-
let s = String::deserialize(deserializer)?;
33-
let decoded = hex::decode(&s).map_err(SerdeError::custom)?;
34-
let decoded_len = decoded.len();
35-
let byte_length_str = format!("{CONTRACT_ID_BYTES}");
3627
let bytes: [u8; CONTRACT_ID_BYTES] =
37-
decoded.try_into().map_err(|_| {
38-
SerdeError::invalid_length(
39-
decoded_len,
40-
&byte_length_str.as_str(),
41-
)
42-
})?;
28+
hex::serde::deserialize(deserializer)?;
4329
Ok(bytes.into())
4430
}
4531
}
@@ -52,8 +38,7 @@ impl Serialize for Event {
5238
let mut struct_ser = serializer.serialize_struct("Event", 3)?;
5339
struct_ser.serialize_field("source", &self.source)?;
5440
struct_ser.serialize_field("topic", &self.topic)?;
55-
struct_ser
56-
.serialize_field("data", &BASE64_STANDARD.encode(&self.data))?;
41+
struct_ser.serialize_field("data", &hex::encode(&self.data))?;
5742
struct_ser.end()
5843
}
5944
}
@@ -62,79 +47,21 @@ impl<'de> Deserialize<'de> for Event {
6247
fn deserialize<D: Deserializer<'de>>(
6348
deserializer: D,
6449
) -> Result<Self, D::Error> {
65-
struct StructVisitor;
66-
67-
impl<'de> Visitor<'de> for StructVisitor {
68-
type Value = Event;
69-
70-
fn expecting(
71-
&self,
72-
formatter: &mut alloc::fmt::Formatter,
73-
) -> alloc::fmt::Result {
74-
formatter
75-
.write_str("a struct with fields: source, topic, and data")
76-
}
77-
78-
fn visit_map<A: MapAccess<'de>>(
79-
self,
80-
mut map: A,
81-
) -> Result<Self::Value, A::Error> {
82-
let (mut source, mut topic, mut data) = (None, None, None);
83-
while let Some(key) = map.next_key()? {
84-
match key {
85-
"source" => {
86-
if source.is_some() {
87-
return Err(SerdeError::duplicate_field(
88-
"source",
89-
));
90-
}
91-
source = Some(map.next_value()?);
92-
}
93-
"topic" => {
94-
if topic.is_some() {
95-
return Err(SerdeError::duplicate_field(
96-
"topic",
97-
));
98-
}
99-
topic = Some(map.next_value()?);
100-
}
101-
"data" => {
102-
if data.is_some() {
103-
return Err(SerdeError::duplicate_field(
104-
"data",
105-
));
106-
}
107-
data = Some(map.next_value()?);
108-
}
109-
field => {
110-
return Err(SerdeError::unknown_field(
111-
field,
112-
&["source", "topic", "data"],
113-
))
114-
}
115-
};
116-
}
117-
let data: String =
118-
data.ok_or_else(|| SerdeError::missing_field("data"))?;
119-
let data = BASE64_STANDARD.decode(data).map_err(|e| {
120-
SerdeError::custom(format!(
121-
"failed to base64 decode Event data: {e}"
122-
))
123-
})?;
124-
Ok(Event {
125-
source: source
126-
.ok_or_else(|| SerdeError::missing_field("source"))?,
127-
topic: topic
128-
.ok_or_else(|| SerdeError::missing_field("topic"))?,
129-
data,
130-
})
131-
}
50+
#[derive(Deserialize)]
51+
struct IntermediateEvent {
52+
source: ContractId,
53+
topic: String,
54+
data: String,
13255
}
13356

134-
deserializer.deserialize_struct(
135-
"Event",
136-
&["source", "topic", "data"],
137-
StructVisitor,
138-
)
57+
let intermediate: IntermediateEvent =
58+
Deserialize::deserialize(deserializer)?;
59+
let data = hex::decode(&intermediate.data)
60+
.map_err(serde::de::Error::custom)?;
61+
Ok(Event {
62+
source: intermediate.source,
63+
topic: intermediate.topic,
64+
data,
65+
})
13966
}
14067
}

0 commit comments

Comments
 (0)