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(&data, self.max_num_length, self.verify_minimal_data, self.after_genesis)
81 }
82
83 pub fn pop_bool(&mut self) -> Result<bool, InterpreterError> {
85 let data = self.pop_byte_array()?;
86 Ok(as_bool(&data))
87 }
88
89 pub fn peek_byte_array(&self, idx: i32) -> Result<Vec<u8>, InterpreterError> {
91 let sz = self.stk.len() as i32;
92 if idx < 0 || idx >= sz {
93 return Err(InterpreterError::new(
94 InterpreterErrorCode::InvalidStackOperation,
95 format!("index {} is invalid for stack size {}", idx, sz),
96 ));
97 }
98 Ok(self.stk[(sz - idx - 1) as usize].clone())
99 }
100
101 pub fn peek_int(&self, idx: i32) -> Result<ScriptNumber, InterpreterError> {
103 let data = self.peek_byte_array(idx)?;
104 ScriptNumber::from_bytes(&data, self.max_num_length, self.verify_minimal_data, self.after_genesis)
105 }
106
107 pub fn peek_bool(&self, idx: i32) -> Result<bool, InterpreterError> {
109 let data = self.peek_byte_array(idx)?;
110 Ok(as_bool(&data))
111 }
112
113 fn nip_n(&mut self, idx: i32) -> Result<Vec<u8>, InterpreterError> {
114 let sz = self.stk.len() as i32;
115 if idx < 0 || idx > sz - 1 {
116 return Err(InterpreterError::new(
117 InterpreterErrorCode::InvalidStackOperation,
118 format!("index {} is invalid for stack size {}", idx, sz),
119 ));
120 }
121 let pos = (sz - idx - 1) as usize;
122 Ok(self.stk.remove(pos))
123 }
124
125 pub fn nip_n_discard(&mut self, idx: i32) -> Result<(), InterpreterError> {
127 self.nip_n(idx)?;
128 Ok(())
129 }
130
131 pub fn tuck(&mut self) -> Result<(), InterpreterError> {
133 let so2 = self.pop_byte_array()?;
134 let so1 = self.pop_byte_array()?;
135 self.push_byte_array(so2.clone());
136 self.push_byte_array(so1);
137 self.push_byte_array(so2);
138 Ok(())
139 }
140
141 pub fn drop_n(&mut self, n: i32) -> Result<(), InterpreterError> {
143 if n < 1 {
144 return Err(InterpreterError::new(
145 InterpreterErrorCode::InvalidStackOperation,
146 format!("attempt to drop {} items from stack", n),
147 ));
148 }
149 for _ in 0..n {
150 self.pop_byte_array()?;
151 }
152 Ok(())
153 }
154
155 pub fn dup_n(&mut self, n: i32) -> Result<(), InterpreterError> {
157 if n < 1 {
158 return Err(InterpreterError::new(
159 InterpreterErrorCode::InvalidStackOperation,
160 format!("attempt to dup {} stack items", n),
161 ));
162 }
163 for _ in (0..n).rev() {
164 let so = self.peek_byte_array(n - 1)?;
165 self.push_byte_array(so);
166 }
167 Ok(())
168 }
169
170 pub fn rot_n(&mut self, n: i32) -> Result<(), InterpreterError> {
172 if n < 1 {
173 return Err(InterpreterError::new(
174 InterpreterErrorCode::InvalidStackOperation,
175 format!("attempt to rotate {} stack items", n),
176 ));
177 }
178 let entry = 3 * n - 1;
179 for _ in (0..n).rev() {
180 let so = self.nip_n(entry)?;
181 self.push_byte_array(so);
182 }
183 Ok(())
184 }
185
186 pub fn swap_n(&mut self, n: i32) -> Result<(), InterpreterError> {
188 if n < 1 {
189 return Err(InterpreterError::new(
190 InterpreterErrorCode::InvalidStackOperation,
191 format!("attempt to swap {} stack items", n),
192 ));
193 }
194 let entry = 2 * n - 1;
195 for _ in (0..n).rev() {
196 let so = self.nip_n(entry)?;
197 self.push_byte_array(so);
198 }
199 Ok(())
200 }
201
202 pub fn over_n(&mut self, n: i32) -> Result<(), InterpreterError> {
204 if n < 1 {
205 return Err(InterpreterError::new(
206 InterpreterErrorCode::InvalidStackOperation,
207 format!("attempt to perform over on {} stack items", n),
208 ));
209 }
210 let entry = 2 * n - 1;
211 for _ in (0..n).rev() {
212 let so = self.peek_byte_array(entry)?;
213 self.push_byte_array(so);
214 }
215 Ok(())
216 }
217
218 pub fn pick_n(&mut self, n: i32) -> Result<(), InterpreterError> {
220 let so = self.peek_byte_array(n)?;
221 self.push_byte_array(so);
222 Ok(())
223 }
224
225 pub fn roll_n(&mut self, n: i32) -> Result<(), InterpreterError> {
227 let so = self.nip_n(n)?;
228 self.push_byte_array(so);
229 Ok(())
230 }
231
232 pub fn get_stack(&self) -> Vec<Vec<u8>> {
234 self.stk.clone()
235 }
236
237 pub fn set_stack(&mut self, data: Vec<Vec<u8>>) {
239 self.stk = data;
240 }
241
242 pub fn clear(&mut self) {
244 self.stk.clear();
245 }
246}
247
248pub struct BoolStack {
250 stk: Vec<bool>,
251}
252
253impl BoolStack {
254 pub fn new() -> Self {
256 BoolStack { stk: Vec::new() }
257 }
258
259 pub fn push_bool(&mut self, b: bool) {
261 self.stk.push(b);
262 }
263
264 pub fn pop_bool(&mut self) -> Result<bool, InterpreterError> {
266 self.stk.pop().ok_or_else(|| {
267 InterpreterError::new(
268 InterpreterErrorCode::InvalidStackOperation,
269 "bool stack empty".to_string(),
270 )
271 })
272 }
273
274 pub fn depth(&self) -> i32 {
276 self.stk.len() as i32
277 }
278}
279
280#[cfg(test)]
281mod tests {
282 use super::*;
283
284 #[test]
285 fn test_as_bool() {
286 assert!(!as_bool(&[]));
287 assert!(!as_bool(&[0x00]));
288 assert!(!as_bool(&[0x80])); assert!(as_bool(&[0x01]));
290 assert!(as_bool(&[0x00, 0x01]));
291 assert!(!as_bool(&[0x00, 0x00]));
292 assert!(!as_bool(&[0x00, 0x80])); }
294
295 #[test]
296 fn test_stack_basic_ops() {
297 let mut s = Stack::new(4, false, false);
298 s.push_byte_array(vec![1, 2, 3]);
299 s.push_byte_array(vec![4, 5]);
300 assert_eq!(s.depth(), 2);
301 let top = s.pop_byte_array().unwrap();
302 assert_eq!(top, vec![4, 5]);
303 assert_eq!(s.depth(), 1);
304 }
305
306 #[test]
307 fn test_stack_dup() {
308 let mut s = Stack::new(4, false, false);
309 s.push_byte_array(vec![1]);
310 s.push_byte_array(vec![2]);
311 s.dup_n(2).unwrap();
312 assert_eq!(s.depth(), 4);
313 assert_eq!(s.pop_byte_array().unwrap(), vec![2]);
314 assert_eq!(s.pop_byte_array().unwrap(), vec![1]);
315 }
316
317 #[test]
318 fn test_stack_swap() {
319 let mut s = Stack::new(4, false, false);
320 s.push_byte_array(vec![1]);
321 s.push_byte_array(vec![2]);
322 s.swap_n(1).unwrap();
323 assert_eq!(s.pop_byte_array().unwrap(), vec![1]);
324 assert_eq!(s.pop_byte_array().unwrap(), vec![2]);
325 }
326}