bitcoin/blockdata/script/
push_bytes.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Contains `PushBytes` & co
4
5use core::ops::{Deref, DerefMut};
6
7#[allow(unused)]
8use crate::prelude::*;
9
10#[rustfmt::skip]                // Keep public re-exports separate.
11#[doc(inline)]
12pub use self::primitive::*;
13
14/// This module only contains required operations so that outside functions wouldn't accidentally
15/// break invariants. Therefore auditing this module should be sufficient.
16mod primitive {
17    use core::ops::{
18        Bound, Index, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
19    };
20
21    use super::PushBytesError;
22    #[allow(unused)]
23    use crate::prelude::*;
24
25    #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
26    fn check_limit(_: usize) -> Result<(), PushBytesError> { Ok(()) }
27
28    #[cfg(not(any(target_pointer_width = "16", target_pointer_width = "32")))]
29    fn check_limit(len: usize) -> Result<(), PushBytesError> {
30        if len < 0x100000000 {
31            Ok(())
32        } else {
33            Err(PushBytesError { len })
34        }
35    }
36
37    /// Byte slices that can be in Bitcoin script.
38    ///
39    /// The encoding of Bitcoin script restricts data pushes to be less than 2^32 bytes long.
40    /// This type represents slices that are guaranteed to be within the limit so they can be put in
41    /// the script safely.
42    #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
43    #[repr(transparent)]
44    pub struct PushBytes([u8]);
45
46    impl PushBytes {
47        /// Creates `&Self` without checking the length.
48        ///
49        /// ## Safety
50        ///
51        /// The caller is responsible for checking that the length is less than the [`LIMIT`].
52        unsafe fn from_slice_unchecked(bytes: &[u8]) -> &Self {
53            &*(bytes as *const [u8] as *const PushBytes)
54        }
55
56        /// Creates `&mut Self` without checking the length.
57        ///
58        /// ## Safety
59        ///
60        /// The caller is responsible for checking that the length is less than the [`LIMIT`].
61        unsafe fn from_mut_slice_unchecked(bytes: &mut [u8]) -> &mut Self {
62            &mut *(bytes as *mut [u8] as *mut PushBytes)
63        }
64
65        /// Creates an empty `PushBytes`.
66        pub fn empty() -> &'static Self {
67            // 0 < LIMIT
68            unsafe { Self::from_slice_unchecked(&[]) }
69        }
70
71        /// Returns the underlying bytes.
72        pub fn as_bytes(&self) -> &[u8] { &self.0 }
73
74        /// Returns the underlying mutbale bytes.
75        pub fn as_mut_bytes(&mut self) -> &mut [u8] { &mut self.0 }
76    }
77
78    macro_rules! delegate_index {
79        ($($type:ty),* $(,)?) => {
80            $(
81                /// Script subslicing operation - read [slicing safety](#slicing-safety)!
82                impl Index<$type> for PushBytes {
83                    type Output = Self;
84
85                    #[inline]
86                    #[track_caller]
87                    fn index(&self, index: $type) -> &Self::Output {
88                        // Slicing can not make slices longer
89                        unsafe {
90                            Self::from_slice_unchecked(&self.0[index])
91                        }
92                    }
93                }
94            )*
95        }
96    }
97
98    delegate_index!(
99        Range<usize>,
100        RangeFrom<usize>,
101        RangeTo<usize>,
102        RangeFull,
103        RangeInclusive<usize>,
104        RangeToInclusive<usize>,
105        (Bound<usize>, Bound<usize>)
106    );
107
108    impl Index<usize> for PushBytes {
109        type Output = u8;
110
111        #[inline]
112        #[track_caller]
113        fn index(&self, index: usize) -> &Self::Output { &self.0[index] }
114    }
115
116    impl<'a> TryFrom<&'a [u8]> for &'a PushBytes {
117        type Error = PushBytesError;
118
119        fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
120            check_limit(bytes.len())?;
121            // We've just checked the length
122            Ok(unsafe { PushBytes::from_slice_unchecked(bytes) })
123        }
124    }
125
126    impl<'a> TryFrom<&'a mut [u8]> for &'a mut PushBytes {
127        type Error = PushBytesError;
128
129        fn try_from(bytes: &'a mut [u8]) -> Result<Self, Self::Error> {
130            check_limit(bytes.len())?;
131            // We've just checked the length
132            Ok(unsafe { PushBytes::from_mut_slice_unchecked(bytes) })
133        }
134    }
135
136    macro_rules! from_array {
137        ($($len:literal),* $(,)?) => {
138            $(
139                impl<'a> From<&'a [u8; $len]> for &'a PushBytes {
140                    fn from(bytes: &'a [u8; $len]) -> Self {
141                        // Check that the macro wasn't called with a wrong number.
142                        const _: () = [(); 1][($len >= 0x100000000u64) as usize];
143                        // We know the size of array statically and we checked macro input.
144                        unsafe { PushBytes::from_slice_unchecked(bytes) }
145                    }
146                }
147
148                impl<'a> From<&'a mut [u8; $len]> for &'a mut PushBytes {
149                    fn from(bytes: &'a mut [u8; $len]) -> Self {
150                        // Macro check already above, no need to duplicate.
151                        // We know the size of array statically and we checked macro input.
152                        unsafe { PushBytes::from_mut_slice_unchecked(bytes) }
153                    }
154                }
155
156                impl AsRef<PushBytes> for [u8; $len] {
157                    fn as_ref(&self) -> &PushBytes {
158                        self.into()
159                    }
160                }
161
162                impl AsMut<PushBytes> for [u8; $len] {
163                    fn as_mut(&mut self) -> &mut PushBytes {
164                        self.into()
165                    }
166                }
167
168                impl From<[u8; $len]> for PushBytesBuf {
169                    fn from(bytes: [u8; $len]) -> Self {
170                        PushBytesBuf(Vec::from(&bytes as &[_]))
171                    }
172                }
173
174                impl<'a> From<&'a [u8; $len]> for PushBytesBuf {
175                    fn from(bytes: &'a [u8; $len]) -> Self {
176                        PushBytesBuf(Vec::from(bytes as &[_]))
177                    }
178                }
179            )*
180        }
181    }
182
183    // Sizes up to 76 to support all pubkey and signature sizes
184    from_array! {
185        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
186        25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
187        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
188        71, 72, 73, 74, 75, 76
189    }
190
191    /// Owned, growable counterpart to `PushBytes`.
192    #[derive(Default, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
193    pub struct PushBytesBuf(Vec<u8>);
194
195    impl PushBytesBuf {
196        /// Creates a new empty `PushBytesBuf`.
197        #[inline]
198        pub const fn new() -> Self { PushBytesBuf(Vec::new()) }
199
200        /// Creates a new empty `PushBytesBuf` with reserved capacity.
201        pub fn with_capacity(capacity: usize) -> Self { PushBytesBuf(Vec::with_capacity(capacity)) }
202
203        /// Reserve capacity for `additional_capacity` bytes.
204        pub fn reserve(&mut self, additional_capacity: usize) {
205            self.0.reserve(additional_capacity)
206        }
207
208        /// Try pushing a single byte.
209        ///
210        /// ## Errors
211        ///
212        /// This method fails if `self` would exceed the limit.
213        #[allow(deprecated)]
214        pub fn push(&mut self, byte: u8) -> Result<(), PushBytesError> {
215            // This is OK on 32 bit archs since vec has its own check and this check is pointless.
216            check_limit(self.0.len().saturating_add(1))?;
217            self.0.push(byte);
218            Ok(())
219        }
220
221        /// Try appending a slice to `PushBytesBuf`
222        ///
223        /// ## Errors
224        ///
225        /// This method fails if `self` would exceed the limit.
226        pub fn extend_from_slice(&mut self, bytes: &[u8]) -> Result<(), PushBytesError> {
227            let len = self.0.len().saturating_add(bytes.len());
228            check_limit(len)?;
229            self.0.extend_from_slice(bytes);
230            Ok(())
231        }
232
233        /// Remove the last byte from buffer if any.
234        pub fn pop(&mut self) -> Option<u8> { self.0.pop() }
235
236        /// Remove the byte at `index` and return it.
237        ///
238        /// ## Panics
239        ///
240        /// This method panics if `index` is out of bounds.
241        #[track_caller]
242        pub fn remove(&mut self, index: usize) -> u8 { self.0.remove(index) }
243
244        /// Remove all bytes from buffer without affecting capacity.
245        pub fn clear(&mut self) { self.0.clear() }
246
247        /// Remove bytes from buffer past `len`.
248        pub fn truncate(&mut self, len: usize) { self.0.truncate(len) }
249
250        /// Extracts `PushBytes` slice
251        pub fn as_push_bytes(&self) -> &PushBytes {
252            // length guaranteed by our invariant
253            unsafe { PushBytes::from_slice_unchecked(&self.0) }
254        }
255
256        /// Extracts mutable `PushBytes` slice
257        pub fn as_mut_push_bytes(&mut self) -> &mut PushBytes {
258            // length guaranteed by our invariant
259            unsafe { PushBytes::from_mut_slice_unchecked(&mut self.0) }
260        }
261
262        /// Accesses inner `Vec` - provided for `super` to impl other methods.
263        pub(super) fn inner(&self) -> &Vec<u8> { &self.0 }
264    }
265
266    impl From<PushBytesBuf> for Vec<u8> {
267        fn from(value: PushBytesBuf) -> Self { value.0 }
268    }
269
270    impl TryFrom<Vec<u8>> for PushBytesBuf {
271        type Error = PushBytesError;
272
273        fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
274            // check len
275            let _: &PushBytes = vec.as_slice().try_into()?;
276            Ok(PushBytesBuf(vec))
277        }
278    }
279
280    impl ToOwned for PushBytes {
281        type Owned = PushBytesBuf;
282
283        fn to_owned(&self) -> Self::Owned { PushBytesBuf(self.0.to_owned()) }
284    }
285}
286
287impl PushBytes {
288    /// Returns the number of bytes in buffer.
289    pub fn len(&self) -> usize { self.as_bytes().len() }
290
291    /// Returns true if the buffer contains zero bytes.
292    pub fn is_empty(&self) -> bool { self.as_bytes().is_empty() }
293}
294
295impl PushBytesBuf {
296    /// Returns the number of bytes in buffer.
297    pub fn len(&self) -> usize { self.inner().len() }
298
299    /// Returns the number of bytes the buffer can contain without reallocating.
300    pub fn capacity(&self) -> usize { self.inner().capacity() }
301
302    /// Returns true if the buffer contains zero bytes.
303    pub fn is_empty(&self) -> bool { self.inner().is_empty() }
304}
305
306impl AsRef<[u8]> for PushBytes {
307    fn as_ref(&self) -> &[u8] { self.as_bytes() }
308}
309
310impl AsMut<[u8]> for PushBytes {
311    fn as_mut(&mut self) -> &mut [u8] { self.as_mut_bytes() }
312}
313
314impl Deref for PushBytesBuf {
315    type Target = PushBytes;
316
317    fn deref(&self) -> &Self::Target { self.as_push_bytes() }
318}
319
320impl DerefMut for PushBytesBuf {
321    fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_push_bytes() }
322}
323
324impl AsRef<PushBytes> for PushBytes {
325    fn as_ref(&self) -> &PushBytes { self }
326}
327
328impl AsMut<PushBytes> for PushBytes {
329    fn as_mut(&mut self) -> &mut PushBytes { self }
330}
331
332impl AsRef<PushBytes> for PushBytesBuf {
333    fn as_ref(&self) -> &PushBytes { self.as_push_bytes() }
334}
335
336impl AsMut<PushBytes> for PushBytesBuf {
337    fn as_mut(&mut self) -> &mut PushBytes { self.as_mut_push_bytes() }
338}
339
340impl Borrow<PushBytes> for PushBytesBuf {
341    fn borrow(&self) -> &PushBytes { self.as_push_bytes() }
342}
343
344impl BorrowMut<PushBytes> for PushBytesBuf {
345    fn borrow_mut(&mut self) -> &mut PushBytes { self.as_mut_push_bytes() }
346}
347
348/// Reports information about failed conversion into `PushBytes`.
349///
350/// This should not be needed by general public, except as an additional bound on `TryFrom` when
351/// converting to `WitnessProgram`.
352pub trait PushBytesErrorReport {
353    /// How many bytes the input had.
354    fn input_len(&self) -> usize;
355}
356
357impl PushBytesErrorReport for core::convert::Infallible {
358    #[inline]
359    fn input_len(&self) -> usize { match *self {} }
360}
361
362pub use error::*;
363
364#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
365mod error {
366    use core::fmt;
367
368    /// Error returned on attempt to create too large `PushBytes`.
369    #[allow(unused)]
370    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
371    pub struct PushBytesError {
372        never: core::convert::Infallible,
373    }
374
375    impl super::PushBytesErrorReport for PushBytesError {
376        #[inline]
377        fn input_len(&self) -> usize { match self.never {} }
378    }
379
380    impl fmt::Display for PushBytesError {
381        fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { match self.never {} }
382    }
383}
384
385// we have 64 bits in mind, but even for esoteric sizes, this code is correct, since it's the
386// conservative one that checks for errors
387#[cfg(not(any(target_pointer_width = "16", target_pointer_width = "32")))]
388mod error {
389    use core::fmt;
390
391    /// Error returned on attempt to create too large `PushBytes`.
392    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
393    pub struct PushBytesError {
394        /// How long the input was.
395        pub(super) len: usize,
396    }
397
398    impl super::PushBytesErrorReport for PushBytesError {
399        #[inline]
400        fn input_len(&self) -> usize { self.len }
401    }
402
403    impl fmt::Display for PushBytesError {
404        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
405            write!(
406                f,
407                "attempt to prepare {} bytes to be pushed into script but the limit is 2^32-1",
408                self.len
409            )
410        }
411    }
412}
413
414#[cfg(feature = "std")]
415impl std::error::Error for PushBytesError {
416    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
417}