1#![cfg_attr(not(feature = "std"), no_std)]
3#![deny(
4 unused,
5 warnings,
6 future_incompatible,
7 nonstandard_style,
8 rust_2018_idioms,
9 missing_docs,
10 unused_imports
11)]
12#![forbid(unsafe_code)]
13
14pub mod base;
16pub mod config;
18pub mod error;
20pub mod machine;
26pub mod memory;
28
29#[cfg(test)]
30mod tests {
31 use crate::base::{Base, UsizeConvertible, U256};
32 use crate::config::{ConfigArgs, DefaultConfig};
33 use crate::machine::{
34 RAMMachine, RegisterMachine, StackMachine, StateMachine256, StateMachine32,
35 };
36
37 #[test]
38 fn sm256_write_read_one_cell() {
39 let mut sm = StateMachine256::new(DefaultConfig::default());
40 let chunk = U256::from_bytes([5u8; 32]);
41 assert!(sm.write(sm.base_address(), chunk).is_ok());
42 let read_result = sm.read(sm.base_address());
43 assert!(read_result.is_ok());
44 assert_eq!(read_result.unwrap(), chunk);
45 }
46
47 #[test]
48 fn sm256_read_empty_cell() {
49 let mut sm = StateMachine256::new(DefaultConfig::default());
50 let chunk = U256::from_bytes([0u8; 32]);
51 let read_result = sm.read(sm.base_address());
52 assert!(read_result.is_ok());
53 assert_eq!(read_result.unwrap(), chunk);
54 }
55
56 #[test]
57 fn sm256_write_one_cell_read_two_cell() {
58 let mut sm = StateMachine256::new(DefaultConfig::default());
59 let chunk_1 = U256::from_bytes([5u8; 32]);
60 let chunk_2 = U256::from_bytes([10u8; 32]);
61 let base_addr = sm.base_address().to_usize();
62
63 let expected: [u8; 32] = [[5u8; 17].as_slice(), [10u8; 15].as_slice()]
64 .concat()
65 .try_into()
66 .unwrap();
67
68 assert!(sm.write(U256::from_usize(base_addr), chunk_1).is_ok());
69 assert!(sm.write(U256::from_usize(base_addr + 32), chunk_2).is_ok());
70 let read_result = sm.read(U256::from_usize(base_addr + 15));
71 assert!(read_result.is_ok());
72 assert_eq!(read_result.unwrap(), U256::from_bytes(expected));
73 }
74
75 #[test]
76 fn sm256_write_two_cell_read_one_cell() {
77 let mut sm = StateMachine256::new(DefaultConfig::default());
78 let base_addr = sm.base_address().to_usize();
79
80 let chunk = U256::from_bytes([1u8; 32]);
81 assert!(sm.write(U256::from_usize(base_addr + 23), chunk).is_ok());
82 let expected_lo: [u8; 32] = [[0u8; 23].as_slice(), [1u8; 9].as_slice()]
83 .concat()
84 .try_into()
85 .unwrap();
86 let expected_hi: [u8; 32] = [[1u8; 23].as_slice(), [0u8; 9].as_slice()]
87 .concat()
88 .try_into()
89 .unwrap();
90
91 let read_result_lo = sm.read(U256::from_usize(base_addr));
92 let read_result_hi = sm.read(U256::from_usize(base_addr + 32));
93
94 assert!(read_result_lo.is_ok());
95 assert!(read_result_hi.is_ok());
96 assert_eq!(read_result_lo.unwrap(), U256::from_bytes(expected_lo));
97 assert_eq!(read_result_hi.unwrap(), U256::from_bytes(expected_hi));
98 }
99
100 #[test]
101 #[should_panic]
102 fn sm32_read_prohibited_cell() {
103 let mut sm = StateMachine32::new(DefaultConfig::default());
104 assert_eq!(sm.read(64).unwrap(), 0u32);
105 }
106
107 #[test]
108 fn sm32_read_empty_cell() {
109 let mut sm = StateMachine32::new(DefaultConfig::default());
110 assert_eq!(sm.read(sm.base_address() + 64).unwrap(), 0u32);
111 }
112
113 #[test]
114 fn sm32_write_read_one_cell() {
115 let mut sm = StateMachine32::new(DefaultConfig::default());
116 let chunk = 12u32;
117 assert!(sm.write(sm.base_address(), chunk).is_ok());
118 assert_eq!(sm.read(sm.base_address()).unwrap(), 12u32);
119 }
120
121 #[test]
122 fn sm32_write_one_cell_read_two_cells() {
123 let mut sm = StateMachine32::new(DefaultConfig::default());
124 let chunk_1 = u32::from_bytes([7u8; 4]);
125 let chunk_2 = u32::from_bytes([10u8; 4]);
126 assert!(sm.write(sm.base_address(), chunk_1).is_ok());
127 assert!(sm.write(sm.base_address() + 4u32, chunk_2).is_ok());
128 assert_eq!(
129 sm.read(sm.base_address() + 3u32).unwrap(),
130 u32::from_be_bytes([7u8, 10, 10, 10])
131 );
132 }
133
134 #[test]
135 fn sm32_write_two_cells_read_one_cells() {
136 let mut sm = StateMachine32::new(DefaultConfig::default());
137 let chunk = u32::from_bytes([3u8; 4]);
138 assert!(sm.write(sm.base_address() + 2u32, chunk).is_ok());
139 assert_eq!(sm.read(sm.base_address()).unwrap(), 0x00000303u32);
140 assert_eq!(sm.read(sm.base_address() + 4u32).unwrap(), 0x03030000u32);
141 }
142
143 #[test]
144 fn u256_test() {
145 let chunk_1 = U256::from_bytes([9u8; 32]);
146 let chunk_2 = U256::from_usize(10);
147 assert_eq!(chunk_1.to_bytes(), [9u8; 32]);
148 assert_eq!(U256::zero(), U256::from_bytes([0u8; 32]));
149 assert_eq!(chunk_2.to_usize(), 10 as usize);
150 assert!(!chunk_1.is_zero());
151 }
152
153 #[test]
154 fn u256_arithmetic_test() {
156 let chunk_1 = U256::from_bytes([34u8; 32]);
157 let chunk_2 = U256::from_bytes([17u8; 32]);
158 assert_eq!(chunk_1 / chunk_2, U256::from_usize(2));
159 }
160
161 #[test]
162 fn u32_test() {
163 let chunk_1 = u32::from_bytes([73u8; 4]);
164 let chunk_2 = u32::from_usize(103);
165 assert_eq!(chunk_1.to_bytes(), [73u8; 4]);
166 assert_eq!(u32::zero(), u32::from_bytes([0u8; 4]));
167 assert_eq!(chunk_2.to_usize(), 103 as usize);
168 assert!(!chunk_1.is_zero());
169 }
170
171 #[test]
172 fn u64_test() {
173 let chunk_1 = u64::from_bytes([15u8; 8]);
174 let chunk_2 = u64::from_usize(235);
175 assert_eq!(chunk_1.to_bytes(), [15u8; 8]);
176 assert_eq!(u64::zero(), u64::from_bytes([0u8; 8]));
177 assert_eq!(chunk_2.to_usize(), 235 as usize);
178 assert!(!chunk_1.is_zero());
179 }
180
181 #[test]
182 fn u32_stack_functional() {
183 let mut sm = StateMachine32::new(DefaultConfig::default());
184
185 assert!(sm.push(0x01020304).is_ok());
186 assert!(sm.push(0xaabbccdd).is_ok());
187 assert!(sm.stack_depth() == 2);
188
189 assert_eq!(sm.pop().unwrap(), 0xaabbccdd);
190 assert_eq!(sm.pop().unwrap(), 0x01020304);
191 assert!(sm.stack_depth() == 0);
192 }
193
194 #[test]
195 #[should_panic]
196 fn u32_stack_underflow() {
197 let mut sm = StateMachine32::new(DefaultConfig::default());
198 sm.pop().unwrap();
199 }
200
201 #[test]
202 #[should_panic]
203 fn u32_stack_overflow() {
204 let mut sm = StateMachine32::new(ConfigArgs {
205 head_layout: true,
206 stack_depth: 2,
207 no_register: 0,
208 buffer_size: 64,
209 });
210 assert!(sm.push(0x01020304).is_ok());
211 assert!(sm.push(0x01020304).is_ok());
212 assert!(sm.push(0x01020304).is_ok());
213 assert!(sm.push(0x01020304).is_ok());
214 }
215
216 #[test]
217 fn u32_register_functional() {
218 let mut sm = StateMachine32::new(DefaultConfig::default());
219
220 let r0 = sm.register(0).unwrap();
221 let r1 = sm.register(1).unwrap();
222
223 assert!(sm.set(r0, 0x01020304).is_ok());
224 assert!(sm.set(r1, 0xaabbccdd).is_ok());
225
226 assert_eq!(sm.get(r0).unwrap(), 0x01020304);
227 assert_eq!(sm.get(r1).unwrap(), 0xaabbccdd);
228
229 assert!(sm.mov(r0, r1).is_ok());
230
231 assert!(sm.get(r0).unwrap() == 0xaabbccdd);
232 }
233}