1use super::error::{InterpreterError, InterpreterErrorCode};
4use super::scriptnum::ScriptNumber;
5
6pub fn as_bool(t: &[u8]) -> bool {
8 for i in 0..t.len() {
9 if t[i] != 0 {
10 if i == t.len() - 1 && t[i] == 0x80 {
12 return false;
13 }
14 return true;
15 }
16 }
17 false
18}
19
20pub fn from_bool(v: bool) -> Vec<u8> {
22 if v {
23 vec![1]
24 } else {
25 vec![]
26 }
27}
28
29pub struct Stack {
31 pub stk: Vec<Vec<u8>>,
33 pub max_num_length: usize,
35 pub after_genesis: bool,
37 pub verify_minimal_data: bool,
39}
40
41impl Stack {
42 pub fn new(max_num_length: usize, after_genesis: bool, verify_minimal_data: bool) -> Self {
44 Stack {
45 stk: Vec::new(),
46 max_num_length,
47 after_genesis,
48 verify_minimal_data,
49 }
50 }
51
52 pub fn depth(&self) -> i32 {
54 self.stk.len() as i32
55 }
56
57 pub fn push_byte_array(&mut self, data: Vec<u8>) {
59 self.stk.push(data);
60 }
61
62 pub fn push_int(&mut self, n: &ScriptNumber) {
64 self.push_byte_array(n.to_bytes());
65 }
66
67 pub fn push_bool(&mut self, val: bool) {
69 self.push_byte_array(from_bool(val));
70 }
71
72 pub fn pop_byte_array(&mut self) -> Result<Vec<u8>, InterpreterError> {
74 self.nip_n(0)
75 }
76
77 pub fn pop_int(&mut self) -> Result<ScriptNumber, InterpreterError> {
79 let data = self.pop_byte_array()?;
80 ScriptNumber::from_bytes(
81 &data,
82 self.max_num_length,
83 self.verify_minimal_data,
84 self.after_genesis,
85 )
86 }
87
88 pub fn pop_bool(&mut self) -> Result<bool, InterpreterError> {
90 let data = self.pop_byte_array()?;
91 Ok(as_bool(&data))
92 }
93
94 pub fn peek_byte_array(&self, idx: i32) -> Result<Vec<u8>, InterpreterError> {
96 let sz = self.stk.len() as i32;
97 if idx < 0 || idx >= sz {
98 return Err(InterpreterError::new(
99 InterpreterErrorCode::InvalidStackOperation,
100 format!("index {} is invalid for stack size {}", idx, sz),
101 ));
102 }
103 Ok(self.stk[(sz - idx - 1) as usize].clone())
104 }
105
106 pub fn peek_int(&self, idx: i32) -> Result<ScriptNumber, InterpreterError> {
108 let data = self.peek_byte_array(idx)?;
109 ScriptNumber::from_bytes(
110 &data,
111 self.max_num_length,
112 self.verify_minimal_data,
113 self.after_genesis,
114 )
115 }
116
117 pub fn peek_bool(&self, idx: i32) -> Result<bool, InterpreterError> {
119 let data = self.peek_byte_array(idx)?;
120 Ok(as_bool(&data))
121 }
122
123 fn nip_n(&mut self, idx: i32) -> Result<Vec<u8>, InterpreterError> {
124 let sz = self.stk.len() as i32;
125 if idx < 0 || idx > sz - 1 {
126 return Err(InterpreterError::new(
127 InterpreterErrorCode::InvalidStackOperation,
128 format!("index {} is invalid for stack size {}", idx, sz),
129 ));
130 }
131 let pos = (sz - idx - 1) as usize;
132 Ok(self.stk.remove(pos))
133 }
134
135 pub fn nip_n_discard(&mut self, idx: i32) -> Result<(), InterpreterError> {
137 self.nip_n(idx)?;
138 Ok(())
139 }
140
141 pub fn tuck(&mut self) -> Result<(), InterpreterError> {
143 let so2 = self.pop_byte_array()?;
144 let so1 = self.pop_byte_array()?;
145 self.push_byte_array(so2.clone());
146 self.push_byte_array(so1);
147 self.push_byte_array(so2);
148 Ok(())
149 }
150
151 pub fn drop_n(&mut self, n: i32) -> Result<(), InterpreterError> {
153 if n < 1 {
154 return Err(InterpreterError::new(
155 InterpreterErrorCode::InvalidStackOperation,
156 format!("attempt to drop {} items from stack", n),
157 ));
158 }
159 for _ in 0..n {
160 self.pop_byte_array()?;
161 }
162 Ok(())
163 }
164
165 pub fn dup_n(&mut self, n: i32) -> Result<(), InterpreterError> {
167 if n < 1 {
168 return Err(InterpreterError::new(
169 InterpreterErrorCode::InvalidStackOperation,
170 format!("attempt to dup {} stack items", n),
171 ));
172 }
173 for _ in (0..n).rev() {
174 let so = self.peek_byte_array(n - 1)?;
175 self.push_byte_array(so);
176 }
177 Ok(())
178 }
179
180 pub fn rot_n(&mut self, n: i32) -> Result<(), InterpreterError> {
182 if n < 1 {
183 return Err(InterpreterError::new(
184 InterpreterErrorCode::InvalidStackOperation,
185 format!("attempt to rotate {} stack items", n),
186 ));
187 }
188 let entry = 3 * n - 1;
189 for _ in (0..n).rev() {
190 let so = self.nip_n(entry)?;
191 self.push_byte_array(so);
192 }
193 Ok(())
194 }
195
196 pub fn swap_n(&mut self, n: i32) -> Result<(), InterpreterError> {
198 if n < 1 {
199 return Err(InterpreterError::new(
200 InterpreterErrorCode::InvalidStackOperation,
201 format!("attempt to swap {} stack items", n),
202 ));
203 }
204 let entry = 2 * n - 1;
205 for _ in (0..n).rev() {
206 let so = self.nip_n(entry)?;
207 self.push_byte_array(so);
208 }
209 Ok(())
210 }
211
212 pub fn over_n(&mut self, n: i32) -> Result<(), InterpreterError> {
214 if n < 1 {
215 return Err(InterpreterError::new(
216 InterpreterErrorCode::InvalidStackOperation,
217 format!("attempt to perform over on {} stack items", n),
218 ));
219 }
220 let entry = 2 * n - 1;
221 for _ in (0..n).rev() {
222 let so = self.peek_byte_array(entry)?;
223 self.push_byte_array(so);
224 }
225 Ok(())
226 }
227
228 pub fn pick_n(&mut self, n: i32) -> Result<(), InterpreterError> {
230 let so = self.peek_byte_array(n)?;
231 self.push_byte_array(so);
232 Ok(())
233 }
234
235 pub fn roll_n(&mut self, n: i32) -> Result<(), InterpreterError> {
237 let so = self.nip_n(n)?;
238 self.push_byte_array(so);
239 Ok(())
240 }
241
242 pub fn get_stack(&self) -> Vec<Vec<u8>> {
244 self.stk.clone()
245 }
246
247 pub fn set_stack(&mut self, data: Vec<Vec<u8>>) {
249 self.stk = data;
250 }
251
252 pub fn clear(&mut self) {
254 self.stk.clear();
255 }
256}
257
258pub struct BoolStack {
260 stk: Vec<bool>,
261}
262
263impl BoolStack {
264 pub fn new() -> Self {
266 BoolStack { stk: Vec::new() }
267 }
268
269 pub fn push_bool(&mut self, b: bool) {
271 self.stk.push(b);
272 }
273
274 pub fn pop_bool(&mut self) -> Result<bool, InterpreterError> {
276 self.stk.pop().ok_or_else(|| {
277 InterpreterError::new(
278 InterpreterErrorCode::InvalidStackOperation,
279 "bool stack empty".to_string(),
280 )
281 })
282 }
283
284 pub fn depth(&self) -> i32 {
286 self.stk.len() as i32
287 }
288}
289
290#[cfg(test)]
291mod tests {
292 use super::*;
293
294 #[test]
295 fn test_as_bool() {
296 assert!(!as_bool(&[]));
297 assert!(!as_bool(&[0x00]));
298 assert!(!as_bool(&[0x80])); assert!(as_bool(&[0x01]));
300 assert!(as_bool(&[0x00, 0x01]));
301 assert!(!as_bool(&[0x00, 0x00]));
302 assert!(!as_bool(&[0x00, 0x80])); }
304
305 #[test]
306 fn test_stack_basic_ops() {
307 let mut s = Stack::new(4, false, false);
308 s.push_byte_array(vec![1, 2, 3]);
309 s.push_byte_array(vec![4, 5]);
310 assert_eq!(s.depth(), 2);
311 let top = s.pop_byte_array().unwrap();
312 assert_eq!(top, vec![4, 5]);
313 assert_eq!(s.depth(), 1);
314 }
315
316 #[test]
317 fn test_stack_dup() {
318 let mut s = Stack::new(4, false, false);
319 s.push_byte_array(vec![1]);
320 s.push_byte_array(vec![2]);
321 s.dup_n(2).unwrap();
322 assert_eq!(s.depth(), 4);
323 assert_eq!(s.pop_byte_array().unwrap(), vec![2]);
324 assert_eq!(s.pop_byte_array().unwrap(), vec![1]);
325 }
326
327 #[test]
328 fn test_stack_swap() {
329 let mut s = Stack::new(4, false, false);
330 s.push_byte_array(vec![1]);
331 s.push_byte_array(vec![2]);
332 s.swap_n(1).unwrap();
333 assert_eq!(s.pop_byte_array().unwrap(), vec![1]);
334 assert_eq!(s.pop_byte_array().unwrap(), vec![2]);
335 }
336}