snarkvm_console_program/data/register/
mod.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
16mod bytes;
17mod parse;
18mod serialize;
19
20use crate::Access;
21use snarkvm_console_network::prelude::*;
22
23/// A register contains the location data to a value in memory.
24#[derive(Clone, PartialEq, Eq, Hash)]
25pub enum Register<N: Network> {
26    /// A register contains its locator in memory.
27    Locator(u64),
28    /// A register access contains its locator and access(es) in memory.
29    Access(u64, Vec<Access<N>>),
30}
31
32impl<N: Network> Register<N> {
33    /// Returns the locator of the register.
34    #[inline]
35    pub const fn locator(&self) -> u64 {
36        match self {
37            Self::Locator(locator) => *locator,
38            Self::Access(locator, _) => *locator,
39        }
40    }
41}
42
43impl<N: Network> Ord for Register<N> {
44    /// Ordering is determined by the register locator (any accesses are ignored).
45    fn cmp(&self, other: &Self) -> Ordering {
46        self.locator().cmp(&other.locator())
47    }
48}
49
50impl<N: Network> PartialOrd for Register<N> {
51    /// Ordering is determined by the register locator (any accesses are ignored).
52    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
53        Some(self.cmp(other))
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use crate::{Identifier, U32};
61    use snarkvm_console_network::MainnetV0;
62
63    type CurrentNetwork = MainnetV0;
64
65    #[test]
66    fn test_register_partial_ord() -> Result<()> {
67        // Register::Locator
68        assert_eq!(
69            Some(Ordering::Equal),
70            Register::<CurrentNetwork>::Locator(0).partial_cmp(&Register::<CurrentNetwork>::Locator(0))
71        );
72        assert_eq!(
73            Some(Ordering::Less),
74            Register::<CurrentNetwork>::Locator(0).partial_cmp(&Register::<CurrentNetwork>::Locator(1))
75        );
76        assert_eq!(
77            Some(Ordering::Greater),
78            Register::<CurrentNetwork>::Locator(1).partial_cmp(&Register::<CurrentNetwork>::Locator(0))
79        );
80
81        // Register::Access with Access::Member
82        assert_eq!(
83            Some(Ordering::Equal),
84            Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]).partial_cmp(
85                &Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)])
86            )
87        );
88        assert_eq!(
89            Some(Ordering::Less),
90            Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]).partial_cmp(
91                &Register::<CurrentNetwork>::Access(1, vec![Access::Member(Identifier::from_str("owner")?)])
92            )
93        );
94        assert_eq!(
95            Some(Ordering::Greater),
96            Register::<CurrentNetwork>::Access(1, vec![Access::Member(Identifier::from_str("owner")?)]).partial_cmp(
97                &Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)])
98            )
99        );
100
101        // Register::Access with Access::Index
102        assert_eq!(
103            Some(Ordering::Equal),
104            Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]).partial_cmp(&Register::<
105                CurrentNetwork,
106            >::Access(
107                0,
108                vec![Access::Index(U32::new(0))]
109            ))
110        );
111        assert_eq!(
112            Some(Ordering::Less),
113            Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]).partial_cmp(&Register::<
114                CurrentNetwork,
115            >::Access(
116                1,
117                vec![Access::Index(U32::new(0))]
118            ))
119        );
120        assert_eq!(
121            Some(Ordering::Greater),
122            Register::<CurrentNetwork>::Access(1, vec![Access::Index(U32::new(0))]).partial_cmp(&Register::<
123                CurrentNetwork,
124            >::Access(
125                0,
126                vec![Access::Index(U32::new(0))]
127            ))
128        );
129
130        // Register::Access with a combination of Access::Member and Access::Index
131        assert_eq!(
132            Some(Ordering::Equal),
133            Register::<CurrentNetwork>::Access(0, vec![
134                Access::Member(Identifier::from_str("owner")?),
135                Access::Index(U32::new(0))
136            ])
137            .partial_cmp(&Register::<CurrentNetwork>::Access(0, vec![
138                Access::Member(Identifier::from_str("owner")?),
139                Access::Index(U32::new(0))
140            ]))
141        );
142        assert_eq!(
143            Some(Ordering::Less),
144            Register::<CurrentNetwork>::Access(0, vec![
145                Access::Member(Identifier::from_str("owner")?),
146                Access::Index(U32::new(0))
147            ])
148            .partial_cmp(&Register::<CurrentNetwork>::Access(1, vec![
149                Access::Member(Identifier::from_str("owner")?),
150                Access::Index(U32::new(0))
151            ]))
152        );
153        assert_eq!(
154            Some(Ordering::Greater),
155            Register::<CurrentNetwork>::Access(1, vec![
156                Access::Member(Identifier::from_str("owner")?),
157                Access::Index(U32::new(0))
158            ])
159            .partial_cmp(&Register::<CurrentNetwork>::Access(0, vec![
160                Access::Member(Identifier::from_str("owner")?),
161                Access::Index(U32::new(0))
162            ]))
163        );
164
165        Ok(())
166    }
167
168    #[test]
169    fn test_register_eq() -> Result<()> {
170        // Register::Locator
171        assert_eq!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(0));
172        assert_ne!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(1));
173        assert_ne!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(2));
174        assert_ne!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(3));
175        assert_ne!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(4));
176
177        // Register::Access with Access::Member
178        assert_eq!(
179            Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
180            Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)])
181        );
182        assert_ne!(
183            Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
184            Register::<CurrentNetwork>::Access(1, vec![Access::Member(Identifier::from_str("owner")?)])
185        );
186        assert_ne!(
187            Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
188            Register::<CurrentNetwork>::Access(2, vec![Access::Member(Identifier::from_str("owner")?)])
189        );
190        assert_ne!(
191            Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
192            Register::<CurrentNetwork>::Access(3, vec![Access::Member(Identifier::from_str("owner")?)])
193        );
194        assert_ne!(
195            Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
196            Register::<CurrentNetwork>::Access(4, vec![Access::Member(Identifier::from_str("owner")?)])
197        );
198
199        // Register::Access with Access::Index
200        assert_eq!(
201            Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
202            Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))])
203        );
204        assert_ne!(
205            Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
206            Register::<CurrentNetwork>::Access(1, vec![Access::Index(U32::new(0))])
207        );
208        assert_ne!(
209            Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
210            Register::<CurrentNetwork>::Access(2, vec![Access::Index(U32::new(0))])
211        );
212        assert_ne!(
213            Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
214            Register::<CurrentNetwork>::Access(3, vec![Access::Index(U32::new(0))])
215        );
216        assert_ne!(
217            Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
218            Register::<CurrentNetwork>::Access(4, vec![Access::Index(U32::new(0))])
219        );
220
221        // Register::Access with a combination of Access::Member and Access::Index
222        assert_eq!(
223            Register::<CurrentNetwork>::Access(0, vec![
224                Access::Member(Identifier::from_str("owner")?),
225                Access::Index(U32::new(0))
226            ]),
227            Register::<CurrentNetwork>::Access(0, vec![
228                Access::Member(Identifier::from_str("owner")?),
229                Access::Index(U32::new(0))
230            ])
231        );
232        assert_ne!(
233            Register::<CurrentNetwork>::Access(0, vec![
234                Access::Member(Identifier::from_str("owner")?),
235                Access::Index(U32::new(0))
236            ]),
237            Register::<CurrentNetwork>::Access(1, vec![
238                Access::Member(Identifier::from_str("owner")?),
239                Access::Index(U32::new(0))
240            ])
241        );
242        assert_ne!(
243            Register::<CurrentNetwork>::Access(0, vec![
244                Access::Member(Identifier::from_str("owner")?),
245                Access::Index(U32::new(0))
246            ]),
247            Register::<CurrentNetwork>::Access(2, vec![
248                Access::Member(Identifier::from_str("owner")?),
249                Access::Index(U32::new(0))
250            ])
251        );
252        assert_ne!(
253            Register::<CurrentNetwork>::Access(0, vec![
254                Access::Member(Identifier::from_str("owner")?),
255                Access::Index(U32::new(0))
256            ]),
257            Register::<CurrentNetwork>::Access(3, vec![
258                Access::Member(Identifier::from_str("owner")?),
259                Access::Index(U32::new(0))
260            ])
261        );
262        assert_ne!(
263            Register::<CurrentNetwork>::Access(0, vec![
264                Access::Member(Identifier::from_str("owner")?),
265                Access::Index(U32::new(0))
266            ]),
267            Register::<CurrentNetwork>::Access(4, vec![
268                Access::Member(Identifier::from_str("owner")?),
269                Access::Index(U32::new(0))
270            ])
271        );
272
273        Ok(())
274    }
275}