tidecoin_primitives/script/
owned.rs1use core::convert::Infallible;
4use core::fmt;
5use core::marker::PhantomData;
6use core::ops::{Deref, DerefMut};
7
8#[cfg(feature = "arbitrary")]
9use arbitrary::{Arbitrary, Unstructured};
10use encoding::{ByteVecDecoder, ByteVecDecoderError, Encodable};
11use internals::write_err;
12
13use super::{encode_scriptnum, Error, Instruction, Script, ScriptEncoder};
14#[cfg(feature = "hex")]
15use crate::hex;
16use crate::opcodes::all::{
17 OP_1, OP_1NEGATE, OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY, OP_CHECKSIG, OP_CHECKSIGVERIFY,
18 OP_EQUAL, OP_EQUALVERIFY, OP_NUMEQUAL, OP_NUMEQUALVERIFY, OP_PUSHBYTES_0, OP_PUSHDATA1,
19 OP_PUSHDATA2, OP_PUSHDATA4, OP_VERIFY,
20};
21use crate::opcodes::Opcode;
22use crate::prelude::{Box, Vec};
23
24#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
47pub struct ScriptBuf<T>(PhantomData<T>, Vec<u8>);
48
49impl<T> ScriptBuf<T> {
50 #[inline]
52 pub const fn new() -> Self {
53 Self::from_bytes(Vec::new())
54 }
55
56 #[inline]
61 pub const fn from_bytes(bytes: Vec<u8>) -> Self {
62 Self(PhantomData, bytes)
63 }
64
65 #[cfg(feature = "hex")]
74 pub fn from_hex_prefixed(s: &str) -> Result<Self, FromHexError> {
75 let v = hex::decode_to_vec(s)?;
76 Ok(encoding::decode_from_slice(&v)?)
77 }
78
79 #[cfg(feature = "hex")]
92 pub fn from_hex_no_length_prefix(s: &str) -> Result<Self, hex::DecodeVariableLengthBytesError> {
93 let v = hex::decode_to_vec(s)?;
94 Ok(Self::from_bytes(v))
95 }
96
97 #[inline]
99 pub fn as_script(&self) -> &Script<T> {
100 Script::from_bytes(&self.1)
101 }
102
103 #[inline]
105 pub fn as_mut_script(&mut self) -> &mut Script<T> {
106 Script::from_bytes_mut(&mut self.1)
107 }
108
109 #[inline]
117 pub fn into_bytes(self) -> Vec<u8> {
118 self.1
119 }
120
121 #[must_use]
128 #[inline]
129 pub fn into_boxed_script(self) -> Box<Script<T>> {
130 Script::from_boxed_bytes(self.into_bytes().into_boxed_slice())
131 }
132
133 #[inline]
135 pub fn with_capacity(capacity: usize) -> Self {
136 Self::from_bytes(Vec::with_capacity(capacity))
137 }
138
139 #[inline]
150 pub fn reserve(&mut self, additional_len: usize) {
151 self.1.reserve(additional_len);
152 }
153
154 #[inline]
168 pub fn reserve_exact(&mut self, additional_len: usize) {
169 self.1.reserve_exact(additional_len);
170 }
171
172 pub(crate) fn as_byte_vec(&mut self) -> &mut Vec<u8> {
173 &mut self.1
174 }
175
176 #[inline]
180 pub fn capacity(&self) -> usize {
181 self.1.capacity()
182 }
183
184 pub fn reserved_len_for_slice(len: usize) -> usize {
186 len + if len < 0x4c {
187 1
188 } else if len <= 0xff {
189 2
190 } else if len <= 0xffff {
191 3
192 } else {
193 5
194 }
195 }
196
197 pub fn push_opcode(&mut self, opcode: Opcode) {
199 self.as_byte_vec().push(opcode.to_u8());
200 }
201
202 pub fn push_int(&mut self, n: i32) -> Result<(), Error> {
208 if n == i32::MIN {
209 Err(Error::NumericOverflow)
210 } else {
211 self.push_int_unchecked(n.into());
212 Ok(())
213 }
214 }
215
216 pub fn push_int_unchecked(&mut self, n: i64) {
218 match n {
219 -1 => self.push_opcode(OP_1NEGATE),
220 0 => self.push_opcode(OP_PUSHBYTES_0),
221 1..=16 => self.push_opcode(Opcode::from(n as u8 + (OP_1.to_u8() - 1))),
222 _ => self.push_int_non_minimal(n),
223 }
224 }
225
226 pub fn push_int_non_minimal(&mut self, data: i64) {
232 let buf = encode_scriptnum(data);
233 let len = buf.len();
234 self.reserve(Self::reserved_len_for_slice(len));
235 self.push_slice_no_opt(
236 <&super::PushBytes>::try_from(buf.as_slice()).expect("scriptint bytes fit PushBytes"),
237 );
238 }
239
240 pub fn push_slice<D: AsRef<[u8]>>(&mut self, data: D) {
242 let bytes = data.as_ref();
243 if bytes.len() == 1 {
244 match bytes[0] {
245 0x81 => self.push_opcode(OP_1NEGATE),
246 1..=16 => self.push_opcode(Opcode::from(bytes[0] + (OP_1.to_u8() - 1))),
247 _ => self.push_slice_non_minimal(data),
248 }
249 } else {
250 self.push_slice_non_minimal(data);
251 }
252 }
253
254 pub fn push_slice_non_minimal<D: AsRef<[u8]>>(&mut self, data: D) {
260 let data =
261 <&super::PushBytes>::try_from(data.as_ref()).expect("push data length fits PushBytes");
262 self.reserve(Self::reserved_len_for_slice(data.len()));
263 self.push_slice_no_opt(data);
264 }
265
266 pub fn push_instruction(&mut self, instruction: Instruction<'_>) {
268 match instruction {
269 Instruction::Op(opcode) => self.push_opcode(opcode),
270 Instruction::PushBytes(bytes) => self.push_slice(bytes),
271 }
272 }
273
274 pub fn scan_and_push_verify(&mut self) {
276 match opcode_to_verify(self.last_opcode()) {
277 Some(opcode) => {
278 self.as_byte_vec().pop();
279 self.push_opcode(opcode);
280 }
281 None => self.push_opcode(OP_VERIFY),
282 }
283 }
284
285 fn push_slice_no_opt(&mut self, data: &super::PushBytes) {
286 let len = data.len();
287 let bytes = self.as_byte_vec();
288 match len {
289 n if n < OP_PUSHDATA1.to_u8() as usize => bytes.push(n as u8),
290 n if n <= 0xff => {
291 bytes.push(OP_PUSHDATA1.to_u8());
292 bytes.push(n as u8);
293 }
294 n if n <= 0xffff => {
295 bytes.push(OP_PUSHDATA2.to_u8());
296 bytes.extend_from_slice(&(n as u16).to_le_bytes());
297 }
298 n => {
299 bytes.push(OP_PUSHDATA4.to_u8());
300 bytes.extend_from_slice(&(n as u32).to_le_bytes());
301 }
302 }
303 bytes.extend_from_slice(data.as_bytes());
304 }
305}
306
307fn opcode_to_verify(opcode: Option<Opcode>) -> Option<Opcode> {
308 opcode.and_then(|opcode| match opcode {
309 OP_EQUAL => Some(OP_EQUALVERIFY),
310 OP_NUMEQUAL => Some(OP_NUMEQUALVERIFY),
311 OP_CHECKSIG => Some(OP_CHECKSIGVERIFY),
312 OP_CHECKMULTISIG => Some(OP_CHECKMULTISIGVERIFY),
313 _ => None,
314 })
315}
316
317impl<T> Default for ScriptBuf<T> {
319 fn default() -> Self {
320 Self(PhantomData, Vec::new())
321 }
322}
323
324impl<T> Deref for ScriptBuf<T> {
325 type Target = Script<T>;
326
327 #[inline]
328 fn deref(&self) -> &Self::Target {
329 self.as_script()
330 }
331}
332
333impl<T> DerefMut for ScriptBuf<T> {
334 #[inline]
335 fn deref_mut(&mut self) -> &mut Self::Target {
336 self.as_mut_script()
337 }
338}
339
340impl<T> Encodable for ScriptBuf<T> {
341 type Encoder<'e>
342 = ScriptEncoder<'e>
343 where
344 Self: 'e;
345
346 #[inline]
347 fn encoder(&self) -> Self::Encoder<'_> {
348 self.as_script().encoder()
349 }
350}
351
352pub struct ScriptBufDecoder<T>(ByteVecDecoder, PhantomData<T>);
354
355impl<T> ScriptBufDecoder<T> {
356 pub const fn new() -> Self {
358 Self(ByteVecDecoder::new(), PhantomData)
359 }
360}
361
362impl<T> Default for ScriptBufDecoder<T> {
363 fn default() -> Self {
364 Self::new()
365 }
366}
367
368impl<T> encoding::Decoder for ScriptBufDecoder<T> {
369 type Output = ScriptBuf<T>;
370 type Error = ScriptBufDecoderError;
371
372 #[inline]
373 fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
374 self.0.push_bytes(bytes).map_err(ScriptBufDecoderError)
375 }
376
377 #[inline]
378 fn end(self) -> Result<Self::Output, Self::Error> {
379 Ok(ScriptBuf::from_bytes(self.0.end().map_err(ScriptBufDecoderError)?))
380 }
381
382 #[inline]
383 fn read_limit(&self) -> usize {
384 self.0.read_limit()
385 }
386}
387
388impl<T> encoding::Decodable for ScriptBuf<T> {
389 type Decoder = ScriptBufDecoder<T>;
390 fn decoder() -> Self::Decoder {
391 ScriptBufDecoder(ByteVecDecoder::new(), PhantomData)
392 }
393}
394
395#[derive(Debug, Clone, PartialEq, Eq)]
397pub struct ScriptBufDecoderError(ByteVecDecoderError);
398
399impl From<Infallible> for ScriptBufDecoderError {
400 fn from(never: Infallible) -> Self {
401 match never {}
402 }
403}
404
405impl fmt::Display for ScriptBufDecoderError {
406 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
407 write_err!(f, "decoder error"; self.0)
408 }
409}
410
411#[cfg(feature = "std")]
412impl std::error::Error for ScriptBufDecoderError {
413 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
414 Some(&self.0)
415 }
416}
417
418#[derive(Debug, Clone, PartialEq, Eq)]
420#[non_exhaustive]
421#[cfg(feature = "hex")]
422pub enum FromHexError {
423 Hex(hex::DecodeVariableLengthBytesError),
425 Decoder(encoding::DecodeError<ScriptBufDecoderError>),
427}
428
429#[cfg(feature = "hex")]
430impl From<Infallible> for FromHexError {
431 fn from(never: Infallible) -> Self {
432 match never {}
433 }
434}
435
436#[cfg(feature = "hex")]
437impl fmt::Display for FromHexError {
438 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
439 match *self {
440 Self::Hex(ref e) => write_err!(f, "script hex"; e),
441 Self::Decoder(ref e) => write_err!(f, "script decoder"; e),
442 }
443 }
444}
445
446#[cfg(all(feature = "std", feature = "hex"))]
447impl std::error::Error for FromHexError {
448 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
449 match *self {
450 Self::Hex(ref e) => Some(e),
451 Self::Decoder(ref e) => Some(e),
452 }
453 }
454}
455
456#[cfg(feature = "hex")]
457impl From<hex::DecodeVariableLengthBytesError> for FromHexError {
458 fn from(e: hex::DecodeVariableLengthBytesError) -> Self {
459 Self::Hex(e)
460 }
461}
462
463#[cfg(feature = "hex")]
464impl From<encoding::DecodeError<ScriptBufDecoderError>> for FromHexError {
465 fn from(e: encoding::DecodeError<ScriptBufDecoderError>) -> Self {
466 Self::Decoder(e)
467 }
468}
469
470#[cfg(feature = "arbitrary")]
471impl<'a, T> Arbitrary<'a> for ScriptBuf<T> {
472 #[inline]
473 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
474 let v = Vec::<u8>::arbitrary(u)?;
475 Ok(Self::from_bytes(v))
476 }
477}
478
479impl<'a, Tg> core::iter::FromIterator<Instruction<'a>> for ScriptBuf<Tg> {
480 fn from_iter<T>(iter: T) -> Self
481 where
482 T: IntoIterator<Item = Instruction<'a>>,
483 {
484 let mut script = Self::new();
485 script.extend(iter);
486 script
487 }
488}
489
490impl<'a, Tg> Extend<Instruction<'a>> for ScriptBuf<Tg> {
491 fn extend<T>(&mut self, iter: T)
492 where
493 T: IntoIterator<Item = Instruction<'a>>,
494 {
495 let iter = iter.into_iter();
496 if iter.size_hint().1.is_some_and(|max| max < 6) {
497 let mut iter = iter.fuse();
498 let mut head = [None; 5];
499 let mut total_size = 0;
500 for (head, instr) in head.iter_mut().zip(&mut iter) {
501 total_size += instr.script_serialized_len();
502 *head = Some(instr);
503 }
504 assert!(
505 iter.next().is_none(),
506 "Buggy implementation of `Iterator` on {} returns invalid upper bound",
507 core::any::type_name::<T::IntoIter>()
508 );
509 self.reserve(total_size);
510 for instr in head.iter().copied().flatten() {
511 match instr {
512 Instruction::Op(opcode) => self.push_opcode(opcode),
513 Instruction::PushBytes(bytes) => self.push_slice_no_opt(bytes),
514 }
515 }
516 } else {
517 for instr in iter {
518 self.push_instruction(instr);
519 }
520 }
521 }
522}