1use crate::opcodes::*;
4use crate::Script;
5
6use super::config::Config;
7use super::error::{InterpreterError, InterpreterErrorCode};
8use super::flags::ScriptFlags;
9use super::ops_crypto::HashType;
10use super::parsed_opcode::*;
11use super::scriptnum::*;
12use super::stack::*;
13use super::TxContext;
14
15fn stas3_trace_enabled() -> bool {
22 use std::sync::atomic::{AtomicU8, Ordering};
23 static CACHE: AtomicU8 = AtomicU8::new(0xff); let v = CACHE.load(Ordering::Relaxed);
25 if v != 0xff {
26 return v == 1;
27 }
28 let on = std::env::var("STAS3_TRACE")
29 .map(|s| !s.is_empty())
30 .unwrap_or(false);
31 CACHE.store(if on { 1 } else { 0 }, Ordering::Relaxed);
32 on
33}
34
35fn fmt_top(stk: &[Vec<u8>], n: usize) -> String {
36 let len = stk.len();
37 let take = n.min(len);
38 let mut out = String::from("[");
39 for i in 0..take {
41 let item = &stk[len - 1 - i]; let hex: String = item.iter().map(|b| format!("{:02x}", b)).collect();
43 let display = if hex.len() > 64 {
44 format!("{}..(len={})", &hex[..64], item.len())
45 } else {
46 hex
47 };
48 if i > 0 {
49 out.push_str(", ");
50 }
51 out.push_str(&format!("@-{}={}", i, display));
52 }
53 out.push(']');
54 out
55}
56
57const OP_COND_FALSE: i32 = 0;
59const OP_COND_TRUE: i32 = 1;
60
61pub struct Thread<'a> {
63 pub dstack: Stack,
65 pub astack: Stack,
67 pub else_stack: BoolStack,
69 pub cfg: Config,
71 pub scripts: Vec<ParsedScript>,
73 pub cond_stack: Vec<i32>,
75 pub saved_first_stack: Vec<Vec<u8>>,
77 pub script_idx: usize,
79 pub script_off: usize,
81 pub last_code_sep: usize,
83 pub num_ops: usize,
85 pub flags: ScriptFlags,
87 pub bip16: bool,
89 pub after_genesis: bool,
91 pub early_return_after_genesis: bool,
93 pub tx_context: Option<&'a dyn TxContext>,
95 pub input_idx: usize,
97}
98
99impl<'a> Thread<'a> {
100 pub fn new(
105 unlocking_script: &Script,
106 locking_script: &Script,
107 flags: ScriptFlags,
108 tx_context: Option<&'a dyn TxContext>,
109 input_idx: usize,
110 ) -> Result<Self, InterpreterError> {
111 let after_genesis = flags.has_flag(ScriptFlags::UTXO_AFTER_GENESIS);
112 let cfg = if after_genesis {
113 Config::after_genesis()
114 } else {
115 Config::before_genesis()
116 };
117
118 let mut actual_flags = flags;
119
120 if actual_flags.has_flag(ScriptFlags::ENABLE_SIGHASH_FORKID) {
122 actual_flags.add_flag(ScriptFlags::VERIFY_STRICT_ENCODING);
123 }
124
125 if actual_flags.has_flag(ScriptFlags::VERIFY_CLEAN_STACK)
127 && !actual_flags.has_flag(ScriptFlags::BIP16)
128 {
129 return Err(InterpreterError::new(
130 InterpreterErrorCode::InvalidFlags,
131 "invalid scriptflag combination".to_string(),
132 ));
133 }
134
135 let verify_minimal_data = actual_flags.has_flag(ScriptFlags::VERIFY_MINIMAL_DATA);
136
137 if unlocking_script.to_bytes().len() > cfg.max_script_size() {
139 return Err(InterpreterError::new(
140 InterpreterErrorCode::ScriptTooBig,
141 format!(
142 "unlocking script size {} is larger than the max allowed size {}",
143 unlocking_script.to_bytes().len(),
144 cfg.max_script_size()
145 ),
146 ));
147 }
148 if locking_script.to_bytes().len() > cfg.max_script_size() {
149 return Err(InterpreterError::new(
150 InterpreterErrorCode::ScriptTooBig,
151 format!(
152 "locking script size {} is larger than the max allowed size {}",
153 locking_script.to_bytes().len(),
154 cfg.max_script_size()
155 ),
156 ));
157 }
158
159 if unlocking_script.to_bytes().is_empty() && locking_script.to_bytes().is_empty() {
161 return Err(InterpreterError::new(
162 InterpreterErrorCode::EvalFalse,
163 "false stack entry at end of script execution".to_string(),
164 ));
165 }
166
167 let error_on_checksig = tx_context.is_none();
168
169 let uscript = parse_script(unlocking_script, error_on_checksig)?;
170 let lscript = parse_script(locking_script, error_on_checksig)?;
171
172 if actual_flags.has_flag(ScriptFlags::VERIFY_SIG_PUSH_ONLY) && !is_push_only(&uscript) {
174 return Err(InterpreterError::new(
175 InterpreterErrorCode::NotPushOnly,
176 "signature script is not push only".to_string(),
177 ));
178 }
179
180 let bip16 = actual_flags.has_flag(ScriptFlags::BIP16) && locking_script.is_p2sh();
181 if bip16 && !is_push_only(&uscript) {
182 return Err(InterpreterError::new(
183 InterpreterErrorCode::NotPushOnly,
184 "pay to script hash is not push only".to_string(),
185 ));
186 }
187
188 let scripts = vec![uscript, lscript];
189 let mut script_idx = 0;
190
191 if unlocking_script.to_bytes().is_empty() {
193 script_idx = 1;
194 }
195
196 let max_num_len = cfg.max_script_number_length();
197
198 let thread = Thread {
199 dstack: Stack::new(max_num_len, after_genesis, verify_minimal_data),
200 astack: Stack::new(max_num_len, after_genesis, verify_minimal_data),
201 else_stack: BoolStack::new(),
202 cfg,
203 scripts,
204 cond_stack: Vec::new(),
205 saved_first_stack: Vec::new(),
206 script_idx,
207 script_off: 0,
208 last_code_sep: 0,
209 num_ops: 0,
210 flags: actual_flags,
211 bip16,
212 after_genesis,
213 early_return_after_genesis: false,
214 tx_context,
215 input_idx,
216 };
217
218 Ok(thread)
219 }
220
221 pub fn has_flag(&self, flag: ScriptFlags) -> bool {
223 self.flags.has_flag(flag)
224 }
225
226 pub fn has_any(&self, flags: &[ScriptFlags]) -> bool {
228 self.flags.has_any(flags)
229 }
230
231 pub fn is_branch_executing(&self) -> bool {
233 self.cond_stack.is_empty() || *self.cond_stack.last().unwrap() == OP_COND_TRUE
234 }
235
236 pub fn should_exec(&self, pop: &ParsedOpcode) -> bool {
238 if !self.after_genesis {
239 return true;
240 }
241 let cf = self.cond_stack.iter().all(|&v| v != OP_COND_FALSE);
242 cf && (!self.early_return_after_genesis || pop.opcode == OP_RETURN)
243 }
244
245 pub fn execute(&mut self) -> Result<(), InterpreterError> {
247 loop {
248 let done = self.step()?;
249 if done {
250 break;
251 }
252 }
253 self.check_error_condition(true)
254 }
255
256 pub fn step(&mut self) -> Result<bool, InterpreterError> {
258 if self.script_idx >= self.scripts.len() {
260 return Err(InterpreterError::new(
261 InterpreterErrorCode::InvalidProgramCounter,
262 format!(
263 "past input scripts {}:{} {}:xxxx",
264 self.script_idx,
265 self.script_off,
266 self.scripts.len()
267 ),
268 ));
269 }
270 if self.script_off >= self.scripts[self.script_idx].len() {
271 return Err(InterpreterError::new(
272 InterpreterErrorCode::InvalidProgramCounter,
273 format!(
274 "past input scripts {}:{} {}:{:04}",
275 self.script_idx,
276 self.script_off,
277 self.script_idx,
278 self.scripts[self.script_idx].len()
279 ),
280 ));
281 }
282
283 let opcode = self.scripts[self.script_idx][self.script_off].clone();
284
285 if stas3_trace_enabled() {
287 use std::sync::atomic::{AtomicUsize, Ordering};
288 static STEP: AtomicUsize = AtomicUsize::new(0);
289 let step_no = STEP.fetch_add(1, Ordering::Relaxed);
290 eprintln!(
291 "TRACE step={} script={}:{} op=0x{:02x}({}) data_len={} depth={} astack={} top5={}",
292 step_no,
293 self.script_idx,
294 self.script_off,
295 opcode.opcode,
296 opcode.name(),
297 opcode.data.len(),
298 self.dstack.depth(),
299 self.astack.depth(),
300 fmt_top(&self.dstack.stk, 5),
301 );
302 }
303
304 if let Err(e) = self.execute_opcode(&opcode) {
305 if e.code == InterpreterErrorCode::Ok {
306 self.shift_script();
308 return Ok(self.script_idx >= self.scripts.len());
309 }
310 return Err(e);
311 }
312
313 self.script_off += 1;
314
315 let combined = self.dstack.depth() + self.astack.depth();
317 if combined > self.cfg.max_stack_size() as i32 {
318 return Err(InterpreterError::new(
319 InterpreterErrorCode::StackOverflow,
320 format!(
321 "combined stack size {} > max allowed {}",
322 combined,
323 self.cfg.max_stack_size()
324 ),
325 ));
326 }
327
328 if self.script_off < self.scripts[self.script_idx].len() {
329 return Ok(false);
330 }
331
332 if !self.cond_stack.is_empty() {
334 return Err(InterpreterError::new(
335 InterpreterErrorCode::UnbalancedConditional,
336 "end of script reached in conditional execution".to_string(),
337 ));
338 }
339
340 self.astack.clear();
342
343 self.shift_script();
345
346 if self.bip16 && !self.after_genesis && self.script_idx <= 2 {
348 match self.script_idx {
349 1 => {
350 self.saved_first_stack = self.dstack.get_stack();
351 }
352 2 => {
353 self.check_error_condition(false)?;
354 let scr_bytes = self.saved_first_stack.last().cloned().unwrap_or_default();
355 let scr = Script::from_bytes(&scr_bytes);
356 let pops = parse_script(&scr, false)?;
357 self.scripts.push(pops);
358 let len = self.saved_first_stack.len();
359 let new_stack = self.saved_first_stack[..len.saturating_sub(1)].to_vec();
360 self.dstack.set_stack(new_stack);
361 }
362 _ => {}
363 }
364 }
365
366 if self.script_idx < self.scripts.len()
368 && self.script_off >= self.scripts[self.script_idx].len()
369 {
370 self.script_idx += 1;
371 }
372
373 self.last_code_sep = 0;
374 if self.script_idx >= self.scripts.len() {
375 return Ok(true);
376 }
377
378 Ok(false)
379 }
380
381 fn shift_script(&mut self) {
382 self.num_ops = 0;
383 self.script_off = 0;
384 self.script_idx += 1;
385 self.early_return_after_genesis = false;
386 }
387
388 fn check_error_condition(&mut self, final_script: bool) -> Result<(), InterpreterError> {
389 if self.dstack.depth() < 1 {
390 return Err(InterpreterError::new(
391 InterpreterErrorCode::EmptyStack,
392 "stack empty at end of script execution".to_string(),
393 ));
394 }
395
396 if final_script
397 && self.has_flag(ScriptFlags::VERIFY_CLEAN_STACK)
398 && self.dstack.depth() != 1
399 {
400 return Err(InterpreterError::new(
401 InterpreterErrorCode::CleanStack,
402 format!(
403 "stack contains {} unexpected items",
404 self.dstack.depth() - 1
405 ),
406 ));
407 }
408
409 let v = self.dstack.pop_bool()?;
410 if !v {
411 return Err(InterpreterError::new(
412 InterpreterErrorCode::EvalFalse,
413 "false stack entry at end of script execution".to_string(),
414 ));
415 }
416
417 Ok(())
418 }
419
420 fn execute_opcode(&mut self, pop: &ParsedOpcode) -> Result<(), InterpreterError> {
421 if pop.data.len() > self.cfg.max_script_element_size() {
423 return Err(InterpreterError::new(
424 InterpreterErrorCode::ElementTooBig,
425 format!(
426 "element size {} exceeds max allowed size {}",
427 pop.data.len(),
428 self.cfg.max_script_element_size()
429 ),
430 ));
431 }
432
433 let exec = self.should_exec(pop);
434
435 if pop.is_disabled() && (!self.after_genesis || exec) {
437 return Err(InterpreterError::new(
438 InterpreterErrorCode::DisabledOpcode,
439 format!("attempt to execute disabled opcode {}", pop.name()),
440 ));
441 }
442
443 if pop.always_illegal() && !self.after_genesis {
445 return Err(InterpreterError::new(
446 InterpreterErrorCode::ReservedOpcode,
447 format!("attempt to execute reserved opcode {}", pop.name()),
448 ));
449 }
450
451 if pop.opcode > OP_16 {
453 self.num_ops += 1;
454 if self.num_ops > self.cfg.max_ops() {
455 return Err(InterpreterError::new(
456 InterpreterErrorCode::TooManyOperations,
457 format!("exceeded max operation limit of {}", self.cfg.max_ops()),
458 ));
459 }
460 }
461
462 if !self.is_branch_executing() && !pop.is_conditional() {
464 return Ok(());
465 }
466
467 if self.dstack.verify_minimal_data
469 && self.is_branch_executing()
470 && pop.opcode <= OP_PUSHDATA4
471 && exec
472 {
473 pop.enforce_minimum_data_push()?;
474 }
475
476 if !exec && !pop.is_conditional() {
478 return Ok(());
479 }
480
481 self.dispatch_opcode(pop)
483 }
484
485 fn dispatch_opcode(&mut self, pop: &ParsedOpcode) -> Result<(), InterpreterError> {
486 match pop.opcode {
487 OP_FALSE => {
488 self.dstack.push_byte_array(vec![]);
489 Ok(())
490 }
491 op if (OP_DATA_1..=OP_DATA_75).contains(&op) => {
492 self.dstack.push_byte_array(pop.data.clone());
493 Ok(())
494 }
495 OP_PUSHDATA1 | OP_PUSHDATA2 | OP_PUSHDATA4 => {
496 self.dstack.push_byte_array(pop.data.clone());
497 Ok(())
498 }
499 OP_1NEGATE => {
500 self.dstack
501 .push_int(&ScriptNumber::new(-1, self.after_genesis));
502 Ok(())
503 }
504 OP_RESERVED => self.op_reserved(pop),
505 op if (OP_1..=OP_16).contains(&op) => {
506 self.dstack.push_byte_array(vec![op - (OP_1 - 1)]);
507 Ok(())
508 }
509 OP_NOP => Ok(()),
510 OP_VER => self.op_reserved(pop),
511 OP_IF => self.op_if(pop),
512 OP_NOTIF => self.op_notif(pop),
513 OP_VERIF | OP_VERNOTIF => self.op_ver_conditional(pop),
514 OP_ELSE => self.op_else(pop),
515 OP_ENDIF => self.op_endif(pop),
516 OP_VERIFY => self.op_verify(pop),
517 OP_RETURN => self.op_return(),
518
519 OP_CHECKLOCKTIMEVERIFY => self.op_check_locktime_verify(),
521 OP_CHECKSEQUENCEVERIFY => self.op_check_sequence_verify(),
522
523 OP_TOALTSTACK => self.op_to_alt_stack(),
525 OP_FROMALTSTACK => self.op_from_alt_stack(),
526 OP_2DROP => self.dstack.drop_n(2),
527 OP_2DUP => self.dstack.dup_n(2),
528 OP_3DUP => self.dstack.dup_n(3),
529 OP_2OVER => self.dstack.over_n(2),
530 OP_2ROT => self.dstack.rot_n(2),
531 OP_2SWAP => self.dstack.swap_n(2),
532 OP_IFDUP => self.op_ifdup(),
533 OP_DEPTH => {
534 let d = self.dstack.depth();
535 self.dstack
536 .push_int(&ScriptNumber::new(d as i64, self.after_genesis));
537 Ok(())
538 }
539 OP_DROP => self.dstack.drop_n(1),
540 OP_DUP => self.dstack.dup_n(1),
541 OP_NIP => self.dstack.nip_n_discard(1),
542 OP_OVER => self.dstack.over_n(1),
543 OP_PICK => self.op_pick(),
544 OP_ROLL => self.op_roll(),
545 OP_ROT => self.dstack.rot_n(1),
546 OP_SWAP => self.dstack.swap_n(1),
547 OP_TUCK => self.dstack.tuck(),
548
549 OP_CAT => self.op_cat(),
551 OP_SPLIT => self.op_split(),
552 OP_NUM2BIN => self.op_num2bin(),
553 OP_BIN2NUM => self.op_bin2num(),
554 OP_SIZE => self.op_size(),
555
556 OP_INVERT => self.op_invert(),
558 OP_AND => self.op_bitwise(|a, b| a & b),
559 OP_OR => self.op_bitwise(|a, b| a | b),
560 OP_XOR => self.op_bitwise(|a, b| a ^ b),
561 OP_EQUAL => self.op_equal(),
562 OP_EQUALVERIFY => self.op_equalverify(pop),
563 OP_RESERVED1 | OP_RESERVED2 => self.op_reserved(pop),
564
565 OP_1ADD => self.op_unary_int(|m| {
567 m.incr();
568 }),
569 OP_1SUB => self.op_unary_int(|m| {
570 m.decr();
571 }),
572 OP_2MUL | OP_2DIV => Err(InterpreterError::new(
573 InterpreterErrorCode::DisabledOpcode,
574 format!("attempt to execute disabled opcode {}", pop.name()),
575 )),
576 OP_NEGATE => self.op_unary_int(|m| {
577 m.neg();
578 }),
579 OP_ABS => self.op_unary_int(|m| {
580 m.abs();
581 }),
582 OP_NOT => self.op_not(),
583 OP_0NOTEQUAL => self.op_0notequal(),
584 OP_ADD => self.op_add(),
585 OP_SUB => self.op_sub(),
586 OP_MUL => self.op_mul(),
587 OP_DIV => self.op_div(),
588 OP_MOD => self.op_mod(),
589 OP_LSHIFT => self.op_lshift(),
590 OP_RSHIFT => self.op_rshift(),
591 OP_BOOLAND => self.op_bool_binop(|a, b| !a.is_zero() && !b.is_zero()),
592 OP_BOOLOR => self.op_bool_binop(|a, b| !a.is_zero() || !b.is_zero()),
593 OP_NUMEQUAL => self.op_bool_binop(|a, b| a.equal(b)),
594 OP_NUMEQUALVERIFY => self.op_numequalverify(pop),
595 OP_NUMNOTEQUAL => self.op_bool_binop(|a, b| !a.equal(b)),
596 OP_LESSTHAN => self.op_bool_binop(|a, b| a.less_than(b)),
597 OP_GREATERTHAN => self.op_bool_binop(|a, b| a.greater_than(b)),
598 OP_LESSTHANOREQUAL => self.op_bool_binop(|a, b| a.less_than_or_equal(b)),
599 OP_GREATERTHANOREQUAL => self.op_bool_binop(|a, b| a.greater_than_or_equal(b)),
600 OP_MIN => self.op_min(),
601 OP_MAX => self.op_max(),
602 OP_WITHIN => self.op_within(),
603
604 OP_RIPEMD160 => self.op_hash(HashType::Ripemd160),
606 OP_SHA1 => self.op_hash(HashType::Sha1),
607 OP_SHA256 => self.op_hash(HashType::Sha256),
608 OP_HASH160 => self.op_hash(HashType::Hash160),
609 OP_HASH256 => self.op_hash(HashType::Hash256),
610 OP_CODESEPARATOR => {
611 self.last_code_sep = self.script_off;
612 Ok(())
613 }
614 OP_CHECKSIG => self.op_checksig(),
615 OP_CHECKSIGVERIFY => self.op_checksigverify(pop),
616 OP_CHECKMULTISIG => self.op_checkmultisig(),
617 OP_CHECKMULTISIGVERIFY => self.op_checkmultisigverify(pop),
618
619 OP_NOP1 | OP_NOP4 | OP_NOP5 | OP_NOP6 | OP_NOP7 | OP_NOP8 | OP_NOP9 | OP_NOP10 => {
621 if self.has_flag(ScriptFlags::DISCOURAGE_UPGRADABLE_NOPS) {
622 return Err(InterpreterError::new(
623 InterpreterErrorCode::DiscourageUpgradableNOPs,
624 format!(
625 "OP_NOP{} reserved for soft-fork upgrades",
626 pop.opcode - (OP_NOP1 - 1)
627 ),
628 ));
629 }
630 Ok(())
631 }
632
633 _ => Err(InterpreterError::new(
635 InterpreterErrorCode::ReservedOpcode,
636 format!("attempt to execute invalid opcode {}", pop.name()),
637 )),
638 }
639 }
640}