snarkvm_ledger_block/transition/output/
bytes.rs1use super::*;
17
18impl<N: Network> FromBytes for Output<N> {
19 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
21 let index = Variant::read_le(&mut reader)?;
22 let literal = match index {
23 0 => {
24 let plaintext_hash: Field<N> = FromBytes::read_le(&mut reader)?;
25 let plaintext_exists: bool = FromBytes::read_le(&mut reader)?;
26 let plaintext = match plaintext_exists {
27 true => Some(FromBytes::read_le(&mut reader)?),
28 false => None,
29 };
30
31 Self::Constant(plaintext_hash, plaintext)
32 }
33 1 => {
34 let plaintext_hash: Field<N> = FromBytes::read_le(&mut reader)?;
35 let plaintext_exists: bool = FromBytes::read_le(&mut reader)?;
36 let plaintext = match plaintext_exists {
37 true => Some(FromBytes::read_le(&mut reader)?),
38 false => None,
39 };
40 Self::Public(plaintext_hash, plaintext)
41 }
42 2 => {
43 let ciphertext_hash: Field<N> = FromBytes::read_le(&mut reader)?;
44 let ciphertext_exists: bool = FromBytes::read_le(&mut reader)?;
45 let ciphertext = match ciphertext_exists {
46 true => Some(FromBytes::read_le(&mut reader)?),
47 false => None,
48 };
49 Self::Private(ciphertext_hash, ciphertext)
50 }
51 3 => {
52 let commitment = FromBytes::read_le(&mut reader)?;
53 let checksum = FromBytes::read_le(&mut reader)?;
54 let record_ciphertext_exists: bool = FromBytes::read_le(&mut reader)?;
55 let record_ciphertext: Option<Record<N, _>> = match record_ciphertext_exists {
56 true => Some(FromBytes::read_le(&mut reader)?),
57 false => None,
58 };
59 let sender_ciphertext = match &record_ciphertext {
61 Some(record) => match record.version().is_zero() {
62 true => None,
63 false => {
64 let sender_ciphertext_version: u8 = FromBytes::read_le(&mut reader)?;
66 if sender_ciphertext_version != 0 {
68 return Err(error(format!(
69 "Failed to decode sender ciphertext version {sender_ciphertext_version}"
70 )));
71 }
72 Some(FromBytes::read_le(&mut reader)?)
74 }
75 },
76 None => None,
77 };
78
79 Self::Record(commitment, checksum, record_ciphertext, sender_ciphertext)
80 }
81 4 => {
82 let commitment = FromBytes::read_le(&mut reader)?;
83 Self::ExternalRecord(commitment)
84 }
85 5 => {
86 let future_hash: Field<N> = FromBytes::read_le(&mut reader)?;
87 let future_exists: bool = FromBytes::read_le(&mut reader)?;
88 let future = match future_exists {
89 true => Some(FromBytes::read_le(&mut reader)?),
90 false => None,
91 };
92 Self::Future(future_hash, future)
93 }
94 6.. => return Err(error(format!("Failed to decode output variant {index}"))),
95 };
96 Ok(literal)
97 }
98}
99
100impl<N: Network> ToBytes for Output<N> {
101 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
103 match self {
104 Self::Constant(plaintext_hash, plaintext) => {
105 (0 as Variant).write_le(&mut writer)?;
106 plaintext_hash.write_le(&mut writer)?;
107 match plaintext {
108 Some(plaintext) => {
109 true.write_le(&mut writer)?;
110 plaintext.write_le(&mut writer)
111 }
112 None => false.write_le(&mut writer),
113 }
114 }
115 Self::Public(plaintext_hash, plaintext) => {
116 (1 as Variant).write_le(&mut writer)?;
117 plaintext_hash.write_le(&mut writer)?;
118 match plaintext {
119 Some(plaintext) => {
120 true.write_le(&mut writer)?;
121 plaintext.write_le(&mut writer)
122 }
123 None => false.write_le(&mut writer),
124 }
125 }
126 Self::Private(ciphertext_hash, ciphertext) => {
127 (2 as Variant).write_le(&mut writer)?;
128 ciphertext_hash.write_le(&mut writer)?;
129 match ciphertext {
130 Some(ciphertext) => {
131 true.write_le(&mut writer)?;
132 ciphertext.write_le(&mut writer)
133 }
134 None => false.write_le(&mut writer),
135 }
136 }
137 Self::Record(commitment, checksum, record_ciphertext, sender_ciphertext) => {
138 (3 as Variant).write_le(&mut writer)?;
139 commitment.write_le(&mut writer)?;
140 checksum.write_le(&mut writer)?;
141 match record_ciphertext {
142 Some(record) => {
143 true.write_le(&mut writer)?;
144 record.write_le(&mut writer)?;
145 if !record.version().is_zero() {
147 0u8.write_le(&mut writer)?;
149 match sender_ciphertext {
151 Some(sender) => sender.write_le(&mut writer)?,
152 None => {
153 return Err(error(
154 "Failed to encode sender ciphertext for non-zero version record",
155 ));
156 }
157 }
158 }
159 Ok(())
160 }
161 None => false.write_le(&mut writer),
162 }
163 }
164 Self::ExternalRecord(commitment) => {
165 (4 as Variant).write_le(&mut writer)?;
166 commitment.write_le(&mut writer)
167 }
168 Self::Future(future_hash, future) => {
169 (5 as Variant).write_le(&mut writer)?;
170 future_hash.write_le(&mut writer)?;
171 match future {
172 Some(future) => {
173 true.write_le(&mut writer)?;
174 future.write_le(&mut writer)
175 }
176 None => false.write_le(&mut writer),
177 }
178 }
179 }
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186
187 #[test]
188 fn test_bytes() {
189 for (_, expected) in crate::transition::output::test_helpers::sample_outputs() {
190 let expected_bytes = expected.to_bytes_le().unwrap();
192 assert_eq!(expected, Output::read_le(&expected_bytes[..]).unwrap());
193 }
194 }
195}