1use std::fmt;
5use std::fmt::Write;
6use std::fmt::{Debug, Display, Formatter};
7use std::marker::PhantomData;
8use std::ops::Deref;
9use std::str::FromStr;
10
11use move_core_types::account_address::AccountAddress;
12use move_core_types::language_storage::{StructTag, TypeTag};
13use schemars::JsonSchema;
14use serde;
15use serde::de::{Deserializer, Error};
16use serde::ser::{Error as SerError, Serializer};
17use serde::{Deserialize, Serialize};
18use serde_with::DisplayFromStr;
19use serde_with::serde_as;
20use serde_with::{Bytes, DeserializeAs, SerializeAs};
21
22use sui_protocol_config::ProtocolVersion;
23
24use crate::governance::MAX_VALIDATOR_COUNT;
25use crate::{
26 DEEPBOOK_ADDRESS, SUI_CLOCK_ADDRESS, SUI_FRAMEWORK_ADDRESS, SUI_SYSTEM_ADDRESS,
27 SUI_SYSTEM_STATE_ADDRESS, parse_sui_struct_tag, parse_sui_type_tag,
28};
29
30#[inline]
31pub(crate) fn to_custom_deser_error<'de, D, E>(e: E) -> D::Error
32where
33 E: Debug,
34 D: Deserializer<'de>,
35{
36 Error::custom(format!("byte deserialization failed, cause by: {:?}", e))
37}
38
39#[inline]
40pub(crate) fn to_custom_ser_error<S, E>(e: E) -> S::Error
41where
42 E: Debug,
43 S: Serializer,
44{
45 S::Error::custom(format!("byte serialization failed, cause by: {:?}", e))
46}
47
48pub struct Readable<H, R> {
63 human_readable: PhantomData<H>,
64 non_human_readable: PhantomData<R>,
65}
66
67impl<T: ?Sized, H, R> SerializeAs<T> for Readable<H, R>
68where
69 H: SerializeAs<T>,
70 R: SerializeAs<T>,
71{
72 fn serialize_as<S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
73 where
74 S: Serializer,
75 {
76 if serializer.is_human_readable() {
77 H::serialize_as(value, serializer)
78 } else {
79 R::serialize_as(value, serializer)
80 }
81 }
82}
83
84impl<'de, R, H, T> DeserializeAs<'de, T> for Readable<H, R>
85where
86 H: DeserializeAs<'de, T>,
87 R: DeserializeAs<'de, T>,
88{
89 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
90 where
91 D: Deserializer<'de>,
92 {
93 if deserializer.is_human_readable() {
94 H::deserialize_as(deserializer)
95 } else {
96 R::deserialize_as(deserializer)
97 }
98 }
99}
100
101pub struct SuiStructTag;
102
103impl SerializeAs<StructTag> for SuiStructTag {
104 fn serialize_as<S>(value: &StructTag, serializer: S) -> Result<S::Ok, S::Error>
105 where
106 S: Serializer,
107 {
108 let f = to_sui_struct_tag_string(value).map_err(S::Error::custom)?;
109 f.serialize(serializer)
110 }
111}
112
113const SUI_ADDRESSES: [AccountAddress; 7] = [
114 AccountAddress::ZERO,
115 AccountAddress::ONE,
116 SUI_FRAMEWORK_ADDRESS,
117 SUI_SYSTEM_ADDRESS,
118 DEEPBOOK_ADDRESS,
119 SUI_SYSTEM_STATE_ADDRESS,
120 SUI_CLOCK_ADDRESS,
121];
122pub fn to_sui_struct_tag_string(value: &StructTag) -> Result<String, fmt::Error> {
124 let mut f = String::new();
125 let address = if SUI_ADDRESSES.contains(&value.address) {
127 value.address.short_str_lossless()
128 } else {
129 value.address.to_canonical_string(false)
130 };
131
132 write!(f, "0x{}::{}::{}", address, value.module, value.name)?;
133 if let Some(first_ty) = value.type_params.first() {
134 write!(f, "<")?;
135 write!(f, "{}", to_sui_type_tag_string(first_ty)?)?;
136 for ty in value.type_params.iter().skip(1) {
137 write!(f, ", {}", to_sui_type_tag_string(ty)?)?;
138 }
139 write!(f, ">")?;
140 }
141 Ok(f)
142}
143
144fn to_sui_type_tag_string(value: &TypeTag) -> Result<String, fmt::Error> {
145 match value {
146 TypeTag::Vector(t) => Ok(format!("vector<{}>", to_sui_type_tag_string(t)?)),
147 TypeTag::Struct(s) => to_sui_struct_tag_string(s),
148 _ => Ok(value.to_string()),
149 }
150}
151
152impl<'de> DeserializeAs<'de, StructTag> for SuiStructTag {
153 fn deserialize_as<D>(deserializer: D) -> Result<StructTag, D::Error>
154 where
155 D: Deserializer<'de>,
156 {
157 let s = String::deserialize(deserializer)?;
158 parse_sui_struct_tag(&s).map_err(D::Error::custom)
159 }
160}
161
162pub struct SuiTypeTag;
163
164impl SerializeAs<TypeTag> for SuiTypeTag {
165 fn serialize_as<S>(value: &TypeTag, serializer: S) -> Result<S::Ok, S::Error>
166 where
167 S: Serializer,
168 {
169 let s = to_sui_type_tag_string(value).map_err(S::Error::custom)?;
170 s.serialize(serializer)
171 }
172}
173
174impl<'de> DeserializeAs<'de, TypeTag> for SuiTypeTag {
175 fn deserialize_as<D>(deserializer: D) -> Result<TypeTag, D::Error>
176 where
177 D: Deserializer<'de>,
178 {
179 let s = String::deserialize(deserializer)?;
180 parse_sui_type_tag(&s).map_err(D::Error::custom)
181 }
182}
183
184#[serde_as]
185#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Copy, JsonSchema)]
186pub struct BigInt<T>(
187 #[schemars(with = "String")]
188 #[serde_as(as = "DisplayFromStr")]
189 T,
190)
191where
192 T: Display + FromStr,
193 <T as FromStr>::Err: Display;
194
195impl<T> BigInt<T>
196where
197 T: Display + FromStr,
198 <T as FromStr>::Err: Display,
199{
200 pub fn into_inner(self) -> T {
201 self.0
202 }
203}
204
205impl<T> SerializeAs<T> for BigInt<T>
206where
207 T: Display + FromStr + Copy,
208 <T as FromStr>::Err: Display,
209{
210 fn serialize_as<S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
211 where
212 S: Serializer,
213 {
214 BigInt(*value).serialize(serializer)
215 }
216}
217
218impl<'de, T> DeserializeAs<'de, T> for BigInt<T>
219where
220 T: Display + FromStr + Copy,
221 <T as FromStr>::Err: Display,
222{
223 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
224 where
225 D: Deserializer<'de>,
226 {
227 Ok(*BigInt::deserialize(deserializer)?)
228 }
229}
230
231impl<T> From<T> for BigInt<T>
232where
233 T: Display + FromStr,
234 <T as FromStr>::Err: Display,
235{
236 fn from(v: T) -> BigInt<T> {
237 BigInt(v)
238 }
239}
240
241impl<T> Deref for BigInt<T>
242where
243 T: Display + FromStr,
244 <T as FromStr>::Err: Display,
245{
246 type Target = T;
247
248 fn deref(&self) -> &Self::Target {
249 &self.0
250 }
251}
252
253impl<T> Display for BigInt<T>
254where
255 T: Display + FromStr,
256 <T as FromStr>::Err: Display,
257{
258 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
259 write!(f, "{}", self.0)
260 }
261}
262
263#[serde_as]
264#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Copy, JsonSchema)]
265pub struct SequenceNumber(#[schemars(with = "BigInt<u64>")] u64);
266
267impl SerializeAs<crate::base_types::SequenceNumber> for SequenceNumber {
268 fn serialize_as<S>(
269 value: &crate::base_types::SequenceNumber,
270 serializer: S,
271 ) -> Result<S::Ok, S::Error>
272 where
273 S: Serializer,
274 {
275 let s = value.value().to_string();
276 s.serialize(serializer)
277 }
278}
279
280impl<'de> DeserializeAs<'de, crate::base_types::SequenceNumber> for SequenceNumber {
281 fn deserialize_as<D>(deserializer: D) -> Result<crate::base_types::SequenceNumber, D::Error>
282 where
283 D: Deserializer<'de>,
284 {
285 let b = BigInt::deserialize(deserializer)?;
286 Ok(crate::base_types::SequenceNumber::from_u64(*b))
287 }
288}
289
290#[serde_as]
291#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Copy, JsonSchema)]
292#[serde(rename = "ProtocolVersion")]
293pub struct AsProtocolVersion(#[schemars(with = "BigInt<u64>")] u64);
294
295impl SerializeAs<ProtocolVersion> for AsProtocolVersion {
296 fn serialize_as<S>(value: &ProtocolVersion, serializer: S) -> Result<S::Ok, S::Error>
297 where
298 S: Serializer,
299 {
300 let s = value.as_u64().to_string();
301 s.serialize(serializer)
302 }
303}
304
305impl<'de> DeserializeAs<'de, ProtocolVersion> for AsProtocolVersion {
306 fn deserialize_as<D>(deserializer: D) -> Result<ProtocolVersion, D::Error>
307 where
308 D: Deserializer<'de>,
309 {
310 let b = BigInt::<u64>::deserialize(deserializer)?;
311 Ok(ProtocolVersion::from(*b))
312 }
313}
314
315pub(crate) struct SuiBitmap;
318
319impl SerializeAs<roaring::RoaringBitmap> for SuiBitmap {
320 fn serialize_as<S>(source: &roaring::RoaringBitmap, serializer: S) -> Result<S::Ok, S::Error>
321 where
322 S: Serializer,
323 {
324 let mut bytes = vec![];
325
326 source
327 .serialize_into(&mut bytes)
328 .map_err(to_custom_ser_error::<S, _>)?;
329 Bytes::serialize_as(&bytes, serializer)
330 }
331}
332
333impl<'de> DeserializeAs<'de, roaring::RoaringBitmap> for SuiBitmap {
334 fn deserialize_as<D>(deserializer: D) -> Result<roaring::RoaringBitmap, D::Error>
335 where
336 D: Deserializer<'de>,
337 {
338 let bytes: Vec<u8> = Bytes::deserialize_as(deserializer)?;
339 deserialize_sui_bitmap(&bytes).map_err(to_custom_deser_error::<'de, D, _>)
340 }
341}
342
343pub(crate) fn deserialize_sui_bitmap(bytes: &[u8]) -> std::io::Result<roaring::RoaringBitmap> {
346 let orig_bitmap = roaring::RoaringBitmap::deserialize_from(bytes)?;
347
348 if orig_bitmap.len() > MAX_VALIDATOR_COUNT {
350 return Err(std::io::Error::new(
351 std::io::ErrorKind::InvalidData,
352 format!(
353 "bitmap cardinality {} exceeds max {}",
354 orig_bitmap.len(),
355 MAX_VALIDATOR_COUNT
356 ),
357 ));
358 }
359
360 let mut seen = std::collections::BTreeSet::new();
362 let mut new_bitmap = roaring::RoaringBitmap::new();
363 for v in orig_bitmap.iter() {
364 if seen.insert(v) {
365 new_bitmap.insert(v);
366 }
367 }
368 Ok(new_bitmap)
369}
370
371#[cfg(test)]
372mod test {
373 use base64::Engine as _;
374
375 use super::*;
376
377 #[test]
378 fn test_sui_bitmap_unique_deserialize() {
379 let raw = "OjAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAAAFoAAABcAAAAXgAAAGAAAABiAAAAZAAAAGYAAABoAAAAagAAAAEAAQABAAEAAQABAAEAAQABAAEA";
380 let bytes = base64::engine::general_purpose::STANDARD
381 .decode(raw)
382 .unwrap();
383
384 let bitmap = roaring::RoaringBitmap::deserialize_from(&bytes[..]).unwrap();
385 assert_eq!(bitmap.len(), 10);
386 let bitmap_values: Vec<u32> = bitmap.iter().collect();
387 assert_eq!(bitmap_values, vec![1; 10]);
388
389 let sui_bitmap = deserialize_sui_bitmap(&bytes[..]).unwrap();
390 assert_eq!(sui_bitmap.len(), 1);
391 let bitmap_values: Vec<u32> = sui_bitmap.iter().collect();
392 assert_eq!(bitmap_values, vec![1]);
393 }
394}