consensus: Run the formatter
Run `cargo +nightly fmt`, no other manual changes.
This commit is contained in:
parent
89143205f9
commit
450a84f6e8
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")]
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue