snarkvm_ledger_block/transaction/deployment/
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 Deployment<N> {
19    /// Serializes the deployment 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 => {
23                // Note: `Deployment::version` checks that either both or neither of the program checksum and program owner are present.
24                let len = match self.version().map_err(ser::Error::custom)? {
25                    DeploymentVersion::V1 => 3,
26                    DeploymentVersion::V2 => 5,
27                };
28                let mut deployment = serializer.serialize_struct("Deployment", len)?;
29                deployment.serialize_field("edition", &self.edition)?;
30                deployment.serialize_field("program", &self.program)?;
31                deployment.serialize_field("verifying_keys", &self.verifying_keys)?;
32                if let Some(program_checksum) = &self.program_checksum {
33                    deployment.serialize_field("program_checksum", program_checksum)?;
34                }
35                if let Some(program_owner) = &self.program_owner {
36                    deployment.serialize_field("program_owner", program_owner)?;
37                }
38                deployment.end()
39            }
40            false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
41        }
42    }
43}
44
45impl<'de, N: Network> Deserialize<'de> for Deployment<N> {
46    /// Deserializes the deployment from a string or bytes.
47    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
48        match deserializer.is_human_readable() {
49            true => {
50                // Parse the deployment from a string into a value.
51                let mut deployment = serde_json::Value::deserialize(deserializer)?;
52
53                // Recover the deployment.
54                let deployment = Self::new(
55                    // Retrieve the edition.
56                    DeserializeExt::take_from_value::<D>(&mut deployment, "edition")?,
57                    // Retrieve the program.
58                    DeserializeExt::take_from_value::<D>(&mut deployment, "program")?,
59                    // Retrieve the verifying keys.
60                    DeserializeExt::take_from_value::<D>(&mut deployment, "verifying_keys")?,
61                    // Retrieve the program checksum, if it exists.
62                    serde_json::from_value(
63                        deployment.get_mut("program_checksum").unwrap_or(&mut serde_json::Value::Null).take(),
64                    )
65                    .map_err(de::Error::custom)?,
66                    // Retrieve the owner, if it exists.
67                    serde_json::from_value(
68                        deployment.get_mut("program_owner").unwrap_or(&mut serde_json::Value::Null).take(),
69                    )
70                    .map_err(de::Error::custom)?,
71                )
72                .map_err(de::Error::custom)?;
73
74                Ok(deployment)
75            }
76            false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "deployment"),
77        }
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn test_serde_json() -> Result<()> {
87        let rng = &mut TestRng::default();
88
89        // Sample the deployments.
90        for expected in [
91            test_helpers::sample_deployment_v1(Uniform::rand(rng), rng),
92            test_helpers::sample_deployment_v2(Uniform::rand(rng), rng),
93        ] {
94            // Serialize
95            let expected_string = &expected.to_string();
96            let candidate_string = serde_json::to_string(&expected)?;
97            assert_eq!(expected, serde_json::from_str(&candidate_string)?);
98
99            // Deserialize
100            assert_eq!(expected, Deployment::from_str(expected_string)?);
101            assert_eq!(expected, serde_json::from_str(&candidate_string)?);
102        }
103
104        Ok(())
105    }
106
107    #[test]
108    fn test_bincode() -> Result<()> {
109        let rng = &mut TestRng::default();
110
111        // Sample the deployments
112        for expected in [
113            test_helpers::sample_deployment_v1(Uniform::rand(rng), rng),
114            test_helpers::sample_deployment_v2(Uniform::rand(rng), rng),
115        ] {
116            // Serialize
117            let expected_bytes = expected.to_bytes_le()?;
118            let expected_bytes_with_size_encoding = bincode::serialize(&expected)?;
119            assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]);
120
121            // Deserialize
122            assert_eq!(expected, Deployment::read_le(&expected_bytes[..])?);
123            assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..])?);
124        }
125
126        Ok(())
127    }
128}