bitcoin_cash/
deserializer.rs

1use crate::encoding_utils::read_var_int;
2use crate::error::{BitcoinCodeError, Error, ErrorKind, Result};
3use byteorder::{LittleEndian, ReadBytesExt};
4use serde::de::Visitor;
5use std::io::{self, Read};
6
7struct Input<'de> {
8    input: &'de [u8],
9    pos: usize,
10}
11
12struct Deserializer<'de> {
13    input: Input<'de>,
14}
15
16struct Access<'a, 'de: 'a> {
17    de: &'a mut Deserializer<'de>,
18    len: usize,
19}
20
21impl serde::de::Error for Error {
22    fn custom<T: std::fmt::Display>(msg: T) -> Self {
23        ErrorKind::Msg(format!("{}", msg)).into()
24    }
25}
26
27impl<'de> io::Read for Input<'de> {
28    fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, io::Error> {
29        let n_bytes = io::Cursor::new(&self.input[self.pos..]).read(buf)?;
30        self.pos += n_bytes;
31        Ok(n_bytes)
32    }
33}
34
35impl<'de> Input<'de> {
36    fn read_slice(&mut self, n_bytes: usize) -> std::result::Result<&'de [u8], io::Error> {
37        let remaining_slice = &self.input[self.pos..];
38        if remaining_slice.len() < n_bytes {
39            return Err(io::Error::from(io::ErrorKind::UnexpectedEof));
40        }
41        self.pos += n_bytes;
42        Ok(&remaining_slice[..n_bytes])
43    }
44
45    fn is_empty(&self) -> bool {
46        self.input[self.pos..].len() == 0
47    }
48}
49
50macro_rules! impl_nums {
51    ($ty:ty, $dser_method:ident, $visitor_method:ident, $reader_method:ident) => {
52        #[inline]
53        fn $dser_method<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
54            let value = self.input.$reader_method::<LittleEndian>()?;
55            visitor.$visitor_method(value)
56        }
57    };
58}
59
60impl<'de, 'a> serde::de::SeqAccess<'de> for Access<'a, 'de> {
61    type Error = Error;
62
63    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
64    where
65        T: serde::de::DeserializeSeed<'de>,
66    {
67        if self.len > 0 {
68            self.len -= 1;
69            let value = serde::de::DeserializeSeed::deserialize(seed, &mut *self.de)?;
70            Ok(Some(value))
71        } else {
72            Ok(None)
73        }
74    }
75
76    fn size_hint(&self) -> Option<usize> {
77        Some(self.len)
78    }
79}
80
81impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de> {
82    type Error = Error;
83
84    fn deserialize_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
85        BitcoinCodeError::DeserializeAnyNotSupported.into_err()
86    }
87
88    fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
89        let value: u8 = serde::Deserialize::deserialize(self)?;
90        match value {
91            1 => visitor.visit_bool(true),
92            0 => visitor.visit_bool(false),
93            value => BitcoinCodeError::InvalidBoolEncoding(value).into_err(),
94        }
95    }
96
97    fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
98        visitor.visit_u8(self.input.read_u8()?)
99    }
100
101    fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
102        visitor.visit_i8(self.input.read_i8()?)
103    }
104
105    impl_nums!(u16, deserialize_u16, visit_u16, read_u16);
106    impl_nums!(u32, deserialize_u32, visit_u32, read_u32);
107    impl_nums!(u64, deserialize_u64, visit_u64, read_u64);
108    impl_nums!(i16, deserialize_i16, visit_i16, read_i16);
109    impl_nums!(i32, deserialize_i32, visit_i32, read_i32);
110    impl_nums!(i64, deserialize_i64, visit_i64, read_i64);
111
112    fn deserialize_f32<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
113        BitcoinCodeError::DataTypeNotSupported("f32").into_err()
114    }
115    fn deserialize_f64<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
116        BitcoinCodeError::DataTypeNotSupported("f64").into_err()
117    }
118    fn deserialize_u128<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
119        BitcoinCodeError::DataTypeNotSupported("u128").into_err()
120    }
121    fn deserialize_i128<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
122        BitcoinCodeError::DataTypeNotSupported("i128").into_err()
123    }
124    fn deserialize_char<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
125        BitcoinCodeError::DataTypeNotSupported("char").into_err()
126    }
127
128    fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
129        visitor.visit_unit()
130    }
131
132    fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
133        let len = read_var_int(&mut self.input)? as usize;
134        let slice = self.input.read_slice(len)?;
135        visitor.visit_borrowed_str(&std::str::from_utf8(slice)?)
136    }
137
138    fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
139        let len = read_var_int(&mut self.input)? as usize;
140        let mut buf = vec![0; len];
141        self.input.read_exact(&mut buf)?;
142        visitor.visit_string(String::from_utf8(buf).map_err(|err| err.utf8_error())?)
143    }
144
145    fn deserialize_bytes<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
146        let len = read_var_int(&mut self.input)? as usize;
147        visitor.visit_borrowed_bytes(self.input.read_slice(len)?)
148    }
149
150    fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
151        let len = read_var_int(&mut self.input)? as usize;
152        let mut buf = vec![0; len];
153        self.input.read_exact(&mut buf)?;
154        visitor.visit_byte_buf(buf)
155    }
156
157    fn deserialize_enum<V: Visitor<'de>>(
158        self,
159        _enum: &'static str,
160        _variants: &'static [&'static str],
161        _visitor: V,
162    ) -> Result<V::Value> {
163        BitcoinCodeError::MethodNotSupported("deserialize_enum").into_err()
164    }
165
166    fn deserialize_tuple<V: Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
167        visitor.visit_seq(Access { de: self, len })
168    }
169
170    fn deserialize_option<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
171        BitcoinCodeError::DataTypeNotSupported("Option<T>").into_err()
172    }
173
174    fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
175        let len = read_var_int(&mut self.input)? as usize;
176        self.deserialize_tuple(len, visitor)
177    }
178
179    fn deserialize_map<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
180        BitcoinCodeError::MethodNotSupported("deserialize_map").into_err()
181    }
182
183    fn deserialize_struct<V: Visitor<'de>>(
184        self,
185        _name: &str,
186        fields: &'static [&'static str],
187        visitor: V,
188    ) -> Result<V::Value> {
189        self.deserialize_tuple(fields.len(), visitor)
190    }
191
192    fn deserialize_identifier<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
193        BitcoinCodeError::MethodNotSupported("deserialize_identifier").into_err()
194    }
195
196    fn deserialize_newtype_struct<V: Visitor<'de>>(
197        self,
198        _name: &str,
199        visitor: V,
200    ) -> Result<V::Value> {
201        visitor.visit_newtype_struct(self)
202    }
203
204    fn deserialize_unit_struct<V: Visitor<'de>>(
205        self,
206        _name: &'static str,
207        visitor: V,
208    ) -> Result<V::Value> {
209        visitor.visit_unit()
210    }
211
212    fn deserialize_tuple_struct<V: Visitor<'de>>(
213        self,
214        _name: &'static str,
215        len: usize,
216        visitor: V,
217    ) -> Result<V::Value> {
218        self.deserialize_tuple(len, visitor)
219    }
220
221    fn deserialize_ignored_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
222        BitcoinCodeError::MethodNotSupported("deserialize_ignored_any").into_err()
223    }
224
225    fn is_human_readable(&self) -> bool {
226        false
227    }
228}
229
230pub fn decode_bitcoin_code<'a, T>(input: &'a [u8]) -> Result<T>
231where
232    T: serde::de::Deserialize<'a>,
233{
234    let mut deserializer = Deserializer {
235        input: Input { input, pos: 0 },
236    };
237    let t = T::deserialize(&mut deserializer)?;
238    if deserializer.input.is_empty() {
239        Ok(t)
240    } else {
241        BitcoinCodeError::LeftoverBytes.into_err()
242    }
243}
244
245#[cfg(test)]
246mod tests {
247    use super::decode_bitcoin_code;
248    use crate::error::Result;
249    use crate::serializer::encode_bitcoin_code;
250    use crate::{Hashed, Sha256d};
251    use serde_derive::{Deserialize, Serialize};
252
253    #[derive(Deserialize, Serialize, PartialEq, Debug)]
254    struct TxInput {
255        pub prev_tx_hash: Sha256d,
256        pub prev_vout: u32,
257        pub script: Vec<u8>,
258        pub sequence: u32,
259    }
260
261    #[derive(Deserialize, Serialize, PartialEq, Debug)]
262    struct TxOutput {
263        pub value: u64,
264        pub script: Vec<u8>,
265    }
266
267    #[derive(Deserialize, Serialize, PartialEq, Debug)]
268    struct Tx {
269        pub version: u32,
270        pub inputs: Vec<TxInput>,
271        pub outputs: Vec<TxOutput>,
272        pub locktime: u32,
273    }
274
275    #[test]
276    fn test_struct() -> Result<()> {
277        use hex_literal::hex;
278        #[derive(Deserialize, PartialEq, Debug)]
279        struct Test {
280            int: u32,
281            seq: Vec<Vec<u8>>,
282        }
283
284        let j = hex!("010000000201770199");
285        let expected = Test {
286            int: 1,
287            seq: vec![b"\x77".to_vec(), b"\x99".to_vec()],
288        };
289        assert_eq!(expected, decode_bitcoin_code(&j)?);
290        Ok(())
291    }
292
293    #[test]
294    fn test_fields() -> Result<()> {
295        #[derive(Deserialize, Serialize, PartialEq, Debug)]
296        struct TestElement<'a> {
297            name: String,
298            name_ref: &'a str,
299        }
300
301        #[derive(Deserialize, Serialize, PartialEq, Debug)]
302        struct TestPack(u8, u16, u32, u64, i8, i16, i32, i64);
303
304        #[derive(Deserialize, Serialize, PartialEq, Debug)]
305        struct TestUnit;
306
307        #[derive(Deserialize, Serialize, PartialEq, Debug)]
308        struct Test<'a> {
309            int: u32,
310            seq: Vec<Vec<u8>>,
311            relay: bool,
312            slice: &'a [u8],
313            pack: TestPack,
314            unit_struct: TestUnit,
315            unit: (),
316            vec: Vec<(TestElement<'a>, ())>,
317        }
318
319        let sample = Test {
320            int: 1,
321            seq: vec![b"\x77".to_vec(), b"\x99".to_vec()],
322            relay: true,
323            slice: b"whatever",
324            pack: TestPack(1, 2, 3, 4, 5, 6, 7, 8),
325            unit_struct: TestUnit,
326            unit: (),
327            vec: vec![
328                (
329                    TestElement {
330                        name: "banana".to_string(),
331                        name_ref: "teracotta",
332                    },
333                    (),
334                ),
335                (
336                    TestElement {
337                        name: "pie".to_string(),
338                        name_ref: "what",
339                    },
340                    (),
341                ),
342            ],
343        };
344        let sample_encoded = hex::decode(format!(
345            "01000000\
346             0201770199\
347             01\
348             08{}\
349             010200030000000400000000000000\
350             050600070000000800000000000000\
351             02\
352             06{}09{}\
353             03{}04{}",
354            hex::encode(b"whatever"),
355            hex::encode(b"banana"),
356            hex::encode(b"teracotta"),
357            hex::encode(b"pie"),
358            hex::encode(b"what"),
359        ))?;
360        assert_eq!(sample, decode_bitcoin_code(&encode_bitcoin_code(&sample)?)?);
361        assert_eq!(sample, decode_bitcoin_code(&sample_encoded)?);
362        assert_eq!(encode_bitcoin_code(&sample)?, sample_encoded);
363        Ok(())
364    }
365
366    #[test]
367    fn test_encode_lengths() -> Result<()> {
368        #[derive(Deserialize, Serialize, PartialEq, Debug)]
369        struct Test(Vec<u8>);
370        let encoded = encode_bitcoin_code(&Test(vec![0x77; 0xfc]))?;
371        assert_eq!(encoded[0], 0xfc);
372        assert_eq!(&encoded[1..], &[0x77; 0xfc][..]);
373        let encoded = encode_bitcoin_code(&Test(vec![0x88; 0xfd]))?;
374        assert_eq!(&encoded[0..3], &[0xfd, 0xfd, 0x00][..]);
375        assert_eq!(&encoded[3..], &[0x88; 0xfd][..]);
376        let encoded = encode_bitcoin_code(&Test(vec![0x99; 0x103]))?;
377        assert_eq!(&encoded[0..3], &[0xfd, 0x03, 0x01][..]);
378        assert_eq!(&encoded[3..], &[0x99; 0x103][..]);
379        let encoded = encode_bitcoin_code(&Test(vec![0xaa; 0xffff]))?;
380        assert_eq!(&encoded[0..3], &[0xfd, 0xff, 0xff][..]);
381        assert_eq!(&encoded[3..], &[0xaa; 0xffff][..]);
382        let encoded = encode_bitcoin_code(&Test(vec![0xbb; 0x10000]))?;
383        assert_eq!(&encoded[0..5], &[0xfe, 0x00, 0x00, 0x01, 0x00][..]);
384        assert_eq!(&encoded[5..], &[0xbb; 0x10000][..]);
385        let encoded = encode_bitcoin_code(&Test(vec![0xbb; 0x123456]))?;
386        assert_eq!(&encoded[0..5], &[0xfe, 0x56, 0x34, 0x12, 0x00][..]);
387        assert_eq!(&encoded[5..], &[0xbb; 0x123456][..]);
388        Ok(())
389    }
390
391    #[test]
392    fn test_decode_lengths() -> Result<()> {
393        #[derive(Deserialize, Serialize, PartialEq, Debug)]
394        struct Test(Vec<u8>);
395        let t: Test = decode_bitcoin_code(&[&[0xfc][..], &vec![0x77; 0xfc][..]].concat())?;
396        assert_eq!(t, Test(vec![0x77; 0xfc]));
397        let t: Test =
398            decode_bitcoin_code(&[&[0xfd, 0xfd, 0x00][..], &vec![0x88; 0xfd][..]].concat())?;
399        assert_eq!(t, Test(vec![0x88; 0xfd]));
400        let t: Test =
401            decode_bitcoin_code(&[&[0xfd, 0x03, 0x01][..], &vec![0x99; 0x103][..]].concat())?;
402        assert_eq!(t, Test(vec![0x99; 0x103]));
403        let t: Test =
404            decode_bitcoin_code(&[&[0xfd, 0xff, 0xff][..], &vec![0xaa; 0xffff][..]].concat())?;
405        assert_eq!(t, Test(vec![0xaa; 0xffff]));
406        let t: Test = decode_bitcoin_code(
407            &[
408                &[0xfe, 0x00, 0x00, 0x01, 0x00][..],
409                &vec![0xbb; 0x10000][..],
410            ]
411            .concat(),
412        )?;
413        assert_eq!(t, Test(vec![0xbb; 0x10000]));
414        let t: Test = decode_bitcoin_code(
415            &[
416                &[0xfe, 0x56, 0x34, 0x12, 0x00][..],
417                &vec![0xcc; 0x123456][..],
418            ]
419            .concat(),
420        )?;
421        assert_eq!(t, Test(vec![0xcc; 0x123456]));
422        Ok(())
423    }
424
425    #[test]
426    fn test_tx() -> Result<()> {
427        let tx_raw = hex::decode(
428            "0100000002b1c5c527d23f2f559ccac3748568806e617b38d76894b1e36c5e795e10ebe29400000000fc0047\
429            304402207a8ed9b57865ce56935b60794526c9c48833f752394ba920faddb08a14cbd02502200879a7fe141b\
430            dab57d28fc778f85fa0dc5df1f6af2bcd1d793387e2f4ef7492a414730440220623322db152ba053ed861fcd\
431            148d5fc0cc49158019911cf2a8411693e0bb95c602201f04cf4f81ec37e32aa030b89b359e3c49491014bac2\
432            d70a201e14932647ef11414c6952210257be20743c0bc14d33e6c0fe5b887b6cf47883b8924282a6948db577\
433            4502acd4210280b4d5ca10b008b757999dae9bdad11a2c856490c3582bcdc9ff8ca458529bd12103ec98d577\
434            ea245b65ca8c77f94463920ca53356b99b5ce49691c65e26f5b5683153aeffffffff3cbac2af90aa4e622214\
435            8238ef3d5e268fa577ff01ecc67b8b534039c7403b8206000000fdfd000047304402207ac1f3a87aeef786e1\
436            550b7832ca355da2195cff83bb5546569511920b2a2b5c02207d28e7b02d57f59bfad26c681071a88b4e3903\
437            b07243735a9be5149bb28be2ed41483045022100a8a8af3a437c0dfa9c5bab36230d9e72727c972859a6facc\
438            c76b506a4ae3294702206b924799bdc4880a707ec4b15e76e2503e2693dc8c1694fde237b60ad71cb637414c\
439            69522102a9c79875e2de1a769831dba1a9cf20b7bddc48fbcbdb9c5eeab67d7fb682a01c21031187abcee948\
440            d3c93c065fe5e560f7ae9cb7735b4e70507cebdf18ac7860a793210314d67175239913da79a0c905e086ad84\
441            2a0470fcb774929eec0c9cc1222a6ef153aeffffffff01a0d90800000000001976a914f450f83dd8d1b09326\
442            ae64857c3e9dfaa8a34ee688ac00000000"
443        ).unwrap();
444        assert_eq!(
445            Sha256d::digest(tx_raw.as_slice()),
446            Sha256d::from_hex_le(
447                "fff9979f9c7afb3cbe7fe34083e6dd206e33b19df176772feefd55d71667bae1"
448            )?,
449        );
450        let tx = decode_bitcoin_code::<Tx>(&tx_raw).unwrap();
451        assert_eq!(tx.version, 1);
452        assert_eq!(tx.locktime, 0);
453        let tx_in0 = &tx.inputs[0];
454        let tx_in1 = &tx.inputs[1];
455        assert_eq!(tx.inputs.len(), 2);
456        assert_eq!(
457            tx_in0.prev_tx_hash,
458            Sha256d::from_hex_le(
459                "94e2eb105e795e6ce3b19468d7387b616e80688574c3ca9c552f3fd227c5c5b1"
460            )?
461        );
462        assert_eq!(tx_in0.prev_vout, 0);
463        assert_eq!(
464            hex::encode(&tx_in0.script),
465            "0047304402207a8ed9b57865ce56935b60794526c9c48833f752394ba920faddb08a14cbd02502200879a\
466             7fe141bdab57d28fc778f85fa0dc5df1f6af2bcd1d793387e2f4ef7492a414730440220623322db152ba05\
467             3ed861fcd148d5fc0cc49158019911cf2a8411693e0bb95c602201f04cf4f81ec37e32aa030b89b359e3c4\
468             9491014bac2d70a201e14932647ef11414c6952210257be20743c0bc14d33e6c0fe5b887b6cf47883b8924\
469             282a6948db5774502acd4210280b4d5ca10b008b757999dae9bdad11a2c856490c3582bcdc9ff8ca458529\
470             bd12103ec98d577ea245b65ca8c77f94463920ca53356b99b5ce49691c65e26f5b5683153ae",
471        );
472        assert_eq!(tx_in0.sequence, 0xffff_ffff);
473
474        assert_eq!(
475            tx_in1.prev_tx_hash,
476            Sha256d::from_hex_le(
477                "823b40c73940538b7bc6ec01ff77a58f265e3def38821422624eaa90afc2ba3c"
478            )?
479        );
480        assert_eq!(tx_in1.prev_vout, 6);
481        assert_eq!(
482            hex::encode(&tx_in1.script),
483            "0047304402207ac1f3a87aeef786e1550b7832ca355da2195cff83bb5546569511920b2a2b5c02207d28e\
484             7b02d57f59bfad26c681071a88b4e3903b07243735a9be5149bb28be2ed41483045022100a8a8af3a437c0\
485             dfa9c5bab36230d9e72727c972859a6faccc76b506a4ae3294702206b924799bdc4880a707ec4b15e76e25\
486             03e2693dc8c1694fde237b60ad71cb637414c69522102a9c79875e2de1a769831dba1a9cf20b7bddc48fbc\
487             bdb9c5eeab67d7fb682a01c21031187abcee948d3c93c065fe5e560f7ae9cb7735b4e70507cebdf18ac786\
488             0a793210314d67175239913da79a0c905e086ad842a0470fcb774929eec0c9cc1222a6ef153ae",
489        );
490        assert_eq!(tx_in1.sequence, 0xffff_ffff);
491
492        let tx_out0 = &tx.outputs[0];
493        assert_eq!(tx.outputs.len(), 1);
494        assert_eq!(tx_out0.value, 5_800_00);
495        assert_eq!(
496            hex::encode(&tx_out0.script),
497            "76a914f450f83dd8d1b09326ae64857c3e9dfaa8a34ee688ac",
498        );
499
500        assert_eq!(encode_bitcoin_code(&tx)?, tx_raw);
501
502        Ok(())
503    }
504}