Skip to main content

snarkvm_ledger_block/ratify/
serialize.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM 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
16use super::*;
17
18impl<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
49impl<'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)]
94mod 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}