diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index b07d0384..7a523b69 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -16,22 +16,23 @@ //! typically big-endian decimals, etc.) //! -use crate::prelude::*; - -use core::{fmt, mem, u32, convert::From}; +use core::convert::From; +use core::{fmt, mem, u32}; use bitcoin_internals::write_err; -use crate::hashes::{sha256d, Hash, sha256}; -use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader}; +use crate::bip152::{PrefilledTransaction, ShortId}; +use crate::blockdata::transaction::{Transaction, TxIn, TxOut}; +use crate::hash_types::{BlockHash, FilterHash, FilterHeader, TxMerkleNode}; +use crate::hashes::{sha256, sha256d, Hash}; use crate::io::{self, Cursor, Read}; - -use crate::bip152::{ShortId, PrefilledTransaction}; -use crate::taproot::TapLeafHash; - -use crate::blockdata::transaction::{TxOut, Transaction, TxIn}; #[cfg(feature = "std")] -use crate::network::{message_blockdata::Inventory, address::{Address, AddrV2Message}}; +use crate::network::{ + address::{AddrV2Message, Address}, + message_blockdata::Inventory, +}; +use crate::prelude::*; +use crate::taproot::TapLeafHash; /// Encoding error. #[derive(Debug)] @@ -65,14 +66,14 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Error::Io(ref e) => write_err!(f, "IO error"; e), - Error::OversizedVectorAllocation { requested: ref r, max: ref m } => write!(f, - "allocation of oversized vector: requested {}, maximum {}", r, m), - Error::InvalidChecksum { expected: ref e, actual: ref a } => write!(f, - "invalid checksum: expected {:x}, actual {:x}", e.as_hex(), a.as_hex()), + Error::OversizedVectorAllocation { requested: ref r, max: ref m } => + write!(f, "allocation of oversized vector: requested {}, maximum {}", r, m), + Error::InvalidChecksum { expected: ref e, actual: ref a } => + write!(f, "invalid checksum: expected {:x}, actual {:x}", e.as_hex(), a.as_hex()), Error::NonMinimalVarInt => write!(f, "non-minimal varint"), Error::ParseFailed(ref s) => write!(f, "parse failed: {}", s), - Error::UnsupportedSegwitFlag(ref swflag) => write!(f, - "unsupported segwit version: {}", swflag), + Error::UnsupportedSegwitFlag(ref swflag) => + write!(f, "unsupported segwit version: {}", swflag), } } } @@ -96,9 +97,7 @@ impl std::error::Error for Error { #[doc(hidden)] impl From for Error { - fn from(error: io::Error) -> Self { - Error::Io(error) - } + fn from(error: io::Error) -> Self { Error::Io(error) } } /// Encodes an object into a vector. @@ -137,9 +136,8 @@ pub fn deserialize_partial(data: &[u8]) -> Result<(T, usize), Erro Ok((rv, consumed)) } - /// Extensions of `Write` to encode data as per Bitcoin consensus. -pub trait WriteExt : io::Write { +pub trait WriteExt: io::Write { /// Outputs a 64-bit unsigned integer. fn emit_u64(&mut self, v: u64) -> Result<(), io::Error>; /// Outputs a 32-bit unsigned integer. @@ -166,7 +164,7 @@ pub trait WriteExt : io::Write { } /// Extensions of `Read` to decode data as per Bitcoin consensus. -pub trait ReadExt : io::Read { +pub trait ReadExt: io::Read { /// Reads a 64-bit unsigned integer. fn read_u64(&mut self) -> Result; /// Reads a 32-bit unsigned integer. @@ -198,7 +196,7 @@ macro_rules! encoder_fn { fn $name(&mut self, v: $val_type) -> Result<(), io::Error> { self.write_all(&v.to_le_bytes()) } - } + }; } macro_rules! decoder_fn { @@ -209,7 +207,7 @@ macro_rules! decoder_fn { self.read_exact(&mut val[..]).map_err(Error::Io)?; Ok(<$val_type>::from_le_bytes(val)) } - } + }; } impl WriteExt for W { @@ -221,21 +219,13 @@ impl WriteExt for W { encoder_fn!(emit_i16, i16); #[inline] - fn emit_i8(&mut self, v: i8) -> Result<(), io::Error> { - self.write_all(&[v as u8]) - } + fn emit_i8(&mut self, v: i8) -> Result<(), io::Error> { self.write_all(&[v as u8]) } #[inline] - fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> { - self.write_all(&[v]) - } + fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> { self.write_all(&[v]) } #[inline] - fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> { - self.write_all(&[v as u8]) - } + fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> { self.write_all(&[v as u8]) } #[inline] - fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error> { - self.write_all(v) - } + fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error> { self.write_all(v) } } impl ReadExt for R { @@ -259,9 +249,7 @@ impl ReadExt for R { Ok(slice[0] as i8) } #[inline] - fn read_bool(&mut self) -> Result { - ReadExt::read_i8(self).map(|bit| bit != 0) - } + fn read_bool(&mut self) -> Result { ReadExt::read_i8(self).map(|bit| bit != 0) } #[inline] fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), Error> { self.read_exact(slice).map_err(Error::Io) @@ -313,7 +301,9 @@ pub trait Decodable: Sized { /// avoid creating redundant `Take` wrappers. Failure to do so might result only in a tiny /// performance hit. #[inline] - fn consensus_decode_from_finite_reader(reader: &mut R) -> Result { + fn consensus_decode_from_finite_reader( + reader: &mut R, + ) -> Result { // This method is always strictly less general than, `consensus_decode`, so it's safe and // make sense to default to just calling it. This way most types, that don't care about // protecting against resource exhaustion due to malicious input, can just ignore it. @@ -353,19 +343,22 @@ macro_rules! impl_int_encodable { } impl Encodable for $ty { #[inline] - fn consensus_encode(&self, w: &mut W) -> Result { + fn consensus_encode( + &self, + w: &mut W, + ) -> Result { w.$meth_enc(*self)?; Ok(mem::size_of::<$ty>()) } } - } + }; } -impl_int_encodable!(u8, read_u8, emit_u8); +impl_int_encodable!(u8, read_u8, emit_u8); impl_int_encodable!(u16, read_u16, emit_u16); impl_int_encodable!(u32, read_u32, emit_u32); impl_int_encodable!(u64, read_u64, emit_u64); -impl_int_encodable!(i8, read_i8, emit_i8); +impl_int_encodable!(i8, read_i8, emit_i8); impl_int_encodable!(i16, read_i16, emit_i16); impl_int_encodable!(i32, read_i32, emit_i32); impl_int_encodable!(i64, read_i64, emit_i64); @@ -398,22 +391,22 @@ impl Encodable for VarInt { 0..=0xFC => { (self.0 as u8).consensus_encode(w)?; Ok(1) - }, + } 0xFD..=0xFFFF => { w.emit_u8(0xFD)?; (self.0 as u16).consensus_encode(w)?; Ok(3) - }, + } 0x10000..=0xFFFFFFFF => { w.emit_u8(0xFE)?; (self.0 as u32).consensus_encode(w)?; Ok(5) - }, + } _ => { w.emit_u8(0xFF)?; self.0.consensus_encode(w)?; Ok(9) - }, + } } } } @@ -447,7 +440,7 @@ impl Decodable for VarInt { Ok(VarInt(x as u64)) } } - n => Ok(VarInt(n as u64)) + n => Ok(VarInt(n as u64)), } } } @@ -508,7 +501,10 @@ macro_rules! impl_array { ( $size:literal ) => { impl Encodable for [u8; $size] { #[inline] - fn consensus_encode(&self, w: &mut W) -> Result { + fn consensus_encode( + &self, + w: &mut W, + ) -> Result { w.emit_slice(&self[..])?; Ok(self.len()) } @@ -549,7 +545,9 @@ impl Decodable for [u16; 8] { impl Encodable for [u16; 8] { #[inline] fn consensus_encode(&self, w: &mut W) -> Result { - for c in self.iter() { c.consensus_encode(w)?; } + for c in self.iter() { + c.consensus_encode(w)?; + } Ok(16) } } @@ -558,7 +556,10 @@ macro_rules! impl_vec { ($type: ty) => { impl Encodable for Vec<$type> { #[inline] - fn consensus_encode(&self, w: &mut W) -> Result { + fn consensus_encode( + &self, + w: &mut W, + ) -> Result { let mut len = 0; len += VarInt(self.len() as u64).consensus_encode(w)?; for c in self.iter() { @@ -570,7 +571,9 @@ macro_rules! impl_vec { impl Decodable for Vec<$type> { #[inline] - fn consensus_decode_from_finite_reader(r: &mut R) -> Result { + fn consensus_decode_from_finite_reader( + r: &mut R, + ) -> Result { let len = VarInt::consensus_decode_from_finite_reader(r)?.0; // Do not allocate upfront more items than if the sequnce of type // occupied roughly quarter a block. This should never be the case @@ -586,7 +589,7 @@ macro_rules! impl_vec { Ok(ret) } } - } + }; } impl_vec!(BlockHash); impl_vec!(FilterHash); @@ -602,17 +605,22 @@ impl_vec!(VarInt); impl_vec!(ShortId); impl_vec!(PrefilledTransaction); -#[cfg(feature = "std")] impl_vec!(Inventory); -#[cfg(feature = "std")] impl_vec!((u32, Address)); -#[cfg(feature = "std")] impl_vec!(AddrV2Message); +#[cfg(feature = "std")] +impl_vec!(Inventory); +#[cfg(feature = "std")] +impl_vec!((u32, Address)); +#[cfg(feature = "std")] +impl_vec!(AddrV2Message); -pub(crate) fn consensus_encode_with_size(data: &[u8], mut s: S) -> Result { +pub(crate) fn consensus_encode_with_size( + data: &[u8], + mut s: S, +) -> Result { let vi_len = VarInt(data.len() as u64).consensus_encode(&mut s)?; s.emit_slice(data)?; Ok(vi_len + data.len()) } - struct ReadBytesFromFiniteReaderOpts { len: usize, chunk_size: usize, @@ -623,7 +631,10 @@ struct ReadBytesFromFiniteReaderOpts { /// This function relies on reader being bound in amount of data /// it returns for OOM protection. See [`Decodable::consensus_decode_from_finite_reader`]. #[inline] -fn read_bytes_from_finite_reader(mut d: D, mut opts: ReadBytesFromFiniteReaderOpts) -> Result, Error> { +fn read_bytes_from_finite_reader( + mut d: D, + mut opts: ReadBytesFromFiniteReaderOpts, +) -> Result, Error> { let mut ret = vec![]; assert_ne!(opts.chunk_size, 0); @@ -671,7 +682,6 @@ impl Decodable for Box<[u8]> { } } - /// Does a double-SHA256 on `data` and returns the first 4 bytes. fn sha2_checksum(data: &[u8]) -> [u8; 4] { let checksum = ::hash(data); @@ -698,10 +708,7 @@ impl Decodable for CheckedData { let ret = read_bytes_from_finite_reader(r, opts)?; let expected_checksum = sha2_checksum(&ret); if expected_checksum != checksum { - Err(self::Error::InvalidChecksum { - expected: expected_checksum, - actual: checksum, - }) + Err(self::Error::InvalidChecksum { expected: expected_checksum, actual: checksum }) } else { Ok(CheckedData(ret)) } @@ -807,11 +814,13 @@ impl Decodable for TapLeafHash { #[cfg(test)] mod tests { + use core::fmt; + use core::mem::{self, discriminant}; + use super::*; - use core::{mem::{self, discriminant}, fmt}; - use crate::consensus::{Encodable, deserialize_partial, Decodable}; + use crate::consensus::{deserialize_partial, Decodable, Encodable}; #[cfg(feature = "std")] - use crate::network::{Address, message_blockdata::Inventory}; + use crate::network::{message_blockdata::Inventory, Address}; #[test] fn serialize_int_test() { @@ -854,7 +863,10 @@ mod tests { assert_eq!(serialize(&-256i64), vec![0u8, 255, 255, 255, 255, 255, 255, 255]); assert_eq!(serialize(&-5000i64), vec![120u8, 236, 255, 255, 255, 255, 255, 255]); assert_eq!(serialize(&-500000i64), vec![224u8, 94, 248, 255, 255, 255, 255, 255]); - assert_eq!(serialize(&-723401728380766730i64), vec![246u8, 245, 245, 245, 245, 245, 245, 245]); + assert_eq!( + serialize(&-723401728380766730i64), + vec![246u8, 245, 245, 245, 245, 245, 245, 245] + ); assert_eq!(serialize(&1i64), vec![1u8, 0, 0, 0, 0, 0, 0, 0]); assert_eq!(serialize(&256i64), vec![0u8, 1, 0, 0, 0, 0, 0, 0]); assert_eq!(serialize(&5000i64), vec![136u8, 19, 0, 0, 0, 0, 0, 0]); @@ -869,8 +881,14 @@ mod tests { assert_eq!(serialize(&VarInt(0xFD)), vec![0xFDu8, 0xFD, 0]); assert_eq!(serialize(&VarInt(0xFFF)), vec![0xFDu8, 0xFF, 0xF]); assert_eq!(serialize(&VarInt(0xF0F0F0F)), vec![0xFEu8, 0xF, 0xF, 0xF, 0xF]); - assert_eq!(serialize(&VarInt(0xF0F0F0F0F0E0)), vec![0xFFu8, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0, 0]); - assert_eq!(test_varint_encode(0xFF, &0x100000000_u64.to_le_bytes()).unwrap(), VarInt(0x100000000)); + assert_eq!( + serialize(&VarInt(0xF0F0F0F0F0E0)), + vec![0xFFu8, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0, 0] + ); + assert_eq!( + test_varint_encode(0xFF, &0x100000000_u64.to_le_bytes()).unwrap(), + VarInt(0x100000000) + ); assert_eq!(test_varint_encode(0xFE, &0x10000_u64.to_le_bytes()).unwrap(), VarInt(0x10000)); assert_eq!(test_varint_encode(0xFD, &0xFD_u64.to_le_bytes()).unwrap(), VarInt(0xFD)); @@ -881,7 +899,7 @@ mod tests { test_varint_len(VarInt(0xFFFF), 3); test_varint_len(VarInt(0x10000), 5); test_varint_len(VarInt(0xFFFFFFFF), 5); - test_varint_len(VarInt(0xFFFFFFFF+1), 9); + test_varint_len(VarInt(0xFFFFFFFF + 1), 9); test_varint_len(VarInt(u64::max_value()), 9); } @@ -894,35 +912,62 @@ mod tests { fn test_varint_encode(n: u8, x: &[u8]) -> Result { let mut input = [0u8; 9]; input[0] = n; - input[1..x.len()+1].copy_from_slice(x); - deserialize_partial::(&input).map(|t|t.0) + input[1..x.len() + 1].copy_from_slice(x); + deserialize_partial::(&input).map(|t| t.0) } #[test] fn deserialize_nonminimal_vec() { // Check the edges for variant int - assert_eq!(discriminant(&test_varint_encode(0xFF, &(0x100000000_u64-1).to_le_bytes()).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - assert_eq!(discriminant(&test_varint_encode(0xFE, &(0x10000_u64-1).to_le_bytes()).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - assert_eq!(discriminant(&test_varint_encode(0xFD, &(0xFD_u64-1).to_le_bytes()).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - - assert_eq!(discriminant(&deserialize::>(&[0xfd, 0x00, 0x00]).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - assert_eq!(discriminant(&deserialize::>(&[0xfd, 0xfc, 0x00]).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - assert_eq!(discriminant(&deserialize::>(&[0xfd, 0xfc, 0x00]).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - assert_eq!(discriminant(&deserialize::>(&[0xfe, 0xff, 0x00, 0x00, 0x00]).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - assert_eq!(discriminant(&deserialize::>(&[0xfe, 0xff, 0xff, 0x00, 0x00]).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - assert_eq!(discriminant(&deserialize::>(&[0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); - assert_eq!(discriminant(&deserialize::>(&[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00]).unwrap_err()), - discriminant(&Error::NonMinimalVarInt)); + assert_eq!( + discriminant( + &test_varint_encode(0xFF, &(0x100000000_u64 - 1).to_le_bytes()).unwrap_err() + ), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant(&test_varint_encode(0xFE, &(0x10000_u64 - 1).to_le_bytes()).unwrap_err()), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant(&test_varint_encode(0xFD, &(0xFD_u64 - 1).to_le_bytes()).unwrap_err()), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant(&deserialize::>(&[0xfd, 0x00, 0x00]).unwrap_err()), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant(&deserialize::>(&[0xfd, 0xfc, 0x00]).unwrap_err()), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant(&deserialize::>(&[0xfd, 0xfc, 0x00]).unwrap_err()), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant(&deserialize::>(&[0xfe, 0xff, 0x00, 0x00, 0x00]).unwrap_err()), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant(&deserialize::>(&[0xfe, 0xff, 0xff, 0x00, 0x00]).unwrap_err()), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant( + &deserialize::>(&[0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) + .unwrap_err() + ), + discriminant(&Error::NonMinimalVarInt) + ); + assert_eq!( + discriminant( + &deserialize::>(&[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00]) + .unwrap_err() + ), + discriminant(&Error::NonMinimalVarInt) + ); let mut vec_256 = vec![0; 259]; vec_256[0] = 0xfd; @@ -1003,21 +1048,38 @@ mod tests { // u64 assert_eq!(deserialize(&[0xABu8, 0xCD, 0, 0, 0, 0, 0, 0]).ok(), Some(0xCDABu64)); - assert_eq!(deserialize(&[0xA0u8, 0x0D, 0xAB, 0xCD, 0x99, 0, 0, 0x99]).ok(), Some(0x99000099CDAB0DA0u64)); + assert_eq!( + deserialize(&[0xA0u8, 0x0D, 0xAB, 0xCD, 0x99, 0, 0, 0x99]).ok(), + Some(0x99000099CDAB0DA0u64) + ); let failure64: Result = deserialize(&[1u8, 2, 3, 4, 5, 6, 7]); assert!(failure64.is_err()); // i64 assert_eq!(deserialize(&[0xABu8, 0xCD, 0, 0, 0, 0, 0, 0]).ok(), Some(0xCDABi64)); - assert_eq!(deserialize(&[0xA0u8, 0x0D, 0xAB, 0xCD, 0x99, 0, 0, 0x99]).ok(), Some(-0x66ffff663254f260i64)); - assert_eq!(deserialize(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), Some(-1_i64)); - assert_eq!(deserialize(&[0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), Some(-2_i64)); - assert_eq!(deserialize(&[0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), Some(-255_i64)); - assert_eq!(deserialize(&[0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), Some(-254_i64)); + assert_eq!( + deserialize(&[0xA0u8, 0x0D, 0xAB, 0xCD, 0x99, 0, 0, 0x99]).ok(), + Some(-0x66ffff663254f260i64) + ); + assert_eq!( + deserialize(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), + Some(-1_i64) + ); + assert_eq!( + deserialize(&[0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), + Some(-2_i64) + ); + assert_eq!( + deserialize(&[0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), + Some(-255_i64) + ); + assert_eq!( + deserialize(&[0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), + Some(-254_i64) + ); let failurei64: Result = deserialize(&[1u8, 2, 3, 4, 5, 6, 7]); assert!(failurei64.is_err()); - } #[test] @@ -1025,13 +1087,18 @@ mod tests { assert_eq!(deserialize(&[3u8, 2, 3, 4]).ok(), Some(vec![2u8, 3, 4])); assert!((deserialize(&[4u8, 2, 3, 4, 5, 6]) as Result, _>).is_err()); // found by cargo fuzz - assert!(deserialize::>(&[0xff,0xff,0xff,0xff,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0xa,0xa,0x3a]).is_err()); + assert!(deserialize::>(&[ + 0xff, 0xff, 0xff, 0xff, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, + 0x6b, 0x6b, 0xa, 0xa, 0x3a + ]) + .is_err()); let rand_io_err = Error::Io(io::Error::new(io::ErrorKind::Other, "")); // Check serialization that `if len > MAX_VEC_SIZE {return err}` isn't inclusive, // by making sure it fails with IO Error and not an `OversizedVectorAllocation` Error. - let err = deserialize::(&serialize(&(super::MAX_VEC_SIZE as u32))).unwrap_err(); + let err = + deserialize::(&serialize(&(super::MAX_VEC_SIZE as u32))).unwrap_err(); assert_eq!(discriminant(&err), discriminant(&rand_io_err)); test_len_is_max_vec::(); @@ -1049,7 +1116,11 @@ mod tests { test_len_is_max_vec::(); } - fn test_len_is_max_vec() where Vec: Decodable, T: fmt::Debug { + fn test_len_is_max_vec() + where + Vec: Decodable, + T: fmt::Debug, + { let rand_io_err = Error::Io(io::Error::new(io::ErrorKind::Other, "")); let varint = VarInt((super::MAX_VEC_SIZE / mem::size_of::()) as u64); let err = deserialize::>(&serialize(&varint)).unwrap_err(); @@ -1058,7 +1129,10 @@ mod tests { #[test] fn deserialize_strbuf_test() { - assert_eq!(deserialize(&[6u8, 0x41, 0x6e, 0x64, 0x72, 0x65, 0x77]).ok(), Some("Andrew".to_string())); + assert_eq!( + deserialize(&[6u8, 0x41, 0x6e, 0x64, 0x72, 0x65, 0x77]).ok(), + Some("Andrew".to_string()) + ); assert_eq!( deserialize(&[6u8, 0x41, 0x6e, 0x64, 0x72, 0x65, 0x77]).ok(), Some(Cow::Borrowed("Andrew")) @@ -1067,7 +1141,8 @@ mod tests { #[test] fn deserialize_checkeddata_test() { - let cd: Result = deserialize(&[5u8, 0, 0, 0, 162, 107, 175, 90, 1, 2, 3, 4, 5]); + let cd: Result = + deserialize(&[5u8, 0, 0, 0, 162, 107, 175, 90, 1, 2, 3, 4, 5]); assert_eq!(cd.ok(), Some(CheckedData(vec![1u8, 2, 3, 4, 5]))); } @@ -1105,7 +1180,7 @@ mod tests { let mut data = Vec::with_capacity(256); let mut data64 = Vec::with_capacity(256); for _ in 0..10 { - round_trip!{bool, i8, u8, i16, u16, i32, u32, i64, u64, + round_trip! {bool, i8, u8, i16, u16, i32, u32, i64, u64, (bool, i8, u16, i32), (u64, i64, u32, i32, u16, i16), (i8, u8, i16, u16, i32, u32, i64, u64), [u8; 2], [u8; 4], [u8; 8], [u8; 12], [u8; 16], [u8; 32]}; @@ -1116,22 +1191,21 @@ mod tests { data64.resize(len, 0u64); let mut arr33 = [0u8; 33]; let mut arr16 = [0u16; 8]; - round_trip_bytes!{(Vec, data), ([u8; 33], arr33), ([u16; 8], arr16), (Vec, data64)}; - - + round_trip_bytes! {(Vec, data), ([u8; 33], arr33), ([u16; 8], arr16), (Vec, data64)}; } } #[test] fn test_read_bytes_from_finite_reader() { - let data : Vec = (0..10).collect(); + let data: Vec = (0..10).collect(); for chunk_size in 1..20 { assert_eq!( read_bytes_from_finite_reader( io::Cursor::new(&data), ReadBytesFromFiniteReaderOpts { len: data.len(), chunk_size } - ).unwrap(), + ) + .unwrap(), data ); } diff --git a/bitcoin/src/consensus/mod.rs b/bitcoin/src/consensus/mod.rs index 9ccae25f..0759358f 100644 --- a/bitcoin/src/consensus/mod.rs +++ b/bitcoin/src/consensus/mod.rs @@ -9,8 +9,9 @@ pub mod encode; pub mod params; -pub use self::encode::{Encodable, Decodable, WriteExt, ReadExt}; -pub use self::encode::{serialize, deserialize, deserialize_partial}; +pub use self::encode::{ + deserialize, deserialize_partial, serialize, Decodable, Encodable, ReadExt, WriteExt, +}; pub use self::params::Params; #[cfg(feature = "serde")] diff --git a/bitcoin/src/consensus/params.rs b/bitcoin/src/consensus/params.rs index dc4909d4..07b5ff8d 100644 --- a/bitcoin/src/consensus/params.rs +++ b/bitcoin/src/consensus/params.rs @@ -83,7 +83,7 @@ impl Params { }, Network::Signet => Params { network: Network::Signet, - bip16_time: 1333238400, // Apr 1 2012 + bip16_time: 1333238400, // Apr 1 2012 bip34_height: 1, bip65_height: 1, bip66_height: 1, diff --git a/bitcoin/src/consensus/serde.rs b/bitcoin/src/consensus/serde.rs index cbae90cd..7b411d01 100644 --- a/bitcoin/src/consensus/serde.rs +++ b/bitcoin/src/consensus/serde.rs @@ -9,20 +9,22 @@ use core::fmt; use core::marker::PhantomData; -use crate::io; -use serde::{Serializer, Deserializer}; -use serde::de::{Visitor, SeqAccess, Unexpected}; + +use serde::de::{SeqAccess, Unexpected, Visitor}; use serde::ser::SerializeSeq; -use super::{Encodable, Decodable}; +use serde::{Deserializer, Serializer}; + use super::encode::Error as ConsensusError; +use super::{Decodable, Encodable}; +use crate::io; /// Hex-encoding strategy -pub struct Hex(PhantomData) where Case: hex::Case; +pub struct Hex(PhantomData) +where + Case: hex::Case; impl Default for Hex { - fn default() -> Self { - Hex(Default::default()) - } + fn default() -> Self { Hex(Default::default()) } } impl ByteEncoder for Hex { @@ -33,6 +35,7 @@ impl ByteEncoder for Hex { pub mod hex { use core::fmt; use core::marker::PhantomData; + use bitcoin_internals as internals; use internals::hex::BufEncoder; @@ -131,9 +134,7 @@ pub mod hex { type DecodeError = DecodeError; type Decoder = Decoder<'a>; - fn from_str(s: &'a str) -> Result { - Decoder::new(s) - } + fn from_str(s: &'a str) -> Result { Decoder::new(s) } } impl super::IntoDeError for DecodeInitError { @@ -141,7 +142,8 @@ pub mod hex { use bitcoin_hashes::hex::Error; match self.0 { - Error::OddLengthString(len) => E::invalid_length(len, &"an even number of ASCII-encoded hex digits"), + Error::OddLengthString(len) => + E::invalid_length(len, &"an even number of ASCII-encoded hex digits"), error => panic!("unexpected error: {:?}", error), } } @@ -155,8 +157,10 @@ pub mod hex { const EXPECTED_CHAR: &str = "an ASCII-encoded hex digit"; match self.0 { - Error::InvalidChar(c) if c.is_ascii() => E::invalid_value(Unexpected::Char(c as _), &EXPECTED_CHAR), - Error::InvalidChar(c) => E::invalid_value(Unexpected::Unsigned(c.into()), &EXPECTED_CHAR), + Error::InvalidChar(c) if c.is_ascii() => + E::invalid_value(Unexpected::Char(c as _), &EXPECTED_CHAR), + Error::InvalidChar(c) => + E::invalid_value(Unexpected::Unsigned(c.into()), &EXPECTED_CHAR), error => panic!("unexpected error: {:?}", error), } } @@ -173,8 +177,15 @@ impl<'a, T: 'a + Encodable, E: ByteEncoder> fmt::Display for DisplayWrapper<'a, { use crate::StdError; - if error.kind() != io::ErrorKind::Other || error.source().is_some() || !writer.writer.was_error { - panic!("{} returned an unexpected error: {:?}", core::any::type_name::(), error); + if error.kind() != io::ErrorKind::Other + || error.source().is_some() + || !writer.writer.was_error + { + panic!( + "{} returned an unexpected error: {:?}", + core::any::type_name::(), + error + ); } } fmt::Error @@ -255,15 +266,10 @@ struct IoWrapper<'a, W: fmt::Write, E: EncodeBytes> { impl<'a, W: fmt::Write, E: EncodeBytes> IoWrapper<'a, W, E> { fn new(writer: &'a mut W, encoder: E) -> Self { - IoWrapper { - writer: ErrorTrackingWriter::new(writer), - encoder, - } + IoWrapper { writer: ErrorTrackingWriter::new(writer), encoder } } - fn actually_flush(&mut self) -> fmt::Result { - self.encoder.flush(&mut self.writer) - } + fn actually_flush(&mut self) -> fmt::Result { self.encoder.flush(&mut self.writer) } } impl<'a, W: fmt::Write, E: EncodeBytes> io::Write for IoWrapper<'a, W, E> { @@ -319,7 +325,7 @@ pub trait ByteDecoder<'a> { type DecodeError: IntoDeError + fmt::Debug; /// The decoder state. - type Decoder: Iterator>; + type Decoder: Iterator>; /// Constructs the decoder from string. fn from_str(s: &'a str) -> Result; @@ -331,15 +337,13 @@ pub trait IntoDeError { fn into_de_error(self) -> E; } -struct BinWriter{ +struct BinWriter { serializer: S, error: Option, } impl io::Write for BinWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.write_all(buf).map(|_| buf.len()) - } + fn write(&mut self, buf: &[u8]) -> io::Result { self.write_all(buf).map(|_| buf.len()) } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { for byte in buf { @@ -372,15 +376,29 @@ enum DecodeError { fn consensus_error_into_serde(error: ConsensusError) -> E { match error { ConsensusError::Io(error) => panic!("unexpected IO error {:?}", error), - ConsensusError::OversizedVectorAllocation { requested, max } => E::custom(format_args!("the requested allocation of {} items exceeds maximum of {}", requested, max)), - ConsensusError::InvalidChecksum { expected, actual } => E::invalid_value(Unexpected::Bytes(&actual), &DisplayExpected(format_args!("checksum {:02x}{:02x}{:02x}{:02x}", expected[0], expected[1], expected[2], expected[3]))), - ConsensusError::NonMinimalVarInt => E::custom(format_args!("compact size was not encoded minimally")), + ConsensusError::OversizedVectorAllocation { requested, max } => E::custom(format_args!( + "the requested allocation of {} items exceeds maximum of {}", + requested, max + )), + ConsensusError::InvalidChecksum { expected, actual } => E::invalid_value( + Unexpected::Bytes(&actual), + &DisplayExpected(format_args!( + "checksum {:02x}{:02x}{:02x}{:02x}", + expected[0], expected[1], expected[2], expected[3] + )), + ), + ConsensusError::NonMinimalVarInt => + E::custom(format_args!("compact size was not encoded minimally")), ConsensusError::ParseFailed(msg) => E::custom(msg), - ConsensusError::UnsupportedSegwitFlag(flag) => E::invalid_value(Unexpected::Unsigned(flag.into()), &"segwit version 1 flag"), + ConsensusError::UnsupportedSegwitFlag(flag) => + E::invalid_value(Unexpected::Unsigned(flag.into()), &"segwit version 1 flag"), } } -impl DecodeError where E: serde::de::Error { +impl DecodeError +where + E: serde::de::Error, +{ fn unify(self) -> E { match self { DecodeError::Other(error) => error, @@ -390,7 +408,10 @@ impl DecodeError where E: serde::de::Error { } } -impl IntoDeError for DecodeError where E: IntoDeError { +impl IntoDeError for DecodeError +where + E: IntoDeError, +{ fn into_de_error(self) -> DE { match self { DecodeError::Other(error) => error.into_de_error(), @@ -400,18 +421,13 @@ impl IntoDeError for DecodeError where E: IntoDeError { } } -struct IterReader>> { +struct IterReader>> { iterator: core::iter::Fuse, error: Option, } -impl>> IterReader { - fn new(iterator: I) -> Self { - IterReader { - iterator: iterator.fuse(), - error: None, - } - } +impl>> IterReader { + fn new(iterator: I) -> Self { IterReader { iterator: iterator.fuse(), error: None } } fn decode(mut self) -> Result> { use crate::StdError; @@ -431,7 +447,7 @@ impl>> IterReader { } } -impl>> io::Read for IterReader { +impl>> io::Read for IterReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { let mut count = 0; for (dst, src) in buf.iter_mut().zip(&mut self.iterator) { @@ -469,30 +485,46 @@ pub struct With(PhantomData); impl With { /// Serializes the value as consensus-encoded - pub fn serialize(value: &T, serializer: S) -> Result where E: ByteEncoder { + pub fn serialize( + value: &T, + serializer: S, + ) -> Result + where + E: ByteEncoder, + { if serializer.is_human_readable() { serializer.collect_str(&DisplayWrapper::<'_, _, E>(value, Default::default())) } else { use crate::StdError; let serializer = serializer.serialize_seq(None)?; - let mut writer = BinWriter { - serializer, - error: None, - }; + let mut writer = BinWriter { serializer, error: None }; let result = value.consensus_encode(&mut writer); match (result, writer.error) { (Ok(_), None) => writer.serializer.end(), - (Ok(_), Some(error)) => panic!("{} silently ate an IO error: {:?}", core::any::type_name::(), error), - (Err(io_error), Some(ser_error)) if io_error.kind() == io::ErrorKind::Other && io_error.source().is_none() => Err(ser_error), - (Err(io_error), ser_error) => panic!("{} returned an unexpected IO error: {:?} serialization error: {:?}", core::any::type_name::(), io_error, ser_error), + (Ok(_), Some(error)) => + panic!("{} silently ate an IO error: {:?}", core::any::type_name::(), error), + (Err(io_error), Some(ser_error)) + if io_error.kind() == io::ErrorKind::Other && io_error.source().is_none() => + Err(ser_error), + (Err(io_error), ser_error) => panic!( + "{} returned an unexpected IO error: {:?} serialization error: {:?}", + core::any::type_name::(), + io_error, + ser_error + ), } } } /// Deserializes the value as consensus-encoded - pub fn deserialize<'d, T: Decodable, D: Deserializer<'d>>(deserializer: D) -> Result where for<'a> E: ByteDecoder<'a> { + pub fn deserialize<'d, T: Decodable, D: Deserializer<'d>>( + deserializer: D, + ) -> Result + where + for<'a> E: ByteDecoder<'a>, + { if deserializer.is_human_readable() { deserializer.deserialize_str(HRVisitor::<_, E>(Default::default())) } else { @@ -535,7 +567,5 @@ struct SeqIterator<'a, S: serde::de::SeqAccess<'a>>(S, PhantomData<&'a ()>); impl<'a, S: serde::de::SeqAccess<'a>> Iterator for SeqIterator<'a, S> { type Item = Result; - fn next(&mut self) -> Option { - self.0.next_element::().transpose() - } + fn next(&mut self) -> Option { self.0.next_element::().transpose() } }