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.)
|
||||
//!
|
||||
|
||||
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<io::Error> 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<T: Decodable>(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<u64, Error>;
|
||||
/// 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<W: io::Write + ?Sized> WriteExt for W {
|
||||
|
@ -221,21 +219,13 @@ impl<W: io::Write + ?Sized> 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<R: Read + ?Sized> ReadExt for R {
|
||||
|
@ -259,9 +249,7 @@ impl<R: Read + ?Sized> ReadExt for R {
|
|||
Ok(slice[0] as i8)
|
||||
}
|
||||
#[inline]
|
||||
fn read_bool(&mut self) -> Result<bool, Error> {
|
||||
ReadExt::read_i8(self).map(|bit| bit != 0)
|
||||
}
|
||||
fn read_bool(&mut self) -> Result<bool, Error> { 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<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
|
||||
// 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<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)?;
|
||||
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<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[..])?;
|
||||
Ok(self.len())
|
||||
}
|
||||
|
@ -549,7 +545,9 @@ impl Decodable for [u16; 8] {
|
|||
impl Encodable for [u16; 8] {
|
||||
#[inline]
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -558,7 +556,10 @@ macro_rules! impl_vec {
|
|||
($type: ty) => {
|
||||
impl Encodable for Vec<$type> {
|
||||
#[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;
|
||||
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: 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;
|
||||
// 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<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)?;
|
||||
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<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![];
|
||||
|
||||
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 = <sha256d::Hash as Hash>::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<VarInt, Error> {
|
||||
let mut input = [0u8; 9];
|
||||
input[0] = n;
|
||||
input[1..x.len()+1].copy_from_slice(x);
|
||||
deserialize_partial::<VarInt>(&input).map(|t|t.0)
|
||||
input[1..x.len() + 1].copy_from_slice(x);
|
||||
deserialize_partial::<VarInt>(&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::<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));
|
||||
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::<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];
|
||||
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<u64, _> = 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<i64, _> = 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<Vec<u8>, _>).is_err());
|
||||
// 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, ""));
|
||||
|
||||
// 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::<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));
|
||||
|
||||
test_len_is_max_vec::<u8>();
|
||||
|
@ -1049,7 +1116,11 @@ mod tests {
|
|||
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 varint = VarInt((super::MAX_VEC_SIZE / mem::size_of::<T>()) as u64);
|
||||
let err = deserialize::<Vec<T>>(&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<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])));
|
||||
}
|
||||
|
||||
|
@ -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<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)};
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_bytes_from_finite_reader() {
|
||||
let data : Vec<u8> = (0..10).collect();
|
||||
let data: Vec<u8> = (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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<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> {
|
||||
fn default() -> Self {
|
||||
Hex(Default::default())
|
||||
}
|
||||
fn default() -> Self { Hex(Default::default()) }
|
||||
}
|
||||
|
||||
impl<C: hex::Case> ByteEncoder for Hex<C> {
|
||||
|
@ -33,6 +35,7 @@ impl<C: hex::Case> ByteEncoder for Hex<C> {
|
|||
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<Self::Decoder, Self::InitError> {
|
||||
Decoder::new(s)
|
||||
}
|
||||
fn from_str(s: &'a str) -> Result<Self::Decoder, Self::InitError> { 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::<T>(), error);
|
||||
if error.kind() != io::ErrorKind::Other
|
||||
|| error.source().is_some()
|
||||
|| !writer.writer.was_error
|
||||
{
|
||||
panic!(
|
||||
"{} returned an unexpected error: {:?}",
|
||||
core::any::type_name::<T>(),
|
||||
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<Item=Result<u8, Self::DecodeError>>;
|
||||
type Decoder: Iterator<Item = Result<u8, Self::DecodeError>>;
|
||||
|
||||
/// Constructs the decoder from string.
|
||||
fn from_str(s: &'a str) -> Result<Self::Decoder, Self::InitError>;
|
||||
|
@ -331,15 +337,13 @@ pub trait IntoDeError {
|
|||
fn into_de_error<E: serde::de::Error>(self) -> E;
|
||||
}
|
||||
|
||||
struct BinWriter<S: SerializeSeq>{
|
||||
struct BinWriter<S: SerializeSeq> {
|
||||
serializer: S,
|
||||
error: Option<S::Error>,
|
||||
}
|
||||
|
||||
impl<S: SerializeSeq> io::Write for BinWriter<S> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.write_all(buf).map(|_| buf.len())
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 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<E> {
|
|||
fn consensus_error_into_serde<E: serde::de::Error>(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<E> DecodeError<E> where E: serde::de::Error {
|
||||
impl<E> DecodeError<E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
fn unify(self) -> E {
|
||||
match self {
|
||||
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 {
|
||||
match self {
|
||||
DecodeError::Other(error) => error.into_de_error(),
|
||||
|
@ -400,18 +421,13 @@ impl<E> IntoDeError for DecodeError<E> where E: IntoDeError {
|
|||
}
|
||||
}
|
||||
|
||||
struct IterReader<E: fmt::Debug, I: Iterator<Item=Result<u8, E>>> {
|
||||
struct IterReader<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> {
|
||||
iterator: core::iter::Fuse<I>,
|
||||
error: Option<E>,
|
||||
}
|
||||
|
||||
impl<E: fmt::Debug, I: Iterator<Item=Result<u8, E>>> IterReader<E, I> {
|
||||
fn new(iterator: I) -> Self {
|
||||
IterReader {
|
||||
iterator: iterator.fuse(),
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> IterReader<E, I> {
|
||||
fn new(iterator: I) -> Self { IterReader { iterator: iterator.fuse(), error: None } }
|
||||
|
||||
fn decode<T: Decodable>(mut self) -> Result<T, DecodeError<E>> {
|
||||
use crate::StdError;
|
||||
|
@ -431,7 +447,7 @@ impl<E: fmt::Debug, I: Iterator<Item=Result<u8, E>>> IterReader<E, I> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<E: fmt::Debug, I: Iterator<Item=Result<u8, E>>> io::Read for IterReader<E, I> {
|
||||
impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> io::Read for IterReader<E, I> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let mut count = 0;
|
||||
for (dst, src) in buf.iter_mut().zip(&mut self.iterator) {
|
||||
|
@ -469,30 +485,46 @@ pub struct With<E>(PhantomData<E>);
|
|||
|
||||
impl<E> With<E> {
|
||||
/// 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() {
|
||||
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::<T>(), 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),
|
||||
(Ok(_), Some(error)) =>
|
||||
panic!("{} silently ate an IO error: {:?}", core::any::type_name::<T>(), 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
|
||||
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() {
|
||||
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<u8, S::Error>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0.next_element::<u8>().transpose()
|
||||
}
|
||||
fn next(&mut self) -> Option<Self::Item> { self.0.next_element::<u8>().transpose() }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue