1#[macro_use]
2mod macros;
3
4use crate::data_stack::{DataStack, OpcodeData};
5use crate::{
6 ScriptSource, TxScriptEngine, TxScriptError, LOCK_TIME_THRESHOLD, MAX_TX_IN_SEQUENCE_NUM, NO_COST_OPCODE,
7 SEQUENCE_LOCK_TIME_DISABLED, SEQUENCE_LOCK_TIME_MASK,
8};
9use blake2b_simd::Params;
10use core::cmp::{max, min};
11use kaspa_consensus_core::hashing::sighash_type::SigHashType;
12use kaspa_consensus_core::tx::VerifiableTransaction;
13use sha2::{Digest, Sha256};
14use std::fmt::{Debug, Formatter};
15
16pub const OP_SMALL_INT_MIN_VAL: u8 = 1;
18pub const OP_SMALL_INT_MAX_VAL: u8 = 16;
20pub const OP_DATA_MIN_VAL: u8 = self::codes::OpData1;
22pub const OP_DATA_MAX_VAL: u8 = self::codes::OpData75;
24pub const OP_1_NEGATE_VAL: u8 = 0x81;
26
27#[derive(Debug, PartialEq, Eq)]
28pub(crate) enum OpCond {
29 False,
30 True,
31 Skip,
32}
33
34impl OpCond {
35 pub fn negate(&self) -> OpCond {
36 match self {
37 OpCond::True => OpCond::False,
38 OpCond::False => OpCond::True,
39 OpCond::Skip => OpCond::Skip,
40 }
41 }
42}
43
44type OpCodeResult = Result<(), TxScriptError>;
45
46pub(crate) struct OpCode<const CODE: u8> {
47 data: Vec<u8>,
48}
49
50impl<const CODE: u8> Debug for OpCode<CODE> {
51 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52 write!(f, "Opcode<{:#2x}>{{ data:{:?} }}", CODE, self.data)
53 }
54}
55
56pub trait OpCodeMetadata: Debug {
57 fn value(&self) -> u8;
59 fn len(&self) -> usize;
61 fn is_conditional(&self) -> bool;
63 fn check_minimal_data_push(&self) -> Result<(), TxScriptError>;
65
66 fn is_disabled(&self) -> bool;
67 fn always_illegal(&self) -> bool;
68 fn is_push_opcode(&self) -> bool;
69 fn get_data(&self) -> &[u8];
70
71 fn is_empty(&self) -> bool {
72 self.len() == 0
73 }
74}
75
76pub trait OpCodeExecution<T: VerifiableTransaction> {
77 fn empty() -> Result<Box<dyn OpCodeImplementation<T>>, TxScriptError>
78 where
79 Self: Sized;
80 #[allow(clippy::new_ret_no_self)]
81 fn new(data: Vec<u8>) -> Result<Box<dyn OpCodeImplementation<T>>, TxScriptError>
82 where
83 Self: Sized;
84
85 fn execute(&self, vm: &mut TxScriptEngine<T>) -> OpCodeResult;
86}
87
88pub trait OpcodeSerialization {
89 fn serialize(&self) -> Vec<u8>;
90 fn deserialize<'i, I: Iterator<Item = &'i u8>, T: VerifiableTransaction>(
91 it: &mut I,
92 ) -> Result<Box<dyn OpCodeImplementation<T>>, TxScriptError>
93 where
94 Self: Sized;
95}
96
97pub trait OpCodeImplementation<T: VerifiableTransaction>: OpCodeExecution<T> + OpCodeMetadata + OpcodeSerialization {}
98
99impl<const CODE: u8> OpCodeMetadata for OpCode<CODE> {
100 fn value(&self) -> u8 {
101 CODE
102 }
103
104 fn is_disabled(&self) -> bool {
105 matches!(
106 CODE,
107 codes::OpCat
108 | codes::OpSubStr
109 | codes::OpLeft
110 | codes::OpRight
111 | codes::OpInvert
112 | codes::OpAnd
113 | codes::OpOr
114 | codes::OpXor
115 | codes::Op2Mul
116 | codes::Op2Div
117 | codes::OpMul
118 | codes::OpDiv
119 | codes::OpMod
120 | codes::OpLShift
121 | codes::OpRShift
122 )
123 }
124
125 fn always_illegal(&self) -> bool {
126 matches!(CODE, codes::OpVerIf | codes::OpVerNotIf)
127 }
128
129 fn is_push_opcode(&self) -> bool {
130 CODE <= NO_COST_OPCODE
131 }
132
133 fn len(&self) -> usize {
134 self.data.len()
135 }
136
137 fn is_conditional(&self) -> bool {
139 self.value() >= 0x63 && self.value() <= 0x68
140 }
141
142 fn check_minimal_data_push(&self) -> Result<(), TxScriptError> {
143 let data_len = self.len();
144 let opcode = self.value();
145
146 if data_len == 0 {
147 if opcode != codes::OpFalse {
148 return Err(TxScriptError::NotMinimalData(format!(
149 "zero length data push is encoded with opcode {self:?} instead of OpFalse"
150 )));
151 }
152 } else if data_len == 1 && OP_SMALL_INT_MIN_VAL <= self.data[0] && self.data[0] <= OP_SMALL_INT_MAX_VAL {
153 if opcode != codes::OpTrue + self.data[0] - 1 {
154 return Err(TxScriptError::NotMinimalData(format!(
155 "zero length data push is encoded with opcode {:?} instead of Op_{}",
156 self, self.data[0]
157 )));
158 }
159 } else if data_len == 1 && self.data[0] == OP_1_NEGATE_VAL {
160 if opcode != codes::Op1Negate {
161 return Err(TxScriptError::NotMinimalData(format!(
162 "data push of the value -1 encoded \
163 with opcode {self:?} instead of OP_1NEGATE"
164 )));
165 }
166 } else if data_len <= OP_DATA_MAX_VAL as usize {
167 if opcode as usize != data_len {
168 return Err(TxScriptError::NotMinimalData(format!(
169 "data push of {data_len} bytes encoded \
170 with opcode {self:?} instead of OP_DATA_{data_len}"
171 )));
172 }
173 } else if data_len <= u8::MAX as usize {
174 if opcode != codes::OpPushData1 {
175 return Err(TxScriptError::NotMinimalData(format!(
176 "data push of {data_len} bytes encoded \
177 with opcode {self:?} instead of OP_PUSHDATA1"
178 )));
179 }
180 } else if data_len < u16::MAX as usize && opcode != codes::OpPushData2 {
181 return Err(TxScriptError::NotMinimalData(format!(
182 "data push of {data_len} bytes encoded \
183 with opcode {self:?} instead of OP_PUSHDATA2"
184 )));
185 }
186 Ok(())
187 }
188
189 fn get_data(&self) -> &[u8] {
190 &self.data
191 }
192}
193
194#[inline]
196fn push_data<T: VerifiableTransaction>(data: Vec<u8>, vm: &mut TxScriptEngine<T>) -> OpCodeResult {
197 vm.dstack.push(data);
198 Ok(())
199}
200
201#[inline]
202fn push_number<T: VerifiableTransaction>(number: i64, vm: &mut TxScriptEngine<T>) -> OpCodeResult {
203 vm.dstack.push_item(number);
204 Ok(())
205}
206
207opcode_list! {
238
239 opcode |Op0| OpFalse<0x00, 1>(self , vm) {
241 vm.dstack.push(vec![]);
242 Ok(())
243 }
244
245 opcode OpData1<0x01, 2>(self, vm) push_data(self.data.clone(), vm)
246 opcode OpData2<0x02, 3>(self, vm) push_data(self.data.clone(), vm)
247 opcode OpData3<0x03, 4>(self, vm) push_data(self.data.clone(), vm)
248 opcode OpData4<0x04, 5>(self, vm) push_data(self.data.clone(), vm)
249 opcode OpData5<0x05, 6>(self, vm) push_data(self.data.clone(), vm)
250 opcode OpData6<0x06, 7>(self, vm) push_data(self.data.clone(), vm)
251 opcode OpData7<0x07, 8>(self, vm) push_data(self.data.clone(), vm)
252 opcode OpData8<0x08, 9>(self, vm) push_data(self.data.clone(), vm)
253 opcode OpData9<0x09, 10>(self, vm) push_data(self.data.clone(), vm)
254 opcode OpData10<0x0a, 11>(self, vm) push_data(self.data.clone(), vm)
255 opcode OpData11<0x0b, 12>(self, vm) push_data(self.data.clone(), vm)
256 opcode OpData12<0x0c, 13>(self, vm) push_data(self.data.clone(), vm)
257 opcode OpData13<0x0d, 14>(self, vm) push_data(self.data.clone(), vm)
258 opcode OpData14<0x0e, 15>(self, vm) push_data(self.data.clone(), vm)
259 opcode OpData15<0x0f, 16>(self, vm) push_data(self.data.clone(), vm)
260 opcode OpData16<0x10, 17>(self, vm) push_data(self.data.clone(), vm)
261 opcode OpData17<0x11, 18>(self, vm) push_data(self.data.clone(), vm)
262 opcode OpData18<0x12, 19>(self, vm) push_data(self.data.clone(), vm)
263 opcode OpData19<0x13, 20>(self, vm) push_data(self.data.clone(), vm)
264 opcode OpData20<0x14, 21>(self, vm) push_data(self.data.clone(), vm)
265 opcode OpData21<0x15, 22>(self, vm) push_data(self.data.clone(), vm)
266 opcode OpData22<0x16, 23>(self, vm) push_data(self.data.clone(), vm)
267 opcode OpData23<0x17, 24>(self, vm) push_data(self.data.clone(), vm)
268 opcode OpData24<0x18, 25>(self, vm) push_data(self.data.clone(), vm)
269 opcode OpData25<0x19, 26>(self, vm) push_data(self.data.clone(), vm)
270 opcode OpData26<0x1a, 27>(self, vm) push_data(self.data.clone(), vm)
271 opcode OpData27<0x1b, 28>(self, vm) push_data(self.data.clone(), vm)
272 opcode OpData28<0x1c, 29>(self, vm) push_data(self.data.clone(), vm)
273 opcode OpData29<0x1d, 30>(self, vm) push_data(self.data.clone(), vm)
274 opcode OpData30<0x1e, 31>(self, vm) push_data(self.data.clone(), vm)
275 opcode OpData31<0x1f, 32>(self, vm) push_data(self.data.clone(), vm)
276 opcode OpData32<0x20, 33>(self, vm) push_data(self.data.clone(), vm)
277 opcode OpData33<0x21, 34>(self, vm) push_data(self.data.clone(), vm)
278 opcode OpData34<0x22, 35>(self, vm) push_data(self.data.clone(), vm)
279 opcode OpData35<0x23, 36>(self, vm) push_data(self.data.clone(), vm)
280 opcode OpData36<0x24, 37>(self, vm) push_data(self.data.clone(), vm)
281 opcode OpData37<0x25, 38>(self, vm) push_data(self.data.clone(), vm)
282 opcode OpData38<0x26, 39>(self, vm) push_data(self.data.clone(), vm)
283 opcode OpData39<0x27, 40>(self, vm) push_data(self.data.clone(), vm)
284 opcode OpData40<0x28, 41>(self, vm) push_data(self.data.clone(), vm)
285 opcode OpData41<0x29, 42>(self, vm) push_data(self.data.clone(), vm)
286 opcode OpData42<0x2a, 43>(self, vm) push_data(self.data.clone(), vm)
287 opcode OpData43<0x2b, 44>(self, vm) push_data(self.data.clone(), vm)
288 opcode OpData44<0x2c, 45>(self, vm) push_data(self.data.clone(), vm)
289 opcode OpData45<0x2d, 46>(self, vm) push_data(self.data.clone(), vm)
290 opcode OpData46<0x2e, 47>(self, vm) push_data(self.data.clone(), vm)
291 opcode OpData47<0x2f, 48>(self, vm) push_data(self.data.clone(), vm)
292 opcode OpData48<0x30, 49>(self, vm) push_data(self.data.clone(), vm)
293 opcode OpData49<0x31, 50>(self, vm) push_data(self.data.clone(), vm)
294 opcode OpData50<0x32, 51>(self, vm) push_data(self.data.clone(), vm)
295 opcode OpData51<0x33, 52>(self, vm) push_data(self.data.clone(), vm)
296 opcode OpData52<0x34, 53>(self, vm) push_data(self.data.clone(), vm)
297 opcode OpData53<0x35, 54>(self, vm) push_data(self.data.clone(), vm)
298 opcode OpData54<0x36, 55>(self, vm) push_data(self.data.clone(), vm)
299 opcode OpData55<0x37, 56>(self, vm) push_data(self.data.clone(), vm)
300 opcode OpData56<0x38, 57>(self, vm) push_data(self.data.clone(), vm)
301 opcode OpData57<0x39, 58>(self, vm) push_data(self.data.clone(), vm)
302 opcode OpData58<0x3a, 59>(self, vm) push_data(self.data.clone(), vm)
303 opcode OpData59<0x3b, 60>(self, vm) push_data(self.data.clone(), vm)
304 opcode OpData60<0x3c, 61>(self, vm) push_data(self.data.clone(), vm)
305 opcode OpData61<0x3d, 62>(self, vm) push_data(self.data.clone(), vm)
306 opcode OpData62<0x3e, 63>(self, vm) push_data(self.data.clone(), vm)
307 opcode OpData63<0x3f, 64>(self, vm) push_data(self.data.clone(), vm)
308 opcode OpData64<0x40, 65>(self, vm) push_data(self.data.clone(), vm)
309 opcode OpData65<0x41, 66>(self, vm) push_data(self.data.clone(), vm)
310 opcode OpData66<0x42, 67>(self, vm) push_data(self.data.clone(), vm)
311 opcode OpData67<0x43, 68>(self, vm) push_data(self.data.clone(), vm)
312 opcode OpData68<0x44, 69>(self, vm) push_data(self.data.clone(), vm)
313 opcode OpData69<0x45, 70>(self, vm) push_data(self.data.clone(), vm)
314 opcode OpData70<0x46, 71>(self, vm) push_data(self.data.clone(), vm)
315 opcode OpData71<0x47, 72>(self, vm) push_data(self.data.clone(), vm)
316 opcode OpData72<0x48, 73>(self, vm) push_data(self.data.clone(), vm)
317 opcode OpData73<0x49, 74>(self, vm) push_data(self.data.clone(), vm)
318 opcode OpData74<0x4a, 75>(self, vm) push_data(self.data.clone(), vm)
319 opcode OpData75<0x4b, 76>(self, vm) push_data(self.data.clone(), vm)
320 opcode OpPushData1<0x4c, u8>(self, vm) push_data(self.data.clone(), vm)
321 opcode OpPushData2<0x4d, u16>(self, vm) push_data(self.data.clone(), vm)
322 opcode OpPushData4<0x4e, u32>(self, vm) push_data(self.data.clone(), vm)
323
324 opcode Op1Negate<0x4f, 1>(self, vm) push_number(-1, vm)
325
326 opcode OpReserved<0x50, 1>(self, vm) Err(TxScriptError::OpcodeReserved(format!("{self:?}")))
327
328 opcode |Op1| OpTrue<0x51, 1>(self, vm) push_number(1, vm)
329 opcode Op2<0x52, 1>(self, vm) push_number(2, vm)
330 opcode Op3<0x53, 1>(self, vm) push_number(3, vm)
331 opcode Op4<0x54, 1>(self, vm) push_number(4, vm)
332 opcode Op5<0x55, 1>(self, vm) push_number(5, vm)
333 opcode Op6<0x56, 1>(self, vm) push_number(6, vm)
334 opcode Op7<0x57, 1>(self, vm) push_number(7, vm)
335 opcode Op8<0x58, 1>(self, vm) push_number(8, vm)
336 opcode Op9<0x59, 1>(self, vm) push_number(9, vm)
337 opcode Op10<0x5a, 1>(self, vm) push_number(10, vm)
338 opcode Op11<0x5b, 1>(self, vm) push_number(11, vm)
339 opcode Op12<0x5c, 1>(self, vm) push_number(12, vm)
340 opcode Op13<0x5d, 1>(self, vm) push_number(13, vm)
341 opcode Op14<0x5e, 1>(self, vm) push_number(14, vm)
342 opcode Op15<0x5f, 1>(self, vm) push_number(15, vm)
343 opcode Op16<0x60, 1>(self, vm) push_number(16, vm)
344
345 opcode OpNop<0x61, 1>(self, vm) Ok(())
347 opcode OpVer<0x62, 1>(self, vm) Err(TxScriptError::OpcodeReserved(format!("{self:?}")))
348
349 opcode OpIf<0x63, 1>(self, vm) {
350 let mut cond = OpCond::Skip;
351 if vm.is_executing() {
352 if let Some(mut cond_buf) = vm.dstack.pop() {
355 if cond_buf.len() > 1 {
356 return Err(TxScriptError::InvalidState("expected boolean".to_string()));
357 }
358 cond = match cond_buf.pop() {
359 Some(stack_cond) => match stack_cond {
360 1 => OpCond::True,
361 _ => return Err(TxScriptError::InvalidState("expected boolean".to_string())),
362 }
363 None => OpCond::False,
364 }
365 } else {
366 return Err(TxScriptError::EmptyStack);
367 }
368 }
369 vm.cond_stack.push(cond);
370 Ok(())
371 }
372
373 opcode OpNotIf<0x64, 1>(self, vm) {
374 let mut cond = OpCond::Skip;
375 if vm.is_executing() {
376 if let Some(mut cond_buf) = vm.dstack.pop() {
377 if cond_buf.len() > 1 {
378 return Err(TxScriptError::InvalidState("expected boolean".to_string()));
379 }
380 cond = match cond_buf.pop() {
381 Some(stack_cond) => match stack_cond {
382 1 => OpCond::False,
383 _ => return Err(TxScriptError::InvalidState("expected boolean".to_string())),
384 }
385 None => OpCond::True,
386 }
387 } else {
388 return Err(TxScriptError::EmptyStack);
389 }
390 }
391 vm.cond_stack.push(cond);
392 Ok(())
393 }
394
395 opcode OpVerIf<0x65, 1>(self, vm) Err(TxScriptError::OpcodeReserved(format!("{self:?}")))
396 opcode OpVerNotIf<0x66, 1>(self, vm) Err(TxScriptError::OpcodeReserved(format!("{self:?}")))
397
398 opcode OpElse<0x67, 1>(self, vm) {
399 if let Some(cond) = vm.cond_stack.last_mut() {
400 *cond = cond.negate();
401 Ok(())
402 } else {
403 Err(TxScriptError::InvalidState("condition stack empty".to_string()))
404 }
405 }
406
407 opcode OpEndIf<0x68, 1>(self, vm) {
408 match vm.cond_stack.pop() {
409 None => Err(TxScriptError::InvalidState("condition stack empty".to_string())),
410 _ => Ok(())
411 }
412 }
413
414 opcode OpVerify<0x69, 1>(self, vm) {
415 let [result]: [bool; 1] = vm.dstack.pop_items()?;
416 match result {
417 true => Ok(()),
418 false => Err(TxScriptError::VerifyError)
419 }
420 }
421
422 opcode OpReturn<0x6a, 1>(self, vm) Err(TxScriptError::EarlyReturn)
423
424 opcode OpToAltStack<0x6b, 1>(self, vm) {
426 let [item] = vm.dstack.pop_raw()?;
427 vm.astack.push(item);
428 Ok(())
429 }
430
431 opcode OpFromAltStack<0x6c, 1>(self, vm) {
432 match vm.astack.pop() {
433 Some(last) => {
434 vm.dstack.push(last);
435 Ok(())
436 },
437 None => Err(TxScriptError::EmptyStack)
438 }
439 }
440
441 opcode Op2Drop<0x6d, 1>(self, vm) vm.dstack.drop_items::<2>()
442 opcode Op2Dup<0x6e, 1>(self, vm) vm.dstack.dup_items::<2>()
443 opcode Op3Dup<0x6f, 1>(self, vm) vm.dstack.dup_items::<3>()
444 opcode Op2Over<0x70, 1>(self, vm) vm.dstack.over_items::<2>()
445 opcode Op2Rot<0x71, 1>(self, vm) vm.dstack.rot_items::<2>()
446 opcode Op2Swap<0x72, 1>(self, vm) vm.dstack.swap_items::<2>()
447
448 opcode OpIfDup<0x73, 1>(self, vm) {
449 let [result] = vm.dstack.peek_raw()?;
450 if <Vec<u8> as OpcodeData<bool>>::deserialize(&result)? {
451 vm.dstack.push(result);
452 }
453 Ok(())
454 }
455
456 opcode OpDepth<0x74, 1>(self, vm) push_number(vm.dstack.len() as i64, vm)
457
458 opcode OpDrop<0x75, 1>(self, vm) vm.dstack.drop_items::<1>()
459 opcode OpDup<0x76, 1>(self, vm) vm.dstack.dup_items::<1>()
460
461 opcode OpNip<0x77, 1>(self, vm) {
462 match vm.dstack.len() >= 2 {
463 true => {
464 vm.dstack.remove(vm.dstack.len()-2);
465 Ok(())
466 }
467 false => Err(TxScriptError::InvalidStackOperation(2, vm.dstack.len())),
468 }
469 }
470
471 opcode OpOver<0x78, 1>(self, vm) vm.dstack.over_items::<1>()
472
473 opcode OpPick<0x79, 1>(self, vm) {
474 let [loc]: [i32; 1] = vm.dstack.pop_items()?;
475 if loc < 0 || loc as usize >= vm.dstack.len() {
476 return Err(TxScriptError::InvalidState("pick at an invalid location".to_string()));
477 }
478 vm.dstack.push(vm.dstack[vm.dstack.len()-(loc as usize)-1].clone());
479 Ok(())
480 }
481
482 opcode OpRoll<0x7a, 1>(self, vm) {
483 let [loc]: [i32; 1] = vm.dstack.pop_items()?;
484 if loc < 0 || loc as usize >= vm.dstack.len() {
485 return Err(TxScriptError::InvalidState("roll at an invalid location".to_string()));
486 }
487 let item = vm.dstack.remove(vm.dstack.len()-(loc as usize)-1);
488 vm.dstack.push(item);
489 Ok(())
490 }
491
492 opcode OpRot<0x7b, 1>(self, vm) vm.dstack.rot_items::<1>()
493 opcode OpSwap<0x7c, 1>(self, vm) vm.dstack.swap_items::<1>()
494
495 opcode OpTuck<0x7d, 1>(self, vm) {
496 match vm.dstack.len() >= 2 {
497 true => {
498 vm.dstack.insert(vm.dstack.len()-2, vm.dstack.last().expect("We have at least two items").clone());
499 Ok(())
500 }
501 false => Err(TxScriptError::InvalidStackOperation(2, vm.dstack.len()))
502 }
503 }
504
505 opcode OpCat<0x7e, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
507 opcode OpSubStr<0x7f, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
508 opcode OpLeft<0x80, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
509 opcode OpRight<0x81, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
510
511 opcode OpSize<0x82, 1>(self, vm) {
512 match vm.dstack.last() {
513 Some(last) => {
514 vm.dstack.push_item(i64::try_from(last.len()).map_err(|e| TxScriptError::NumberTooBig(e.to_string()))?);
515 Ok(())
516 },
517 None => Err(TxScriptError::InvalidStackOperation(1, 0))
518 }
519 }
520
521 opcode OpInvert<0x83, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
523 opcode OpAnd<0x84, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
524 opcode OpOr<0x85, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
525 opcode OpXor<0x86, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
526
527 opcode OpEqual<0x87, 1>(self, vm) {
528 match vm.dstack.len() >= 2 {
529 true => {
530 let pair = vm.dstack.split_off(vm.dstack.len() - 2);
531 match pair[0] == pair[1] {
532 true => vm.dstack.push(vec![1]),
533 false => vm.dstack.push(vec![]),
534 }
535 Ok(())
536 }
537 false => Err(TxScriptError::InvalidStackOperation(2, vm.dstack.len()))
538 }
539 }
540
541 opcode OpEqualVerify<0x88, 1>(self, vm) {
542 match vm.dstack.len() >= 2 {
543 true => {
544 let pair = vm.dstack.split_off(vm.dstack.len() - 2);
545 match pair[0] == pair[1] {
546 true => Ok(()),
547 false => Err(TxScriptError::VerifyError),
548 }
549 }
550 false => Err(TxScriptError::InvalidStackOperation(2, vm.dstack.len()))
551 }
552 }
553
554 opcode OpReserved1<0x89, 1>(self, vm) Err(TxScriptError::OpcodeReserved(format!("{self:?}")))
555 opcode OpReserved2<0x8a, 1>(self, vm) Err(TxScriptError::OpcodeReserved(format!("{self:?}")))
556
557 opcode Op1Add<0x8b, 1>(self, vm) {
559 let [value]: [i64; 1] = vm.dstack.pop_items()?;
560 vm.dstack.push_item(value + 1);
561 Ok(())
562 }
563
564 opcode Op1Sub<0x8c, 1>(self, vm) {
565 let [value]: [i64; 1] = vm.dstack.pop_items()?;
566 vm.dstack.push_item(value - 1);
567 Ok(())
568 }
569
570 opcode Op2Mul<0x8d, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
571 opcode Op2Div<0x8e, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
572
573 opcode OpNegate<0x8f, 1>(self, vm) {
574 let [value]: [i64; 1] = vm.dstack.pop_items()?;
575 vm.dstack.push_item(-value);
576 Ok(())
577 }
578
579 opcode OpAbs<0x90, 1>(self, vm) {
580 let [m]: [i64; 1] = vm.dstack.pop_items()?;
581 vm.dstack.push_item(m.abs());
582 Ok(())
583 }
584
585 opcode OpNot<0x91, 1>(self, vm) {
586 let [m]: [i64; 1] = vm.dstack.pop_items()?;
587 vm.dstack.push_item((m == 0) as i64);
588 Ok(())
589 }
590
591 opcode Op0NotEqual<0x92, 1>(self, vm) {
592 let [m]: [i64; 1] = vm.dstack.pop_items()?;
593 vm.dstack.push_item((m != 0) as i64 );
594 Ok(())
595 }
596
597 opcode OpAdd<0x93, 1>(self, vm) {
598 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
599 vm.dstack.push_item(a+b);
600 Ok(())
601 }
602
603 opcode OpSub<0x94, 1>(self, vm) {
604 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
605 vm.dstack.push_item(a-b);
606 Ok(())
607 }
608
609 opcode OpMul<0x95, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
610 opcode OpDiv<0x96, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
611 opcode OpMod<0x97, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
612 opcode OpLShift<0x98, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
613 opcode OpRShift<0x99, 1>(self, vm) Err(TxScriptError::OpcodeDisabled(format!("{self:?}")))
614
615 opcode OpBoolAnd<0x9a, 1>(self, vm) {
616 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
617 vm.dstack.push_item(((a != 0) && (b != 0)) as i64);
618 Ok(())
619 }
620
621 opcode OpBoolOr<0x9b, 1>(self, vm) {
622 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
623 vm.dstack.push_item(((a != 0) || (b != 0)) as i64);
624 Ok(())
625 }
626
627 opcode OpNumEqual<0x9c, 1>(self, vm) {
628 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
629 vm.dstack.push_item((a == b) as i64);
630 Ok(())
631 }
632
633 opcode OpNumEqualVerify<0x9d, 1>(self, vm) {
634 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
635 match a == b {
636 true => Ok(()),
637 false => Err(TxScriptError::VerifyError)
638 }
639 }
640
641 opcode OpNumNotEqual<0x9e, 1>(self, vm) {
642 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
643 vm.dstack.push_item((a != b) as i64);
644 Ok(())
645 }
646
647 opcode OpLessThan<0x9f, 1>(self, vm) {
648 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
649 vm.dstack.push_item((a < b) as i64);
650 Ok(())
651 }
652
653 opcode OpGreaterThan<0xa0, 1>(self, vm) {
654 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
655 vm.dstack.push_item((a > b) as i64);
656 Ok(())
657 }
658
659 opcode OpLessThanOrEqual<0xa1, 1>(self, vm) {
660 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
661 vm.dstack.push_item((a <= b) as i64);
662 Ok(())
663 }
664
665 opcode OpGreaterThanOrEqual<0xa2, 1>(self, vm) {
666 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
667 vm.dstack.push_item((a >= b) as i64);
668 Ok(())
669 }
670
671 opcode OpMin<0xa3, 1>(self, vm) {
672 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
673 vm.dstack.push_item(min(a,b));
674 Ok(())
675 }
676
677 opcode OpMax<0xa4, 1>(self, vm) {
678 let [a,b]: [i64; 2] = vm.dstack.pop_items()?;
679 vm.dstack.push_item(max(a,b));
680 Ok(())
681 }
682
683 opcode OpWithin<0xa5, 1>(self, vm) {
684 let [x,l,u]: [i64; 3] = vm.dstack.pop_items()?;
685 vm.dstack.push_item((x >= l && x < u) as i64);
686 Ok(())
687 }
688
689 opcode OpUnknown166<0xa6, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
691 opcode OpUnknown167<0xa7, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
692
693 opcode OpSHA256<0xa8, 1>(self, vm) {
695 let [last] = vm.dstack.pop_raw()?;
696 let mut hasher = Sha256::new();
697 hasher.update(last);
698 vm.dstack.push(hasher.finalize().to_vec());
699 Ok(())
700 }
701
702 opcode OpCheckMultiSigECDSA<0xa9, 1>(self, vm) {
703 vm.op_check_multisig_schnorr_or_ecdsa(true)
704 }
705
706 opcode OpBlake2b<0xaa, 1>(self, vm) {
707 let [last] = vm.dstack.pop_raw()?;
708 let hash = Params::new().hash_length(32).to_state().update(&last).finalize();
710 vm.dstack.push(hash.as_bytes().to_vec());
711 Ok(())
712 }
713
714 opcode OpCheckSigECDSA<0xab, 1>(self, vm) {
715 let [mut sig, key] = vm.dstack.pop_raw()?;
716 match sig.pop() {
718 Some(typ) => {
719 let hash_type = SigHashType::from_u8(typ).map_err(|e| TxScriptError::InvalidSigHashType(typ))?;
720 match vm.check_ecdsa_signature(hash_type, key.as_slice(), sig.as_slice()) {
721 Ok(valid) => {
722 vm.dstack.push_item(valid);
723 Ok(())
724 },
725 Err(e) => {
726 Err(e)
727 }
728 }
729 }
730 None => {
731 vm.dstack.push_item(false);
732 Ok(())
733 }
734 }
735 }
736
737 opcode OpCheckSig<0xac, 1>(self, vm) {
738 let [mut sig, key] = vm.dstack.pop_raw()?;
739 match sig.pop() {
741 Some(typ) => {
742 let hash_type = SigHashType::from_u8(typ).map_err(|e| TxScriptError::InvalidSigHashType(typ))?;
743 match vm.check_schnorr_signature(hash_type, key.as_slice(), sig.as_slice()) {
744 Ok(valid) => {
745 vm.dstack.push_item(valid);
746 Ok(())
747 },
748 Err(e) => {
749 Err(e)
750 }
751 }
752 }
753 None => {
754 vm.dstack.push_item(false);
755 Ok(())
756 }
757 }
758 }
759
760 opcode OpCheckSigVerify<0xad, 1>(self, vm) {
761 OpCheckSig{data: self.data.clone()}.execute(vm)?;
763 let [valid]: [bool; 1] = vm.dstack.pop_items()?;
764 match valid {
765 true => Ok(()),
766 false => Err(TxScriptError::VerifyError)
767 }
768 }
769
770 opcode OpCheckMultiSig<0xae, 1>(self, vm) {
771 vm.op_check_multisig_schnorr_or_ecdsa(false)
772 }
773
774 opcode OpCheckMultiSigVerify<0xaf, 1>(self, vm) {
775 OpCheckMultiSig{data: self.data.clone()}.execute(vm)?;
777 let [valid]: [bool; 1] = vm.dstack.pop_items()?;
778 match valid {
779 true => Ok(()),
780 false => Err(TxScriptError::VerifyError)
781 }
782 }
783
784 opcode OpCheckLockTimeVerify<0xb0, 1>(self, vm) {
785 match vm.script_source {
786 ScriptSource::TxInput {input, tx, ..} => {
787 let [mut lock_time_bytes] = vm.dstack.pop_raw()?;
788
789 if lock_time_bytes.len() > 8 {
793 return Err(TxScriptError::NumberTooBig(format!("lockTime value represented as {lock_time_bytes:x?} is longer then 8 bytes")))
794 }
795 lock_time_bytes.resize(8, 0);
796 let stack_lock_time = u64::from_le_bytes(lock_time_bytes.try_into().expect("checked vector size"));
797
798 if !(
803 (tx.tx().lock_time < LOCK_TIME_THRESHOLD && stack_lock_time < LOCK_TIME_THRESHOLD) ||
804 (tx.tx().lock_time >= LOCK_TIME_THRESHOLD && stack_lock_time >= LOCK_TIME_THRESHOLD)
805 ){
806 return Err(TxScriptError::UnsatisfiedLockTime(format!("mismatched locktime types -- tx locktime {}, stack locktime {}", tx.tx().lock_time, stack_lock_time)))
807 }
808
809 if stack_lock_time > tx.tx().lock_time {
810 return Err(TxScriptError::UnsatisfiedLockTime(format!("locktime requirement not satisfied -- locktime is greater than the transaction locktime: {} > {}", stack_lock_time, tx.tx().lock_time)))
811 }
812
813 if input.sequence == MAX_TX_IN_SEQUENCE_NUM {
828 return Err(TxScriptError::UnsatisfiedLockTime("transaction input is finalized".to_string()));
829 }
830 Ok(())
831 }
832 _ => Err(TxScriptError::InvalidSource("LockTimeVerify only applies to transaction inputs".to_string()))
833 }
834 }
835
836 opcode OpCheckSequenceVerify<0xb1, 1>(self, vm) {
837 match vm.script_source {
838 ScriptSource::TxInput {input, tx, ..} => {
839 let [mut sequence_bytes] = vm.dstack.pop_raw()?;
840
841 if sequence_bytes.len() > 8 {
845 return Err(TxScriptError::NumberTooBig(format!("lockTime value represented as {sequence_bytes:x?} is longer then 8 bytes")))
846 }
847 sequence_bytes.resize(8, 0);
850 let stack_sequence = u64::from_le_bytes(sequence_bytes.try_into().expect("ensured size checks"));
851
852 if stack_sequence & SEQUENCE_LOCK_TIME_DISABLED != 0 {
856 return Ok(());
857 }
858
859 if input.sequence & SEQUENCE_LOCK_TIME_DISABLED != 0 {
864 return Err(TxScriptError::UnsatisfiedLockTime(format!("transaction sequence has sequence locktime disabled bit set: {:#x}", input.sequence)));
865 }
866
867 if (stack_sequence & SEQUENCE_LOCK_TIME_MASK) > (input.sequence & SEQUENCE_LOCK_TIME_MASK) {
869 return Err(TxScriptError::UnsatisfiedLockTime(format!("locktime requirement not satisfied -- locktime is greater than the transaction locktime: {} > {}", stack_sequence & SEQUENCE_LOCK_TIME_MASK, input.sequence & SEQUENCE_LOCK_TIME_MASK)))
870 }
871 Ok(())
872 }
873 _ => Err(TxScriptError::InvalidSource("LockTimeVerify only applies to transaction inputs".to_string()))
874 }
875 }
876
877 opcode OpUnknown178<0xb2, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
879 opcode OpUnknown179<0xb3, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
880 opcode OpUnknown180<0xb4, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
881 opcode OpUnknown181<0xb5, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
882 opcode OpUnknown182<0xb6, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
883 opcode OpUnknown183<0xb7, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
884 opcode OpUnknown184<0xb8, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
885 opcode OpUnknown185<0xb9, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
886 opcode OpUnknown186<0xba, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
887 opcode OpUnknown187<0xbb, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
888 opcode OpUnknown188<0xbc, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
889 opcode OpUnknown189<0xbd, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
890 opcode OpUnknown190<0xbe, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
891 opcode OpUnknown191<0xbf, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
892 opcode OpUnknown192<0xc0, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
893 opcode OpUnknown193<0xc1, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
894 opcode OpUnknown194<0xc2, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
895 opcode OpUnknown195<0xc3, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
896 opcode OpUnknown196<0xc4, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
897 opcode OpUnknown197<0xc5, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
898 opcode OpUnknown198<0xc6, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
899 opcode OpUnknown199<0xc7, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
900 opcode OpUnknown200<0xc8, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
901 opcode OpUnknown201<0xc9, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
902 opcode OpUnknown202<0xca, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
903 opcode OpUnknown203<0xcb, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
904 opcode OpUnknown204<0xcc, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
905 opcode OpUnknown205<0xcd, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
906 opcode OpUnknown206<0xce, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
907 opcode OpUnknown207<0xcf, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
908 opcode OpUnknown208<0xd0, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
909 opcode OpUnknown209<0xd1, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
910 opcode OpUnknown210<0xd2, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
911 opcode OpUnknown211<0xd3, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
912 opcode OpUnknown212<0xd4, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
913 opcode OpUnknown213<0xd5, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
914 opcode OpUnknown214<0xd6, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
915 opcode OpUnknown215<0xd7, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
916 opcode OpUnknown216<0xd8, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
917 opcode OpUnknown217<0xd9, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
918 opcode OpUnknown218<0xda, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
919 opcode OpUnknown219<0xdb, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
920 opcode OpUnknown220<0xdc, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
921 opcode OpUnknown221<0xdd, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
922 opcode OpUnknown222<0xde, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
923 opcode OpUnknown223<0xdf, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
924 opcode OpUnknown224<0xe0, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
925 opcode OpUnknown225<0xe1, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
926 opcode OpUnknown226<0xe2, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
927 opcode OpUnknown227<0xe3, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
928 opcode OpUnknown228<0xe4, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
929 opcode OpUnknown229<0xe5, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
930 opcode OpUnknown230<0xe6, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
931 opcode OpUnknown231<0xe7, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
932 opcode OpUnknown232<0xe8, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
933 opcode OpUnknown233<0xe9, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
934 opcode OpUnknown234<0xea, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
935 opcode OpUnknown235<0xeb, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
936 opcode OpUnknown236<0xec, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
937 opcode OpUnknown237<0xed, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
938 opcode OpUnknown238<0xee, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
939 opcode OpUnknown239<0xef, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
940 opcode OpUnknown240<0xf0, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
941 opcode OpUnknown241<0xf1, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
942 opcode OpUnknown242<0xf2, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
943 opcode OpUnknown243<0xf3, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
944 opcode OpUnknown244<0xf4, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
945 opcode OpUnknown245<0xf5, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
946 opcode OpUnknown246<0xf6, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
947 opcode OpUnknown247<0xf7, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
948 opcode OpUnknown248<0xf8, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
949 opcode OpUnknown249<0xf9, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
950
951 opcode OpSmallInteger<0xfa, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
952 opcode OpPubKeys<0xfb, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
953 opcode OpUnknown252<0xfc, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
954 opcode OpPubKeyHash<0xfd, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
955 opcode OpPubKey<0xfe, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
956 opcode OpInvalidOpCode<0xff, 1>(self, vm) Err(TxScriptError::InvalidOpcode(format!("{self:?}")))
957}
958
959#[allow(clippy::borrowed_box)]
961pub fn to_small_int<T: VerifiableTransaction>(opcode: &Box<dyn OpCodeImplementation<T>>) -> u8 {
962 let value = opcode.value();
963 if value == codes::OpFalse {
964 return 0;
965 }
966
967 assert!((codes::OpTrue..codes::Op16).contains(&value), "expected op codes between from the list of Op0 to Op16");
968 value - (codes::OpTrue - 1)
969}
970
971#[cfg(test)]
972mod test {
973 use crate::caches::Cache;
974 use crate::data_stack::Stack;
975 use crate::opcodes::{OpCodeExecution, OpCodeImplementation};
976 use crate::{opcodes, pay_to_address_script, TxScriptEngine, TxScriptError, LOCK_TIME_THRESHOLD};
977 use kaspa_addresses::{Address, Prefix, Version};
978 use kaspa_consensus_core::constants::{SOMPI_PER_KASPA, TX_VERSION};
979 use kaspa_consensus_core::hashing::sighash::SigHashReusedValues;
980 use kaspa_consensus_core::subnets::SUBNETWORK_ID_NATIVE;
981 use kaspa_consensus_core::tx::{
982 PopulatedTransaction, ScriptPublicKey, Transaction, TransactionInput, TransactionOutpoint, TransactionOutput, UtxoEntry,
983 VerifiableTransaction,
984 };
985
986 struct TestCase<'a> {
987 init: Stack,
988 code: Box<dyn OpCodeImplementation<PopulatedTransaction<'a>>>,
989 dstack: Stack,
990 }
991
992 struct ErrorTestCase<'a> {
993 init: Stack,
994 code: Box<dyn OpCodeImplementation<PopulatedTransaction<'a>>>,
995 error: TxScriptError,
996 }
997
998 fn run_success_test_cases(tests: Vec<TestCase>) {
999 let cache = Cache::new(10_000);
1000 let mut reused_values = SigHashReusedValues::new();
1001 for TestCase { init, code, dstack } in tests {
1002 let mut vm = TxScriptEngine::new(&mut reused_values, &cache);
1003 vm.dstack = init;
1004 code.execute(&mut vm).unwrap_or_else(|_| panic!("Opcode {} should not fail", code.value()));
1005 assert_eq!(*vm.dstack, dstack, "OpCode {} Pushed wrong value", code.value());
1006 }
1007 }
1008
1009 fn run_error_test_cases(tests: Vec<ErrorTestCase>) {
1010 let cache = Cache::new(10_000);
1011 let mut reused_values = SigHashReusedValues::new();
1012 for ErrorTestCase { init, code, error } in tests {
1013 let mut vm = TxScriptEngine::new(&mut reused_values, &cache);
1014 vm.dstack.clone_from(&init);
1015 assert_eq!(
1016 code.execute(&mut vm)
1017 .expect_err(format!("Opcode {} should have errored (init: {:?})", code.value(), init.clone()).as_str()),
1018 error,
1019 "Opcode {} returned wrong error {:?}",
1020 code.value(),
1021 init
1022 );
1023 }
1024 }
1025
1026 #[test]
1027 fn test_opcode_disabled() {
1028 let tests: Vec<Box<dyn OpCodeImplementation<PopulatedTransaction>>> = vec![
1029 opcodes::OpCat::empty().expect("Should accept empty"),
1030 opcodes::OpSubStr::empty().expect("Should accept empty"),
1031 opcodes::OpLeft::empty().expect("Should accept empty"),
1032 opcodes::OpRight::empty().expect("Should accept empty"),
1033 opcodes::OpInvert::empty().expect("Should accept empty"),
1034 opcodes::OpAnd::empty().expect("Should accept empty"),
1035 opcodes::OpOr::empty().expect("Should accept empty"),
1036 opcodes::OpXor::empty().expect("Should accept empty"),
1037 opcodes::Op2Mul::empty().expect("Should accept empty"),
1038 opcodes::Op2Div::empty().expect("Should accept empty"),
1039 opcodes::OpMul::empty().expect("Should accept empty"),
1040 opcodes::OpDiv::empty().expect("Should accept empty"),
1041 opcodes::OpMod::empty().expect("Should accept empty"),
1042 opcodes::OpLShift::empty().expect("Should accept empty"),
1043 opcodes::OpRShift::empty().expect("Should accept empty"),
1044 ];
1045
1046 let cache = Cache::new(10_000);
1047 let mut reused_values = SigHashReusedValues::new();
1048 let mut vm = TxScriptEngine::new(&mut reused_values, &cache);
1049
1050 for pop in tests {
1051 match pop.execute(&mut vm) {
1052 Err(TxScriptError::OpcodeDisabled(_)) => {}
1053 _ => panic!("Opcode {pop:?} should be disabled"),
1054 }
1055 }
1056 }
1057
1058 #[test]
1059 fn test_opcode_reserved() {
1060 let tests: Vec<Box<dyn OpCodeImplementation<PopulatedTransaction>>> = vec![
1061 opcodes::OpReserved::empty().expect("Should accept empty"),
1062 opcodes::OpVer::empty().expect("Should accept empty"),
1063 opcodes::OpVerIf::empty().expect("Should accept empty"),
1064 opcodes::OpVerNotIf::empty().expect("Should accept empty"),
1065 opcodes::OpReserved1::empty().expect("Should accept empty"),
1066 opcodes::OpReserved2::empty().expect("Should accept empty"),
1067 ];
1068
1069 let cache = Cache::new(10_000);
1070 let mut reused_values = SigHashReusedValues::new();
1071 let mut vm = TxScriptEngine::new(&mut reused_values, &cache);
1072
1073 for pop in tests {
1074 match pop.execute(&mut vm) {
1075 Err(TxScriptError::OpcodeReserved(_)) => {}
1076 _ => panic!("Opcode {pop:?} should be disabled"),
1077 }
1078 }
1079 }
1080
1081 #[test]
1082 fn test_opcode_invalid() {
1083 let tests: Vec<Box<dyn OpCodeImplementation<PopulatedTransaction>>> = vec![
1084 opcodes::OpUnknown166::empty().expect("Should accept empty"),
1085 opcodes::OpUnknown167::empty().expect("Should accept empty"),
1086 opcodes::OpUnknown178::empty().expect("Should accept empty"),
1087 opcodes::OpUnknown179::empty().expect("Should accept empty"),
1088 opcodes::OpUnknown180::empty().expect("Should accept empty"),
1089 opcodes::OpUnknown181::empty().expect("Should accept empty"),
1090 opcodes::OpUnknown182::empty().expect("Should accept empty"),
1091 opcodes::OpUnknown183::empty().expect("Should accept empty"),
1092 opcodes::OpUnknown184::empty().expect("Should accept empty"),
1093 opcodes::OpUnknown185::empty().expect("Should accept empty"),
1094 opcodes::OpUnknown186::empty().expect("Should accept empty"),
1095 opcodes::OpUnknown187::empty().expect("Should accept empty"),
1096 opcodes::OpUnknown188::empty().expect("Should accept empty"),
1097 opcodes::OpUnknown189::empty().expect("Should accept empty"),
1098 opcodes::OpUnknown190::empty().expect("Should accept empty"),
1099 opcodes::OpUnknown191::empty().expect("Should accept empty"),
1100 opcodes::OpUnknown192::empty().expect("Should accept empty"),
1101 opcodes::OpUnknown193::empty().expect("Should accept empty"),
1102 opcodes::OpUnknown194::empty().expect("Should accept empty"),
1103 opcodes::OpUnknown195::empty().expect("Should accept empty"),
1104 opcodes::OpUnknown196::empty().expect("Should accept empty"),
1105 opcodes::OpUnknown197::empty().expect("Should accept empty"),
1106 opcodes::OpUnknown198::empty().expect("Should accept empty"),
1107 opcodes::OpUnknown199::empty().expect("Should accept empty"),
1108 opcodes::OpUnknown200::empty().expect("Should accept empty"),
1109 opcodes::OpUnknown201::empty().expect("Should accept empty"),
1110 opcodes::OpUnknown202::empty().expect("Should accept empty"),
1111 opcodes::OpUnknown203::empty().expect("Should accept empty"),
1112 opcodes::OpUnknown204::empty().expect("Should accept empty"),
1113 opcodes::OpUnknown205::empty().expect("Should accept empty"),
1114 opcodes::OpUnknown206::empty().expect("Should accept empty"),
1115 opcodes::OpUnknown207::empty().expect("Should accept empty"),
1116 opcodes::OpUnknown208::empty().expect("Should accept empty"),
1117 opcodes::OpUnknown209::empty().expect("Should accept empty"),
1118 opcodes::OpUnknown210::empty().expect("Should accept empty"),
1119 opcodes::OpUnknown211::empty().expect("Should accept empty"),
1120 opcodes::OpUnknown212::empty().expect("Should accept empty"),
1121 opcodes::OpUnknown213::empty().expect("Should accept empty"),
1122 opcodes::OpUnknown214::empty().expect("Should accept empty"),
1123 opcodes::OpUnknown215::empty().expect("Should accept empty"),
1124 opcodes::OpUnknown216::empty().expect("Should accept empty"),
1125 opcodes::OpUnknown217::empty().expect("Should accept empty"),
1126 opcodes::OpUnknown218::empty().expect("Should accept empty"),
1127 opcodes::OpUnknown219::empty().expect("Should accept empty"),
1128 opcodes::OpUnknown220::empty().expect("Should accept empty"),
1129 opcodes::OpUnknown221::empty().expect("Should accept empty"),
1130 opcodes::OpUnknown222::empty().expect("Should accept empty"),
1131 opcodes::OpUnknown223::empty().expect("Should accept empty"),
1132 opcodes::OpUnknown224::empty().expect("Should accept empty"),
1133 opcodes::OpUnknown225::empty().expect("Should accept empty"),
1134 opcodes::OpUnknown226::empty().expect("Should accept empty"),
1135 opcodes::OpUnknown227::empty().expect("Should accept empty"),
1136 opcodes::OpUnknown228::empty().expect("Should accept empty"),
1137 opcodes::OpUnknown229::empty().expect("Should accept empty"),
1138 opcodes::OpUnknown230::empty().expect("Should accept empty"),
1139 opcodes::OpUnknown231::empty().expect("Should accept empty"),
1140 opcodes::OpUnknown232::empty().expect("Should accept empty"),
1141 opcodes::OpUnknown233::empty().expect("Should accept empty"),
1142 opcodes::OpUnknown234::empty().expect("Should accept empty"),
1143 opcodes::OpUnknown235::empty().expect("Should accept empty"),
1144 opcodes::OpUnknown236::empty().expect("Should accept empty"),
1145 opcodes::OpUnknown237::empty().expect("Should accept empty"),
1146 opcodes::OpUnknown238::empty().expect("Should accept empty"),
1147 opcodes::OpUnknown239::empty().expect("Should accept empty"),
1148 opcodes::OpUnknown240::empty().expect("Should accept empty"),
1149 opcodes::OpUnknown241::empty().expect("Should accept empty"),
1150 opcodes::OpUnknown242::empty().expect("Should accept empty"),
1151 opcodes::OpUnknown243::empty().expect("Should accept empty"),
1152 opcodes::OpUnknown244::empty().expect("Should accept empty"),
1153 opcodes::OpUnknown245::empty().expect("Should accept empty"),
1154 opcodes::OpUnknown246::empty().expect("Should accept empty"),
1155 opcodes::OpUnknown247::empty().expect("Should accept empty"),
1156 opcodes::OpUnknown248::empty().expect("Should accept empty"),
1157 opcodes::OpUnknown249::empty().expect("Should accept empty"),
1158 ];
1159
1160 let cache = Cache::new(10_000);
1161 let mut reused_values = SigHashReusedValues::new();
1162 let mut vm = TxScriptEngine::new(&mut reused_values, &cache);
1163
1164 for pop in tests {
1165 match pop.execute(&mut vm) {
1166 Err(TxScriptError::InvalidOpcode(_)) => {}
1167 _ => panic!("Opcode {pop:?} should be disabled"),
1168 }
1169 }
1170 }
1171
1172 #[test]
1173 fn test_push_data() {
1174 run_success_test_cases(vec![
1175 TestCase { code: opcodes::OpFalse::empty().expect("Should accept empty"), dstack: vec![vec![]], init: Default::default() },
1176 TestCase {
1177 code: opcodes::OpData1::new([1u8; 1].to_vec()).expect("Valid opcode"),
1178 dstack: vec![[1u8; 1].to_vec()],
1179 init: Default::default(),
1180 },
1181 TestCase {
1182 code: opcodes::OpData2::new([1u8; 2].to_vec()).expect("Valid opcode"),
1183 dstack: vec![[1u8; 2].to_vec()],
1184 init: Default::default(),
1185 },
1186 TestCase {
1187 code: opcodes::OpData3::new([1u8; 3].to_vec()).expect("Valid opcode"),
1188 dstack: vec![[1u8; 3].to_vec()],
1189 init: Default::default(),
1190 },
1191 TestCase {
1192 code: opcodes::OpData4::new([1u8; 4].to_vec()).expect("Valid opcode"),
1193 dstack: vec![[1u8; 4].to_vec()],
1194 init: Default::default(),
1195 },
1196 TestCase {
1197 code: opcodes::OpData5::new([1u8; 5].to_vec()).expect("Valid opcode"),
1198 dstack: vec![[1u8; 5].to_vec()],
1199 init: Default::default(),
1200 },
1201 TestCase {
1202 code: opcodes::OpData6::new([1u8; 6].to_vec()).expect("Valid opcode"),
1203 dstack: vec![[1u8; 6].to_vec()],
1204 init: Default::default(),
1205 },
1206 TestCase {
1207 code: opcodes::OpData7::new([1u8; 7].to_vec()).expect("Valid opcode"),
1208 dstack: vec![[1u8; 7].to_vec()],
1209 init: Default::default(),
1210 },
1211 TestCase {
1212 code: opcodes::OpData8::new([1u8; 8].to_vec()).expect("Valid opcode"),
1213 dstack: vec![[1u8; 8].to_vec()],
1214 init: Default::default(),
1215 },
1216 TestCase {
1217 code: opcodes::OpData9::new([1u8; 9].to_vec()).expect("Valid opcode"),
1218 dstack: vec![[1u8; 9].to_vec()],
1219 init: Default::default(),
1220 },
1221 TestCase {
1222 code: opcodes::OpData10::new([1u8; 10].to_vec()).expect("Valid opcode"),
1223 dstack: vec![[1u8; 10].to_vec()],
1224 init: Default::default(),
1225 },
1226 TestCase {
1227 code: opcodes::OpData11::new([1u8; 11].to_vec()).expect("Valid opcode"),
1228 dstack: vec![[1u8; 11].to_vec()],
1229 init: Default::default(),
1230 },
1231 TestCase {
1232 code: opcodes::OpData12::new([1u8; 12].to_vec()).expect("Valid opcode"),
1233 dstack: vec![[1u8; 12].to_vec()],
1234 init: Default::default(),
1235 },
1236 TestCase {
1237 code: opcodes::OpData13::new([1u8; 13].to_vec()).expect("Valid opcode"),
1238 dstack: vec![[1u8; 13].to_vec()],
1239 init: Default::default(),
1240 },
1241 TestCase {
1242 code: opcodes::OpData14::new([1u8; 14].to_vec()).expect("Valid opcode"),
1243 dstack: vec![[1u8; 14].to_vec()],
1244 init: Default::default(),
1245 },
1246 TestCase {
1247 code: opcodes::OpData15::new([1u8; 15].to_vec()).expect("Valid opcode"),
1248 dstack: vec![[1u8; 15].to_vec()],
1249 init: Default::default(),
1250 },
1251 TestCase {
1252 code: opcodes::OpData16::new([1u8; 16].to_vec()).expect("Valid opcode"),
1253 dstack: vec![[1u8; 16].to_vec()],
1254 init: Default::default(),
1255 },
1256 TestCase {
1257 code: opcodes::OpData17::new([1u8; 17].to_vec()).expect("Valid opcode"),
1258 dstack: vec![[1u8; 17].to_vec()],
1259 init: Default::default(),
1260 },
1261 TestCase {
1262 code: opcodes::OpData18::new([1u8; 18].to_vec()).expect("Valid opcode"),
1263 dstack: vec![[1u8; 18].to_vec()],
1264 init: Default::default(),
1265 },
1266 TestCase {
1267 code: opcodes::OpData19::new([1u8; 19].to_vec()).expect("Valid opcode"),
1268 dstack: vec![[1u8; 19].to_vec()],
1269 init: Default::default(),
1270 },
1271 TestCase {
1272 code: opcodes::OpData20::new([1u8; 20].to_vec()).expect("Valid opcode"),
1273 dstack: vec![[1u8; 20].to_vec()],
1274 init: Default::default(),
1275 },
1276 TestCase {
1277 code: opcodes::OpData21::new([1u8; 21].to_vec()).expect("Valid opcode"),
1278 dstack: vec![[1u8; 21].to_vec()],
1279 init: Default::default(),
1280 },
1281 TestCase {
1282 code: opcodes::OpData22::new([1u8; 22].to_vec()).expect("Valid opcode"),
1283 dstack: vec![[1u8; 22].to_vec()],
1284 init: Default::default(),
1285 },
1286 TestCase {
1287 code: opcodes::OpData23::new([1u8; 23].to_vec()).expect("Valid opcode"),
1288 dstack: vec![[1u8; 23].to_vec()],
1289 init: Default::default(),
1290 },
1291 TestCase {
1292 code: opcodes::OpData24::new([1u8; 24].to_vec()).expect("Valid opcode"),
1293 dstack: vec![[1u8; 24].to_vec()],
1294 init: Default::default(),
1295 },
1296 TestCase {
1297 code: opcodes::OpData25::new([1u8; 25].to_vec()).expect("Valid opcode"),
1298 dstack: vec![[1u8; 25].to_vec()],
1299 init: Default::default(),
1300 },
1301 TestCase {
1302 code: opcodes::OpData26::new([1u8; 26].to_vec()).expect("Valid opcode"),
1303 dstack: vec![[1u8; 26].to_vec()],
1304 init: Default::default(),
1305 },
1306 TestCase {
1307 code: opcodes::OpData27::new([1u8; 27].to_vec()).expect("Valid opcode"),
1308 dstack: vec![[1u8; 27].to_vec()],
1309 init: Default::default(),
1310 },
1311 TestCase {
1312 code: opcodes::OpData28::new([1u8; 28].to_vec()).expect("Valid opcode"),
1313 dstack: vec![[1u8; 28].to_vec()],
1314 init: Default::default(),
1315 },
1316 TestCase {
1317 code: opcodes::OpData29::new([1u8; 29].to_vec()).expect("Valid opcode"),
1318 dstack: vec![[1u8; 29].to_vec()],
1319 init: Default::default(),
1320 },
1321 TestCase {
1322 code: opcodes::OpData30::new([1u8; 30].to_vec()).expect("Valid opcode"),
1323 dstack: vec![[1u8; 30].to_vec()],
1324 init: Default::default(),
1325 },
1326 TestCase {
1327 code: opcodes::OpData31::new([1u8; 31].to_vec()).expect("Valid opcode"),
1328 dstack: vec![[1u8; 31].to_vec()],
1329 init: Default::default(),
1330 },
1331 TestCase {
1332 code: opcodes::OpData32::new([1u8; 32].to_vec()).expect("Valid opcode"),
1333 dstack: vec![[1u8; 32].to_vec()],
1334 init: Default::default(),
1335 },
1336 TestCase {
1337 code: opcodes::OpData33::new([1u8; 33].to_vec()).expect("Valid opcode"),
1338 dstack: vec![[1u8; 33].to_vec()],
1339 init: Default::default(),
1340 },
1341 TestCase {
1342 code: opcodes::OpData34::new([1u8; 34].to_vec()).expect("Valid opcode"),
1343 dstack: vec![[1u8; 34].to_vec()],
1344 init: Default::default(),
1345 },
1346 TestCase {
1347 code: opcodes::OpData35::new([1u8; 35].to_vec()).expect("Valid opcode"),
1348 dstack: vec![[1u8; 35].to_vec()],
1349 init: Default::default(),
1350 },
1351 TestCase {
1352 code: opcodes::OpData36::new([1u8; 36].to_vec()).expect("Valid opcode"),
1353 dstack: vec![[1u8; 36].to_vec()],
1354 init: Default::default(),
1355 },
1356 TestCase {
1357 code: opcodes::OpData37::new([1u8; 37].to_vec()).expect("Valid opcode"),
1358 dstack: vec![[1u8; 37].to_vec()],
1359 init: Default::default(),
1360 },
1361 TestCase {
1362 code: opcodes::OpData38::new([1u8; 38].to_vec()).expect("Valid opcode"),
1363 dstack: vec![[1u8; 38].to_vec()],
1364 init: Default::default(),
1365 },
1366 TestCase {
1367 code: opcodes::OpData39::new([1u8; 39].to_vec()).expect("Valid opcode"),
1368 dstack: vec![[1u8; 39].to_vec()],
1369 init: Default::default(),
1370 },
1371 TestCase {
1372 code: opcodes::OpData40::new([1u8; 40].to_vec()).expect("Valid opcode"),
1373 dstack: vec![[1u8; 40].to_vec()],
1374 init: Default::default(),
1375 },
1376 TestCase {
1377 code: opcodes::OpData41::new([1u8; 41].to_vec()).expect("Valid opcode"),
1378 dstack: vec![[1u8; 41].to_vec()],
1379 init: Default::default(),
1380 },
1381 TestCase {
1382 code: opcodes::OpData42::new([1u8; 42].to_vec()).expect("Valid opcode"),
1383 dstack: vec![[1u8; 42].to_vec()],
1384 init: Default::default(),
1385 },
1386 TestCase {
1387 code: opcodes::OpData43::new([1u8; 43].to_vec()).expect("Valid opcode"),
1388 dstack: vec![[1u8; 43].to_vec()],
1389 init: Default::default(),
1390 },
1391 TestCase {
1392 code: opcodes::OpData44::new([1u8; 44].to_vec()).expect("Valid opcode"),
1393 dstack: vec![[1u8; 44].to_vec()],
1394 init: Default::default(),
1395 },
1396 TestCase {
1397 code: opcodes::OpData45::new([1u8; 45].to_vec()).expect("Valid opcode"),
1398 dstack: vec![[1u8; 45].to_vec()],
1399 init: Default::default(),
1400 },
1401 TestCase {
1402 code: opcodes::OpData46::new([1u8; 46].to_vec()).expect("Valid opcode"),
1403 dstack: vec![[1u8; 46].to_vec()],
1404 init: Default::default(),
1405 },
1406 TestCase {
1407 code: opcodes::OpData47::new([1u8; 47].to_vec()).expect("Valid opcode"),
1408 dstack: vec![[1u8; 47].to_vec()],
1409 init: Default::default(),
1410 },
1411 TestCase {
1412 code: opcodes::OpData48::new([1u8; 48].to_vec()).expect("Valid opcode"),
1413 dstack: vec![[1u8; 48].to_vec()],
1414 init: Default::default(),
1415 },
1416 TestCase {
1417 code: opcodes::OpData49::new([1u8; 49].to_vec()).expect("Valid opcode"),
1418 dstack: vec![[1u8; 49].to_vec()],
1419 init: Default::default(),
1420 },
1421 TestCase {
1422 code: opcodes::OpData50::new([1u8; 50].to_vec()).expect("Valid opcode"),
1423 dstack: vec![[1u8; 50].to_vec()],
1424 init: Default::default(),
1425 },
1426 TestCase {
1427 code: opcodes::OpData51::new([1u8; 51].to_vec()).expect("Valid opcode"),
1428 dstack: vec![[1u8; 51].to_vec()],
1429 init: Default::default(),
1430 },
1431 TestCase {
1432 code: opcodes::OpData52::new([1u8; 52].to_vec()).expect("Valid opcode"),
1433 dstack: vec![[1u8; 52].to_vec()],
1434 init: Default::default(),
1435 },
1436 TestCase {
1437 code: opcodes::OpData53::new([1u8; 53].to_vec()).expect("Valid opcode"),
1438 dstack: vec![[1u8; 53].to_vec()],
1439 init: Default::default(),
1440 },
1441 TestCase {
1442 code: opcodes::OpData54::new([1u8; 54].to_vec()).expect("Valid opcode"),
1443 dstack: vec![[1u8; 54].to_vec()],
1444 init: Default::default(),
1445 },
1446 TestCase {
1447 code: opcodes::OpData55::new([1u8; 55].to_vec()).expect("Valid opcode"),
1448 dstack: vec![[1u8; 55].to_vec()],
1449 init: Default::default(),
1450 },
1451 TestCase {
1452 code: opcodes::OpData56::new([1u8; 56].to_vec()).expect("Valid opcode"),
1453 dstack: vec![[1u8; 56].to_vec()],
1454 init: Default::default(),
1455 },
1456 TestCase {
1457 code: opcodes::OpData57::new([1u8; 57].to_vec()).expect("Valid opcode"),
1458 dstack: vec![[1u8; 57].to_vec()],
1459 init: Default::default(),
1460 },
1461 TestCase {
1462 code: opcodes::OpData58::new([1u8; 58].to_vec()).expect("Valid opcode"),
1463 dstack: vec![[1u8; 58].to_vec()],
1464 init: Default::default(),
1465 },
1466 TestCase {
1467 code: opcodes::OpData59::new([1u8; 59].to_vec()).expect("Valid opcode"),
1468 dstack: vec![[1u8; 59].to_vec()],
1469 init: Default::default(),
1470 },
1471 TestCase {
1472 code: opcodes::OpData60::new([1u8; 60].to_vec()).expect("Valid opcode"),
1473 dstack: vec![[1u8; 60].to_vec()],
1474 init: Default::default(),
1475 },
1476 TestCase {
1477 code: opcodes::OpData61::new([1u8; 61].to_vec()).expect("Valid opcode"),
1478 dstack: vec![[1u8; 61].to_vec()],
1479 init: Default::default(),
1480 },
1481 TestCase {
1482 code: opcodes::OpData62::new([1u8; 62].to_vec()).expect("Valid opcode"),
1483 dstack: vec![[1u8; 62].to_vec()],
1484 init: Default::default(),
1485 },
1486 TestCase {
1487 code: opcodes::OpData63::new([1u8; 63].to_vec()).expect("Valid opcode"),
1488 dstack: vec![[1u8; 63].to_vec()],
1489 init: Default::default(),
1490 },
1491 TestCase {
1492 code: opcodes::OpData64::new([1u8; 64].to_vec()).expect("Valid opcode"),
1493 dstack: vec![[1u8; 64].to_vec()],
1494 init: Default::default(),
1495 },
1496 TestCase {
1497 code: opcodes::OpData65::new([1u8; 65].to_vec()).expect("Valid opcode"),
1498 dstack: vec![[1u8; 65].to_vec()],
1499 init: Default::default(),
1500 },
1501 TestCase {
1502 code: opcodes::OpData66::new([1u8; 66].to_vec()).expect("Valid opcode"),
1503 dstack: vec![[1u8; 66].to_vec()],
1504 init: Default::default(),
1505 },
1506 TestCase {
1507 code: opcodes::OpData67::new([1u8; 67].to_vec()).expect("Valid opcode"),
1508 dstack: vec![[1u8; 67].to_vec()],
1509 init: Default::default(),
1510 },
1511 TestCase {
1512 code: opcodes::OpData68::new([1u8; 68].to_vec()).expect("Valid opcode"),
1513 dstack: vec![[1u8; 68].to_vec()],
1514 init: Default::default(),
1515 },
1516 TestCase {
1517 code: opcodes::OpData69::new([1u8; 69].to_vec()).expect("Valid opcode"),
1518 dstack: vec![[1u8; 69].to_vec()],
1519 init: Default::default(),
1520 },
1521 TestCase {
1522 code: opcodes::OpData70::new([1u8; 70].to_vec()).expect("Valid opcode"),
1523 dstack: vec![[1u8; 70].to_vec()],
1524 init: Default::default(),
1525 },
1526 TestCase {
1527 code: opcodes::OpData71::new([1u8; 71].to_vec()).expect("Valid opcode"),
1528 dstack: vec![[1u8; 71].to_vec()],
1529 init: Default::default(),
1530 },
1531 TestCase {
1532 code: opcodes::OpData72::new([1u8; 72].to_vec()).expect("Valid opcode"),
1533 dstack: vec![[1u8; 72].to_vec()],
1534 init: Default::default(),
1535 },
1536 TestCase {
1537 code: opcodes::OpData73::new([1u8; 73].to_vec()).expect("Valid opcode"),
1538 dstack: vec![[1u8; 73].to_vec()],
1539 init: Default::default(),
1540 },
1541 TestCase {
1542 code: opcodes::OpData74::new([1u8; 74].to_vec()).expect("Valid opcode"),
1543 dstack: vec![[1u8; 74].to_vec()],
1544 init: Default::default(),
1545 },
1546 TestCase {
1547 code: opcodes::OpData75::new([1u8; 75].to_vec()).expect("Valid opcode"),
1548 dstack: vec![[1u8; 75].to_vec()],
1549 init: Default::default(),
1550 },
1551 TestCase {
1552 code: opcodes::OpPushData1::new([1u8; 76].to_vec()).expect("Valid opcode"),
1553 dstack: vec![[1u8; 76].to_vec()],
1554 init: Default::default(),
1555 },
1556 TestCase {
1557 code: opcodes::OpPushData2::new([1u8; 0x100].to_vec()).expect("Valid opcode"),
1558 dstack: vec![[1u8; 0x100].to_vec()],
1559 init: Default::default(),
1560 },
1561 TestCase {
1562 code: opcodes::OpPushData4::new([1u8; 0x10000].to_vec()).expect("Valid opcode"),
1563 dstack: vec![[1u8; 0x10000].to_vec()],
1564 init: Default::default(),
1565 },
1566 ]);
1567 }
1568
1569 #[test]
1570 fn test_push_num() {
1571 run_success_test_cases(vec![
1572 TestCase {
1573 code: opcodes::Op1Negate::empty().expect("Should accept empty"),
1574 dstack: vec![vec![0x81]],
1575 init: Default::default(),
1576 },
1577 TestCase { code: opcodes::Op1::empty().expect("Should accept empty"), dstack: vec![vec![1]], init: Default::default() },
1578 TestCase { code: opcodes::Op2::empty().expect("Should accept empty"), dstack: vec![vec![2]], init: Default::default() },
1579 TestCase { code: opcodes::Op3::empty().expect("Should accept empty"), dstack: vec![vec![3]], init: Default::default() },
1580 TestCase { code: opcodes::Op4::empty().expect("Should accept empty"), dstack: vec![vec![4]], init: Default::default() },
1581 TestCase { code: opcodes::Op5::empty().expect("Should accept empty"), dstack: vec![vec![5]], init: Default::default() },
1582 TestCase { code: opcodes::Op6::empty().expect("Should accept empty"), dstack: vec![vec![6]], init: Default::default() },
1583 TestCase { code: opcodes::Op7::empty().expect("Should accept empty"), dstack: vec![vec![7]], init: Default::default() },
1584 TestCase { code: opcodes::Op8::empty().expect("Should accept empty"), dstack: vec![vec![8]], init: Default::default() },
1585 TestCase { code: opcodes::Op9::empty().expect("Should accept empty"), dstack: vec![vec![9]], init: Default::default() },
1586 TestCase { code: opcodes::Op10::empty().expect("Should accept empty"), dstack: vec![vec![10]], init: Default::default() },
1587 TestCase { code: opcodes::Op11::empty().expect("Should accept empty"), dstack: vec![vec![11]], init: Default::default() },
1588 TestCase { code: opcodes::Op12::empty().expect("Should accept empty"), dstack: vec![vec![12]], init: Default::default() },
1589 TestCase { code: opcodes::Op13::empty().expect("Should accept empty"), dstack: vec![vec![13]], init: Default::default() },
1590 TestCase { code: opcodes::Op14::empty().expect("Should accept empty"), dstack: vec![vec![14]], init: Default::default() },
1591 TestCase { code: opcodes::Op15::empty().expect("Should accept empty"), dstack: vec![vec![15]], init: Default::default() },
1592 TestCase { code: opcodes::Op16::empty().expect("Should accept empty"), dstack: vec![vec![16]], init: Default::default() },
1593 ]);
1594 }
1595
1596 #[test]
1597 fn test_uniary_num_ops() {
1598 run_success_test_cases(vec![
1599 TestCase { code: opcodes::Op1Add::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![1]] },
1600 TestCase { code: opcodes::Op1Add::empty().expect("Should accept empty"), init: vec![vec![1]], dstack: vec![vec![2]] },
1601 TestCase {
1602 code: opcodes::Op1Add::empty().expect("Should accept empty"),
1603 init: vec![vec![2, 1]],
1604 dstack: vec![vec![3, 1]],
1605 },
1606 TestCase { code: opcodes::Op1Add::empty().expect("Should accept empty"), init: vec![vec![0x81]], dstack: vec![vec![]] },
1607 TestCase { code: opcodes::Op1Sub::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![0x81]] },
1608 TestCase { code: opcodes::Op1Sub::empty().expect("Should accept empty"), init: vec![vec![1]], dstack: vec![vec![]] },
1609 TestCase { code: opcodes::Op1Sub::empty().expect("Should accept empty"), init: vec![vec![2]], dstack: vec![vec![1]] },
1610 TestCase {
1611 code: opcodes::Op1Sub::empty().expect("Should accept empty"),
1612 init: vec![vec![3, 1]],
1613 dstack: vec![vec![2, 1]],
1614 },
1615 TestCase { code: opcodes::OpNegate::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![]] },
1616 TestCase { code: opcodes::OpNegate::empty().expect("Should accept empty"), init: vec![vec![1]], dstack: vec![vec![0x81]] },
1617 TestCase { code: opcodes::OpNegate::empty().expect("Should accept empty"), init: vec![vec![0x81]], dstack: vec![vec![1]] },
1618 TestCase {
1619 code: opcodes::OpNegate::empty().expect("Should accept empty"),
1620 init: vec![vec![3, 1]],
1621 dstack: vec![vec![3, 0x81]],
1622 },
1623 TestCase { code: opcodes::OpAbs::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![]] },
1624 TestCase { code: opcodes::OpAbs::empty().expect("Should accept empty"), init: vec![vec![3, 1]], dstack: vec![vec![3, 1]] },
1625 TestCase {
1626 code: opcodes::OpAbs::empty().expect("Should accept empty"),
1627 init: vec![vec![3, 0x81]],
1628 dstack: vec![vec![3, 1]],
1629 },
1630 TestCase { code: opcodes::OpAbs::empty().expect("Should accept empty"), init: vec![vec![1]], dstack: vec![vec![1]] },
1631 TestCase { code: opcodes::OpAbs::empty().expect("Should accept empty"), init: vec![vec![0x81]], dstack: vec![vec![1]] },
1632 TestCase {
1633 code: opcodes::OpAbs::empty().expect("Should accept empty"),
1634 init: vec![vec![1, 1, 0x82]],
1635 dstack: vec![vec![1, 1, 2]],
1636 },
1637 TestCase { code: opcodes::OpNot::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![1]] },
1638 TestCase { code: opcodes::OpNot::empty().expect("Should accept empty"), init: vec![vec![1]], dstack: vec![vec![]] },
1639 TestCase { code: opcodes::OpNot::empty().expect("Should accept empty"), init: vec![vec![1, 2, 3]], dstack: vec![vec![]] },
1640 TestCase { code: opcodes::Op0NotEqual::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![]] },
1641 TestCase { code: opcodes::Op0NotEqual::empty().expect("Should accept empty"), init: vec![vec![1]], dstack: vec![vec![1]] },
1642 TestCase { code: opcodes::Op0NotEqual::empty().expect("Should accept empty"), init: vec![vec![2]], dstack: vec![vec![1]] },
1643 TestCase {
1644 code: opcodes::Op0NotEqual::empty().expect("Should accept empty"),
1645 init: vec![vec![1, 2, 3]],
1646 dstack: vec![vec![1]],
1647 },
1648 ]);
1649 }
1650
1651 #[test]
1652 fn test_binary_num_ops() {
1653 run_success_test_cases(vec![
1654 TestCase { code: opcodes::OpAdd::empty().expect("Should accept empty"), init: vec![vec![], vec![]], dstack: vec![vec![]] },
1655 TestCase {
1656 code: opcodes::OpAdd::empty().expect("Should accept empty"),
1657 init: vec![vec![], vec![1]],
1658 dstack: vec![vec![1]],
1659 },
1660 TestCase {
1661 code: opcodes::OpAdd::empty().expect("Should accept empty"),
1662 init: vec![vec![1], vec![]],
1663 dstack: vec![vec![1]],
1664 },
1665 TestCase {
1666 code: opcodes::OpAdd::empty().expect("Should accept empty"),
1667 init: vec![vec![1], vec![1]],
1668 dstack: vec![vec![2]],
1669 },
1670 TestCase {
1671 code: opcodes::OpAdd::empty().expect("Should accept empty"),
1672 init: vec![vec![0x81], vec![1]],
1673 dstack: vec![vec![]],
1674 },
1675 TestCase {
1676 code: opcodes::OpAdd::empty().expect("Should accept empty"),
1677 init: vec![vec![0x7f], vec![1]],
1678 dstack: vec![vec![0x80, 0]],
1679 },
1680 TestCase {
1681 code: opcodes::OpAdd::empty().expect("Should accept empty"),
1682 init: vec![vec![0x80, 0], vec![0x80, 0]],
1683 dstack: vec![vec![0, 1]],
1684 },
1685 TestCase {
1686 code: opcodes::OpAdd::empty().expect("Should accept empty"),
1687 init: vec![vec![0xff, 0], vec![1]],
1688 dstack: vec![vec![0, 1]],
1689 },
1690 TestCase { code: opcodes::OpSub::empty().expect("Should accept empty"), init: vec![vec![], vec![]], dstack: vec![vec![]] },
1691 TestCase {
1692 code: opcodes::OpSub::empty().expect("Should accept empty"),
1693 init: vec![vec![], vec![1]],
1694 dstack: vec![vec![0x81]],
1695 },
1696 TestCase {
1697 code: opcodes::OpSub::empty().expect("Should accept empty"),
1698 init: vec![vec![1], vec![]],
1699 dstack: vec![vec![1]],
1700 },
1701 TestCase {
1702 code: opcodes::OpSub::empty().expect("Should accept empty"),
1703 init: vec![vec![1], vec![1]],
1704 dstack: vec![vec![]],
1705 },
1706 TestCase {
1707 code: opcodes::OpSub::empty().expect("Should accept empty"),
1708 init: vec![vec![0x81], vec![1]],
1709 dstack: vec![vec![0x82]],
1710 },
1711 TestCase {
1712 code: opcodes::OpSub::empty().expect("Should accept empty"),
1713 init: vec![vec![0x80, 0], vec![1]],
1714 dstack: vec![vec![0x7f]],
1715 },
1716 TestCase {
1717 code: opcodes::OpSub::empty().expect("Should accept empty"),
1718 init: vec![vec![0, 1], vec![0x80, 0]],
1719 dstack: vec![vec![0x80, 0]],
1720 },
1721 TestCase {
1722 code: opcodes::OpSub::empty().expect("Should accept empty"),
1723 init: vec![vec![0, 1], vec![1]],
1724 dstack: vec![vec![0xff, 0]],
1725 },
1726 TestCase {
1727 code: opcodes::OpMax::empty().expect("Should accept empty"),
1728 init: vec![vec![0, 1], vec![1]],
1729 dstack: vec![vec![0, 1]],
1730 },
1731 TestCase {
1732 code: opcodes::OpMax::empty().expect("Should accept empty"),
1733 init: vec![vec![1], vec![0, 1]],
1734 dstack: vec![vec![0, 1]],
1735 },
1736 TestCase {
1737 code: opcodes::OpMax::empty().expect("Should accept empty"),
1738 init: vec![vec![0, 0x81], vec![1]],
1739 dstack: vec![vec![1]],
1740 },
1741 TestCase {
1742 code: opcodes::OpMin::empty().expect("Should accept empty"),
1743 init: vec![vec![0, 1], vec![1]],
1744 dstack: vec![vec![1]],
1745 },
1746 TestCase {
1747 code: opcodes::OpMin::empty().expect("Should accept empty"),
1748 init: vec![vec![1], vec![0, 1]],
1749 dstack: vec![vec![1]],
1750 },
1751 TestCase {
1752 code: opcodes::OpMin::empty().expect("Should accept empty"),
1753 init: vec![vec![0, 0x81], vec![1]],
1754 dstack: vec![vec![0, 0x81]],
1755 },
1756 ]);
1757 }
1758
1759 #[test]
1760 fn test_logical_ops() {
1761 run_success_test_cases(vec![
1762 TestCase {
1763 code: opcodes::OpEqual::empty().expect("Should accept empty"),
1764 init: vec![vec![], vec![]],
1765 dstack: vec![vec![1]],
1766 },
1767 TestCase {
1768 code: opcodes::OpEqual::empty().expect("Should accept empty"),
1769 init: vec![vec![0, 1, 1, 0], vec![0, 1, 1, 0]],
1770 dstack: vec![vec![1]],
1771 },
1772 TestCase {
1773 code: opcodes::OpEqual::empty().expect("Should accept empty"),
1774 init: vec![vec![], vec![0]],
1775 dstack: vec![vec![]],
1776 },
1777 TestCase {
1778 code: opcodes::OpEqual::empty().expect("Should accept empty"),
1779 init: vec![vec![0, 1, 1, 0], vec![0, 1, 1, 1]],
1780 dstack: vec![vec![]],
1781 },
1782 TestCase {
1783 code: opcodes::OpBoolAnd::empty().expect("Should accept empty"),
1784 init: vec![vec![], vec![]],
1785 dstack: vec![vec![]],
1786 },
1787 TestCase {
1788 code: opcodes::OpBoolAnd::empty().expect("Should accept empty"),
1789 init: vec![vec![1], vec![]],
1790 dstack: vec![vec![]],
1791 },
1792 TestCase {
1793 code: opcodes::OpBoolAnd::empty().expect("Should accept empty"),
1794 init: vec![vec![], vec![1]],
1795 dstack: vec![vec![]],
1796 },
1797 TestCase {
1798 code: opcodes::OpBoolAnd::empty().expect("Should accept empty"),
1799 init: vec![vec![1], vec![1]],
1800 dstack: vec![vec![1]],
1801 },
1802 TestCase {
1803 code: opcodes::OpBoolAnd::empty().expect("Should accept empty"),
1804 init: vec![vec![1], vec![0x81]],
1805 dstack: vec![vec![1]],
1806 },
1807 TestCase {
1808 code: opcodes::OpBoolOr::empty().expect("Should accept empty"),
1809 init: vec![vec![], vec![]],
1810 dstack: vec![vec![]],
1811 },
1812 TestCase {
1813 code: opcodes::OpBoolOr::empty().expect("Should accept empty"),
1814 init: vec![vec![1], vec![]],
1815 dstack: vec![vec![1]],
1816 },
1817 TestCase {
1818 code: opcodes::OpBoolOr::empty().expect("Should accept empty"),
1819 init: vec![vec![], vec![1]],
1820 dstack: vec![vec![1]],
1821 },
1822 TestCase {
1823 code: opcodes::OpBoolOr::empty().expect("Should accept empty"),
1824 init: vec![vec![1], vec![1]],
1825 dstack: vec![vec![1]],
1826 },
1827 TestCase {
1828 code: opcodes::OpBoolOr::empty().expect("Should accept empty"),
1829 init: vec![vec![0x81], vec![1]],
1830 dstack: vec![vec![1]],
1831 },
1832 TestCase {
1833 code: opcodes::OpBoolOr::empty().expect("Should accept empty"),
1834 init: vec![vec![0x81], vec![1]],
1835 dstack: vec![vec![1]],
1836 },
1837 TestCase {
1838 code: opcodes::OpNumEqual::empty().expect("Should accept empty"),
1839 init: vec![vec![1], vec![1]],
1840 dstack: vec![vec![1]],
1841 },
1842 TestCase {
1843 code: opcodes::OpNumEqual::empty().expect("Should accept empty"),
1844 init: vec![vec![], vec![1]],
1845 dstack: vec![vec![]],
1846 },
1847 TestCase {
1848 code: opcodes::OpNumEqual::empty().expect("Should accept empty"),
1849 init: vec![vec![0x81], vec![1]],
1850 dstack: vec![vec![]],
1851 },
1852 TestCase {
1853 code: opcodes::OpNumEqual::empty().expect("Should accept empty"),
1854 init: vec![vec![], vec![]],
1855 dstack: vec![vec![1]],
1856 },
1857 TestCase {
1858 code: opcodes::OpNumNotEqual::empty().expect("Should accept empty"),
1859 init: vec![vec![1], vec![1]],
1860 dstack: vec![vec![]],
1861 },
1862 TestCase {
1863 code: opcodes::OpNumNotEqual::empty().expect("Should accept empty"),
1864 init: vec![vec![], vec![1]],
1865 dstack: vec![vec![1]],
1866 },
1867 TestCase {
1868 code: opcodes::OpNumNotEqual::empty().expect("Should accept empty"),
1869 init: vec![vec![0x81], vec![1]],
1870 dstack: vec![vec![1]],
1871 },
1872 TestCase {
1873 code: opcodes::OpNumNotEqual::empty().expect("Should accept empty"),
1874 init: vec![vec![], vec![]],
1875 dstack: vec![vec![]],
1876 },
1877 TestCase {
1878 code: opcodes::OpLessThan::empty().expect("Should accept empty"),
1879 init: vec![vec![1], vec![1]],
1880 dstack: vec![vec![]],
1881 },
1882 TestCase {
1883 code: opcodes::OpLessThan::empty().expect("Should accept empty"),
1884 init: vec![vec![], vec![1]],
1885 dstack: vec![vec![1]],
1886 },
1887 TestCase {
1888 code: opcodes::OpLessThan::empty().expect("Should accept empty"),
1889 init: vec![vec![0x81], vec![1]],
1890 dstack: vec![vec![1]],
1891 },
1892 TestCase {
1893 code: opcodes::OpLessThan::empty().expect("Should accept empty"),
1894 init: vec![vec![], vec![]],
1895 dstack: vec![vec![]],
1896 },
1897 TestCase {
1898 code: opcodes::OpLessThan::empty().expect("Should accept empty"),
1899 init: vec![vec![1], vec![]],
1900 dstack: vec![vec![]],
1901 },
1902 TestCase {
1903 code: opcodes::OpLessThan::empty().expect("Should accept empty"),
1904 init: vec![vec![], vec![0x81]],
1905 dstack: vec![vec![]],
1906 },
1907 TestCase {
1908 code: opcodes::OpLessThan::empty().expect("Should accept empty"),
1909 init: vec![vec![1], vec![0x81]],
1910 dstack: vec![vec![]],
1911 },
1912 TestCase {
1913 code: opcodes::OpLessThanOrEqual::empty().expect("Should accept empty"),
1914 init: vec![vec![1], vec![1]],
1915 dstack: vec![vec![1]],
1916 },
1917 TestCase {
1918 code: opcodes::OpLessThanOrEqual::empty().expect("Should accept empty"),
1919 init: vec![vec![], vec![1]],
1920 dstack: vec![vec![1]],
1921 },
1922 TestCase {
1923 code: opcodes::OpLessThanOrEqual::empty().expect("Should accept empty"),
1924 init: vec![vec![0x81], vec![1]],
1925 dstack: vec![vec![1]],
1926 },
1927 TestCase {
1928 code: opcodes::OpLessThanOrEqual::empty().expect("Should accept empty"),
1929 init: vec![vec![], vec![]],
1930 dstack: vec![vec![1]],
1931 },
1932 TestCase {
1933 code: opcodes::OpLessThanOrEqual::empty().expect("Should accept empty"),
1934 init: vec![vec![1], vec![]],
1935 dstack: vec![vec![]],
1936 },
1937 TestCase {
1938 code: opcodes::OpLessThanOrEqual::empty().expect("Should accept empty"),
1939 init: vec![vec![], vec![0x81]],
1940 dstack: vec![vec![]],
1941 },
1942 TestCase {
1943 code: opcodes::OpLessThanOrEqual::empty().expect("Should accept empty"),
1944 init: vec![vec![1], vec![0x81]],
1945 dstack: vec![vec![]],
1946 },
1947 TestCase {
1948 code: opcodes::OpGreaterThan::empty().expect("Should accept empty"),
1949 init: vec![vec![1], vec![1]],
1950 dstack: vec![vec![]],
1951 },
1952 TestCase {
1953 code: opcodes::OpGreaterThan::empty().expect("Should accept empty"),
1954 init: vec![vec![], vec![1]],
1955 dstack: vec![vec![]],
1956 },
1957 TestCase {
1958 code: opcodes::OpGreaterThan::empty().expect("Should accept empty"),
1959 init: vec![vec![0x81], vec![1]],
1960 dstack: vec![vec![]],
1961 },
1962 TestCase {
1963 code: opcodes::OpGreaterThan::empty().expect("Should accept empty"),
1964 init: vec![vec![], vec![]],
1965 dstack: vec![vec![]],
1966 },
1967 TestCase {
1968 code: opcodes::OpGreaterThan::empty().expect("Should accept empty"),
1969 init: vec![vec![1], vec![]],
1970 dstack: vec![vec![1]],
1971 },
1972 TestCase {
1973 code: opcodes::OpGreaterThan::empty().expect("Should accept empty"),
1974 init: vec![vec![], vec![0x81]],
1975 dstack: vec![vec![1]],
1976 },
1977 TestCase {
1978 code: opcodes::OpGreaterThan::empty().expect("Should accept empty"),
1979 init: vec![vec![1], vec![0x81]],
1980 dstack: vec![vec![1]],
1981 },
1982 TestCase {
1983 code: opcodes::OpGreaterThanOrEqual::empty().expect("Should accept empty"),
1984 init: vec![vec![1], vec![1]],
1985 dstack: vec![vec![1]],
1986 },
1987 TestCase {
1988 code: opcodes::OpGreaterThanOrEqual::empty().expect("Should accept empty"),
1989 init: vec![vec![], vec![1]],
1990 dstack: vec![vec![]],
1991 },
1992 TestCase {
1993 code: opcodes::OpGreaterThanOrEqual::empty().expect("Should accept empty"),
1994 init: vec![vec![0x81], vec![1]],
1995 dstack: vec![vec![]],
1996 },
1997 TestCase {
1998 code: opcodes::OpGreaterThanOrEqual::empty().expect("Should accept empty"),
1999 init: vec![vec![], vec![]],
2000 dstack: vec![vec![1]],
2001 },
2002 TestCase {
2003 code: opcodes::OpGreaterThanOrEqual::empty().expect("Should accept empty"),
2004 init: vec![vec![1], vec![]],
2005 dstack: vec![vec![1]],
2006 },
2007 TestCase {
2008 code: opcodes::OpGreaterThanOrEqual::empty().expect("Should accept empty"),
2009 init: vec![vec![], vec![0x81]],
2010 dstack: vec![vec![1]],
2011 },
2012 TestCase {
2013 code: opcodes::OpGreaterThanOrEqual::empty().expect("Should accept empty"),
2014 init: vec![vec![1], vec![0x81]],
2015 dstack: vec![vec![1]],
2016 },
2017 ]);
2018 }
2019
2020 #[test]
2021 fn test_opdepth() {
2022 run_success_test_cases(vec![
2023 TestCase { code: opcodes::OpDepth::empty().expect("Should accept empty"), init: vec![], dstack: vec![vec![]] },
2024 TestCase {
2025 code: opcodes::OpDepth::empty().expect("Should accept empty"),
2026 init: vec![vec![]],
2027 dstack: vec![vec![], vec![1]],
2028 },
2029 TestCase {
2030 code: opcodes::OpDepth::empty().expect("Should accept empty"),
2031 init: vec![vec![1], vec![2], vec![3]],
2032 dstack: vec![vec![1], vec![2], vec![3], vec![3]],
2033 },
2034 ]);
2035 }
2036
2037 #[test]
2038 fn test_opdrop() {
2039 run_success_test_cases(vec![
2040 TestCase { code: opcodes::OpDrop::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![] },
2041 TestCase {
2042 code: opcodes::OpDrop::empty().expect("Should accept empty"),
2043 init: vec![vec![], vec![1]],
2044 dstack: vec![vec![]],
2045 },
2046 TestCase {
2047 code: opcodes::OpDrop::empty().expect("Should accept empty"),
2048 init: vec![vec![1], vec![2], vec![3], vec![3]],
2049 dstack: vec![vec![1], vec![2], vec![3]],
2050 },
2051 ]);
2052
2053 run_error_test_cases(vec![ErrorTestCase {
2054 code: opcodes::OpDrop::empty().expect("Should accept empty"),
2055 init: vec![],
2056 error: TxScriptError::InvalidStackOperation(1, 0),
2057 }])
2058 }
2059
2060 #[test]
2061 fn test_op2drop() {
2062 run_success_test_cases(vec![
2063 TestCase { code: opcodes::Op2Drop::empty().expect("Should accept empty"), init: vec![vec![], vec![1]], dstack: vec![] },
2064 TestCase {
2065 code: opcodes::Op2Drop::empty().expect("Should accept empty"),
2066 init: vec![vec![1], vec![2], vec![3], vec![3]],
2067 dstack: vec![vec![1], vec![2]],
2068 },
2069 ]);
2070
2071 run_error_test_cases(vec![
2072 ErrorTestCase {
2073 code: opcodes::Op2Drop::empty().expect("Should accept empty"),
2074 init: vec![],
2075 error: TxScriptError::InvalidStackOperation(2, 0),
2076 },
2077 ErrorTestCase {
2078 code: opcodes::Op2Drop::empty().expect("Should accept empty"),
2079 init: vec![vec![]],
2080 error: TxScriptError::InvalidStackOperation(2, 1),
2081 },
2082 ])
2083 }
2084
2085 #[test]
2086 fn test_opdup() {
2087 run_success_test_cases(vec![
2088 TestCase { code: opcodes::OpDup::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![], vec![]] },
2089 TestCase {
2090 code: opcodes::OpDup::empty().expect("Should accept empty"),
2091 init: vec![vec![], vec![1]],
2092 dstack: vec![vec![], vec![1], vec![1]],
2093 },
2094 TestCase {
2095 code: opcodes::OpDup::empty().expect("Should accept empty"),
2096 init: vec![vec![1], vec![2], vec![3], vec![3]],
2097 dstack: vec![vec![1], vec![2], vec![3], vec![3], vec![3]],
2098 },
2099 ]);
2100
2101 run_error_test_cases(vec![ErrorTestCase {
2102 code: opcodes::OpDup::empty().expect("Should accept empty"),
2103 init: vec![],
2104 error: TxScriptError::InvalidStackOperation(1, 0),
2105 }])
2106 }
2107
2108 #[test]
2109 fn test_op2dup() {
2110 run_success_test_cases(vec![
2111 TestCase {
2112 code: opcodes::Op2Dup::empty().expect("Should accept empty"),
2113 init: vec![vec![], vec![1]],
2114 dstack: vec![vec![], vec![1], vec![], vec![1]],
2115 },
2116 TestCase {
2117 code: opcodes::Op2Dup::empty().expect("Should accept empty"),
2118 init: vec![vec![1], vec![2], vec![3]],
2119 dstack: vec![vec![1], vec![2], vec![3], vec![2], vec![3]],
2120 },
2121 ]);
2122
2123 run_error_test_cases(vec![
2124 ErrorTestCase {
2125 code: opcodes::Op2Dup::empty().expect("Should accept empty"),
2126 init: vec![],
2127 error: TxScriptError::InvalidStackOperation(2, 0),
2128 },
2129 ErrorTestCase {
2130 code: opcodes::Op2Dup::empty().expect("Should accept empty"),
2131 init: vec![vec![]],
2132 error: TxScriptError::InvalidStackOperation(2, 1),
2133 },
2134 ]);
2135 }
2136
2137 #[test]
2138 fn test_op3dup() {
2139 run_success_test_cases(vec![
2140 TestCase {
2141 code: opcodes::Op3Dup::empty().expect("Should accept empty"),
2142 init: vec![vec![0x81], vec![], vec![1]],
2143 dstack: vec![vec![0x81], vec![], vec![1], vec![0x81], vec![], vec![1]],
2144 },
2145 TestCase {
2146 code: opcodes::Op3Dup::empty().expect("Should accept empty"),
2147 init: vec![vec![1], vec![2], vec![3]],
2148 dstack: vec![vec![1], vec![2], vec![3], vec![1], vec![2], vec![3]],
2149 },
2150 ]);
2151
2152 run_error_test_cases(vec![
2153 ErrorTestCase {
2154 code: opcodes::Op3Dup::empty().expect("Should accept empty"),
2155 init: vec![],
2156 error: TxScriptError::InvalidStackOperation(3, 0),
2157 },
2158 ErrorTestCase {
2159 code: opcodes::Op3Dup::empty().expect("Should accept empty"),
2160 init: vec![vec![]],
2161 error: TxScriptError::InvalidStackOperation(3, 1),
2162 },
2163 ErrorTestCase {
2164 code: opcodes::Op3Dup::empty().expect("Should accept empty"),
2165 init: vec![vec![], vec![]],
2166 error: TxScriptError::InvalidStackOperation(3, 2),
2167 },
2168 ]);
2169 }
2170
2171 #[test]
2172 fn test_opnip() {
2173 run_success_test_cases(vec![
2174 TestCase {
2175 code: opcodes::OpNip::empty().expect("Should accept empty"),
2176 init: vec![vec![], vec![1]],
2177 dstack: vec![vec![1]],
2178 },
2179 TestCase {
2180 code: opcodes::OpNip::empty().expect("Should accept empty"),
2181 init: vec![vec![1], vec![]],
2182 dstack: vec![vec![]],
2183 },
2184 TestCase {
2185 code: opcodes::OpNip::empty().expect("Should accept empty"),
2186 init: vec![vec![2], vec![], vec![1]],
2187 dstack: vec![vec![2], vec![1]],
2188 },
2189 ]);
2190
2191 run_error_test_cases(vec![
2192 ErrorTestCase {
2193 code: opcodes::OpNip::empty().expect("Should accept empty"),
2194 init: vec![],
2195 error: TxScriptError::InvalidStackOperation(2, 0),
2196 },
2197 ErrorTestCase {
2198 code: opcodes::OpNip::empty().expect("Should accept empty"),
2199 init: vec![vec![]],
2200 error: TxScriptError::InvalidStackOperation(2, 1),
2201 },
2202 ]);
2203 }
2204
2205 #[test]
2206 fn test_opover() {
2207 run_success_test_cases(vec![
2208 TestCase {
2209 code: opcodes::OpOver::empty().expect("Should accept empty"),
2210 init: vec![vec![], vec![1]],
2211 dstack: vec![vec![], vec![1], vec![]],
2212 },
2213 TestCase {
2214 code: opcodes::OpOver::empty().expect("Should accept empty"),
2215 init: vec![vec![1], vec![]],
2216 dstack: vec![vec![1], vec![], vec![1]],
2217 },
2218 TestCase {
2219 code: opcodes::OpOver::empty().expect("Should accept empty"),
2220 init: vec![vec![2], vec![], vec![1]],
2221 dstack: vec![vec![2], vec![], vec![1], vec![]],
2222 },
2223 ]);
2224
2225 run_error_test_cases(vec![
2226 ErrorTestCase {
2227 code: opcodes::OpOver::empty().expect("Should accept empty"),
2228 init: vec![],
2229 error: TxScriptError::InvalidStackOperation(2, 0),
2230 },
2231 ErrorTestCase {
2232 code: opcodes::OpOver::empty().expect("Should accept empty"),
2233 init: vec![vec![]],
2234 error: TxScriptError::InvalidStackOperation(2, 1),
2235 },
2236 ]);
2237 }
2238
2239 #[test]
2240 fn test_op2over() {
2241 run_success_test_cases(vec![
2242 TestCase {
2243 code: opcodes::Op2Over::empty().expect("Should accept empty"),
2244 init: vec![vec![0x81], vec![2], vec![], vec![1]],
2245 dstack: vec![vec![0x81], vec![2], vec![], vec![1], vec![0x81], vec![2]],
2246 },
2247 TestCase {
2248 code: opcodes::Op2Over::empty().expect("Should accept empty"),
2249 init: vec![vec![], vec![0x81], vec![2], vec![], vec![1]],
2250 dstack: vec![vec![], vec![0x81], vec![2], vec![], vec![1], vec![0x81], vec![2]],
2251 },
2252 ]);
2253
2254 run_error_test_cases(vec![
2255 ErrorTestCase {
2256 code: opcodes::Op2Over::empty().expect("Should accept empty"),
2257 init: vec![],
2258 error: TxScriptError::InvalidStackOperation(4, 0),
2259 },
2260 ErrorTestCase {
2261 code: opcodes::Op2Over::empty().expect("Should accept empty"),
2262 init: vec![vec![]],
2263 error: TxScriptError::InvalidStackOperation(4, 1),
2264 },
2265 ErrorTestCase {
2266 code: opcodes::Op2Over::empty().expect("Should accept empty"),
2267 init: vec![vec![], vec![]],
2268 error: TxScriptError::InvalidStackOperation(4, 2),
2269 },
2270 ErrorTestCase {
2271 code: opcodes::Op2Over::empty().expect("Should accept empty"),
2272 init: vec![vec![], vec![], vec![]],
2273 error: TxScriptError::InvalidStackOperation(4, 3),
2274 },
2275 ]);
2276 }
2277
2278 #[test]
2279 fn test_oppick() {
2280 run_success_test_cases(vec![
2281 TestCase {
2282 code: opcodes::OpPick::empty().expect("Should accept empty"),
2283 init: vec![vec![], vec![]],
2284 dstack: vec![vec![], vec![]],
2285 },
2286 TestCase {
2287 code: opcodes::OpPick::empty().expect("Should accept empty"),
2288 init: vec![vec![2], vec![], vec![1]],
2289 dstack: vec![vec![2], vec![], vec![2]],
2290 },
2291 TestCase {
2292 code: opcodes::OpPick::empty().expect("Should accept empty"),
2293 init: vec![vec![5], vec![4], vec![3], vec![], vec![2]],
2294 dstack: vec![vec![5], vec![4], vec![3], vec![], vec![4]],
2295 },
2296 ]);
2297
2298 run_error_test_cases(vec![
2299 ErrorTestCase {
2300 code: opcodes::OpPick::empty().expect("Should accept empty"),
2301 init: vec![vec![5], vec![4], vec![3], vec![], vec![4]],
2302 error: TxScriptError::InvalidState("pick at an invalid location".to_string()),
2303 },
2304 ErrorTestCase {
2305 code: opcodes::OpPick::empty().expect("Should accept empty"),
2306 init: vec![vec![5], vec![4], vec![3], vec![], vec![0x81]],
2307 error: TxScriptError::InvalidState("pick at an invalid location".to_string()),
2308 },
2309 ])
2310 }
2311
2312 #[test]
2313 fn test_oproll() {
2314 run_success_test_cases(vec![
2315 TestCase {
2316 code: opcodes::OpRoll::empty().expect("Should accept empty"),
2317 init: vec![vec![], vec![]],
2318 dstack: vec![vec![]],
2319 },
2320 TestCase {
2321 code: opcodes::OpRoll::empty().expect("Should accept empty"),
2322 init: vec![vec![2], vec![], vec![1]],
2323 dstack: vec![vec![], vec![2]],
2324 },
2325 TestCase {
2326 code: opcodes::OpRoll::empty().expect("Should accept empty"),
2327 init: vec![vec![5], vec![4], vec![3], vec![], vec![2]],
2328 dstack: vec![vec![5], vec![3], vec![], vec![4]],
2329 },
2330 ]);
2331
2332 run_error_test_cases(vec![
2333 ErrorTestCase {
2334 code: opcodes::OpRoll::empty().expect("Should accept empty"),
2335 init: vec![vec![5], vec![4], vec![3], vec![], vec![4]],
2336 error: TxScriptError::InvalidState("roll at an invalid location".to_string()),
2337 },
2338 ErrorTestCase {
2339 code: opcodes::OpRoll::empty().expect("Should accept empty"),
2340 init: vec![vec![5], vec![4], vec![3], vec![], vec![0x81]],
2341 error: TxScriptError::InvalidState("roll at an invalid location".to_string()),
2342 },
2343 ])
2344 }
2345
2346 #[test]
2347 fn test_oprot() {
2348 run_success_test_cases(vec![
2349 TestCase {
2350 code: opcodes::OpRot::empty().expect("Should accept empty"),
2351 init: vec![vec![1], vec![2], vec![3]],
2352 dstack: vec![vec![2], vec![3], vec![1]],
2353 },
2354 TestCase {
2355 code: opcodes::OpRot::empty().expect("Should accept empty"),
2356 init: vec![vec![], vec![1], vec![2], vec![3]],
2357 dstack: vec![vec![], vec![2], vec![3], vec![1]],
2358 },
2359 ]);
2360
2361 run_error_test_cases(vec![
2362 ErrorTestCase {
2363 code: opcodes::OpRot::empty().expect("Should accept empty"),
2364 init: vec![vec![2], vec![3]],
2365 error: TxScriptError::InvalidStackOperation(3, 2),
2366 },
2367 ErrorTestCase {
2368 code: opcodes::OpRot::empty().expect("Should accept empty"),
2369 init: vec![vec![3]],
2370 error: TxScriptError::InvalidStackOperation(3, 1),
2371 },
2372 ErrorTestCase {
2373 code: opcodes::OpRot::empty().expect("Should accept empty"),
2374 init: vec![],
2375 error: TxScriptError::InvalidStackOperation(3, 0),
2376 },
2377 ]);
2378 }
2379
2380 #[test]
2381 fn test_op2rot() {
2382 run_success_test_cases(vec![
2383 TestCase {
2384 code: opcodes::Op2Rot::empty().expect("Should accept empty"),
2385 init: vec![vec![1], vec![2], vec![3], vec![4], vec![5], vec![6]],
2386 dstack: vec![vec![3], vec![4], vec![5], vec![6], vec![1], vec![2]],
2387 },
2388 TestCase {
2389 code: opcodes::Op2Rot::empty().expect("Should accept empty"),
2390 init: vec![vec![], vec![1], vec![2], vec![3], vec![4], vec![5], vec![6]],
2391 dstack: vec![vec![], vec![3], vec![4], vec![5], vec![6], vec![1], vec![2]],
2392 },
2393 ]);
2394
2395 run_error_test_cases(vec![
2396 ErrorTestCase {
2397 code: opcodes::Op2Rot::empty().expect("Should accept empty"),
2398 init: vec![vec![1], vec![2], vec![3], vec![4], vec![5]],
2399 error: TxScriptError::InvalidStackOperation(6, 5),
2400 },
2401 ErrorTestCase {
2402 code: opcodes::Op2Rot::empty().expect("Should accept empty"),
2403 init: vec![vec![1], vec![2], vec![3], vec![4]],
2404 error: TxScriptError::InvalidStackOperation(6, 4),
2405 },
2406 ErrorTestCase {
2407 code: opcodes::Op2Rot::empty().expect("Should accept empty"),
2408 init: vec![vec![1], vec![2], vec![3]],
2409 error: TxScriptError::InvalidStackOperation(6, 3),
2410 },
2411 ErrorTestCase {
2412 code: opcodes::Op2Rot::empty().expect("Should accept empty"),
2413 init: vec![vec![1], vec![2]],
2414 error: TxScriptError::InvalidStackOperation(6, 2),
2415 },
2416 ErrorTestCase {
2417 code: opcodes::Op2Rot::empty().expect("Should accept empty"),
2418 init: vec![vec![1]],
2419 error: TxScriptError::InvalidStackOperation(6, 1),
2420 },
2421 ErrorTestCase {
2422 code: opcodes::Op2Rot::empty().expect("Should accept empty"),
2423 init: vec![],
2424 error: TxScriptError::InvalidStackOperation(6, 0),
2425 },
2426 ]);
2427 }
2428
2429 #[test]
2430 fn test_opswap() {
2431 run_success_test_cases(vec![
2432 TestCase {
2433 code: opcodes::OpSwap::empty().expect("Should accept empty"),
2434 init: vec![vec![1], vec![2]],
2435 dstack: vec![vec![2], vec![1]],
2436 },
2437 TestCase {
2438 code: opcodes::OpSwap::empty().expect("Should accept empty"),
2439 init: vec![vec![], vec![1], vec![5]],
2440 dstack: vec![vec![], vec![5], vec![1]],
2441 },
2442 ]);
2443
2444 run_error_test_cases(vec![
2445 ErrorTestCase {
2446 code: opcodes::OpSwap::empty().expect("Should accept empty"),
2447 init: vec![vec![1]],
2448 error: TxScriptError::InvalidStackOperation(2, 1),
2449 },
2450 ErrorTestCase {
2451 code: opcodes::OpSwap::empty().expect("Should accept empty"),
2452 init: vec![],
2453 error: TxScriptError::InvalidStackOperation(2, 0),
2454 },
2455 ]);
2456 }
2457
2458 #[test]
2459 fn test_op2swap() {
2460 run_success_test_cases(vec![
2461 TestCase {
2462 code: opcodes::Op2Swap::empty().expect("Should accept empty"),
2463 init: vec![vec![1], vec![2], vec![3], vec![4]],
2464 dstack: vec![vec![3], vec![4], vec![1], vec![2]],
2465 },
2466 TestCase {
2467 code: opcodes::Op2Swap::empty().expect("Should accept empty"),
2468 init: vec![vec![], vec![1], vec![2], vec![3], vec![4]],
2469 dstack: vec![vec![], vec![3], vec![4], vec![1], vec![2]],
2470 },
2471 ]);
2472
2473 run_error_test_cases(vec![
2474 ErrorTestCase {
2475 code: opcodes::Op2Swap::empty().expect("Should accept empty"),
2476 init: vec![vec![], vec![2], vec![1]],
2477 error: TxScriptError::InvalidStackOperation(4, 3),
2478 },
2479 ErrorTestCase {
2480 code: opcodes::Op2Swap::empty().expect("Should accept empty"),
2481 init: vec![vec![], vec![1]],
2482 error: TxScriptError::InvalidStackOperation(4, 2),
2483 },
2484 ErrorTestCase {
2485 code: opcodes::Op2Swap::empty().expect("Should accept empty"),
2486 init: vec![vec![1]],
2487 error: TxScriptError::InvalidStackOperation(4, 1),
2488 },
2489 ErrorTestCase {
2490 code: opcodes::Op2Swap::empty().expect("Should accept empty"),
2491 init: vec![],
2492 error: TxScriptError::InvalidStackOperation(4, 0),
2493 },
2494 ]);
2495 }
2496
2497 #[test]
2498 fn test_optuck() {
2499 run_success_test_cases(vec![
2500 TestCase {
2501 code: opcodes::OpTuck::empty().expect("Should accept empty"),
2502 init: vec![vec![1], vec![2]],
2503 dstack: vec![vec![2], vec![1], vec![2]],
2504 },
2505 TestCase {
2506 code: opcodes::OpTuck::empty().expect("Should accept empty"),
2507 init: vec![vec![3], vec![9], vec![2]],
2508 dstack: vec![vec![3], vec![2], vec![9], vec![2]],
2509 },
2510 ]);
2511
2512 run_error_test_cases(vec![
2513 ErrorTestCase {
2514 code: opcodes::OpTuck::empty().expect("Should accept empty"),
2515 init: vec![vec![3]],
2516 error: TxScriptError::InvalidStackOperation(2, 1),
2517 },
2518 ErrorTestCase {
2519 code: opcodes::OpTuck::empty().expect("Should accept empty"),
2520 init: vec![],
2521 error: TxScriptError::InvalidStackOperation(2, 0),
2522 },
2523 ]);
2524 }
2525
2526 #[test]
2527 fn test_opequalverify() {
2528 run_success_test_cases(vec![
2529 TestCase {
2530 code: opcodes::OpEqualVerify::empty().expect("Should accept empty"),
2531 init: vec![vec![], vec![]],
2532 dstack: vec![],
2533 },
2534 TestCase {
2535 code: opcodes::OpEqualVerify::empty().expect("Should accept empty"),
2536 init: vec![vec![], vec![1, 0, 1], vec![1, 0, 1]],
2537 dstack: vec![vec![]],
2538 },
2539 TestCase {
2540 code: opcodes::OpNumEqualVerify::empty().expect("Should accept empty"),
2541 init: vec![vec![], vec![]],
2542 dstack: vec![],
2543 },
2544 TestCase {
2545 code: opcodes::OpNumEqualVerify::empty().expect("Should accept empty"),
2546 init: vec![vec![], vec![0, 0, 1], vec![0, 0, 1]],
2547 dstack: vec![vec![]],
2548 },
2549 ]);
2550
2551 run_error_test_cases(vec![
2552 ErrorTestCase {
2553 code: opcodes::OpEqualVerify::empty().expect("Should accept empty"),
2554 init: vec![vec![], vec![2, 0, 1], vec![1, 0, 1]],
2555 error: TxScriptError::VerifyError,
2556 },
2557 ErrorTestCase {
2558 code: opcodes::OpEqualVerify::empty().expect("Should accept empty"),
2559 init: vec![vec![1], vec![]],
2560 error: TxScriptError::VerifyError,
2561 },
2562 ErrorTestCase {
2563 code: opcodes::OpNumEqualVerify::empty().expect("Should accept empty"),
2564 init: vec![vec![], vec![2, 0, 1], vec![1, 0, 1]],
2565 error: TxScriptError::VerifyError,
2566 },
2567 ErrorTestCase {
2568 code: opcodes::OpNumEqualVerify::empty().expect("Should accept empty"),
2569 init: vec![vec![1], vec![]],
2570 error: TxScriptError::VerifyError,
2571 },
2572 ]);
2573 }
2574
2575 #[test]
2576 fn test_opsize() {
2577 run_success_test_cases(vec![
2578 TestCase {
2579 code: opcodes::OpSize::empty().expect("Should accept empty"),
2580 init: vec![vec![]],
2581 dstack: vec![vec![], vec![]],
2582 },
2583 TestCase {
2584 code: opcodes::OpSize::empty().expect("Should accept empty"),
2585 init: vec![vec![5]],
2586 dstack: vec![vec![5], vec![1]],
2587 },
2588 TestCase {
2589 code: opcodes::OpSize::empty().expect("Should accept empty"),
2590 init: vec![vec![0x80, 1]],
2591 dstack: vec![vec![0x80, 1], vec![2]],
2592 },
2593 ]);
2594
2595 run_error_test_cases(vec![ErrorTestCase {
2596 code: opcodes::OpSize::empty().expect("Should accept empty"),
2597 init: vec![],
2598 error: TxScriptError::InvalidStackOperation(1, 0),
2599 }]);
2600 }
2601
2602 #[test]
2603 fn test_opwithin() {
2604 run_success_test_cases(vec![
2605 TestCase {
2606 code: opcodes::OpWithin::empty().expect("Should accept empty"),
2607 init: vec![vec![], vec![], vec![1]],
2608 dstack: vec![vec![1]],
2609 },
2610 TestCase {
2611 code: opcodes::OpWithin::empty().expect("Should accept empty"),
2612 init: vec![vec![], vec![], vec![]],
2613 dstack: vec![vec![]],
2614 },
2615 TestCase {
2616 code: opcodes::OpWithin::empty().expect("Should accept empty"),
2617 init: vec![vec![0x81], vec![0x91], vec![1]],
2618 dstack: vec![vec![1]],
2619 },
2620 ]);
2621
2622 run_error_test_cases(vec![
2623 ErrorTestCase {
2624 code: opcodes::OpWithin::empty().expect("Should accept empty"),
2625 init: vec![vec![], vec![]],
2626 error: TxScriptError::InvalidStackOperation(3, 2),
2627 },
2628 ErrorTestCase {
2629 code: opcodes::OpWithin::empty().expect("Should accept empty"),
2630 init: vec![vec![]],
2631 error: TxScriptError::InvalidStackOperation(3, 1),
2632 },
2633 ErrorTestCase {
2634 code: opcodes::OpWithin::empty().expect("Should accept empty"),
2635 init: vec![],
2636 error: TxScriptError::InvalidStackOperation(3, 0),
2637 },
2638 ]);
2639 }
2640
2641 #[test]
2642 fn test_opsha256() {
2643 run_success_test_cases(vec![
2645 TestCase {
2646 code: opcodes::OpSHA256::empty().expect("Should accept empty"),
2647 init: vec![vec![]],
2648 dstack: vec![b"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55".to_vec()],
2649 },
2650 TestCase {
2651 code: opcodes::OpSHA256::empty().expect("Should accept empty"),
2652 init: vec![b"abc".to_vec()],
2653 dstack: vec![b"\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad".to_vec()],
2654 },
2655 TestCase {
2656 code: opcodes::OpSHA256::empty().expect("Should accept empty"),
2657 init: vec![b"\xde\x18\x89\x41\xa3\x37\x5d\x3a\x8a\x06\x1e\x67\x57\x6e\x92\x6d".to_vec()],
2658 dstack: vec![b"\x06\x7c\x53\x12\x69\x73\x5c\xa7\xf5\x41\xfd\xac\xa8\xf0\xdc\x76\x30\x5d\x3c\xad\xa1\x40\xf8\x93\x72\xa4\x10\xfe\x5e\xff\x6e\x4d".to_vec()],
2659 },
2660 ]);
2661
2662 run_error_test_cases(vec![ErrorTestCase {
2663 code: opcodes::OpSHA256::empty().expect("Should accept empty"),
2664 init: vec![],
2665 error: TxScriptError::InvalidStackOperation(1, 0),
2666 }]);
2667 }
2668
2669 #[test]
2670 fn test_opblake2b() {
2671 run_success_test_cases(vec![
2672 TestCase {
2673 code: opcodes::OpBlake2b::empty().expect("Should accept empty"),
2674 init: vec![b"".to_vec()],
2675 dstack: vec![b"\x0e\x57\x51\xc0\x26\xe5\x43\xb2\xe8\xab\x2e\xb0\x60\x99\xda\xa1\xd1\xe5\xdf\x47\x77\x8f\x77\x87\xfa\xab\x45\xcd\xf1\x2f\xe3\xa8".to_vec()],
2676 },
2677 TestCase {
2678 code: opcodes::OpBlake2b::empty().expect("Should accept empty"),
2679 init: vec![b"abc".to_vec()],
2680 dstack: vec![b"\xbd\xdd\x81\x3c\x63\x42\x39\x72\x31\x71\xef\x3f\xee\x98\x57\x9b\x94\x96\x4e\x3b\xb1\xcb\x3e\x42\x72\x62\xc8\xc0\x68\xd5\x23\x19".to_vec()],
2681 },
2682 ]);
2683
2684 run_error_test_cases(vec![ErrorTestCase {
2685 code: opcodes::OpBlake2b::empty().expect("Should accept empty"),
2686 init: vec![],
2687 error: TxScriptError::InvalidStackOperation(1, 0),
2688 }]);
2689 }
2690
2691 #[test]
2692 fn test_opnop() {
2693 run_success_test_cases(vec![TestCase {
2694 code: opcodes::OpNop::empty().expect("Should accept empty"),
2695 init: vec![vec![], vec![1], vec![2]],
2696 dstack: vec![vec![], vec![1], vec![2]],
2697 }]);
2698 }
2699
2700 #[derive(Clone)]
2701 struct VerifiableTransactionMock(Transaction);
2702
2703 impl VerifiableTransaction for VerifiableTransactionMock {
2704 fn tx(&self) -> &Transaction {
2705 &self.0
2706 }
2707
2708 fn populated_input(&self, _index: usize) -> (&TransactionInput, &UtxoEntry) {
2709 unimplemented!()
2710 }
2711 }
2712
2713 fn make_mock_transaction(lock_time: u64) -> (VerifiableTransactionMock, TransactionInput, UtxoEntry) {
2714 let dummy_prev_out = TransactionOutpoint::new(kaspa_hashes::Hash::from_u64_word(1), 1);
2715 let dummy_sig_script = vec![0u8; 65];
2716 let dummy_tx_input = TransactionInput::new(dummy_prev_out, dummy_sig_script, 10, 1);
2717 let addr_hash = vec![1u8; 32];
2718
2719 let addr = Address::new(Prefix::Testnet, Version::PubKey, &addr_hash);
2720 let dummy_script_public_key = pay_to_address_script(&addr);
2721 let dummy_tx_out = TransactionOutput::new(SOMPI_PER_KASPA, dummy_script_public_key);
2722
2723 let tx = VerifiableTransactionMock(Transaction::new(
2724 TX_VERSION + 1,
2725 vec![dummy_tx_input.clone()],
2726 vec![dummy_tx_out.clone()],
2727 lock_time,
2728 SUBNETWORK_ID_NATIVE,
2729 0,
2730 vec![],
2731 ));
2732 let utxo_entry = UtxoEntry::new(0, ScriptPublicKey::default(), 0, false);
2733 (tx, dummy_tx_input, utxo_entry)
2734 }
2735
2736 #[test]
2737 fn test_opchecklocktimeverify() {
2738 let (base_tx, input, utxo_entry) = make_mock_transaction(1);
2740
2741 let sig_cache = Cache::new(10_000);
2742 let mut reused_values = SigHashReusedValues::new();
2743
2744 let code = opcodes::OpCheckLockTimeVerify::empty().expect("Should accept empty");
2745
2746 for (tx_lock_time, lock_time, should_fail) in [
2747 (1u64, vec![], false), (0x800000, vec![0x7f, 0, 0], false), (0x800000, vec![0x7f, 0, 0, 0, 0, 0, 0, 0, 0], true), (LOCK_TIME_THRESHOLD * 2, vec![0x7f, 0, 0, 0], true), ] {
2752 let mut tx = base_tx.clone();
2753 tx.0.lock_time = tx_lock_time;
2754 let mut vm = TxScriptEngine::from_transaction_input(&tx, &input, 0, &utxo_entry, &mut reused_values, &sig_cache)
2755 .expect("Shouldn't fail");
2756 vm.dstack = vec![lock_time.clone()];
2757 match code.execute(&mut vm) {
2758 Ok(()) => assert!(
2760 !should_fail,
2761 "Opcode {} must fail (tx_lock_time: {}, lock_time: {:?})",
2762 code.value(),
2763 tx_lock_time,
2764 lock_time
2765 ),
2766 Err(e) => assert!(
2767 should_fail,
2768 "Opcode {} should not fail. Got {} (tx_lock_time: {}, lock_time: {:?})",
2769 code.value(),
2770 e,
2771 tx_lock_time,
2772 lock_time
2773 ),
2774 }
2775 }
2776 }
2777
2778 #[test]
2779 fn test_opchecksequencerify() {
2780 let (tx, base_input, utxo_entry) = make_mock_transaction(1);
2782
2783 let sig_cache = Cache::new(10_000);
2784 let mut reused_values = SigHashReusedValues::new();
2785
2786 let code = opcodes::OpCheckSequenceVerify::empty().expect("Should accept empty");
2787
2788 for (tx_sequence, sequence, should_fail) in [
2789 (1u64, vec![], false), (0x800000, vec![0x7f, 0, 0], false), (0x800000, vec![0x7f, 0, 0, 0, 0, 0, 0, 0, 0], true), (1 << 63, vec![0x7f, 0, 0], true), ((1 << 63) | 0xffff, vec![0x7f, 0, 0], true), ] {
2795 let mut input = base_input.clone();
2796 input.sequence = tx_sequence;
2797 let mut vm = TxScriptEngine::from_transaction_input(&tx, &input, 0, &utxo_entry, &mut reused_values, &sig_cache)
2798 .expect("Shouldn't fail");
2799 vm.dstack = vec![sequence.clone()];
2800 match code.execute(&mut vm) {
2801 Ok(()) => {
2803 assert!(!should_fail, "Opcode {} must fail (tx_sequence: {}, sequence: {:?})", code.value(), tx_sequence, sequence)
2804 }
2805 Err(e) => assert!(
2806 should_fail,
2807 "Opcode {} should not fail. Got {} (tx_sequence: {}, sequence: {:?})",
2808 code.value(),
2809 e,
2810 tx_sequence,
2811 sequence
2812 ),
2813 }
2814 }
2815 }
2816
2817 #[test]
2818 fn test_opreturn() {
2819 run_error_test_cases(vec![ErrorTestCase {
2820 code: opcodes::OpReturn::empty().expect("Should accept empty"),
2821 init: vec![],
2822 error: TxScriptError::EarlyReturn,
2823 }]);
2824 }
2825
2826 #[test]
2827 fn test_opverify() {
2828 run_success_test_cases(vec![
2829 TestCase { code: opcodes::OpVerify::empty().expect("Should accept empty"), init: vec![vec![1]], dstack: vec![] },
2830 TestCase { code: opcodes::OpVerify::empty().expect("Should accept empty"), init: vec![vec![0x81]], dstack: vec![] },
2831 TestCase { code: opcodes::OpVerify::empty().expect("Should accept empty"), init: vec![vec![0x80, 0]], dstack: vec![] },
2832 TestCase {
2833 code: opcodes::OpVerify::empty().expect("Should accept empty"),
2834 init: vec![vec![1, 0, 0, 0, 0]],
2835 dstack: vec![],
2836 },
2837 ]);
2838
2839 run_error_test_cases(vec![
2840 ErrorTestCase {
2841 code: opcodes::OpVerify::empty().expect("Should accept empty"),
2842 init: vec![vec![0, 0, 0, 0x80]],
2843 error: TxScriptError::VerifyError,
2844 },
2845 ErrorTestCase {
2846 code: opcodes::OpVerify::empty().expect("Should accept empty"),
2847 init: vec![vec![0, 0, 0, 0]],
2848 error: TxScriptError::VerifyError,
2849 },
2850 ErrorTestCase {
2851 code: opcodes::OpVerify::empty().expect("Should accept empty"),
2852 init: vec![vec![0x80]],
2853 error: TxScriptError::VerifyError,
2854 },
2855 ErrorTestCase {
2856 code: opcodes::OpVerify::empty().expect("Should accept empty"),
2857 init: vec![vec![0]],
2858 error: TxScriptError::VerifyError,
2859 },
2860 ErrorTestCase {
2861 code: opcodes::OpVerify::empty().expect("Should accept empty"),
2862 init: vec![vec![]],
2863 error: TxScriptError::VerifyError,
2864 },
2865 ErrorTestCase {
2866 code: opcodes::OpVerify::empty().expect("Should accept empty"),
2867 init: vec![],
2868 error: TxScriptError::InvalidStackOperation(1, 0),
2869 },
2870 ])
2871 }
2872
2873 #[test]
2874 fn test_opifdup() {
2875 run_success_test_cases(vec![
2876 TestCase {
2877 code: opcodes::OpIfDup::empty().expect("Should accept empty"),
2878 init: vec![vec![1]],
2879 dstack: vec![vec![1], vec![1]],
2880 },
2881 TestCase {
2882 code: opcodes::OpIfDup::empty().expect("Should accept empty"),
2883 init: vec![vec![0x80, 0]],
2884 dstack: vec![vec![0x80, 0], vec![0x80, 0]],
2885 },
2886 TestCase { code: opcodes::OpIfDup::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![]] },
2887 TestCase {
2888 code: opcodes::OpIfDup::empty().expect("Should accept empty"),
2889 init: vec![vec![0x80]],
2890 dstack: vec![vec![0x80]],
2891 },
2892 TestCase {
2893 code: opcodes::OpIfDup::empty().expect("Should accept empty"),
2894 init: vec![vec![0, 0x80]],
2895 dstack: vec![vec![0, 0x80]],
2896 },
2897 TestCase { code: opcodes::OpIfDup::empty().expect("Should accept empty"), init: vec![vec![]], dstack: vec![vec![]] },
2898 ])
2899 }
2900}