1use crate::{MAX_SCRIPT_ELEMENT_SIZE, TxScriptError};
2use core::fmt::Debug;
3use core::iter;
4use kaspa_hashes::Hash;
5use kaspa_txscript_errors::SerializationError;
6use smallvec::SmallVec;
7use std::cmp::Ordering;
8use std::num::TryFromIntError;
9use std::ops::{Deref, Index};
10
11#[derive(PartialEq, Eq, Debug, Default, PartialOrd, Ord)]
12pub(crate) struct SizedEncodeInt<const LEN: usize>(pub(crate) i64);
13
14impl<const LEN: usize> From<i64> for SizedEncodeInt<LEN> {
15 fn from(value: i64) -> Self {
16 SizedEncodeInt(value)
17 }
18}
19
20impl<const LEN: usize> From<i32> for SizedEncodeInt<LEN> {
21 fn from(value: i32) -> Self {
22 SizedEncodeInt(value as i64)
23 }
24}
25
26impl<const LEN: usize> TryFrom<SizedEncodeInt<LEN>> for i32 {
27 type Error = TryFromIntError;
28
29 fn try_from(value: SizedEncodeInt<LEN>) -> Result<Self, Self::Error> {
30 value.0.try_into()
31 }
32}
33
34impl<const LEN: usize> PartialEq<i64> for SizedEncodeInt<LEN> {
35 fn eq(&self, other: &i64) -> bool {
36 self.0 == *other
37 }
38}
39
40impl<const LEN: usize> PartialOrd<i64> for SizedEncodeInt<LEN> {
41 fn partial_cmp(&self, other: &i64) -> Option<Ordering> {
42 self.0.partial_cmp(other)
43 }
44}
45
46impl<const LEN: usize> Deref for SizedEncodeInt<LEN> {
47 type Target = i64;
48
49 fn deref(&self) -> &Self::Target {
50 &self.0
51 }
52}
53
54impl<const LEN: usize> From<SizedEncodeInt<LEN>> for i64 {
55 fn from(value: SizedEncodeInt<LEN>) -> Self {
56 value.0
57 }
58}
59
60#[inline]
61fn total_bytes(items: &[StackEntry]) -> usize {
62 items.iter().map(|item| item.len()).sum()
63}
64
65pub type StackEntry = SmallVec<[u8; 8]>;
66
67#[derive(Clone, Debug)]
68pub(crate) struct Stack {
69 inner: Vec<StackEntry>,
70 pushed_bytes: u64,
71}
72
73#[cfg(test)]
74impl PartialEq for Stack {
75 fn eq(&self, other: &Self) -> bool {
76 self.inner == other.inner
77 }
78}
79
80#[cfg(test)]
81impl Eq for Stack {}
82
83impl Deref for Stack {
84 type Target = Vec<StackEntry>;
85
86 fn deref(&self) -> &Self::Target {
87 &self.inner
88 }
89}
90
91impl Index<usize> for Stack {
92 type Output = StackEntry;
93
94 fn index(&self, index: usize) -> &Self::Output {
95 &self.inner[index]
96 }
97}
98
99#[cfg(test)]
100impl From<Vec<StackEntry>> for Stack {
101 fn from(inner: Vec<StackEntry>) -> Self {
102 Self { inner, pushed_bytes: 0 }
103 }
104}
105
106#[cfg(test)]
107impl From<Vec<Vec<u8>>> for Stack {
108 fn from(inner: Vec<Vec<u8>>) -> Self {
109 Self::from(inner.into_iter().map(SmallVec::from_vec).collect::<Vec<_>>())
110 }
111}
112
113impl From<Stack> for Vec<StackEntry> {
114 fn from(stack: Stack) -> Self {
115 stack.inner
116 }
117}
118
119pub(crate) trait OpcodeData<T> {
120 fn deserialize(&self) -> Result<T, TxScriptError>;
121 fn serialize(from: &T) -> Result<Self, SerializationError>
122 where
123 Self: Sized;
124}
125
126#[inline]
127pub fn serialize_i64(from: i64, size: Option<usize>) -> Result<StackEntry, SerializationError> {
128 let sign = from.signum();
129 let mut positive = from.unsigned_abs();
130 let mut last_saturated = false;
131 let mut number_vec = StackEntry::with_capacity(size.unwrap_or(8));
132 number_vec.extend(iter::from_fn(move || {
133 if positive == 0 {
134 if last_saturated {
135 last_saturated = false;
136 Some(0)
137 } else {
138 None
139 }
140 } else {
141 let value = positive & 0xff;
142 last_saturated = (value & 0x80) != 0;
143 positive >>= 8;
144 Some(value as u8)
145 }
146 }));
147
148 if let Some(size) = size {
149 if number_vec.len() > size {
150 return Err(SerializationError::NumberTooLong(from, size));
151 }
152 number_vec.resize(size, 0);
153 }
154
155 if sign == -1 {
156 match number_vec.last_mut() {
157 Some(num) => *num |= 0x80,
158 _ => unreachable!(),
159 }
160 }
161 Ok(number_vec)
162}
163
164pub fn deserialize_i64(v: &[u8]) -> Result<i64, TxScriptError> {
165 match v.len() {
166 l if l > size_of::<i64>() => {
167 Err(TxScriptError::NotMinimalData(format!("numeric value encoded as {v:x?} is longer than 8 bytes")))
169 }
170 0 => Ok(0),
171 _ => {
172 let msb = v[v.len() - 1];
173 let sign = 1 - 2 * ((msb >> 7) as i64);
174 let first_byte = (msb & 0x7f) as i64;
175 Ok(v[..v.len() - 1].iter().rev().map(|v| *v as i64).fold(first_byte, |accum, item| (accum << 8) + item) * sign)
176 }
177 }
178}
179
180impl OpcodeData<i64> for StackEntry {
181 #[inline]
182 fn deserialize(&self) -> Result<i64, TxScriptError> {
183 OpcodeData::<SizedEncodeInt<8>>::deserialize(self).map(i64::from)
184 }
185
186 #[inline]
187 fn serialize(from: &i64) -> Result<Self, SerializationError> {
188 OpcodeData::<SizedEncodeInt<8>>::serialize(&(*from).into())
189 }
190}
191
192impl OpcodeData<i32> for StackEntry {
193 #[inline]
194 fn deserialize(&self) -> Result<i32, TxScriptError> {
195 OpcodeData::<SizedEncodeInt<8>>::deserialize(self)
196 .and_then(|v| v.try_into().map_err(|e: TryFromIntError| TxScriptError::NumberTooBig(e.to_string())))
197 }
198
199 #[inline]
200 fn serialize(from: &i32) -> Result<Self, SerializationError> {
201 OpcodeData::<SizedEncodeInt<4>>::serialize(&(*from).into())
202 }
203}
204
205impl<const LEN: usize> OpcodeData<SizedEncodeInt<LEN>> for StackEntry {
206 #[inline]
207 fn deserialize(&self) -> Result<SizedEncodeInt<LEN>, TxScriptError> {
208 match self.len() > LEN {
209 true => Err(TxScriptError::NumberTooBig(format!(
210 "numeric value encoded as {:x?} is {} bytes which exceeds the max allowed of {}",
211 self,
212 self.len(),
213 LEN
214 ))),
215 false => deserialize_i64(self).map(SizedEncodeInt::<LEN>),
216 }
217 }
218
219 #[inline]
220 fn serialize(from: &SizedEncodeInt<LEN>) -> Result<Self, SerializationError> {
221 let bytes = serialize_i64(from.0, None)?;
222 if bytes.len() > LEN {
223 return Err(SerializationError::NumberTooLong(from.0, LEN));
224 }
225 Ok(bytes)
226 }
227}
228
229impl OpcodeData<bool> for StackEntry {
230 #[inline]
231 fn deserialize(&self) -> Result<bool, TxScriptError> {
232 if self.is_empty() {
233 Ok(false)
234 } else {
235 Ok(self[self.len() - 1] & 0x7f != 0x0 || self[..self.len() - 1].iter().any(|&b| b != 0x0))
237 }
238 }
239
240 #[inline]
241 fn serialize(from: &bool) -> Result<Self, SerializationError> {
242 Ok(match from {
243 true => SmallVec::from_slice(&[1]),
244 false => SmallVec::new(),
245 })
246 }
247}
248
249#[cfg(test)]
250impl<T> OpcodeData<T> for Vec<u8>
251where
252 StackEntry: OpcodeData<T>,
253{
254 #[inline]
255 fn deserialize(&self) -> Result<T, TxScriptError> {
256 <StackEntry as OpcodeData<T>>::deserialize(&StackEntry::from_slice(self))
257 }
258
259 #[inline]
260 fn serialize(from: &T) -> Result<Self, SerializationError> {
261 <StackEntry as OpcodeData<T>>::serialize(from).map(|v| v.into_vec())
262 }
263}
264
265impl OpcodeData<Hash> for StackEntry {
266 #[inline]
267 fn deserialize(&self) -> Result<Hash, TxScriptError> {
268 Hash::try_from_slice(self).map_err(|_| TxScriptError::InvalidLengthOfBlockHash(self.len()))
269 }
270
271 #[inline]
272 fn serialize(from: &Hash) -> Result<Self, SerializationError> {
273 Ok(from.as_bytes().as_slice().into())
274 }
275}
276
277impl Stack {
278 pub(crate) fn new(inner: Vec<StackEntry>) -> Self {
279 Self { inner, pushed_bytes: 0 }
280 }
281
282 #[inline]
283 fn add_pushed_bytes(&mut self, bytes: usize) {
284 self.pushed_bytes = self.pushed_bytes.checked_add(bytes as u64).expect("stack pushed-bytes accounting should never overflow");
285 }
286
287 #[inline]
289 pub fn pop_pushed_bytes(&mut self) -> u64 {
290 std::mem::take(&mut self.pushed_bytes)
291 }
292
293 #[inline]
294 pub fn insert(&mut self, index: usize, element: StackEntry) -> Result<(), TxScriptError> {
295 if element.len() > MAX_SCRIPT_ELEMENT_SIZE {
296 return Err(TxScriptError::ElementTooBig(element.len(), MAX_SCRIPT_ELEMENT_SIZE));
297 }
298 self.add_pushed_bytes(element.len());
299 self.inner.insert(index, element);
300 Ok(())
301 }
302
303 #[cfg(test)]
304 pub(crate) fn inner(&self) -> &[StackEntry] {
305 &self.inner
306 }
307
308 #[inline]
309 pub fn pop_items<const SIZE: usize, T: Debug>(&mut self) -> Result<[T; SIZE], TxScriptError>
310 where
311 StackEntry: OpcodeData<T>,
312 {
313 if self.len() < SIZE {
314 return Err(TxScriptError::InvalidStackOperation(SIZE, self.len()));
315 }
316 Ok(<[T; SIZE]>::try_from(
317 self.inner.split_off(self.len() - SIZE).iter().map(|v| v.deserialize()).collect::<Result<Vec<T>, _>>()?,
318 )
319 .expect("Already exact item"))
320 }
321
322 #[inline]
323 pub fn pop_raw<const SIZE: usize>(&mut self) -> Result<[StackEntry; SIZE], TxScriptError> {
324 if self.len() < SIZE {
325 return Err(TxScriptError::InvalidStackOperation(SIZE, self.len()));
326 }
327 Ok(<[StackEntry; SIZE]>::try_from(self.inner.split_off(self.len() - SIZE)).expect("Already exact item"))
328 }
329
330 #[inline]
331 pub fn peek_raw<const SIZE: usize>(&self) -> Result<[StackEntry; SIZE], TxScriptError> {
332 if self.len() < SIZE {
333 return Err(TxScriptError::InvalidStackOperation(SIZE, self.len()));
334 }
335 Ok(<[StackEntry; SIZE]>::try_from(self.inner[self.len() - SIZE..].to_vec()).expect("Already exact item"))
336 }
337
338 #[inline]
339 pub fn push_item<T: Debug>(&mut self, item: T) -> Result<(), TxScriptError>
340 where
341 StackEntry: OpcodeData<T>,
342 {
343 let v: StackEntry = OpcodeData::serialize(&item)?;
344 self.add_pushed_bytes(v.len());
345 Vec::push(&mut self.inner, v);
346 Ok(())
347 }
348
349 #[inline]
350 pub fn push_item_unmetered<T: Debug>(&mut self, item: T) -> Result<(), TxScriptError>
351 where
352 StackEntry: OpcodeData<T>,
353 {
354 let v: StackEntry = OpcodeData::serialize(&item)?;
355 Vec::push(&mut self.inner, v);
356 Ok(())
357 }
358
359 #[inline]
360 pub fn drop_items<const SIZE: usize>(&mut self) -> Result<(), TxScriptError> {
361 match self.len() >= SIZE {
362 true => {
363 self.inner.truncate(self.len() - SIZE);
364 Ok(())
365 }
366 false => Err(TxScriptError::InvalidStackOperation(SIZE, self.len())),
367 }
368 }
369
370 #[inline]
371 pub fn dup_items<const SIZE: usize>(&mut self) -> Result<(), TxScriptError> {
372 match self.len() >= SIZE {
373 true => {
374 let added_bytes = total_bytes(&self.inner[self.len() - SIZE..]);
375 self.add_pushed_bytes(added_bytes);
376 self.inner.extend_from_within(self.len() - SIZE..);
377 Ok(())
378 }
379 false => Err(TxScriptError::InvalidStackOperation(SIZE, self.len())),
380 }
381 }
382
383 #[inline]
384 pub fn over_items<const SIZE: usize>(&mut self) -> Result<(), TxScriptError> {
385 match self.len() >= 2 * SIZE {
386 true => {
387 let added_bytes = total_bytes(&self.inner[self.len() - 2 * SIZE..self.len() - SIZE]);
388 self.add_pushed_bytes(added_bytes);
389 self.inner.extend_from_within(self.len() - 2 * SIZE..self.len() - SIZE);
390 Ok(())
391 }
392 false => Err(TxScriptError::InvalidStackOperation(2 * SIZE, self.len())),
393 }
394 }
395
396 #[inline]
397 pub fn rot_items<const SIZE: usize>(&mut self) -> Result<(), TxScriptError> {
398 match self.len() >= 3 * SIZE {
399 true => {
400 let len = self.len();
414 self.inner[len - 3 * SIZE..].rotate_left(SIZE);
415 Ok(())
416 }
417 false => Err(TxScriptError::InvalidStackOperation(3 * SIZE, self.len())),
418 }
419 }
420
421 #[inline]
422 pub fn swap_items<const SIZE: usize>(&mut self) -> Result<(), TxScriptError> {
423 match self.len() >= 2 * SIZE {
424 true => {
425 let len = self.len();
439 self.inner[len - 2 * SIZE..].rotate_left(SIZE);
440 Ok(())
441 }
442 false => Err(TxScriptError::InvalidStackOperation(2 * SIZE, self.len())),
443 }
444 }
445
446 #[inline]
447 pub fn roll(&mut self, loc: usize) -> Result<(), TxScriptError> {
448 if loc >= self.len() {
449 return Err(TxScriptError::InvalidStackOperation(loc, self.len()));
450 }
451 if loc == 0 {
452 return Ok(());
453 }
454 let from = self.len() - loc - 1;
455 self.inner[from..].rotate_left(1);
456 Ok(())
457 }
458
459 pub fn clear(&mut self) {
460 self.inner.clear()
461 }
462
463 pub fn pop(&mut self) -> Result<StackEntry, TxScriptError> {
464 self.inner.pop().ok_or(TxScriptError::EmptyStack)
465 }
466
467 pub fn split_off(&mut self, at: usize) -> Vec<StackEntry> {
468 self.inner.split_off(at)
469 }
470
471 pub fn push(&mut self, item: StackEntry) -> Result<(), TxScriptError> {
472 if item.len() > MAX_SCRIPT_ELEMENT_SIZE {
473 return Err(TxScriptError::ElementTooBig(item.len(), MAX_SCRIPT_ELEMENT_SIZE));
474 }
475 self.add_pushed_bytes(item.len());
476 self.inner.push(item);
477 Ok(())
478 }
479
480 pub fn push_unmetered(&mut self, item: StackEntry) -> Result<(), TxScriptError> {
481 if item.len() > MAX_SCRIPT_ELEMENT_SIZE {
482 return Err(TxScriptError::ElementTooBig(item.len(), MAX_SCRIPT_ELEMENT_SIZE));
483 }
484 self.inner.push(item);
485 Ok(())
486 }
487
488 pub fn remove(&mut self, index: usize) -> StackEntry {
489 self.inner.remove(index)
490 }
491}
492
493#[cfg(test)]
494mod tests {
495 use super::OpcodeData;
496 use crate::data_stack::{SizedEncodeInt, serialize_i64};
497 use kaspa_txscript_errors::{SerializationError, TxScriptError};
498 use kaspa_utils::hex::FromHex;
499
500 #[test]
502 fn test_serialize() {
503 struct TestCase {
504 num: i64,
505 serialized: Vec<u8>,
506 }
507
508 let tests = vec![
509 TestCase { num: 0, serialized: vec![] },
510 TestCase { num: 1, serialized: Vec::from_hex("01").expect("failed parsing hex") },
511 TestCase { num: -1, serialized: Vec::from_hex("81").expect("failed parsing hex") },
512 TestCase { num: 127, serialized: Vec::from_hex("7f").expect("failed parsing hex") },
513 TestCase { num: -127, serialized: Vec::from_hex("ff").expect("failed parsing hex") },
514 TestCase { num: 128, serialized: Vec::from_hex("8000").expect("failed parsing hex") },
515 TestCase { num: -128, serialized: Vec::from_hex("8080").expect("failed parsing hex") },
516 TestCase { num: 129, serialized: Vec::from_hex("8100").expect("failed parsing hex") },
517 TestCase { num: -129, serialized: Vec::from_hex("8180").expect("failed parsing hex") },
518 TestCase { num: 256, serialized: Vec::from_hex("0001").expect("failed parsing hex") },
519 TestCase { num: -256, serialized: Vec::from_hex("0081").expect("failed parsing hex") },
520 TestCase { num: 32767, serialized: Vec::from_hex("ff7f").expect("failed parsing hex") },
521 TestCase { num: -32767, serialized: Vec::from_hex("ffff").expect("failed parsing hex") },
522 TestCase { num: 32768, serialized: Vec::from_hex("008000").expect("failed parsing hex") },
523 TestCase { num: -32768, serialized: Vec::from_hex("008080").expect("failed parsing hex") },
524 TestCase { num: 65535, serialized: Vec::from_hex("ffff00").expect("failed parsing hex") },
525 TestCase { num: -65535, serialized: Vec::from_hex("ffff80").expect("failed parsing hex") },
526 TestCase { num: 524288, serialized: Vec::from_hex("000008").expect("failed parsing hex") },
527 TestCase { num: -524288, serialized: Vec::from_hex("000088").expect("failed parsing hex") },
528 TestCase { num: 7340032, serialized: Vec::from_hex("000070").expect("failed parsing hex") },
529 TestCase { num: -7340032, serialized: Vec::from_hex("0000f0").expect("failed parsing hex") },
530 TestCase { num: 8388608, serialized: Vec::from_hex("00008000").expect("failed parsing hex") },
531 TestCase { num: -8388608, serialized: Vec::from_hex("00008080").expect("failed parsing hex") },
532 TestCase { num: 2147483647, serialized: Vec::from_hex("ffffff7f").expect("failed parsing hex") },
533 TestCase { num: -2147483647, serialized: Vec::from_hex("ffffffff").expect("failed parsing hex") },
534 TestCase { num: 2147483648, serialized: Vec::from_hex("0000008000").expect("failed parsing hex") },
537 TestCase { num: -2147483648, serialized: Vec::from_hex("0000008080").expect("failed parsing hex") },
538 TestCase { num: 2415919104, serialized: Vec::from_hex("0000009000").expect("failed parsing hex") },
539 TestCase { num: -2415919104, serialized: Vec::from_hex("0000009080").expect("failed parsing hex") },
540 TestCase { num: 4294967295, serialized: Vec::from_hex("ffffffff00").expect("failed parsing hex") },
541 TestCase { num: -4294967295, serialized: Vec::from_hex("ffffffff80").expect("failed parsing hex") },
542 TestCase { num: 4294967296, serialized: Vec::from_hex("0000000001").expect("failed parsing hex") },
543 TestCase { num: -4294967296, serialized: Vec::from_hex("0000000081").expect("failed parsing hex") },
544 TestCase { num: 281474976710655, serialized: Vec::from_hex("ffffffffffff00").expect("failed parsing hex") },
545 TestCase { num: -281474976710655, serialized: Vec::from_hex("ffffffffffff80").expect("failed parsing hex") },
546 TestCase { num: 72057594037927935, serialized: Vec::from_hex("ffffffffffffff00").expect("failed parsing hex") },
547 TestCase { num: -72057594037927935, serialized: Vec::from_hex("ffffffffffffff80").expect("failed parsing hex") },
548 TestCase { num: 9223372036854775807, serialized: Vec::from_hex("ffffffffffffff7f").expect("failed parsing hex") },
549 TestCase { num: -9223372036854775807, serialized: Vec::from_hex("ffffffffffffffff").expect("failed parsing hex") },
550 ];
551
552 for test in tests {
553 let serialized: Vec<u8> = OpcodeData::<i64>::serialize(&test.num).unwrap();
554 assert_eq!(serialized, test.serialized);
555 assert_eq!(serialize_i64(test.num, Some(test.serialized.len())).unwrap().into_vec(), test.serialized);
556 if !test.serialized.is_empty() {
557 serialize_i64(test.num, Some(test.serialized.len() - 1)).unwrap_err();
558 }
560 }
561
562 let r: Result<Vec<u8>, _> = OpcodeData::<i64>::serialize(&-9223372036854775808);
564 assert_eq!(r, Err(SerializationError::NumberTooLong(-9223372036854775808, 8)));
565 }
566
567 #[test]
569 fn test_deserialize() {
570 struct TestCase<T> {
571 serialized: Vec<u8>,
572 result: Result<T, TxScriptError>,
573 }
574
575 let tests = vec![
576 TestCase::<i64> { serialized: Vec::from_hex("80").expect("failed parsing hex"), result: Ok(0) },
578 TestCase::<i64> { serialized: vec![], result: Ok(0) },
580 TestCase::<i64> { serialized: Vec::from_hex("01").expect("failed parsing hex"), result: Ok(1) },
581 TestCase::<i64> { serialized: Vec::from_hex("81").expect("failed parsing hex"), result: Ok(-1) },
582 TestCase::<i64> { serialized: Vec::from_hex("7f").expect("failed parsing hex"), result: Ok(127) },
583 TestCase::<i64> { serialized: Vec::from_hex("ff").expect("failed parsing hex"), result: Ok(-127) },
584 TestCase::<i64> { serialized: Vec::from_hex("8000").expect("failed parsing hex"), result: Ok(128) },
585 TestCase::<i64> { serialized: Vec::from_hex("8080").expect("failed parsing hex"), result: Ok(-128) },
586 TestCase::<i64> { serialized: Vec::from_hex("8100").expect("failed parsing hex"), result: Ok(129) },
587 TestCase::<i64> { serialized: Vec::from_hex("8180").expect("failed parsing hex"), result: Ok(-129) },
588 TestCase::<i64> { serialized: Vec::from_hex("0001").expect("failed parsing hex"), result: Ok(256) },
589 TestCase::<i64> { serialized: Vec::from_hex("0081").expect("failed parsing hex"), result: Ok(-256) },
590 TestCase::<i64> { serialized: Vec::from_hex("ff7f").expect("failed parsing hex"), result: Ok(32767) },
591 TestCase::<i64> { serialized: Vec::from_hex("ffff").expect("failed parsing hex"), result: Ok(-32767) },
592 TestCase::<i64> { serialized: Vec::from_hex("008000").expect("failed parsing hex"), result: Ok(32768) },
593 TestCase::<i64> { serialized: Vec::from_hex("008080").expect("failed parsing hex"), result: Ok(-32768) },
594 TestCase::<i64> { serialized: Vec::from_hex("ffff00").expect("failed parsing hex"), result: Ok(65535) },
595 TestCase::<i64> { serialized: Vec::from_hex("ffff80").expect("failed parsing hex"), result: Ok(-65535) },
596 TestCase::<i64> { serialized: Vec::from_hex("000008").expect("failed parsing hex"), result: Ok(524288) },
597 TestCase::<i64> { serialized: Vec::from_hex("000088").expect("failed parsing hex"), result: Ok(-524288) },
598 TestCase::<i64> { serialized: Vec::from_hex("000070").expect("failed parsing hex"), result: Ok(7340032) },
599 TestCase::<i64> { serialized: Vec::from_hex("0000f0").expect("failed parsing hex"), result: Ok(-7340032) },
600 TestCase::<i64> { serialized: Vec::from_hex("00008000").expect("failed parsing hex"), result: Ok(8388608) },
601 TestCase::<i64> { serialized: Vec::from_hex("00008080").expect("failed parsing hex"), result: Ok(-8388608) },
602 TestCase::<i64> { serialized: Vec::from_hex("ffffff7f").expect("failed parsing hex"), result: Ok(2147483647) },
603 TestCase::<i64> { serialized: Vec::from_hex("ffffffff").expect("failed parsing hex"), result: Ok(-2147483647) },
604 TestCase::<i64> { serialized: Vec::from_hex("00").expect("failed parsing hex"), result: Ok(0) },
606 TestCase::<i64> { serialized: Vec::from_hex("0100").expect("failed parsing hex"), result: Ok(1) },
607 TestCase::<i64> { serialized: Vec::from_hex("7f00").expect("failed parsing hex"), result: Ok(127) },
608 TestCase::<i64> { serialized: Vec::from_hex("800000").expect("failed parsing hex"), result: Ok(128) },
609 TestCase::<i64> { serialized: Vec::from_hex("810000").expect("failed parsing hex"), result: Ok(129) },
610 TestCase::<i64> { serialized: Vec::from_hex("000100").expect("failed parsing hex"), result: Ok(256) },
611 TestCase::<i64> { serialized: Vec::from_hex("ff7f00").expect("failed parsing hex"), result: Ok(32767) },
612 TestCase::<i64> { serialized: Vec::from_hex("00800000").expect("failed parsing hex"), result: Ok(32768) },
613 TestCase::<i64> { serialized: Vec::from_hex("ffff0000").expect("failed parsing hex"), result: Ok(65535) },
614 TestCase::<i64> { serialized: Vec::from_hex("00000800").expect("failed parsing hex"), result: Ok(524288) },
615 TestCase::<i64> { serialized: Vec::from_hex("00007000").expect("failed parsing hex"), result: Ok(7340032) },
616 ];
618 let kip10_tests = vec![
619 TestCase::<i64> { serialized: Vec::from_hex("0000008000").expect("failed parsing hex"), result: Ok(2147483648i64) },
620 TestCase::<i64> { serialized: Vec::from_hex("0000008080").expect("failed parsing hex"), result: Ok(-2147483648i64) },
621 TestCase::<i64> { serialized: Vec::from_hex("0000009000").expect("failed parsing hex"), result: Ok(2415919104i64) },
622 TestCase::<i64> { serialized: Vec::from_hex("0000009080").expect("failed parsing hex"), result: Ok(-2415919104i64) },
623 TestCase::<i64> { serialized: Vec::from_hex("ffffffff00").expect("failed parsing hex"), result: Ok(4294967295i64) },
624 TestCase::<i64> { serialized: Vec::from_hex("ffffffff80").expect("failed parsing hex"), result: Ok(-4294967295i64) },
625 TestCase::<i64> { serialized: Vec::from_hex("0000000001").expect("failed parsing hex"), result: Ok(4294967296i64) },
626 TestCase::<i64> { serialized: Vec::from_hex("0000000081").expect("failed parsing hex"), result: Ok(-4294967296i64) },
627 TestCase::<i64> {
628 serialized: Vec::from_hex("ffffffffffff00").expect("failed parsing hex"),
629 result: Ok(281474976710655i64),
630 },
631 TestCase::<i64> {
632 serialized: Vec::from_hex("ffffffffffff80").expect("failed parsing hex"),
633 result: Ok(-281474976710655i64),
634 },
635 TestCase::<i64> {
636 serialized: Vec::from_hex("ffffffffffffff00").expect("failed parsing hex"),
637 result: Ok(72057594037927935i64),
638 },
639 TestCase::<i64> {
640 serialized: Vec::from_hex("ffffffffffffff80").expect("failed parsing hex"),
641 result: Ok(-72057594037927935i64),
642 },
643 TestCase::<i64> {
644 serialized: Vec::from_hex("ffffffffffffff7f").expect("failed parsing hex"),
645 result: Ok(9223372036854775807i64),
646 },
647 TestCase::<i64> {
648 serialized: Vec::from_hex("ffffffffffffffff").expect("failed parsing hex"),
649 result: Ok(-9223372036854775807i64),
650 },
651 TestCase::<i64> {
654 serialized: Vec::from_hex("000000000000008080").expect("failed parsing hex"),
655 result: Err(TxScriptError::NumberTooBig(
656 "numeric value encoded as [0, 0, 0, 0, 0, 0, 0, 80, 80] is 9 bytes which exceeds the max allowed of 8".to_string(),
657 )),
658 },
659 ];
660 let test_of_size_5 = vec![
661 TestCase::<SizedEncodeInt<5>> {
662 serialized: Vec::from_hex("ffffffff7f").expect("failed parsing hex"),
663 result: Ok(SizedEncodeInt::<5>(549755813887)),
664 },
665 TestCase::<SizedEncodeInt<5>> {
666 serialized: Vec::from_hex("ffffffffff").expect("failed parsing hex"),
667 result: Ok(SizedEncodeInt::<5>(-549755813887)),
668 },
669 TestCase::<SizedEncodeInt<5>> {
670 serialized: Vec::from_hex("0009000100").expect("failed parsing hex"),
671 result: Ok(SizedEncodeInt::<5>(16779520)),
672 },
673 ];
674
675 let test_of_size_8 = vec![
676 TestCase::<SizedEncodeInt<8>> {
677 serialized: Vec::from_hex("ffffffffffffff7f").expect("failed parsing hex"),
678 result: Ok(SizedEncodeInt::<8>(i64::MAX)),
679 },
680 TestCase::<SizedEncodeInt<8>> {
681 serialized: Vec::from_hex("ffffffffffffffff").expect("failed parsing hex"),
682 result: Ok(SizedEncodeInt::<8>(i64::MIN + 1)),
683 },
684 ];
685
686 let test_of_size_9 = vec![
687 TestCase::<SizedEncodeInt<9>> {
688 serialized: Vec::from_hex("ffffffffffffffffff").expect("failed parsing hex"),
689 result: Err(TxScriptError::NotMinimalData(
690 "numeric value encoded as [ff, ff, ff, ff, ff, ff, ff, ff, ff] is longer than 8 bytes".to_string(),
691 )),
692 },
693 TestCase::<SizedEncodeInt<9>> {
694 serialized: Vec::from_hex("ffffffffffffffff").expect("failed parsing hex"),
695 result: Ok(SizedEncodeInt::<9>(i64::MIN + 1)),
696 },
697 ];
698
699 let test_of_size_10 = vec![TestCase::<SizedEncodeInt<10>> {
700 serialized: Vec::from_hex("00000000000000000000").expect("failed parsing hex"),
701 result: Err(TxScriptError::NotMinimalData(
702 "numeric value encoded as [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] is longer than 8 bytes".to_string(),
703 )),
704 }];
705
706 let test_bool = vec![
707 TestCase::<bool> { serialized: Vec::from_hex("").expect("failed parsing hex"), result: Ok(false) },
708 TestCase::<bool> { serialized: Vec::from_hex("00").expect("failed parsing hex"), result: Ok(false) },
709 TestCase::<bool> { serialized: Vec::from_hex("0000").expect("failed parsing hex"), result: Ok(false) },
710 TestCase::<bool> { serialized: Vec::from_hex("0011").expect("failed parsing hex"), result: Ok(true) },
711 TestCase::<bool> { serialized: Vec::from_hex("80").expect("failed parsing hex"), result: Ok(false) }, TestCase::<bool> { serialized: Vec::from_hex("8011").expect("failed parsing hex"), result: Ok(true) }, TestCase::<bool> { serialized: Vec::from_hex("8080").expect("failed parsing hex"), result: Ok(true) }, TestCase::<bool> { serialized: Vec::from_hex("1234").expect("failed parsing hex"), result: Ok(true) },
715 TestCase::<bool> { serialized: Vec::from_hex("ffffffff").expect("failed parsing hex"), result: Ok(true) },
716 ];
717
718 for test in tests {
719 assert_eq!(test.serialized.deserialize(), test.result);
722 }
723
724 for test in test_of_size_5 {
725 assert_eq!(test.serialized.deserialize(), test.result);
728 }
729
730 for test in test_of_size_8 {
731 assert_eq!(test.serialized.deserialize(), test.result);
734 }
735
736 for test in test_of_size_9 {
737 assert_eq!(test.serialized.deserialize(), test.result);
740 }
741
742 for test in test_of_size_10 {
743 assert_eq!(test.serialized.deserialize(), test.result);
746 }
747
748 for test in test_bool {
749 assert_eq!(test.serialized.deserialize(), test.result);
752 }
753 for test in kip10_tests {
754 assert_eq!(test.serialized.deserialize(), test.result);
757 }
758 }
759}