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 }