snarkvm_console_program/data/future/
bytes.rs

1// Copyright 2024 Aleo Network Foundation
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 Future<N> {
19    /// Reads in a future from a buffer.
20    fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
21        // Read the program ID.
22        let program_id = ProgramID::read_le(&mut reader)?;
23        // Read the function name.
24        let function_name = Identifier::<N>::read_le(&mut reader)?;
25        // Read the number of arguments to the future.
26        let num_arguments = u8::read_le(&mut reader)? as usize;
27        if num_arguments > N::MAX_INPUTS {
28            return Err(error("Failed to read future: too many arguments"));
29        };
30        // Read the arguments.
31        let mut arguments = Vec::with_capacity(num_arguments);
32        for _ in 0..num_arguments {
33            // Read the argument (in 2 steps to prevent infinite recursion).
34            let num_bytes = u16::read_le(&mut reader)?;
35            // Read the argument bytes.
36            let mut bytes = Vec::new();
37            (&mut reader).take(num_bytes as u64).read_to_end(&mut bytes)?;
38            // Recover the argument.
39            let entry = Argument::read_le(&mut bytes.as_slice())?;
40            // Add the argument.
41            arguments.push(entry);
42        }
43        // Return the future.
44        Ok(Self::new(program_id, function_name, arguments))
45    }
46}
47
48impl<N: Network> ToBytes for Future<N> {
49    /// Writes a future to a buffer.
50    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
51        // Write the program ID.
52        self.program_id.write_le(&mut writer)?;
53        // Write the function name.
54        self.function_name.write_le(&mut writer)?;
55        // Write the number of arguments.
56        if self.arguments.len() > N::MAX_INPUTS {
57            return Err(error("Failed to write future: too many arguments"));
58        };
59        u8::try_from(self.arguments.len()).map_err(error)?.write_le(&mut writer)?;
60        // Write each argument.
61        for argument in &self.arguments {
62            // Write the argument (performed in 2 steps to prevent infinite recursion).
63            let bytes = argument.to_bytes_le().map_err(error)?;
64            // Write the number of bytes.
65            u16::try_from(bytes.len()).map_err(error)?.write_le(&mut writer)?;
66            // Write the bytes.
67            bytes.write_le(&mut writer)?;
68        }
69        Ok(())
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use snarkvm_console_network::MainnetV0;
77
78    type CurrentNetwork = MainnetV0;
79
80    #[test]
81    fn test_bytes() -> Result<()> {
82        // Check the future manually.
83        let expected =
84            Future::<CurrentNetwork>::from_str("{ program_id: credits.aleo, function_name: transfer, arguments: [] }")?;
85
86        // Check the byte representation.
87        let expected_bytes = expected.to_bytes_le()?;
88        assert_eq!(expected, Future::read_le(&expected_bytes[..])?);
89
90        Ok(())
91    }
92}