/ ledger / governor / src / serialize.rs
serialize.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaVM library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  //! JSON and binary serialization for Governor types.
 17  
 18  use crate::{
 19      bls::{AggregateSignature, BlsPublicKey, BlsSignature},
 20      console::prelude::*,
 21      gid::{GidId, GidStatus, GovernorIdentity, KycIdCode, Signer, ValidatorStatus},
 22  };
 23  use std::collections::BTreeMap;
 24  
 25  use serde::{
 26      Deserialize, Serialize,
 27      de::{self, Deserializer},
 28      ser::{SerializeStruct, Serializer},
 29  };
 30  
 31  // ============================================================================
 32  // GidId Serialization
 33  // ============================================================================
 34  
 35  impl<N: Network> Serialize for GidId<N> {
 36      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
 37          match serializer.is_human_readable() {
 38              true => serializer.serialize_str(&self.to_string()),
 39              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
 40          }
 41      }
 42  }
 43  
 44  impl<'de, N: Network> Deserialize<'de> for GidId<N> {
 45      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
 46          match deserializer.is_human_readable() {
 47              true => {
 48                  let s: String = Deserialize::deserialize(deserializer)?;
 49                  Self::from_str(&s).map_err(de::Error::custom)
 50              }
 51              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "GidId"),
 52          }
 53      }
 54  }
 55  
 56  // ============================================================================
 57  // GidStatus Serialization
 58  // ============================================================================
 59  
 60  impl Serialize for GidStatus {
 61      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
 62          match serializer.is_human_readable() {
 63              true => serializer.serialize_str(&self.to_string()),
 64              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
 65          }
 66      }
 67  }
 68  
 69  impl<'de> Deserialize<'de> for GidStatus {
 70      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
 71          match deserializer.is_human_readable() {
 72              true => {
 73                  let s: String = Deserialize::deserialize(deserializer)?;
 74                  match s.as_str() {
 75                      "active" => Ok(GidStatus::Active),
 76                      "frozen" => Ok(GidStatus::Frozen),
 77                      "disabled" => Ok(GidStatus::Disabled),
 78                      _ => Err(de::Error::custom(format!("Invalid GidStatus: {}", s))),
 79                  }
 80              }
 81              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "GidStatus"),
 82          }
 83      }
 84  }
 85  
 86  // ============================================================================
 87  // ValidatorStatus Serialization (F-A20, F-A26)
 88  // ============================================================================
 89  
 90  impl Serialize for ValidatorStatus {
 91      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
 92          match serializer.is_human_readable() {
 93              true => serializer.serialize_str(&self.to_string()),
 94              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
 95          }
 96      }
 97  }
 98  
 99  impl<'de> Deserialize<'de> for ValidatorStatus {
100      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
101          match deserializer.is_human_readable() {
102              true => {
103                  let s: String = Deserialize::deserialize(deserializer)?;
104                  match s.as_str() {
105                      "active" => Ok(ValidatorStatus::Active),
106                      "slashed" => Ok(ValidatorStatus::Slashed),
107                      "ejected" => Ok(ValidatorStatus::Ejected),
108                      "clp_expired" => Ok(ValidatorStatus::ClpExpired),
109                      "backup_active" => Ok(ValidatorStatus::BackupActive),
110                      "not_linked" => Ok(ValidatorStatus::NotLinked),
111                      _ => Err(de::Error::custom(format!("Invalid ValidatorStatus: {}", s))),
112                  }
113              }
114              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "ValidatorStatus"),
115          }
116      }
117  }
118  
119  // ============================================================================
120  // BlsPublicKey Serialization
121  // ============================================================================
122  
123  impl<N: Network> Serialize for BlsPublicKey<N> {
124      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
125          match serializer.is_human_readable() {
126              true => {
127                  let mut s = serializer.serialize_struct("BlsPublicKey", 1)?;
128                  s.serialize_field("point", self.point())?;
129                  s.end()
130              }
131              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
132          }
133      }
134  }
135  
136  impl<'de, N: Network> Deserialize<'de> for BlsPublicKey<N> {
137      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
138          match deserializer.is_human_readable() {
139              true => {
140                  let mut value = serde_json::Value::deserialize(deserializer)?;
141                  let point = DeserializeExt::take_from_value::<D>(&mut value, "point")?;
142                  Ok(Self::new(point))
143              }
144              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "BlsPublicKey"),
145          }
146      }
147  }
148  
149  // ============================================================================
150  // BlsSignature Serialization
151  // ============================================================================
152  
153  impl<N: Network> Serialize for BlsSignature<N> {
154      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
155          match serializer.is_human_readable() {
156              true => {
157                  let mut s = serializer.serialize_struct("BlsSignature", 2)?;
158                  s.serialize_field("r", self.r())?;
159                  s.serialize_field("s", self.s())?;
160                  s.end()
161              }
162              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
163          }
164      }
165  }
166  
167  impl<'de, N: Network> Deserialize<'de> for BlsSignature<N> {
168      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
169          match deserializer.is_human_readable() {
170              true => {
171                  let mut value = serde_json::Value::deserialize(deserializer)?;
172                  let r = DeserializeExt::take_from_value::<D>(&mut value, "r")?;
173                  let s = DeserializeExt::take_from_value::<D>(&mut value, "s")?;
174                  Ok(Self::new(r, s))
175              }
176              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "BlsSignature"),
177          }
178      }
179  }
180  
181  // ============================================================================
182  // AggregateSignature Serialization
183  // ============================================================================
184  
185  impl<N: Network> Serialize for AggregateSignature<N> {
186      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
187          match serializer.is_human_readable() {
188              true => {
189                  let mut s = serializer.serialize_struct("AggregateSignature", 3)?;
190                  s.serialize_field("signature", self.signature())?;
191                  s.serialize_field("signer_bitmap", self.signer_bitmap())?;
192                  s.serialize_field("count", &self.count())?;
193                  s.end()
194              }
195              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
196          }
197      }
198  }
199  
200  impl<'de, N: Network> Deserialize<'de> for AggregateSignature<N> {
201      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
202          match deserializer.is_human_readable() {
203              true => {
204                  let mut value = serde_json::Value::deserialize(deserializer)?;
205                  let signature = DeserializeExt::take_from_value::<D>(&mut value, "signature")?;
206                  let signer_bitmap: Vec<bool> = DeserializeExt::take_from_value::<D>(&mut value, "signer_bitmap")?;
207                  let count: u8 = DeserializeExt::take_from_value::<D>(&mut value, "count")?;
208                  Ok(Self::new(signature, signer_bitmap, count))
209              }
210              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "AggregateSignature"),
211          }
212      }
213  }
214  
215  // ============================================================================
216  // Signer Serialization
217  // ============================================================================
218  
219  impl<N: Network> Serialize for Signer<N> {
220      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
221          match serializer.is_human_readable() {
222              true => {
223                  let mut s = serializer.serialize_struct("Signer", 4)?;
224                  s.serialize_field("public_key", self.public_key())?;
225                  s.serialize_field("index", &self.index())?;
226                  s.serialize_field("active", &self.is_active())?;
227                  s.serialize_field("added_epoch", &self.added_epoch())?;
228                  s.end()
229              }
230              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
231          }
232      }
233  }
234  
235  impl<'de, N: Network> Deserialize<'de> for Signer<N> {
236      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
237          match deserializer.is_human_readable() {
238              true => {
239                  let mut value = serde_json::Value::deserialize(deserializer)?;
240                  let public_key = DeserializeExt::take_from_value::<D>(&mut value, "public_key")?;
241                  let index: u8 = DeserializeExt::take_from_value::<D>(&mut value, "index")?;
242                  let active: bool = DeserializeExt::take_from_value::<D>(&mut value, "active")?;
243                  let added_epoch: u64 = DeserializeExt::take_from_value::<D>(&mut value, "added_epoch")?;
244                  Ok(Self::from_parts(public_key, index, active, added_epoch))
245              }
246              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "Signer"),
247          }
248      }
249  }
250  
251  // ============================================================================
252  // KycIdCode Serialization (F-D44)
253  // ============================================================================
254  
255  impl<N: Network> Serialize for KycIdCode<N> {
256      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
257          match serializer.is_human_readable() {
258              true => {
259                  let mut s = serializer.serialize_struct("KycIdCode", 4)?;
260                  // Serialize code as hex string for human readability
261                  s.serialize_field("code", &hex::encode(self.code()))?;
262                  s.serialize_field("address", self.address())?;
263                  s.serialize_field("added_epoch", &self.added_epoch())?;
264                  s.serialize_field("active", &self.is_active())?;
265                  s.end()
266              }
267              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
268          }
269      }
270  }
271  
272  impl<'de, N: Network> Deserialize<'de> for KycIdCode<N> {
273      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
274          match deserializer.is_human_readable() {
275              true => {
276                  let mut value = serde_json::Value::deserialize(deserializer)?;
277                  let code_hex: String = DeserializeExt::take_from_value::<D>(&mut value, "code")?;
278                  let code_bytes = hex::decode(&code_hex).map_err(de::Error::custom)?;
279                  let mut code = [0u8; 32];
280                  if code_bytes.len() != 32 {
281                      return Err(de::Error::custom("KYC code must be 32 bytes"));
282                  }
283                  code.copy_from_slice(&code_bytes);
284                  let address = DeserializeExt::take_from_value::<D>(&mut value, "address")?;
285                  let added_epoch: u64 = DeserializeExt::take_from_value::<D>(&mut value, "added_epoch")?;
286                  let active: bool = DeserializeExt::take_from_value::<D>(&mut value, "active")?;
287  
288                  let mut kyc = KycIdCode::new(code, address, added_epoch);
289                  if !active {
290                      kyc.deactivate();
291                  }
292                  Ok(kyc)
293              }
294              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "KycIdCode"),
295          }
296      }
297  }
298  
299  // ============================================================================
300  // GovernorIdentity Serialization
301  // ============================================================================
302  
303  impl<N: Network> Serialize for GovernorIdentity<N> {
304      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
305          match serializer.is_human_readable() {
306              true => {
307                  let mut s = serializer.serialize_struct("GovernorIdentity", 13)?;
308                  s.serialize_field("id", self.id())?;
309                  s.serialize_field("registrar", self.registrar())?;
310                  s.serialize_field("status", &self.status())?;
311                  s.serialize_field("required_signatures", &self.required_signatures())?;
312                  s.serialize_field("signers", &self.signers())?;
313                  s.serialize_field("outstanding_balance", &self.outstanding_balance())?;
314                  s.serialize_field("mint_limit", &self.mint_limit())?;
315                  s.serialize_field("nonce", &self.nonce())?;
316                  s.serialize_field("created_epoch", &self.created_epoch())?;
317                  // Validator link fields (F-A20, F-A26)
318                  s.serialize_field("linked_validator", &self.linked_validator())?;
319                  s.serialize_field("backup_validator", &self.backup_validator())?;
320                  s.serialize_field("validator_status", &self.validator_status())?;
321                  // KYC ID list (F-D44)
322                  s.serialize_field("kyc_id_list", self.kyc_id_list())?;
323                  s.end()
324              }
325              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
326          }
327      }
328  }
329  
330  impl<'de, N: Network> Deserialize<'de> for GovernorIdentity<N> {
331      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
332          match deserializer.is_human_readable() {
333              true => {
334                  let mut value = serde_json::Value::deserialize(deserializer)?;
335                  let id = DeserializeExt::take_from_value::<D>(&mut value, "id")?;
336                  let registrar = DeserializeExt::take_from_value::<D>(&mut value, "registrar")?;
337                  let status = DeserializeExt::take_from_value::<D>(&mut value, "status")?;
338                  let required_signatures: u8 = DeserializeExt::take_from_value::<D>(&mut value, "required_signatures")?;
339                  let signers: Vec<Signer<N>> = DeserializeExt::take_from_value::<D>(&mut value, "signers")?;
340                  let outstanding_balance: u64 = DeserializeExt::take_from_value::<D>(&mut value, "outstanding_balance")?;
341                  let mint_limit: u64 = DeserializeExt::take_from_value::<D>(&mut value, "mint_limit")?;
342                  let nonce: u64 = DeserializeExt::take_from_value::<D>(&mut value, "nonce")?;
343                  let created_epoch: u64 = DeserializeExt::take_from_value::<D>(&mut value, "created_epoch")?;
344                  // Validator link fields (F-A20, F-A26)
345                  let linked_validator: Option<BlsPublicKey<N>> =
346                      DeserializeExt::take_from_value::<D>(&mut value, "linked_validator")?;
347                  let backup_validator: Option<BlsPublicKey<N>> =
348                      DeserializeExt::take_from_value::<D>(&mut value, "backup_validator")?;
349                  let validator_status: ValidatorStatus =
350                      DeserializeExt::take_from_value::<D>(&mut value, "validator_status")?;
351                  // KYC ID list (F-D44) - optional for backwards compatibility
352                  let kyc_id_list: BTreeMap<[u8; 32], KycIdCode<N>> =
353                      DeserializeExt::take_from_value::<D>(&mut value, "kyc_id_list").unwrap_or_default();
354  
355                  Ok(Self::from_components(
356                      id,
357                      registrar,
358                      status,
359                      required_signatures,
360                      signers,
361                      outstanding_balance,
362                      mint_limit,
363                      nonce,
364                      created_epoch,
365                      linked_validator,
366                      backup_validator,
367                      validator_status,
368                      kyc_id_list,
369                  ))
370              }
371              false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "GovernorIdentity"),
372          }
373      }
374  }
375  
376  #[cfg(test)]
377  mod tests {
378      use super::*;
379      use crate::{
380          bls::SignatureAggregator,
381          console::{
382              network::MainnetV0,
383              types::{Address, Field, Group},
384          },
385      };
386      use core::ops::Add;
387  
388      type CurrentNetwork = MainnetV0;
389  
390      fn create_test_pubkeys(count: usize) -> Vec<BlsPublicKey<CurrentNetwork>> {
391          let generator = Group::<CurrentNetwork>::generator();
392          let mut point = generator.clone();
393          (0..count)
394              .map(|_| {
395                  let key = BlsPublicKey::new(point.clone());
396                  point = point.add(&generator);
397                  key
398              })
399              .collect()
400      }
401  
402      fn create_test_gid() -> GovernorIdentity<CurrentNetwork> {
403          let registrar: Address<CurrentNetwork> =
404              Address::from_str("ax1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3qtczd").unwrap();
405          let pubkeys = create_test_pubkeys(7);
406          GovernorIdentity::new(registrar, 5, pubkeys, 1_000_000, 100, 0).unwrap()
407      }
408  
409      #[test]
410      fn test_gid_id_serde_json() {
411          let gid_id: GidId<CurrentNetwork> = GidId::new(Field::from_u64(12345));
412  
413          let json = serde_json::to_string(&gid_id).unwrap();
414          let recovered: GidId<CurrentNetwork> = serde_json::from_str(&json).unwrap();
415  
416          assert_eq!(gid_id.id(), recovered.id());
417      }
418  
419      #[test]
420      fn test_gid_status_serde_json() {
421          for status in [GidStatus::Active, GidStatus::Frozen, GidStatus::Disabled] {
422              let json = serde_json::to_string(&status).unwrap();
423              let recovered: GidStatus = serde_json::from_str(&json).unwrap();
424              assert_eq!(status, recovered);
425          }
426      }
427  
428      #[test]
429      fn test_bls_public_key_serde_json() {
430          let pubkey = create_test_pubkeys(1).pop().unwrap();
431  
432          let json = serde_json::to_string(&pubkey).unwrap();
433          let recovered: BlsPublicKey<CurrentNetwork> = serde_json::from_str(&json).unwrap();
434  
435          assert_eq!(pubkey.point(), recovered.point());
436      }
437  
438      #[test]
439      fn test_bls_signature_serde_json() {
440          let sig: BlsSignature<CurrentNetwork> = BlsSignature::new(Field::from_u64(123), Field::from_u64(456));
441  
442          let json = serde_json::to_string(&sig).unwrap();
443          let recovered: BlsSignature<CurrentNetwork> = serde_json::from_str(&json).unwrap();
444  
445          assert_eq!(sig.r(), recovered.r());
446          assert_eq!(sig.s(), recovered.s());
447      }
448  
449      #[test]
450      fn test_aggregate_signature_serde_json() {
451          let mut aggregator = SignatureAggregator::<CurrentNetwork>::new(10);
452          for i in 0..5 {
453              let sig = BlsSignature::new(Field::from_u64(i as u64), Field::from_u64(i as u64 + 1));
454              aggregator.add_signature(i, sig).unwrap();
455          }
456          let aggregate = aggregator.aggregate().unwrap();
457  
458          let json = serde_json::to_string(&aggregate).unwrap();
459          let recovered: AggregateSignature<CurrentNetwork> = serde_json::from_str(&json).unwrap();
460  
461          assert_eq!(aggregate.count(), recovered.count());
462          assert_eq!(aggregate.signer_bitmap(), recovered.signer_bitmap());
463      }
464  
465      #[test]
466      fn test_signer_serde_json() {
467          let pubkey = create_test_pubkeys(1).pop().unwrap();
468          let signer = Signer::new(pubkey, 0, 100);
469  
470          let json = serde_json::to_string(&signer).unwrap();
471          let recovered: Signer<CurrentNetwork> = serde_json::from_str(&json).unwrap();
472  
473          assert_eq!(signer.index(), recovered.index());
474          assert_eq!(signer.is_active(), recovered.is_active());
475          assert_eq!(signer.added_epoch(), recovered.added_epoch());
476      }
477  
478      #[test]
479      fn test_governor_identity_serde_json() {
480          let gid = create_test_gid();
481  
482          let json = serde_json::to_string(&gid).unwrap();
483          let recovered: GovernorIdentity<CurrentNetwork> = serde_json::from_str(&json).unwrap();
484  
485          assert_eq!(gid.id().id(), recovered.id().id());
486          assert_eq!(gid.required_signatures(), recovered.required_signatures());
487          assert_eq!(gid.status(), recovered.status());
488          assert_eq!(gid.outstanding_balance(), recovered.outstanding_balance());
489          assert_eq!(gid.mint_limit(), recovered.mint_limit());
490      }
491  
492      #[test]
493      fn test_governor_identity_bincode() {
494          let gid = create_test_gid();
495  
496          // Test ToBytes/FromBytes
497          let bytes = gid.to_bytes_le().unwrap();
498          let recovered = GovernorIdentity::<CurrentNetwork>::read_le(&bytes[..]).unwrap();
499  
500          assert_eq!(gid.id().id(), recovered.id().id());
501          assert_eq!(gid.required_signatures(), recovered.required_signatures());
502          assert_eq!(gid.status(), recovered.status());
503  
504          // Test bincode roundtrip
505          let bincode_bytes = bincode::serialize(&gid).unwrap();
506          let bincode_recovered: GovernorIdentity<CurrentNetwork> = bincode::deserialize(&bincode_bytes).unwrap();
507  
508          assert_eq!(gid.id().id(), bincode_recovered.id().id());
509      }
510  }