snarkvm_console_program/request/
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 Request<N> {
19    /// Reads the request from a buffer.
20    fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
21        // Read the version.
22        let version = u8::read_le(&mut reader)?;
23        // Ensure the version is valid.
24        if version != 1 {
25            return Err(error("Invalid request version"));
26        }
27
28        // Read the signer.
29        let signer = FromBytes::read_le(&mut reader)?;
30        // Read the network ID.
31        let network_id = FromBytes::read_le(&mut reader)?;
32        // Read the program ID.
33        let program_id = FromBytes::read_le(&mut reader)?;
34        // Read the function name.
35        let function_name = FromBytes::read_le(&mut reader)?;
36
37        // Read the number of inputs.
38        let inputs_len = u16::read_le(&mut reader)?;
39        // Ensure the number of inputs is within bounds.
40        if inputs_len as usize > N::MAX_INPUTS {
41            return Err(error(format!(
42                "Request (from 'read_le') has too many inputs ({} > {})",
43                inputs_len,
44                N::MAX_INPUTS
45            )));
46        }
47        // Read the input IDs.
48        let input_ids = (0..inputs_len).map(|_| FromBytes::read_le(&mut reader)).collect::<Result<Vec<_>, _>>()?;
49        // Read the inputs.
50        let inputs = (0..inputs_len).map(|_| FromBytes::read_le(&mut reader)).collect::<Result<Vec<_>, _>>()?;
51
52        // Read the signature.
53        let signature = FromBytes::read_le(&mut reader)?;
54        // Read the tag secret key.
55        let sk_tag = FromBytes::read_le(&mut reader)?;
56        // Read the transition view key.
57        let tvk = FromBytes::read_le(&mut reader)?;
58        // Read the transition commitment.
59        let tcm = FromBytes::read_le(&mut reader)?;
60        // Read the signer commitment.
61        let scm = FromBytes::read_le(&mut reader)?;
62
63        Ok(Self::from((
64            signer,
65            network_id,
66            program_id,
67            function_name,
68            input_ids,
69            inputs,
70            signature,
71            sk_tag,
72            tvk,
73            tcm,
74            scm,
75        )))
76    }
77}
78
79impl<N: Network> ToBytes for Request<N> {
80    /// Writes the request to a buffer.
81    fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
82        // Write the version.
83        1u8.write_le(&mut writer)?;
84
85        // Write the signer.
86        self.signer.write_le(&mut writer)?;
87        // Write the network ID.
88        self.network_id.write_le(&mut writer)?;
89        // Write the program ID.
90        self.program_id.write_le(&mut writer)?;
91        // Write the function name.
92        self.function_name.write_le(&mut writer)?;
93
94        // Ensure the input IDs and inputs are the same length.
95        if self.input_ids.len() != self.inputs.len() {
96            return Err(error("Invalid request: mismatching number of input IDs and inputs"));
97        }
98
99        // Write the number of inputs.
100        u16::try_from(self.input_ids.len())
101            .or_halt_with::<N>("Request inputs length exceeds u16")
102            .write_le(&mut writer)?;
103        // Write the input IDs.
104        for input_id in &self.input_ids {
105            input_id.write_le(&mut writer)?;
106        }
107        // Write the inputs.
108        for input in &self.inputs {
109            input.write_le(&mut writer)?;
110        }
111
112        // Write the signature.
113        self.signature.write_le(&mut writer)?;
114        // Write the tag secret key.
115        self.sk_tag.write_le(&mut writer)?;
116        // Write the transition view key.
117        self.tvk.write_le(&mut writer)?;
118        // Write the transition commitment.
119        self.tcm.write_le(&mut writer)?;
120        // Write the signer commitment.
121        self.scm.write_le(&mut writer)
122    }
123}
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128
129    #[test]
130    fn test_bytes() {
131        let mut rng = TestRng::default();
132
133        for expected in test_helpers::sample_requests(&mut rng).into_iter() {
134            // Check the byte representation.
135            let expected_bytes = expected.to_bytes_le().unwrap();
136            assert_eq!(expected, Request::read_le(&expected_bytes[..]).unwrap());
137        }
138    }
139}