snarkvm_ledger_block/transactions/confirmed/bytes.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> FromBytes for ConfirmedTransaction<N> {
19 /// Reads the confirmed transaction from a buffer.
20 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
21 let variant = u8::read_le(&mut reader)?;
22 match variant {
23 0 => {
24 // Read the index.
25 let index = u32::read_le(&mut reader)?;
26 // Read the transaction.
27 let transaction = Transaction::<N>::read_le(&mut reader)?;
28 // Read the number of finalize operations.
29 let num_finalize = NumFinalizeSize::read_le(&mut reader)?;
30 // Ensure the number of finalize operations is within bounds.
31 if num_finalize as usize > N::MAX_COMMANDS {
32 return Err(error(format!(
33 "ConfirmedTransaction (from 'read_le') has too many finalize operations ({} > {})",
34 num_finalize,
35 N::MAX_COMMANDS
36 )));
37 }
38 // Read the finalize operations.
39 let finalize =
40 (0..num_finalize).map(|_| FromBytes::read_le(&mut reader)).collect::<Result<Vec<_>, _>>()?;
41 // Return the confirmed transaction.
42 Self::accepted_deploy(index, transaction, finalize).map_err(error)
43 }
44 1 => {
45 // Read the index.
46 let index = u32::read_le(&mut reader)?;
47 // Read the transaction.
48 let transaction = Transaction::<N>::read_le(&mut reader)?;
49 // Read the number of finalize operations.
50 let num_finalize = NumFinalizeSize::read_le(&mut reader)?;
51 // Ensure the number of finalize operations is within bounds.
52 if num_finalize as usize > N::MAX_COMMANDS {
53 return Err(error(format!(
54 "ConfirmedTransaction (from 'read_le') has too many finalize operations ({} > {})",
55 num_finalize,
56 N::MAX_COMMANDS
57 )));
58 }
59 // Read the finalize operations.
60 let finalize =
61 (0..num_finalize).map(|_| FromBytes::read_le(&mut reader)).collect::<Result<Vec<_>, _>>()?;
62 // Return the confirmed transaction.
63 Self::accepted_execute(index, transaction, finalize).map_err(error)
64 }
65 2 => {
66 // Read the index.
67 let index = u32::read_le(&mut reader)?;
68 // Read the transaction.
69 let transaction = Transaction::<N>::read_le(&mut reader)?;
70 // Read the rejected deployment.
71 let rejected = Rejected::<N>::read_le(&mut reader)?;
72 // Read the number of finalize operations.
73 let num_finalize = NumFinalizeSize::read_le(&mut reader)?;
74 // Ensure the number of finalize operations is within bounds.
75 if num_finalize as usize > N::MAX_COMMANDS {
76 return Err(error(format!(
77 "ConfirmedTransaction (from 'read_le') has too many finalize operations ({} > {})",
78 num_finalize,
79 N::MAX_COMMANDS
80 )));
81 }
82 // Read the finalize operations.
83 let finalize =
84 (0..num_finalize).map(|_| FromBytes::read_le(&mut reader)).collect::<Result<Vec<_>, _>>()?;
85 // Return the confirmed transaction.
86 Self::rejected_deploy(index, transaction, rejected, finalize).map_err(error)
87 }
88 3 => {
89 // Read the index.
90 let index = u32::read_le(&mut reader)?;
91 // Read the transaction.
92 let transaction = Transaction::<N>::read_le(&mut reader)?;
93 // Read the rejected execution.
94 let rejected = Rejected::<N>::read_le(&mut reader)?;
95 // Read the number of finalize operations.
96 let num_finalize = NumFinalizeSize::read_le(&mut reader)?;
97 // Ensure the number of finalize operations is within bounds.
98 if num_finalize as usize > N::MAX_COMMANDS {
99 return Err(error(format!(
100 "ConfirmedTransaction (from 'read_le') has too many finalize operations ({} > {})",
101 num_finalize,
102 N::MAX_COMMANDS
103 )));
104 }
105 // Read the finalize operations.
106 let finalize =
107 (0..num_finalize).map(|_| FromBytes::read_le(&mut reader)).collect::<Result<Vec<_>, _>>()?;
108 // Return the confirmed transaction.
109 Self::rejected_execute(index, transaction, rejected, finalize).map_err(error)
110 }
111 4.. => Err(error(format!("Failed to decode confirmed transaction variant {variant}"))),
112 }
113 }
114}
115
116impl<N: Network> ToBytes for ConfirmedTransaction<N> {
117 /// Writes the confirmed transaction to a buffer.
118 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
119 match self {
120 Self::AcceptedDeploy(index, transaction, finalize) => {
121 // Write the variant.
122 0u8.write_le(&mut writer)?;
123 // Write the index.
124 index.write_le(&mut writer)?;
125 // Write the transaction.
126 transaction.write_le(&mut writer)?;
127 // Write the number of finalize operations.
128 NumFinalizeSize::try_from(finalize.len()).map_err(error)?.write_le(&mut writer)?;
129 // Write the finalize operations.
130 finalize.iter().try_for_each(|finalize| finalize.write_le(&mut writer))
131 }
132 Self::AcceptedExecute(index, transaction, finalize) => {
133 // Write the variant.
134 1u8.write_le(&mut writer)?;
135 // Write the index.
136 index.write_le(&mut writer)?;
137 // Write the transaction.
138 transaction.write_le(&mut writer)?;
139 // Write the number of finalize operations.
140 NumFinalizeSize::try_from(finalize.len()).map_err(error)?.write_le(&mut writer)?;
141 // Write the finalize operations.
142 finalize.iter().try_for_each(|finalize| finalize.write_le(&mut writer))
143 }
144 Self::RejectedDeploy(index, transaction, rejected, finalize) => {
145 // Write the variant.
146 2u8.write_le(&mut writer)?;
147 // Write the index.
148 index.write_le(&mut writer)?;
149 // Write the transaction.
150 transaction.write_le(&mut writer)?;
151 // Write the rejected deployment.
152 rejected.write_le(&mut writer)?;
153 // Write the number of finalize operations.
154 NumFinalizeSize::try_from(finalize.len()).map_err(error)?.write_le(&mut writer)?;
155 // Write the finalize operations.
156 finalize.iter().try_for_each(|finalize| finalize.write_le(&mut writer))
157 }
158 Self::RejectedExecute(index, transaction, rejected, finalize) => {
159 // Write the variant.
160 3u8.write_le(&mut writer)?;
161 // Write the index.
162 index.write_le(&mut writer)?;
163 // Write the transaction.
164 transaction.write_le(&mut writer)?;
165 // Write the rejected execution.
166 rejected.write_le(&mut writer)?;
167 // Write the number of finalize operations.
168 NumFinalizeSize::try_from(finalize.len()).map_err(error)?.write_le(&mut writer)?;
169 // Write the finalize operations.
170 finalize.iter().try_for_each(|finalize| finalize.write_le(&mut writer))
171 }
172 }
173 }
174}
175
176#[cfg(test)]
177mod tests {
178 use super::*;
179
180 #[test]
181 fn test_bytes() {
182 for expected in crate::transactions::confirmed::test_helpers::sample_confirmed_transactions() {
183 // Check the byte representation.
184 let expected_bytes = expected.to_bytes_le().unwrap();
185 assert_eq!(expected, ConfirmedTransaction::read_le(&expected_bytes[..]).unwrap());
186 }
187 }
188}