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 use super::*; 17 18 impl<N: Network> Serialize for Ratify<N> { 19 /// Serializes the ratify object into string or bytes. 20 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 21 match serializer.is_human_readable() { 22 true => match self { 23 Self::Genesis(committee, public_balances, bonded_balances) => { 24 let mut input = serializer.serialize_struct("Ratify", 4)?; 25 input.serialize_field("type", "genesis")?; 26 input.serialize_field("committee", &committee)?; 27 input.serialize_field("public_balances", &public_balances)?; 28 input.serialize_field("bonded_balances", &bonded_balances)?; 29 input.end() 30 } 31 Self::BlockReward(amount) => { 32 let mut input = serializer.serialize_struct("Ratify", 2)?; 33 input.serialize_field("type", "block_reward")?; 34 input.serialize_field("amount", &amount)?; 35 input.end() 36 } 37 Self::PuzzleReward(amount) => { 38 let mut input = serializer.serialize_struct("Ratify", 2)?; 39 input.serialize_field("type", "puzzle_reward")?; 40 input.serialize_field("amount", &amount)?; 41 input.end() 42 } 43 }, 44 false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), 45 } 46 } 47 } 48 49 impl<'de, N: Network> Deserialize<'de> for Ratify<N> { 50 /// Deserializes the ratify object from a string or bytes. 51 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { 52 match deserializer.is_human_readable() { 53 true => { 54 // Parse the input from a string into a value. 55 let mut object = serde_json::Value::deserialize(deserializer)?; 56 57 // Recover the ratify object. 58 let ratify = match object.get("type").and_then(|t| t.as_str()) { 59 Some("genesis") => { 60 // Retrieve the committee. 61 let committee: Committee<N> = DeserializeExt::take_from_value::<D>(&mut object, "committee")?; 62 // Retrieve the public balances. 63 let public_balances: PublicBalances<N> = 64 DeserializeExt::take_from_value::<D>(&mut object, "public_balances")?; 65 // Retrieve the bonded balances. 66 let bonded_balances: BondedBalances<N> = 67 DeserializeExt::take_from_value::<D>(&mut object, "bonded_balances")?; 68 // Construct the ratify object. 69 Ratify::Genesis(Box::new(committee), Box::new(public_balances), Box::new(bonded_balances)) 70 } 71 Some("block_reward") => { 72 // Retrieve the amount. 73 let amount: u64 = DeserializeExt::take_from_value::<D>(&mut object, "amount")?; 74 // Construct the ratify object. 75 Ratify::BlockReward(amount) 76 } 77 Some("puzzle_reward") => { 78 // Retrieve the amount. 79 let amount: u64 = DeserializeExt::take_from_value::<D>(&mut object, "amount")?; 80 // Construct the ratify object. 81 Ratify::PuzzleReward(amount) 82 } 83 _ => return Err(de::Error::custom("Invalid ratify object type")), 84 }; 85 // Return the ratify object. 86 Ok(ratify) 87 } 88 false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "ratify object"), 89 } 90 } 91 } 92 93 #[cfg(test)] 94 mod tests { 95 use super::*; 96 97 fn check_serde_json< 98 T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, 99 >( 100 expected: T, 101 ) { 102 // Serialize 103 let expected_string = expected.to_string(); 104 let candidate_string = serde_json::to_string(&expected).unwrap(); 105 let candidate = serde_json::from_str::<T>(&candidate_string).unwrap(); 106 assert_eq!(expected, candidate); 107 assert_eq!(expected_string, candidate_string); 108 assert_eq!(expected_string, candidate.to_string()); 109 110 // Deserialize 111 assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}"))); 112 assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap()); 113 } 114 115 fn check_bincode< 116 T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, 117 >( 118 expected: T, 119 ) { 120 // Serialize 121 let expected_bytes = expected.to_bytes_le().unwrap(); 122 let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap(); 123 assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); 124 125 // Deserialize 126 assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap()); 127 assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap()); 128 } 129 130 #[test] 131 fn test_serde_json() { 132 let rng = &mut TestRng::default(); 133 134 for expected in crate::ratify::test_helpers::sample_ratifications(rng) { 135 check_serde_json(expected); 136 } 137 } 138 139 #[test] 140 fn test_bincode() { 141 let rng = &mut TestRng::default(); 142 143 for expected in crate::ratify::test_helpers::sample_ratifications(rng) { 144 check_bincode(expected); 145 } 146 } 147 }