Support unsized `R` and `W` in consensus encode/decode

This commit is contained in:
Dawid Ciężarkiewicz 2022-06-28 18:22:12 -07:00
parent a24a3b0194
commit 1fea098dfb
20 changed files with 112 additions and 99 deletions

View File

@ -1091,14 +1091,14 @@ impl serde::Serialize for Script {
impl Encodable for Script {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
self.0.consensus_encode(w)
}
}
impl Decodable for Script {
#[inline]
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(Script(Decodable::consensus_decode_from_finite_reader(r)?))
}
}

View File

@ -652,13 +652,13 @@ impl Transaction {
impl_consensus_encoding!(TxOut, value, script_pubkey);
impl Encodable for OutPoint {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let len = self.txid.consensus_encode(w)?;
Ok(len + self.vout.consensus_encode(w)?)
}
}
impl Decodable for OutPoint {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(OutPoint {
txid: Decodable::consensus_decode(r)?,
vout: Decodable::consensus_decode(r)?,
@ -667,7 +667,7 @@ impl Decodable for OutPoint {
}
impl Encodable for TxIn {
fn consensus_encode<W: io::Write>(&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 += self.previous_output.consensus_encode(w)?;
len += self.script_sig.consensus_encode(w)?;
@ -677,7 +677,7 @@ impl Encodable for TxIn {
}
impl Decodable for TxIn {
#[inline]
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(TxIn {
previous_output: Decodable::consensus_decode_from_finite_reader(r)?,
script_sig: Decodable::consensus_decode_from_finite_reader(r)?,
@ -688,7 +688,7 @@ impl Decodable for TxIn {
}
impl Encodable for Transaction {
fn consensus_encode<W: io::Write>(&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 += self.version.consensus_encode(w)?;
// To avoid serialization ambiguity, no inputs means we use BIP141 serialization (see
@ -718,7 +718,7 @@ impl Encodable for Transaction {
}
impl Decodable for Transaction {
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let version = i32::consensus_decode_from_finite_reader(r)?;
let input = Vec::<TxIn>::consensus_decode_from_finite_reader(r)?;
// segwit
@ -953,6 +953,19 @@ mod tests {
use super::EcdsaSighashType;
use crate::util::sighash::SighashCache;
const SOME_TX: &str = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000";
#[test]
fn encode_to_unsized_writer() {
let mut buf = [0u8; 1024];
let raw_tx = Vec::from_hex(SOME_TX).unwrap();
let tx: Transaction = Decodable::consensus_decode(&mut raw_tx.as_slice()).unwrap();
let size = tx.consensus_encode(&mut &mut buf[..]).unwrap();
assert_eq!(size, SOME_TX.len() / 2);
assert_eq!(raw_tx, &buf[..size]);
}
#[test]
fn test_outpoint() {
assert_eq!(OutPoint::from_str("i don't care"),

View File

@ -49,7 +49,7 @@ pub struct Iter<'a> {
}
impl Decodable for Witness {
fn consensus_decode<R: Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
let witness_elements = VarInt::consensus_decode(r)?.0 as usize;
if witness_elements == 0 {
Ok(Witness::default())
@ -116,7 +116,7 @@ fn resize_if_needed(vec: &mut Vec<u8>, required_len: usize) {
}
impl Encodable for Witness {
fn consensus_encode<W: Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let len = VarInt(self.witness_elements as u64);
len.consensus_encode(w)?;
w.emit_slice(&self.content[..])?;

View File

@ -176,7 +176,7 @@ pub fn deserialize_partial<T: Decodable>(data: &[u8]) -> Result<(T, usize), Erro
/// Extensions of `Write` to encode data as per Bitcoin consensus
pub trait WriteExt {
pub trait WriteExt : io::Write {
/// Output a 64-bit uint
fn emit_u64(&mut self, v: u64) -> Result<(), io::Error>;
/// Output a 32-bit uint
@ -203,7 +203,7 @@ pub trait WriteExt {
}
/// Extensions of `Read` to decode data as per Bitcoin consensus
pub trait ReadExt {
pub trait ReadExt : io::Read {
/// Read a 64-bit uint
fn read_u64(&mut self) -> Result<u64, Error>;
/// Read a 32-bit uint
@ -250,7 +250,7 @@ macro_rules! decoder_fn {
}
}
impl<W: io::Write> WriteExt for W {
impl<W: io::Write + ?Sized> WriteExt for W {
encoder_fn!(emit_u64, u64, u64_to_array_le);
encoder_fn!(emit_u32, u32, u32_to_array_le);
encoder_fn!(emit_u16, u16, u16_to_array_le);
@ -276,7 +276,7 @@ impl<W: io::Write> WriteExt for W {
}
}
impl<R: Read> ReadExt for R {
impl<R: Read + ?Sized> ReadExt for R {
decoder_fn!(read_u64, u64, slice_to_u64_le, 8);
decoder_fn!(read_u32, u32, slice_to_u32_le, 4);
decoder_fn!(read_u16, u16, slice_to_u16_le, 2);
@ -315,7 +315,7 @@ pub trait Encodable {
/// Returns the number of bytes written on success.
///
/// The only errors returned are errors propagated from the writer.
fn consensus_encode<W: io::Write>(&self, writer: &mut W) -> Result<usize, io::Error>;
fn consensus_encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error>;
}
/// Data which can be encoded in a consensus-consistent way
@ -354,7 +354,7 @@ pub trait Decodable: Sized {
/// `consensus_decode_from_finite_reader` on all members, to 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>(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
@ -371,7 +371,7 @@ pub trait Decodable: Sized {
/// for types that override [`Self::consensus_decode_from_finite_reader`]
/// instead.
#[inline]
fn consensus_decode<R: io::Read>(reader: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
Self::consensus_decode_from_finite_reader(reader.take(MAX_VEC_SIZE as u64).by_ref())
}
}
@ -389,13 +389,13 @@ macro_rules! impl_int_encodable {
($ty:ident, $meth_dec:ident, $meth_enc:ident) => {
impl Decodable for $ty {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
ReadExt::$meth_dec(r)
}
}
impl Encodable for $ty {
#[inline]
fn consensus_encode<W: WriteExt>(&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>())
}
@ -430,7 +430,7 @@ impl VarInt {
impl Encodable for VarInt {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
match self.0 {
0..=0xFC => {
(self.0 as u8).consensus_encode(w)?;
@ -457,7 +457,7 @@ impl Encodable for VarInt {
impl Decodable for VarInt {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
let n = ReadExt::read_u8(r)?;
match n {
0xFF => {
@ -492,7 +492,7 @@ impl Decodable for VarInt {
// Booleans
impl Encodable for bool {
#[inline]
fn consensus_encode<W: WriteExt>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
w.emit_bool(*self)?;
Ok(1)
}
@ -500,7 +500,7 @@ impl Encodable for bool {
impl Decodable for bool {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<bool, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<bool, Error> {
ReadExt::read_bool(r)
}
}
@ -508,7 +508,7 @@ impl Decodable for bool {
// Strings
impl Encodable for String {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let b = self.as_bytes();
let vi_len = VarInt(b.len() as u64).consensus_encode(w)?;
w.emit_slice(b)?;
@ -518,7 +518,7 @@ impl Encodable for String {
impl Decodable for String {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<String, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<String, Error> {
String::from_utf8(Decodable::consensus_decode(r)?)
.map_err(|_| self::Error::ParseFailed("String was not valid UTF8"))
}
@ -527,7 +527,7 @@ impl Decodable for String {
// Cow<'static, str>
impl Encodable for Cow<'static, str> {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let b = self.as_bytes();
let vi_len = VarInt(b.len() as u64).consensus_encode(w)?;
w.emit_slice(b)?;
@ -537,7 +537,7 @@ impl Encodable for Cow<'static, str> {
impl Decodable for Cow<'static, str> {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Cow<'static, str>, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Cow<'static, str>, Error> {
String::from_utf8(Decodable::consensus_decode(r)?)
.map_err(|_| self::Error::ParseFailed("String was not valid UTF8"))
.map(Cow::Owned)
@ -550,7 +550,7 @@ macro_rules! impl_array {
( $size:expr ) => {
impl Encodable for [u8; $size] {
#[inline]
fn consensus_encode<W: WriteExt>(&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())
}
@ -558,7 +558,7 @@ macro_rules! impl_array {
impl Decodable for [u8; $size] {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
let mut ret = [0; $size];
r.read_slice(&mut ret)?;
Ok(ret)
@ -578,7 +578,7 @@ impl_array!(33);
impl Decodable for [u16; 8] {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
let mut res = [0; 8];
for item in &mut res {
*item = Decodable::consensus_decode(r)?;
@ -589,7 +589,7 @@ impl Decodable for [u16; 8] {
impl Encodable for [u16; 8] {
#[inline]
fn consensus_encode<W: io::Write>(&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)?; }
Ok(16)
}
@ -600,7 +600,7 @@ macro_rules! impl_vec {
($type: ty) => {
impl Encodable for Vec<$type> {
#[inline]
fn consensus_encode<W: io::Write>(&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() {
@ -612,7 +612,7 @@ macro_rules! impl_vec {
impl Decodable for Vec<$type> {
#[inline]
fn consensus_decode_from_finite_reader<R: io::Read>(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
@ -681,14 +681,14 @@ fn read_bytes_from_finite_reader<D: io::Read>(mut d: D, mut opts: ReadBytesFromF
impl Encodable for Vec<u8> {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
consensus_encode_with_size(self, w)
}
}
impl Decodable for Vec<u8> {
#[inline]
fn consensus_decode_from_finite_reader<R: io::Read>(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(r)?.0 as usize;
// most real-world vec of bytes data, wouldn't be larger than 128KiB
read_bytes_from_finite_reader(r, ReadBytesFromFiniteReaderOpts { len, chunk_size: 128 * 1024 })
@ -697,14 +697,14 @@ impl Decodable for Vec<u8> {
impl Encodable for Box<[u8]> {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
consensus_encode_with_size(self, w)
}
}
impl Decodable for Box<[u8]> {
#[inline]
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
<Vec<u8>>::consensus_decode_from_finite_reader(r).map(From::from)
}
}
@ -719,7 +719,7 @@ fn sha2_checksum(data: &[u8]) -> [u8; 4] {
// Checked data
impl Encodable for CheckedData {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
(self.0.len() as u32).consensus_encode(w)?;
sha2_checksum(&self.0).consensus_encode(w)?;
w.emit_slice(&self.0)?;
@ -729,7 +729,7 @@ impl Encodable for CheckedData {
impl Decodable for CheckedData {
#[inline]
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
let len = u32::consensus_decode_from_finite_reader(r)? as usize;
let checksum = <[u8; 4]>::consensus_decode_from_finite_reader(r)?;
@ -748,25 +748,25 @@ impl Decodable for CheckedData {
// References
impl<'a, T: Encodable> Encodable for &'a T {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
(&**self).consensus_encode(w)
}
}
impl<'a, T: Encodable> Encodable for &'a mut T {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
(&**self).consensus_encode(w)
}
}
impl<T: Encodable> Encodable for rc::Rc<T> {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
(&**self).consensus_encode(w)
}
}
impl<T: Encodable> Encodable for sync::Arc<T> {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
(&**self).consensus_encode(w)
}
}
@ -777,7 +777,7 @@ macro_rules! tuple_encode {
impl <$($x: Encodable),*> Encodable for ($($x),*) {
#[inline]
#[allow(non_snake_case)]
fn consensus_encode<W: io::Write>(
fn consensus_encode<W: io::Write + ?Sized>(
&self,
w: &mut W,
) -> Result<usize, io::Error> {
@ -791,7 +791,7 @@ macro_rules! tuple_encode {
impl<$($x: Decodable),*> Decodable for ($($x),*) {
#[inline]
#[allow(non_snake_case)]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
Ok(($({let $x = Decodable::consensus_decode(r)?; $x }),*))
}
}
@ -807,37 +807,37 @@ tuple_encode!(T0, T1, T2, T3, T4, T5, T6);
tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
impl Encodable for sha256d::Hash {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
self.into_inner().consensus_encode(w)
}
}
impl Decodable for sha256d::Hash {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
Ok(Self::from_inner(<<Self as Hash>::Inner>::consensus_decode(r)?))
}
}
impl Encodable for sha256::Hash {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
self.into_inner().consensus_encode(w)
}
}
impl Decodable for sha256::Hash {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
Ok(Self::from_inner(<<Self as Hash>::Inner>::consensus_decode(r)?))
}
}
impl Encodable for TapLeafHash {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
self.into_inner().consensus_encode(w)
}
}
impl Decodable for TapLeafHash {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
Ok(Self::from_inner(<<Self as Hash>::Inner>::consensus_decode(r)?))
}
}

View File

@ -25,13 +25,13 @@ use crate::hashes::{Hash, sha256, sha256d, hash160, hash_newtype};
macro_rules! impl_hashencode {
($hashtype:ident) => {
impl $crate::consensus::Encodable for $hashtype {
fn consensus_encode<W: $crate::io::Write>(&self, w: &mut W) -> Result<usize, $crate::io::Error> {
fn consensus_encode<W: $crate::io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, $crate::io::Error> {
self.0.consensus_encode(w)
}
}
impl $crate::consensus::Decodable for $hashtype {
fn consensus_decode<R: $crate::io::Read>(r: &mut R) -> Result<Self, $crate::consensus::encode::Error> {
fn consensus_decode<R: $crate::io::Read + ?Sized>(r: &mut R) -> Result<Self, $crate::consensus::encode::Error> {
use $crate::hashes::Hash;
Ok(Self::from_inner(<<$hashtype as $crate::hashes::Hash>::Inner>::consensus_decode(r)?))
}

View File

@ -21,7 +21,7 @@ macro_rules! impl_consensus_encoding {
($thing:ident, $($field:ident),+) => (
impl $crate::consensus::Encodable for $thing {
#[inline]
fn consensus_encode<R: $crate::io::Write>(
fn consensus_encode<R: $crate::io::Write + ?Sized>(
&self,
r: &mut R,
) -> Result<usize, $crate::io::Error> {
@ -34,7 +34,7 @@ macro_rules! impl_consensus_encoding {
impl $crate::consensus::Decodable for $thing {
#[inline]
fn consensus_decode_from_finite_reader<R: $crate::io::Read>(
fn consensus_decode_from_finite_reader<R: $crate::io::Read + ?Sized>(
r: &mut R,
) -> Result<$thing, $crate::consensus::encode::Error> {
Ok($thing {
@ -43,7 +43,7 @@ macro_rules! impl_consensus_encoding {
}
#[inline]
fn consensus_decode<R: $crate::io::Read>(
fn consensus_decode<R: $crate::io::Read + ?Sized>(
r: &mut R,
) -> Result<$thing, $crate::consensus::encode::Error> {
use crate::io::Read as _;

View File

@ -69,7 +69,7 @@ impl Address {
impl Encodable for Address {
#[inline]
fn consensus_encode<W: io::Write>(&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 = self.services.consensus_encode(w)?;
for word in &self.address {
@ -86,7 +86,7 @@ impl Encodable for Address {
impl Decodable for Address {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(Address {
services: Decodable::consensus_decode(r)?,
address: read_be_address(r)?,
@ -96,7 +96,7 @@ impl Decodable for Address {
}
/// Read a big-endian address from reader.
fn read_be_address<R: io::Read>(r: &mut R) -> Result<[u16; 8], encode::Error> {
fn read_be_address<R: io::Read + ?Sized>(r: &mut R) -> Result<[u16; 8], encode::Error> {
let mut address = [0u16; 8];
let mut buf = [0u8; 2];
@ -147,8 +147,8 @@ pub enum AddrV2 {
}
impl Encodable for AddrV2 {
fn consensus_encode<W: io::Write>(&self, e: &mut W) -> Result<usize, io::Error> {
fn encode_addr<W: io::Write>(w: &mut W, network: u8, bytes: &[u8]) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, e: &mut W) -> Result<usize, io::Error> {
fn encode_addr<W: io::Write + ?Sized>(w: &mut W, network: u8, bytes: &[u8]) -> Result<usize, io::Error> {
let len = network.consensus_encode(w)?
+ VarInt(bytes.len() as u64).consensus_encode(w)?
+ bytes.len();
@ -168,7 +168,7 @@ impl Encodable for AddrV2 {
}
impl Decodable for AddrV2 {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let network_id = u8::consensus_decode(r)?;
let len = VarInt::consensus_decode(r)?.0;
if len > 512 {
@ -264,7 +264,7 @@ impl AddrV2Message {
}
impl Encodable for AddrV2Message {
fn consensus_encode<W: io::Write>(&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 += self.time.consensus_encode(w)?;
len += VarInt(self.services.to_u64()).consensus_encode(w)?;
@ -278,7 +278,7 @@ impl Encodable for AddrV2Message {
}
impl Decodable for AddrV2Message {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(AddrV2Message {
time: Decodable::consensus_decode(r)?,
services: ServiceFlags::from(VarInt::consensus_decode(r)?.0),

View File

@ -280,14 +280,14 @@ impl ops::BitXorAssign for ServiceFlags {
impl Encodable for ServiceFlags {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
self.0.consensus_encode(w)
}
}
impl Decodable for ServiceFlags {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(ServiceFlags(Decodable::consensus_decode(r)?))
}
}

View File

@ -80,7 +80,7 @@ impl AsRef<str> for CommandString {
impl Encodable for CommandString {
#[inline]
fn consensus_encode<W: io::Write>(&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 rawbytes = [0u8; 12];
let strbytes = self.0.as_bytes();
debug_assert!(strbytes.len() <= 12);
@ -91,7 +91,7 @@ impl Encodable for CommandString {
impl Decodable for CommandString {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let rawbytes: [u8; 12] = Decodable::consensus_decode(r)?;
let rv = iter::FromIterator::from_iter(
rawbytes
@ -287,7 +287,7 @@ struct HeaderSerializationWrapper<'a>(&'a Vec<block::BlockHeader>);
impl<'a> Encodable for HeaderSerializationWrapper<'a> {
#[inline]
fn consensus_encode<W: io::Write>(&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.0.len() as u64).consensus_encode(w)?;
for header in self.0.iter() {
@ -299,7 +299,7 @@ impl<'a> Encodable for HeaderSerializationWrapper<'a> {
}
impl Encodable for RawNetworkMessage {
fn consensus_encode<W: io::Write>(&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 += self.magic.consensus_encode(w)?;
len += self.command().consensus_encode(w)?;
@ -346,7 +346,7 @@ struct HeaderDeserializationWrapper(Vec<block::BlockHeader>);
impl Decodable for HeaderDeserializationWrapper {
#[inline]
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let len = VarInt::consensus_decode(r)?.0;
// should be above usual number of items to avoid
// allocation
@ -361,13 +361,13 @@ impl Decodable for HeaderDeserializationWrapper {
}
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Self::consensus_decode_from_finite_reader(r.take(MAX_MSG_SIZE as u64).by_ref())
}
}
impl Decodable for RawNetworkMessage {
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let magic = Decodable::consensus_decode_from_finite_reader(r)?;
let cmd = CommandString::consensus_decode_from_finite_reader(r)?;
let raw_payload = CheckedData::consensus_decode_from_finite_reader(r)?.0;
@ -420,7 +420,7 @@ impl Decodable for RawNetworkMessage {
}
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Self::consensus_decode_from_finite_reader(r.take(MAX_MSG_SIZE as u64).by_ref())
}
}

View File

@ -54,7 +54,7 @@ pub enum Inventory {
impl Encodable for Inventory {
#[inline]
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
macro_rules! encode_inv {
($code:expr, $item:expr) => {
u32::consensus_encode(&$code, w)? + $item.consensus_encode(w)?
@ -74,7 +74,7 @@ impl Encodable for Inventory {
impl Decodable for Inventory {
#[inline]
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let inv_type: u32 = Decodable::consensus_decode(r)?;
Ok(match inv_type {
0 => Inventory::Error,

View File

@ -34,7 +34,7 @@ pub enum BloomFlags {
}
impl Encodable for BloomFlags {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
w.write_all(&[match self {
BloomFlags::None => 0,
BloomFlags::All => 1,
@ -45,7 +45,7 @@ impl Encodable for BloomFlags {
}
impl Decodable for BloomFlags {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(match r.read_u8()? {
0 => BloomFlags::None,
1 => BloomFlags::All,

View File

@ -106,14 +106,14 @@ pub enum RejectReason {
}
impl Encodable for RejectReason {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
w.write_all(&[*self as u8])?;
Ok(1)
}
}
impl Decodable for RejectReason {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(match r.read_u8()? {
0x01 => RejectReason::Malformed,
0x10 => RejectReason::Invalid,

View File

@ -355,7 +355,7 @@ impl PartialMerkleTree {
}
impl Encodable for PartialMerkleTree {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let ret = self.num_transactions.consensus_encode(w)?
+ self.hashes.consensus_encode(w)?;
let mut bytes: Vec<u8> = vec![0; (self.bits.len() + 7) / 8];
@ -367,7 +367,7 @@ impl Encodable for PartialMerkleTree {
}
impl Decodable for PartialMerkleTree {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let num_transactions: u32 = Decodable::consensus_decode(r)?;
let hashes: Vec<TxMerkleNode> = Decodable::consensus_decode(r)?;
@ -506,7 +506,7 @@ impl MerkleBlock {
}
impl Encodable for MerkleBlock {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let len = self.header.consensus_encode(w)?
+ self.txn.consensus_encode(w)?;
Ok(len)
@ -514,7 +514,7 @@ impl Encodable for MerkleBlock {
}
impl Decodable for MerkleBlock {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(MerkleBlock {
header: Decodable::consensus_decode(r)?,
txn: Decodable::consensus_decode(r)?,

View File

@ -55,7 +55,7 @@ macro_rules! impl_psbt_serialize {
macro_rules! impl_psbtmap_consensus_encoding {
($thing:ty) => {
impl $crate::consensus::Encodable for $thing {
fn consensus_encode<W: $crate::io::Write>(
fn consensus_encode<W: $crate::io::Write + ?Sized>(
&self,
w: &mut W,
) -> Result<usize, $crate::io::Error> {
@ -68,7 +68,7 @@ macro_rules! impl_psbtmap_consensus_encoding {
macro_rules! impl_psbtmap_consensus_decoding {
($thing:ty) => {
impl $crate::consensus::Decodable for $thing {
fn consensus_decode<R: $crate::io::Read>(
fn consensus_decode<R: $crate::io::Read + ?Sized>(
r: &mut R,
) -> Result<Self, $crate::consensus::encode::Error> {
let mut rv: Self = ::core::default::Default::default();

View File

@ -100,7 +100,7 @@ impl Map for PartiallySignedTransaction {
}
impl PartiallySignedTransaction {
pub(crate) fn consensus_decode_global<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
pub(crate) fn consensus_decode_global<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let mut r = r.take(MAX_VEC_SIZE as u64);
let mut tx: Option<Transaction> = None;
let mut version: Option<u32> = None;

View File

@ -32,7 +32,7 @@ pub(super) trait Map {
fn get_pairs(&self) -> Result<Vec<raw::Pair>, io::Error>;
/// Encodes map data with bitcoin consensus encoding.
fn consensus_encode_map<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode_map<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let mut len = 0;
for pair in Map::get_pairs(self)? {
len += encode::Encodable::consensus_encode(&pair, w)?;

View File

@ -277,7 +277,7 @@ mod display_from_str {
pub use self::display_from_str::PsbtParseError;
impl Encodable for PartiallySignedTransaction {
fn consensus_encode<W: io::Write>(&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 += b"psbt".consensus_encode(w)?;
@ -298,7 +298,7 @@ impl Encodable for PartiallySignedTransaction {
}
impl Decodable for PartiallySignedTransaction {
fn consensus_decode_from_finite_reader<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let magic: [u8; 4] = Decodable::consensus_decode(r)?;
if *b"psbt" != magic {

View File

@ -79,7 +79,7 @@ impl fmt::Display for Key {
}
impl Decodable for Key {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?;
if byte_size == 0 {
@ -107,7 +107,7 @@ impl Decodable for Key {
}
impl Encodable for Key {
fn consensus_encode<W: io::Write>(&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.key.len() + 1) as u64).consensus_encode(w)?;
@ -122,14 +122,14 @@ impl Encodable for Key {
}
impl Encodable for Pair {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let len = self.key.consensus_encode(w)?;
Ok(len + self.value.consensus_encode(w)?)
}
}
impl Decodable for Pair {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
Ok(Pair {
key: Decodable::consensus_decode(r)?,
value: Decodable::consensus_decode(r)?,
@ -138,7 +138,7 @@ impl Decodable for Pair {
}
impl<Subtype> Encodable for ProprietaryKey<Subtype> where Subtype: Copy + From<u8> + Into<u8> {
fn consensus_encode<W: io::Write>(&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 = self.prefix.consensus_encode(w)? + 1;
w.emit_u8(self.subtype.into())?;
w.write_all(&self.key)?;
@ -148,7 +148,7 @@ impl<Subtype> Encodable for ProprietaryKey<Subtype> where Subtype: Copy + From<u
}
impl<Subtype> Decodable for ProprietaryKey<Subtype> where Subtype: Copy + From<u8> + Into<u8> {
fn consensus_decode<R: io::Read>(r: &mut R) -> Result<Self, encode::Error> {
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
let prefix = Vec::<u8>::consensus_decode(r)?;
let subtype = Subtype::from(r.read_u8()?);
let key = read_to_end(r)?;

View File

@ -794,7 +794,7 @@ impl<'a> Annex<'a> {
}
impl<'a> Encodable for Annex<'a> {
fn consensus_encode<W: io::Write>(&self, w: &mut W) -> Result<usize, io::Error> {
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
encode::consensus_encode_with_size(self.0, w)
}
}

View File

@ -419,7 +419,7 @@ macro_rules! construct_uint {
impl $crate::consensus::Encodable for $name {
#[inline]
fn consensus_encode<W: $crate::io::Write>(
fn consensus_encode<W: $crate::io::Write + ?Sized>(
&self,
w: &mut W,
) -> Result<usize, $crate::io::Error> {
@ -433,7 +433,7 @@ macro_rules! construct_uint {
}
impl $crate::consensus::Decodable for $name {
fn consensus_decode<R: $crate::io::Read>(
fn consensus_decode<R: $crate::io::Read + ?Sized>(
r: &mut R,
) -> Result<$name, $crate::consensus::encode::Error> {
use $crate::consensus::Decodable;