consensus: Run the formatter

Run `cargo +nightly fmt`, no other manual changes.
This commit is contained in:
Tobin C. Harding 2022-12-06 10:38:48 +11:00
parent 89143205f9
commit 450a84f6e8
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
4 changed files with 277 additions and 172 deletions

View File

@ -16,22 +16,23 @@
//! typically big-endian decimals, etc.) //! typically big-endian decimals, etc.)
//! //!
use crate::prelude::*; use core::convert::From;
use core::{fmt, mem, u32};
use core::{fmt, mem, u32, convert::From};
use bitcoin_internals::write_err; use bitcoin_internals::write_err;
use crate::hashes::{sha256d, Hash, sha256}; use crate::bip152::{PrefilledTransaction, ShortId};
use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader}; 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::io::{self, Cursor, Read};
use crate::bip152::{ShortId, PrefilledTransaction};
use crate::taproot::TapLeafHash;
use crate::blockdata::transaction::{TxOut, Transaction, TxIn};
#[cfg(feature = "std")] #[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. /// Encoding error.
#[derive(Debug)] #[derive(Debug)]
@ -65,14 +66,14 @@ impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
Error::Io(ref e) => write_err!(f, "IO error"; e), Error::Io(ref e) => write_err!(f, "IO error"; e),
Error::OversizedVectorAllocation { requested: ref r, max: ref m } => write!(f, Error::OversizedVectorAllocation { requested: ref r, max: ref m } =>
"allocation of oversized vector: requested {}, maximum {}", r, m), write!(f, "allocation of oversized vector: requested {}, maximum {}", r, m),
Error::InvalidChecksum { expected: ref e, actual: ref a } => write!(f, Error::InvalidChecksum { expected: ref e, actual: ref a } =>
"invalid checksum: expected {:x}, actual {:x}", e.as_hex(), a.as_hex()), write!(f, "invalid checksum: expected {:x}, actual {:x}", e.as_hex(), a.as_hex()),
Error::NonMinimalVarInt => write!(f, "non-minimal varint"), Error::NonMinimalVarInt => write!(f, "non-minimal varint"),
Error::ParseFailed(ref s) => write!(f, "parse failed: {}", s), Error::ParseFailed(ref s) => write!(f, "parse failed: {}", s),
Error::UnsupportedSegwitFlag(ref swflag) => write!(f, Error::UnsupportedSegwitFlag(ref swflag) =>
"unsupported segwit version: {}", swflag), write!(f, "unsupported segwit version: {}", swflag),
} }
} }
} }
@ -96,9 +97,7 @@ impl std::error::Error for Error {
#[doc(hidden)] #[doc(hidden)]
impl From<io::Error> for Error { impl From<io::Error> for Error {
fn from(error: io::Error) -> Self { fn from(error: io::Error) -> Self { Error::Io(error) }
Error::Io(error)
}
} }
/// Encodes an object into a vector. /// Encodes an object into a vector.
@ -137,7 +136,6 @@ pub fn deserialize_partial<T: Decodable>(data: &[u8]) -> Result<(T, usize), Erro
Ok((rv, consumed)) Ok((rv, consumed))
} }
/// Extensions of `Write` to encode data as per Bitcoin consensus. /// 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. /// Outputs a 64-bit unsigned integer.
@ -198,7 +196,7 @@ macro_rules! encoder_fn {
fn $name(&mut self, v: $val_type) -> Result<(), io::Error> { fn $name(&mut self, v: $val_type) -> Result<(), io::Error> {
self.write_all(&v.to_le_bytes()) self.write_all(&v.to_le_bytes())
} }
} };
} }
macro_rules! decoder_fn { macro_rules! decoder_fn {
@ -209,7 +207,7 @@ macro_rules! decoder_fn {
self.read_exact(&mut val[..]).map_err(Error::Io)?; self.read_exact(&mut val[..]).map_err(Error::Io)?;
Ok(<$val_type>::from_le_bytes(val)) Ok(<$val_type>::from_le_bytes(val))
} }
} };
} }
impl<W: io::Write + ?Sized> WriteExt for W { impl<W: io::Write + ?Sized> WriteExt for W {
@ -221,21 +219,13 @@ impl<W: io::Write + ?Sized> WriteExt for W {
encoder_fn!(emit_i16, i16); encoder_fn!(emit_i16, i16);
#[inline] #[inline]
fn emit_i8(&mut self, v: i8) -> Result<(), io::Error> { fn emit_i8(&mut self, v: i8) -> Result<(), io::Error> { self.write_all(&[v as u8]) }
self.write_all(&[v as u8])
}
#[inline] #[inline]
fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> { fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> { self.write_all(&[v]) }
self.write_all(&[v])
}
#[inline] #[inline]
fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> { fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> { self.write_all(&[v as u8]) }
self.write_all(&[v as u8])
}
#[inline] #[inline]
fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error> { fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error> { self.write_all(v) }
self.write_all(v)
}
} }
impl<R: Read + ?Sized> ReadExt for R { impl<R: Read + ?Sized> ReadExt for R {
@ -259,9 +249,7 @@ impl<R: Read + ?Sized> ReadExt for R {
Ok(slice[0] as i8) Ok(slice[0] as i8)
} }
#[inline] #[inline]
fn read_bool(&mut self) -> Result<bool, Error> { fn read_bool(&mut self) -> Result<bool, Error> { ReadExt::read_i8(self).map(|bit| bit != 0) }
ReadExt::read_i8(self).map(|bit| bit != 0)
}
#[inline] #[inline]
fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), Error> { fn read_slice(&mut self, slice: &mut [u8]) -> Result<(), Error> {
self.read_exact(slice).map_err(Error::Io) 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 /// avoid creating redundant `Take` wrappers. Failure to do so might result only in a tiny
/// performance hit. /// performance hit.
#[inline] #[inline]
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, Error> { fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(
reader: &mut R,
) -> Result<Self, Error> {
// This method is always strictly less general than, `consensus_decode`, so it's safe and // 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 // 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. // protecting against resource exhaustion due to malicious input, can just ignore it.
@ -353,12 +343,15 @@ macro_rules! impl_int_encodable {
} }
impl Encodable for $ty { impl Encodable for $ty {
#[inline] #[inline]
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> { fn consensus_encode<W: io::Write + ?Sized>(
&self,
w: &mut W,
) -> Result<usize, io::Error> {
w.$meth_enc(*self)?; w.$meth_enc(*self)?;
Ok(mem::size_of::<$ty>()) Ok(mem::size_of::<$ty>())
} }
} }
} };
} }
impl_int_encodable!(u8, read_u8, emit_u8); impl_int_encodable!(u8, read_u8, emit_u8);
@ -398,22 +391,22 @@ impl Encodable for VarInt {
0..=0xFC => { 0..=0xFC => {
(self.0 as u8).consensus_encode(w)?; (self.0 as u8).consensus_encode(w)?;
Ok(1) Ok(1)
}, }
0xFD..=0xFFFF => { 0xFD..=0xFFFF => {
w.emit_u8(0xFD)?; w.emit_u8(0xFD)?;
(self.0 as u16).consensus_encode(w)?; (self.0 as u16).consensus_encode(w)?;
Ok(3) Ok(3)
}, }
0x10000..=0xFFFFFFFF => { 0x10000..=0xFFFFFFFF => {
w.emit_u8(0xFE)?; w.emit_u8(0xFE)?;
(self.0 as u32).consensus_encode(w)?; (self.0 as u32).consensus_encode(w)?;
Ok(5) Ok(5)
}, }
_ => { _ => {
w.emit_u8(0xFF)?; w.emit_u8(0xFF)?;
self.0.consensus_encode(w)?; self.0.consensus_encode(w)?;
Ok(9) Ok(9)
}, }
} }
} }
} }
@ -447,7 +440,7 @@ impl Decodable for VarInt {
Ok(VarInt(x as u64)) 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 ) => { ( $size:literal ) => {
impl Encodable for [u8; $size] { impl Encodable for [u8; $size] {
#[inline] #[inline]
fn consensus_encode<W: WriteExt + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> { fn consensus_encode<W: WriteExt + ?Sized>(
&self,
w: &mut W,
) -> Result<usize, io::Error> {
w.emit_slice(&self[..])?; w.emit_slice(&self[..])?;
Ok(self.len()) Ok(self.len())
} }
@ -549,7 +545,9 @@ impl Decodable for [u16; 8] {
impl Encodable for [u16; 8] { impl Encodable for [u16; 8] {
#[inline] #[inline]
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> { fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
for c in self.iter() { c.consensus_encode(w)?; } for c in self.iter() {
c.consensus_encode(w)?;
}
Ok(16) Ok(16)
} }
} }
@ -558,7 +556,10 @@ macro_rules! impl_vec {
($type: ty) => { ($type: ty) => {
impl Encodable for Vec<$type> { impl Encodable for Vec<$type> {
#[inline] #[inline]
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> { fn consensus_encode<W: io::Write + ?Sized>(
&self,
w: &mut W,
) -> Result<usize, io::Error> {
let mut len = 0; let mut len = 0;
len += VarInt(self.len() as u64).consensus_encode(w)?; len += VarInt(self.len() as u64).consensus_encode(w)?;
for c in self.iter() { for c in self.iter() {
@ -570,7 +571,9 @@ macro_rules! impl_vec {
impl Decodable for Vec<$type> { impl Decodable for Vec<$type> {
#[inline] #[inline]
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> { fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(
r: &mut R,
) -> Result<Self, Error> {
let len = VarInt::consensus_decode_from_finite_reader(r)?.0; let len = VarInt::consensus_decode_from_finite_reader(r)?.0;
// Do not allocate upfront more items than if the sequnce of type // Do not allocate upfront more items than if the sequnce of type
// occupied roughly quarter a block. This should never be the case // occupied roughly quarter a block. This should never be the case
@ -586,7 +589,7 @@ macro_rules! impl_vec {
Ok(ret) Ok(ret)
} }
} }
} };
} }
impl_vec!(BlockHash); impl_vec!(BlockHash);
impl_vec!(FilterHash); impl_vec!(FilterHash);
@ -602,17 +605,22 @@ impl_vec!(VarInt);
impl_vec!(ShortId); impl_vec!(ShortId);
impl_vec!(PrefilledTransaction); impl_vec!(PrefilledTransaction);
#[cfg(feature = "std")] impl_vec!(Inventory); #[cfg(feature = "std")]
#[cfg(feature = "std")] impl_vec!((u32, Address)); impl_vec!(Inventory);
#[cfg(feature = "std")] impl_vec!(AddrV2Message); #[cfg(feature = "std")]
impl_vec!((u32, Address));
#[cfg(feature = "std")]
impl_vec!(AddrV2Message);
pub(crate) fn consensus_encode_with_size<S: io::Write>(data: &[u8], mut s: S) -> Result<usize, io::Error> { pub(crate) fn consensus_encode_with_size<S: io::Write>(
data: &[u8],
mut s: S,
) -> Result<usize, io::Error> {
let vi_len = VarInt(data.len() as u64).consensus_encode(&mut s)?; let vi_len = VarInt(data.len() as u64).consensus_encode(&mut s)?;
s.emit_slice(data)?; s.emit_slice(data)?;
Ok(vi_len + data.len()) Ok(vi_len + data.len())
} }
struct ReadBytesFromFiniteReaderOpts { struct ReadBytesFromFiniteReaderOpts {
len: usize, len: usize,
chunk_size: usize, chunk_size: usize,
@ -623,7 +631,10 @@ struct ReadBytesFromFiniteReaderOpts {
/// This function relies on reader being bound in amount of data /// This function relies on reader being bound in amount of data
/// it returns for OOM protection. See [`Decodable::consensus_decode_from_finite_reader`]. /// it returns for OOM protection. See [`Decodable::consensus_decode_from_finite_reader`].
#[inline] #[inline]
fn read_bytes_from_finite_reader<D: io::Read>(mut d: D, mut opts: ReadBytesFromFiniteReaderOpts) -> Result<Vec<u8>, Error> { fn read_bytes_from_finite_reader<D: io::Read>(
mut d: D,
mut opts: ReadBytesFromFiniteReaderOpts,
) -> Result<Vec<u8>, Error> {
let mut ret = vec![]; let mut ret = vec![];
assert_ne!(opts.chunk_size, 0); 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. /// Does a double-SHA256 on `data` and returns the first 4 bytes.
fn sha2_checksum(data: &[u8]) -> [u8; 4] { fn sha2_checksum(data: &[u8]) -> [u8; 4] {
let checksum = <sha256d::Hash as Hash>::hash(data); let checksum = <sha256d::Hash as Hash>::hash(data);
@ -698,10 +708,7 @@ impl Decodable for CheckedData {
let ret = read_bytes_from_finite_reader(r, opts)?; let ret = read_bytes_from_finite_reader(r, opts)?;
let expected_checksum = sha2_checksum(&ret); let expected_checksum = sha2_checksum(&ret);
if expected_checksum != checksum { if expected_checksum != checksum {
Err(self::Error::InvalidChecksum { Err(self::Error::InvalidChecksum { expected: expected_checksum, actual: checksum })
expected: expected_checksum,
actual: checksum,
})
} else { } else {
Ok(CheckedData(ret)) Ok(CheckedData(ret))
} }
@ -807,11 +814,13 @@ impl Decodable for TapLeafHash {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use core::fmt;
use core::mem::{self, discriminant};
use super::*; use super::*;
use core::{mem::{self, discriminant}, fmt}; use crate::consensus::{deserialize_partial, Decodable, Encodable};
use crate::consensus::{Encodable, deserialize_partial, Decodable};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::network::{Address, message_blockdata::Inventory}; use crate::network::{message_blockdata::Inventory, Address};
#[test] #[test]
fn serialize_int_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(&-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(&-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(&-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(&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(&256i64), vec![0u8, 1, 0, 0, 0, 0, 0, 0]);
assert_eq!(serialize(&5000i64), vec![136u8, 19, 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(0xFD)), vec![0xFDu8, 0xFD, 0]);
assert_eq!(serialize(&VarInt(0xFFF)), vec![0xFDu8, 0xFF, 0xF]); assert_eq!(serialize(&VarInt(0xFFF)), vec![0xFDu8, 0xFF, 0xF]);
assert_eq!(serialize(&VarInt(0xF0F0F0F)), vec![0xFEu8, 0xF, 0xF, 0xF, 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!(
assert_eq!(test_varint_encode(0xFF, &0x100000000_u64.to_le_bytes()).unwrap(), VarInt(0x100000000)); 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(0xFE, &0x10000_u64.to_le_bytes()).unwrap(), VarInt(0x10000));
assert_eq!(test_varint_encode(0xFD, &0xFD_u64.to_le_bytes()).unwrap(), VarInt(0xFD)); assert_eq!(test_varint_encode(0xFD, &0xFD_u64.to_le_bytes()).unwrap(), VarInt(0xFD));
@ -901,28 +919,55 @@ mod tests {
#[test] #[test]
fn deserialize_nonminimal_vec() { fn deserialize_nonminimal_vec() {
// Check the edges for variant int // Check the edges for variant int
assert_eq!(discriminant(&test_varint_encode(0xFF, &(0x100000000_u64-1).to_le_bytes()).unwrap_err()), assert_eq!(
discriminant(&Error::NonMinimalVarInt)); discriminant(
assert_eq!(discriminant(&test_varint_encode(0xFE, &(0x10000_u64-1).to_le_bytes()).unwrap_err()), &test_varint_encode(0xFF, &(0x100000000_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)
discriminant(&Error::NonMinimalVarInt)); );
assert_eq!(
assert_eq!(discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0x00, 0x00]).unwrap_err()), discriminant(&test_varint_encode(0xFE, &(0x10000_u64 - 1).to_le_bytes()).unwrap_err()),
discriminant(&Error::NonMinimalVarInt)); discriminant(&Error::NonMinimalVarInt)
assert_eq!(discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err()), );
discriminant(&Error::NonMinimalVarInt)); assert_eq!(
assert_eq!(discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err()), discriminant(&test_varint_encode(0xFD, &(0xFD_u64 - 1).to_le_bytes()).unwrap_err()),
discriminant(&Error::NonMinimalVarInt)); discriminant(&Error::NonMinimalVarInt)
assert_eq!(discriminant(&deserialize::<Vec<u8>>(&[0xfe, 0xff, 0x00, 0x00, 0x00]).unwrap_err()), );
discriminant(&Error::NonMinimalVarInt));
assert_eq!(discriminant(&deserialize::<Vec<u8>>(&[0xfe, 0xff, 0xff, 0x00, 0x00]).unwrap_err()),
discriminant(&Error::NonMinimalVarInt));
assert_eq!(discriminant(&deserialize::<Vec<u8>>(&[0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]).unwrap_err()),
discriminant(&Error::NonMinimalVarInt));
assert_eq!(discriminant(&deserialize::<Vec<u8>>(&[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00]).unwrap_err()),
discriminant(&Error::NonMinimalVarInt));
assert_eq!(
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0x00, 0x00]).unwrap_err()),
discriminant(&Error::NonMinimalVarInt)
);
assert_eq!(
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err()),
discriminant(&Error::NonMinimalVarInt)
);
assert_eq!(
discriminant(&deserialize::<Vec<u8>>(&[0xfd, 0xfc, 0x00]).unwrap_err()),
discriminant(&Error::NonMinimalVarInt)
);
assert_eq!(
discriminant(&deserialize::<Vec<u8>>(&[0xfe, 0xff, 0x00, 0x00, 0x00]).unwrap_err()),
discriminant(&Error::NonMinimalVarInt)
);
assert_eq!(
discriminant(&deserialize::<Vec<u8>>(&[0xfe, 0xff, 0xff, 0x00, 0x00]).unwrap_err()),
discriminant(&Error::NonMinimalVarInt)
);
assert_eq!(
discriminant(
&deserialize::<Vec<u8>>(&[0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
.unwrap_err()
),
discriminant(&Error::NonMinimalVarInt)
);
assert_eq!(
discriminant(
&deserialize::<Vec<u8>>(&[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00])
.unwrap_err()
),
discriminant(&Error::NonMinimalVarInt)
);
let mut vec_256 = vec![0; 259]; let mut vec_256 = vec![0; 259];
vec_256[0] = 0xfd; vec_256[0] = 0xfd;
@ -1003,21 +1048,38 @@ mod tests {
// u64 // u64
assert_eq!(deserialize(&[0xABu8, 0xCD, 0, 0, 0, 0, 0, 0]).ok(), Some(0xCDABu64)); 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<u64, _> = deserialize(&[1u8, 2, 3, 4, 5, 6, 7]); let failure64: Result<u64, _> = deserialize(&[1u8, 2, 3, 4, 5, 6, 7]);
assert!(failure64.is_err()); assert!(failure64.is_err());
// i64 // i64
assert_eq!(deserialize(&[0xABu8, 0xCD, 0, 0, 0, 0, 0, 0]).ok(), Some(0xCDABi64)); 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!(
assert_eq!(deserialize(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), Some(-1_i64)); deserialize(&[0xA0u8, 0x0D, 0xAB, 0xCD, 0x99, 0, 0, 0x99]).ok(),
assert_eq!(deserialize(&[0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).ok(), Some(-2_i64)); Some(-0x66ffff663254f260i64)
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(&[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<i64, _> = deserialize(&[1u8, 2, 3, 4, 5, 6, 7]); let failurei64: Result<i64, _> = deserialize(&[1u8, 2, 3, 4, 5, 6, 7]);
assert!(failurei64.is_err()); assert!(failurei64.is_err());
} }
#[test] #[test]
@ -1025,13 +1087,18 @@ mod tests {
assert_eq!(deserialize(&[3u8, 2, 3, 4]).ok(), Some(vec![2u8, 3, 4])); assert_eq!(deserialize(&[3u8, 2, 3, 4]).ok(), Some(vec![2u8, 3, 4]));
assert!((deserialize(&[4u8, 2, 3, 4, 5, 6]) as Result<Vec<u8>, _>).is_err()); assert!((deserialize(&[4u8, 2, 3, 4, 5, 6]) as Result<Vec<u8>, _>).is_err());
// found by cargo fuzz // found by cargo fuzz
assert!(deserialize::<Vec<u64>>(&[0xff,0xff,0xff,0xff,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0x6b,0xa,0xa,0x3a]).is_err()); assert!(deserialize::<Vec<u64>>(&[
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, "")); 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, // 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. // by making sure it fails with IO Error and not an `OversizedVectorAllocation` Error.
let err = deserialize::<CheckedData>(&serialize(&(super::MAX_VEC_SIZE as u32))).unwrap_err(); let err =
deserialize::<CheckedData>(&serialize(&(super::MAX_VEC_SIZE as u32))).unwrap_err();
assert_eq!(discriminant(&err), discriminant(&rand_io_err)); assert_eq!(discriminant(&err), discriminant(&rand_io_err));
test_len_is_max_vec::<u8>(); test_len_is_max_vec::<u8>();
@ -1049,7 +1116,11 @@ mod tests {
test_len_is_max_vec::<Inventory>(); test_len_is_max_vec::<Inventory>();
} }
fn test_len_is_max_vec<T>() where Vec<T>: Decodable, T: fmt::Debug { fn test_len_is_max_vec<T>()
where
Vec<T>: Decodable,
T: fmt::Debug,
{
let rand_io_err = Error::Io(io::Error::new(io::ErrorKind::Other, "")); let rand_io_err = Error::Io(io::Error::new(io::ErrorKind::Other, ""));
let varint = VarInt((super::MAX_VEC_SIZE / mem::size_of::<T>()) as u64); let varint = VarInt((super::MAX_VEC_SIZE / mem::size_of::<T>()) as u64);
let err = deserialize::<Vec<T>>(&serialize(&varint)).unwrap_err(); let err = deserialize::<Vec<T>>(&serialize(&varint)).unwrap_err();
@ -1058,7 +1129,10 @@ mod tests {
#[test] #[test]
fn deserialize_strbuf_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!( assert_eq!(
deserialize(&[6u8, 0x41, 0x6e, 0x64, 0x72, 0x65, 0x77]).ok(), deserialize(&[6u8, 0x41, 0x6e, 0x64, 0x72, 0x65, 0x77]).ok(),
Some(Cow::Borrowed("Andrew")) Some(Cow::Borrowed("Andrew"))
@ -1067,7 +1141,8 @@ mod tests {
#[test] #[test]
fn deserialize_checkeddata_test() { fn deserialize_checkeddata_test() {
let cd: Result<CheckedData, _> = deserialize(&[5u8, 0, 0, 0, 162, 107, 175, 90, 1, 2, 3, 4, 5]); let cd: Result<CheckedData, _> =
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]))); assert_eq!(cd.ok(), Some(CheckedData(vec![1u8, 2, 3, 4, 5])));
} }
@ -1117,8 +1192,6 @@ mod tests {
let mut arr33 = [0u8; 33]; let mut arr33 = [0u8; 33];
let mut arr16 = [0u16; 8]; let mut arr16 = [0u16; 8];
round_trip_bytes! {(Vec<u8>, data), ([u8; 33], arr33), ([u16; 8], arr16), (Vec<u64>, data64)}; round_trip_bytes! {(Vec<u8>, data), ([u8; 33], arr33), ([u16; 8], arr16), (Vec<u64>, data64)};
} }
} }
@ -1131,7 +1204,8 @@ mod tests {
read_bytes_from_finite_reader( read_bytes_from_finite_reader(
io::Cursor::new(&data), io::Cursor::new(&data),
ReadBytesFromFiniteReaderOpts { len: data.len(), chunk_size } ReadBytesFromFiniteReaderOpts { len: data.len(), chunk_size }
).unwrap(), )
.unwrap(),
data data
); );
} }

View File

@ -9,8 +9,9 @@
pub mod encode; pub mod encode;
pub mod params; pub mod params;
pub use self::encode::{Encodable, Decodable, WriteExt, ReadExt}; pub use self::encode::{
pub use self::encode::{serialize, deserialize, deserialize_partial}; deserialize, deserialize_partial, serialize, Decodable, Encodable, ReadExt, WriteExt,
};
pub use self::params::Params; pub use self::params::Params;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]

View File

@ -9,20 +9,22 @@
use core::fmt; use core::fmt;
use core::marker::PhantomData; use core::marker::PhantomData;
use crate::io;
use serde::{Serializer, Deserializer}; use serde::de::{SeqAccess, Unexpected, Visitor};
use serde::de::{Visitor, SeqAccess, Unexpected};
use serde::ser::SerializeSeq; use serde::ser::SerializeSeq;
use super::{Encodable, Decodable}; use serde::{Deserializer, Serializer};
use super::encode::Error as ConsensusError; use super::encode::Error as ConsensusError;
use super::{Decodable, Encodable};
use crate::io;
/// Hex-encoding strategy /// Hex-encoding strategy
pub struct Hex<Case = hex::Lower>(PhantomData<Case>) where Case: hex::Case; pub struct Hex<Case = hex::Lower>(PhantomData<Case>)
where
Case: hex::Case;
impl<C: hex::Case> Default for Hex<C> { impl<C: hex::Case> Default for Hex<C> {
fn default() -> Self { fn default() -> Self { Hex(Default::default()) }
Hex(Default::default())
}
} }
impl<C: hex::Case> ByteEncoder for Hex<C> { impl<C: hex::Case> ByteEncoder for Hex<C> {
@ -33,6 +35,7 @@ impl<C: hex::Case> ByteEncoder for Hex<C> {
pub mod hex { pub mod hex {
use core::fmt; use core::fmt;
use core::marker::PhantomData; use core::marker::PhantomData;
use bitcoin_internals as internals; use bitcoin_internals as internals;
use internals::hex::BufEncoder; use internals::hex::BufEncoder;
@ -131,9 +134,7 @@ pub mod hex {
type DecodeError = DecodeError; type DecodeError = DecodeError;
type Decoder = Decoder<'a>; type Decoder = Decoder<'a>;
fn from_str(s: &'a str) -> Result<Self::Decoder, Self::InitError> { fn from_str(s: &'a str) -> Result<Self::Decoder, Self::InitError> { Decoder::new(s) }
Decoder::new(s)
}
} }
impl super::IntoDeError for DecodeInitError { impl super::IntoDeError for DecodeInitError {
@ -141,7 +142,8 @@ pub mod hex {
use bitcoin_hashes::hex::Error; use bitcoin_hashes::hex::Error;
match self.0 { 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), error => panic!("unexpected error: {:?}", error),
} }
} }
@ -155,8 +157,10 @@ pub mod hex {
const EXPECTED_CHAR: &str = "an ASCII-encoded hex digit"; const EXPECTED_CHAR: &str = "an ASCII-encoded hex digit";
match self.0 { match self.0 {
Error::InvalidChar(c) if c.is_ascii() => E::invalid_value(Unexpected::Char(c as _), &EXPECTED_CHAR), Error::InvalidChar(c) if c.is_ascii() =>
Error::InvalidChar(c) => E::invalid_value(Unexpected::Unsigned(c.into()), &EXPECTED_CHAR), 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), error => panic!("unexpected error: {:?}", error),
} }
} }
@ -173,8 +177,15 @@ impl<'a, T: 'a + Encodable, E: ByteEncoder> fmt::Display for DisplayWrapper<'a,
{ {
use crate::StdError; use crate::StdError;
if error.kind() != io::ErrorKind::Other || error.source().is_some() || !writer.writer.was_error { if error.kind() != io::ErrorKind::Other
panic!("{} returned an unexpected error: {:?}", core::any::type_name::<T>(), error); || error.source().is_some()
|| !writer.writer.was_error
{
panic!(
"{} returned an unexpected error: {:?}",
core::any::type_name::<T>(),
error
);
} }
} }
fmt::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> { impl<'a, W: fmt::Write, E: EncodeBytes> IoWrapper<'a, W, E> {
fn new(writer: &'a mut W, encoder: E) -> Self { fn new(writer: &'a mut W, encoder: E) -> Self {
IoWrapper { IoWrapper { writer: ErrorTrackingWriter::new(writer), encoder }
writer: ErrorTrackingWriter::new(writer),
encoder,
}
} }
fn actually_flush(&mut self) -> fmt::Result { fn actually_flush(&mut self) -> fmt::Result { self.encoder.flush(&mut self.writer) }
self.encoder.flush(&mut self.writer)
}
} }
impl<'a, W: fmt::Write, E: EncodeBytes> io::Write for IoWrapper<'a, W, E> { impl<'a, W: fmt::Write, E: EncodeBytes> io::Write for IoWrapper<'a, W, E> {
@ -337,9 +343,7 @@ struct BinWriter<S: SerializeSeq>{
} }
impl<S: SerializeSeq> io::Write for BinWriter<S> { impl<S: SerializeSeq> io::Write for BinWriter<S> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.write_all(buf).map(|_| buf.len()) }
self.write_all(buf).map(|_| buf.len())
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
for byte in buf { for byte in buf {
@ -372,15 +376,29 @@ enum DecodeError<E> {
fn consensus_error_into_serde<E: serde::de::Error>(error: ConsensusError) -> E { fn consensus_error_into_serde<E: serde::de::Error>(error: ConsensusError) -> E {
match error { match error {
ConsensusError::Io(error) => panic!("unexpected IO error {:?}", 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::OversizedVectorAllocation { requested, max } => E::custom(format_args!(
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]))), "the requested allocation of {} items exceeds maximum of {}",
ConsensusError::NonMinimalVarInt => E::custom(format_args!("compact size was not encoded minimally")), 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::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<E> DecodeError<E> where E: serde::de::Error { impl<E> DecodeError<E>
where
E: serde::de::Error,
{
fn unify(self) -> E { fn unify(self) -> E {
match self { match self {
DecodeError::Other(error) => error, DecodeError::Other(error) => error,
@ -390,7 +408,10 @@ impl<E> DecodeError<E> where E: serde::de::Error {
} }
} }
impl<E> IntoDeError for DecodeError<E> where E: IntoDeError { impl<E> IntoDeError for DecodeError<E>
where
E: IntoDeError,
{
fn into_de_error<DE: serde::de::Error>(self) -> DE { fn into_de_error<DE: serde::de::Error>(self) -> DE {
match self { match self {
DecodeError::Other(error) => error.into_de_error(), DecodeError::Other(error) => error.into_de_error(),
@ -406,12 +427,7 @@ struct IterReader<E: fmt::Debug, I: Iterator<Item=Result<u8, E>>> {
} }
impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> IterReader<E, I> { impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> IterReader<E, I> {
fn new(iterator: I) -> Self { fn new(iterator: I) -> Self { IterReader { iterator: iterator.fuse(), error: None } }
IterReader {
iterator: iterator.fuse(),
error: None,
}
}
fn decode<T: Decodable>(mut self) -> Result<T, DecodeError<E>> { fn decode<T: Decodable>(mut self) -> Result<T, DecodeError<E>> {
use crate::StdError; use crate::StdError;
@ -469,30 +485,46 @@ pub struct With<E>(PhantomData<E>);
impl<E> With<E> { impl<E> With<E> {
/// Serializes the value as consensus-encoded /// Serializes the value as consensus-encoded
pub fn serialize<T: Encodable, S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> where E: ByteEncoder { pub fn serialize<T: Encodable, S: Serializer>(
value: &T,
serializer: S,
) -> Result<S::Ok, S::Error>
where
E: ByteEncoder,
{
if serializer.is_human_readable() { if serializer.is_human_readable() {
serializer.collect_str(&DisplayWrapper::<'_, _, E>(value, Default::default())) serializer.collect_str(&DisplayWrapper::<'_, _, E>(value, Default::default()))
} else { } else {
use crate::StdError; use crate::StdError;
let serializer = serializer.serialize_seq(None)?; let serializer = serializer.serialize_seq(None)?;
let mut writer = BinWriter { let mut writer = BinWriter { serializer, error: None };
serializer,
error: None,
};
let result = value.consensus_encode(&mut writer); let result = value.consensus_encode(&mut writer);
match (result, writer.error) { match (result, writer.error) {
(Ok(_), None) => writer.serializer.end(), (Ok(_), None) => writer.serializer.end(),
(Ok(_), Some(error)) => panic!("{} silently ate an IO error: {:?}", core::any::type_name::<T>(), error), (Ok(_), Some(error)) =>
(Err(io_error), Some(ser_error)) if io_error.kind() == io::ErrorKind::Other && io_error.source().is_none() => Err(ser_error), panic!("{} silently ate an IO error: {:?}", core::any::type_name::<T>(), error),
(Err(io_error), ser_error) => panic!("{} returned an unexpected IO error: {:?} serialization error: {:?}", core::any::type_name::<T>(), io_error, ser_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::<T>(),
io_error,
ser_error
),
} }
} }
} }
/// Deserializes the value as consensus-encoded /// Deserializes the value as consensus-encoded
pub fn deserialize<'d, T: Decodable, D: Deserializer<'d>>(deserializer: D) -> Result<T, D::Error> where for<'a> E: ByteDecoder<'a> { pub fn deserialize<'d, T: Decodable, D: Deserializer<'d>>(
deserializer: D,
) -> Result<T, D::Error>
where
for<'a> E: ByteDecoder<'a>,
{
if deserializer.is_human_readable() { if deserializer.is_human_readable() {
deserializer.deserialize_str(HRVisitor::<_, E>(Default::default())) deserializer.deserialize_str(HRVisitor::<_, E>(Default::default()))
} else { } 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> { impl<'a, S: serde::de::SeqAccess<'a>> Iterator for SeqIterator<'a, S> {
type Item = Result<u8, S::Error>; type Item = Result<u8, S::Error>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> { self.0.next_element::<u8>().transpose() }
self.0.next_element::<u8>().transpose()
}
} }