serialize.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 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 ConfirmedTransaction<N> { 19 /// Serializes the confirmed transaction 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::AcceptedDeploy(index, transaction, finalize_operations) => { 24 let mut object = serializer.serialize_struct("ConfirmedTransaction", 5)?; 25 object.serialize_field("status", "accepted")?; 26 object.serialize_field("type", "deploy")?; 27 object.serialize_field("index", index)?; 28 object.serialize_field("transaction", transaction)?; 29 object.serialize_field("finalize", finalize_operations)?; 30 object.end() 31 } 32 Self::AcceptedExecute(index, transaction, finalize_operations) => { 33 let mut object = serializer.serialize_struct("ConfirmedTransaction", 5)?; 34 object.serialize_field("status", "accepted")?; 35 object.serialize_field("type", "execute")?; 36 object.serialize_field("index", index)?; 37 object.serialize_field("transaction", transaction)?; 38 object.serialize_field("finalize", finalize_operations)?; 39 object.end() 40 } 41 Self::RejectedDeploy(index, transaction, rejected_deployment, finalize_operations) => { 42 let mut object = serializer.serialize_struct("ConfirmedTransaction", 6)?; 43 object.serialize_field("status", "rejected")?; 44 object.serialize_field("type", "deploy")?; 45 object.serialize_field("index", index)?; 46 object.serialize_field("transaction", transaction)?; 47 object.serialize_field("rejected", &rejected_deployment)?; 48 object.serialize_field("finalize", finalize_operations)?; 49 object.end() 50 } 51 Self::RejectedExecute(index, transaction, rejected_execution, finalize_operations) => { 52 let mut object = serializer.serialize_struct("ConfirmedTransaction", 6)?; 53 object.serialize_field("status", "rejected")?; 54 object.serialize_field("type", "execute")?; 55 object.serialize_field("index", index)?; 56 object.serialize_field("transaction", transaction)?; 57 object.serialize_field("rejected", &rejected_execution)?; 58 object.serialize_field("finalize", finalize_operations)?; 59 object.end() 60 } 61 }, 62 false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), 63 } 64 } 65 } 66 67 impl<'de, N: Network> Deserialize<'de> for ConfirmedTransaction<N> { 68 /// Deserializes the confirmed transaction from a string or bytes. 69 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { 70 match deserializer.is_human_readable() { 71 true => { 72 // Parse the confirmed transaction from a string into a value. 73 let mut object = serde_json::Value::deserialize(deserializer)?; 74 75 // Parse the index. 76 let index: u32 = DeserializeExt::take_from_value::<D>(&mut object, "index")?; 77 // Parse the transaction. 78 let transaction: Transaction<N> = DeserializeExt::take_from_value::<D>(&mut object, "transaction")?; 79 80 // Parse the status and type. 81 let status = object.get("status").and_then(|t| t.as_str()); 82 let type_ = object.get("type").and_then(|t| t.as_str()); 83 84 // Recover the confirmed transaction. 85 match (status, type_) { 86 (Some("accepted"), Some("deploy")) => { 87 // Parse the finalize operations. 88 let finalize: Vec<_> = DeserializeExt::take_from_value::<D>(&mut object, "finalize")?; 89 // Return the accepted deploy transaction. 90 Self::accepted_deploy(index, transaction, finalize).map_err(de::Error::custom) 91 } 92 (Some("accepted"), Some("execute")) => { 93 // Parse the finalize operations. 94 let finalize: Vec<_> = DeserializeExt::take_from_value::<D>(&mut object, "finalize")?; 95 // Return the accepted execute transaction. 96 Self::accepted_execute(index, transaction, finalize).map_err(de::Error::custom) 97 } 98 (Some("rejected"), Some("deploy")) => { 99 // Parse the rejected deployment. 100 let rejected: Rejected<N> = DeserializeExt::take_from_value::<D>(&mut object, "rejected")?; 101 // Parse the finalize operations. 102 let finalize: Vec<_> = DeserializeExt::take_from_value::<D>(&mut object, "finalize")?; 103 // Return the rejected deploy transaction. 104 Self::rejected_deploy(index, transaction, rejected, finalize).map_err(de::Error::custom) 105 } 106 (Some("rejected"), Some("execute")) => { 107 // Parse the rejected execution. 108 let rejected: Rejected<N> = DeserializeExt::take_from_value::<D>(&mut object, "rejected")?; 109 // Parse the finalize operations. 110 let finalize: Vec<_> = DeserializeExt::take_from_value::<D>(&mut object, "finalize")?; 111 // Return the rejected execute transaction. 112 Self::rejected_execute(index, transaction, rejected, finalize).map_err(de::Error::custom) 113 } 114 _ => Err(de::Error::custom("Invalid confirmed transaction type")), 115 } 116 } 117 false => { 118 FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "confirmed transaction") 119 } 120 } 121 } 122 } 123 124 #[cfg(test)] 125 mod tests { 126 use super::*; 127 128 fn check_serde_json< 129 T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, 130 >( 131 expected: T, 132 ) { 133 // Serialize 134 let expected_string = expected.to_string(); 135 let candidate_string = serde_json::to_string(&expected).unwrap(); 136 let candidate = serde_json::from_str::<T>(&candidate_string).unwrap(); 137 assert_eq!(expected, candidate); 138 assert_eq!(expected_string, candidate_string); 139 assert_eq!(expected_string, candidate.to_string()); 140 141 // Deserialize 142 assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}"))); 143 assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap()); 144 } 145 146 fn check_bincode< 147 T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, 148 >( 149 expected: T, 150 ) { 151 // Serialize 152 let expected_bytes = expected.to_bytes_le().unwrap(); 153 let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap(); 154 assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); 155 156 // Deserialize 157 assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap()); 158 assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap()); 159 } 160 161 #[test] 162 fn test_serde_json() { 163 for transaction in crate::transactions::confirmed::test_helpers::sample_confirmed_transactions() { 164 check_serde_json(transaction); 165 } 166 } 167 168 #[test] 169 fn test_bincode() { 170 for transaction in crate::transactions::confirmed::test_helpers::sample_confirmed_transactions() { 171 check_bincode(transaction); 172 } 173 } 174 }