snarkvm_ledger_narwhal_data/
lib.rs1extern crate snarkvm_console as console;
17
18use console::prelude::*;
19
20use ::bytes::Bytes;
21
22#[cfg(feature = "async")]
23use tokio::task;
24
25const PREFIX: &str = "data";
26
27const MAX_DATA_SIZE: u32 = 1024 * 1024 * 1024; #[derive(Clone, PartialEq, Eq)]
35pub enum Data<T: FromBytes + ToBytes + Send + 'static> {
36 Object(T),
37 Buffer(Bytes),
38}
39
40impl<T: FromBytes + ToBytes + Send + 'static> Data<T> {
41 pub fn to_checksum<N: Network>(&self) -> Result<N::TransmissionChecksum> {
42 let preimage = match self {
44 Self::Object(object) => object.to_bytes_le()?.to_bits_le(),
45 Self::Buffer(bytes) => bytes.deref().to_bits_le(),
46 };
47 let hash = N::hash_sha3_256(&preimage)?;
49 let num_bits = usize::try_from(N::TransmissionChecksum::BITS).map_err(error)?;
51 N::TransmissionChecksum::from_bits_le(&hash[0..num_bits])
53 }
54
55 pub fn into<T2: From<Data<T>> + From<T> + FromBytes + ToBytes + Send + 'static>(self) -> Data<T2> {
56 match self {
57 Self::Object(x) => Data::Object(x.into()),
58 Self::Buffer(bytes) => Data::Buffer(bytes),
59 }
60 }
61
62 #[cfg(feature = "async")]
63 pub async fn deserialize(self) -> Result<T> {
64 match self {
65 Self::Object(x) => Ok(x),
66 Self::Buffer(bytes) => match task::spawn_blocking(move || T::from_bytes_le(&bytes)).await {
67 Ok(x) => x,
68 Err(err) => Err(err.into()),
69 },
70 }
71 }
72
73 pub fn deserialize_blocking(self) -> Result<T> {
74 match self {
75 Self::Object(x) => Ok(x),
76 Self::Buffer(bytes) => T::from_bytes_le(&bytes),
77 }
78 }
79
80 #[cfg(feature = "async")]
81 pub async fn serialize(self) -> Result<Bytes> {
82 match self {
83 Self::Object(x) => match task::spawn_blocking(move || x.to_bytes_le()).await {
84 Ok(bytes) => bytes.map(|vec| vec.into()),
85 Err(err) => Err(err.into()),
86 },
87 Self::Buffer(bytes) => Ok(bytes),
88 }
89 }
90
91 pub fn serialize_blocking_into<W: Write>(&self, writer: &mut W) -> Result<()> {
92 match self {
93 Self::Object(x) => Ok(x.write_le(writer)?),
94 Self::Buffer(bytes) => Ok(writer.write_all(bytes)?),
95 }
96 }
97}
98
99impl<T: FromBytes + ToBytes + DeserializeOwned + Send + 'static> FromStr for Data<T> {
100 type Err = Error;
101
102 fn from_str(data: &str) -> Result<Self, Self::Err> {
104 Ok(serde_json::from_str(data)?)
105 }
106}
107
108impl<T: FromBytes + ToBytes + Serialize + Send + 'static> Debug for Data<T> {
109 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
111 Display::fmt(self, f)
112 }
113}
114
115impl<T: FromBytes + ToBytes + Serialize + Send + 'static> Display for Data<T> {
116 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
118 write!(f, "{}", serde_json::to_string(self).map_err::<fmt::Error, _>(ser::Error::custom)?)
119 }
120}
121
122impl<T: FromBytes + ToBytes + Send + 'static> FromBytes for Data<T> {
123 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
125 let version = u8::read_le(&mut reader)?;
127 if version != 1 {
129 return Err(error("Invalid data version"));
130 }
131
132 let num_bytes = u32::read_le(&mut reader)?;
134 if num_bytes > MAX_DATA_SIZE {
136 return Err(error(format!("Failed to deserialize data ({num_bytes} bytes)")));
137 }
138 let mut bytes = Vec::new();
140 (&mut reader).take(num_bytes as u64).read_to_end(&mut bytes)?;
141 Ok(Self::Buffer(Bytes::from(bytes)))
143 }
144}
145
146impl<T: FromBytes + ToBytes + Send + 'static> ToBytes for Data<T> {
147 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
149 1u8.write_le(&mut writer)?;
151
152 match self {
154 Self::Object(object) => {
155 let buffer =
157 object.to_bytes_le().map_err(|e| error(format!("Failed to serialize 'Data::Object' - {e}")))?;
158 u32::try_from(buffer.len()).map_err(error)?.write_le(&mut writer)?;
160 writer.write_all(&buffer)
162 }
163 Self::Buffer(buffer) => {
164 u32::try_from(buffer.len()).map_err(error)?.write_le(&mut writer)?;
166 writer.write_all(buffer)
168 }
169 }
170 }
171}
172
173impl<T: FromBytes + ToBytes + Serialize + Send + 'static> Serialize for Data<T> {
174 #[inline]
176 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
177 match serializer.is_human_readable() {
178 true => {
179 let mut data = serializer.serialize_struct("Data", 2)?;
180 match self {
181 Self::Object(object) => {
182 data.serialize_field("type", "object")?;
183 data.serialize_field("data", object)?;
184 }
185 Self::Buffer(buffer) => {
186 use console::prelude::ser::Error;
187
188 data.serialize_field("type", "buffer")?;
189
190 let buffer = bech32::encode(PREFIX, buffer.to_vec().to_base32(), bech32::Variant::Bech32m)
192 .map_err(|_| S::Error::custom("Failed to encode data into bech32m"))?;
193
194 data.serialize_field("data", &buffer)?;
196 }
197 }
198 data.end()
199 }
200 false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
201 }
202 }
203}
204
205impl<'de, T: FromBytes + ToBytes + DeserializeOwned + Send + 'static> Deserialize<'de> for Data<T> {
206 #[inline]
208 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
209 match deserializer.is_human_readable() {
210 true => {
211 let mut data = serde_json::Value::deserialize(deserializer)?;
212 let type_: String = DeserializeExt::take_from_value::<D>(&mut data, "type")?;
213
214 match type_.as_str() {
216 "object" => {
217 let object = DeserializeExt::take_from_value::<D>(&mut data, "data")?;
218 Ok(Self::Object(object))
219 }
220 "buffer" => {
221 let encoding: String = DeserializeExt::take_from_value::<D>(&mut data, "data")?;
222
223 let (hrp, data, variant) = bech32::decode(&encoding).map_err(de::Error::custom)?;
225 if hrp != PREFIX {
226 return Err(de::Error::custom(error(format!("Invalid data HRP - {hrp}"))));
227 };
228 if data.is_empty() {
229 return Err(de::Error::custom(error("Invalid bech32m data (empty)")));
230 }
231 if variant != bech32::Variant::Bech32m {
232 return Err(de::Error::custom(error("Invalid data - variant is not bech32m")));
233 }
234 Ok(Self::Buffer(Bytes::from(Vec::from_base32(&data).map_err(de::Error::custom)?)))
235 }
236 _ => Err(de::Error::custom(error(format!("Invalid data type - {type_}")))),
237 }
238 }
239 false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "data"),
240 }
241 }
242}
243
244#[cfg(test)]
245mod tests {
246 use super::*;
247 use console::network::MainnetV0;
248 use snarkvm_ledger_block::Transaction;
249
250 #[test]
251 fn test_to_checksum() {
252 let rng = &mut TestRng::default();
253
254 let transactions = [
256 snarkvm_ledger_test_helpers::sample_deployment_transaction(1, Uniform::rand(rng), true, rng),
257 snarkvm_ledger_test_helpers::sample_deployment_transaction(1, Uniform::rand(rng), false, rng),
258 snarkvm_ledger_test_helpers::sample_deployment_transaction(2, Uniform::rand(rng), true, rng),
259 snarkvm_ledger_test_helpers::sample_deployment_transaction(2, Uniform::rand(rng), false, rng),
260 snarkvm_ledger_test_helpers::sample_execution_transaction_with_fee(true, rng, 0),
261 snarkvm_ledger_test_helpers::sample_execution_transaction_with_fee(false, rng, 0),
262 snarkvm_ledger_test_helpers::sample_fee_private_transaction(rng),
263 snarkvm_ledger_test_helpers::sample_fee_public_transaction(rng),
264 ];
265
266 for transaction in transactions.into_iter() {
267 let data_bytes: Data<Transaction<MainnetV0>> = Data::Buffer(transaction.to_bytes_le().unwrap().into());
269 let data = Data::Object(transaction);
271
272 let checksum_1 = data_bytes.to_checksum::<MainnetV0>().unwrap();
274 let checksum_2 = data.to_checksum::<MainnetV0>().unwrap();
275
276 assert_eq!(checksum_1, checksum_2);
278 }
279 }
280}