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}