Skip to main content

blvm_consensus/script/
stack.rs

1//! Stack types and operations for script execution.
2//!
3//! StackElement, to_stack_element, and cast_to_bool are used by both
4//! production and non-production script execution paths.
5
6use blvm_spec_lock::spec_locked;
7
8use crate::types::*;
9
10#[cfg(feature = "production")]
11use smallvec::SmallVec;
12
13/// Stack element: inline up to 80 bytes when production (sigs, pubkeys, hashes), else `Vec<u8>`.
14#[cfg(feature = "production")]
15pub type StackElement = SmallVec<[u8; 80]>;
16#[cfg(not(feature = "production"))]
17pub type StackElement = ByteString;
18
19/// Convert bytes to StackElement (for tests and callers needing explicit conversion).
20#[inline]
21pub fn to_stack_element(data: &[u8]) -> StackElement {
22    #[cfg(feature = "production")]
23    return SmallVec::from_slice(data);
24    #[cfg(not(feature = "production"))]
25    return data.to_vec();
26}
27
28/// CastToBool: truthiness check for stack elements (BIP62/consensus).
29/// Returns true if ANY byte is non-zero, except for "negative zero" (0x80 in last byte, rest zeros).
30#[spec_locked("5.2.4", "CastToBool")]
31#[blvm_spec_lock::ensures(result == false || v.len() > 0)]
32#[cfg(feature = "production")]
33#[inline(always)]
34pub fn cast_to_bool(v: &[u8]) -> bool {
35    for i in 0..v.len() {
36        if v[i] != 0 {
37            // Negative zero: all zeros except 0x80 in the last byte
38            if i == v.len() - 1 && v[i] == 0x80 {
39                return false;
40            }
41            return true;
42        }
43    }
44    false
45}
46
47#[spec_locked("5.2.4", "CastToBool")]
48#[blvm_spec_lock::ensures(result == false || v.len() > 0)]
49#[cfg(not(feature = "production"))]
50#[inline]
51pub fn cast_to_bool(v: &[u8]) -> bool {
52    for i in 0..v.len() {
53        if v[i] != 0 {
54            // Negative zero: all zeros except 0x80 in the last byte
55            if i == v.len() - 1 && v[i] == 0x80 {
56                return false;
57            }
58            return true;
59        }
60    }
61    false
62}