diff --git a/bitcoin/src/bip152.rs b/bitcoin/src/bip152.rs index b9da6710..61752610 100644 --- a/bitcoin/src/bip152.rs +++ b/bitcoin/src/bip152.rs @@ -12,7 +12,7 @@ use std::error; use hashes::{sha256, siphash24, Hash}; use internals::impl_array_newtype; -use io::{Read, Write}; +use io::{BufRead, Write}; use crate::consensus::encode::{self, Decodable, Encodable, VarInt}; use crate::internal_macros::{impl_bytes_newtype, impl_consensus_encoding}; @@ -81,7 +81,7 @@ impl Encodable for PrefilledTransaction { impl Decodable for PrefilledTransaction { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let idx = VarInt::consensus_decode(r)?.0; let idx = u16::try_from(idx) .map_err(|_| encode::Error::ParseFailed("BIP152 prefilled tx index out of bounds"))?; @@ -137,7 +137,7 @@ impl Encodable for ShortId { impl Decodable for ShortId { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(ShortId(Decodable::consensus_decode(r)?)) } } @@ -273,7 +273,7 @@ impl Encodable for BlockTransactionsRequest { } impl Decodable for BlockTransactionsRequest { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(BlockTransactionsRequest { block_hash: BlockHash::consensus_decode(r)?, indexes: { diff --git a/bitcoin/src/bip158.rs b/bitcoin/src/bip158.rs index 57b2f4d3..98cbc99e 100644 --- a/bitcoin/src/bip158.rs +++ b/bitcoin/src/bip158.rs @@ -43,7 +43,7 @@ use core::fmt::{self, Display, Formatter}; use hashes::{sha256d, siphash24, Hash}; use internals::write_err; -use io::{Read, Write}; +use io::{BufRead, Write}; use crate::blockdata::block::{Block, BlockHash}; use crate::blockdata::script::Script; @@ -245,7 +245,7 @@ impl BlockFilterReader { where I: Iterator, I::Item: Borrow<[u8]>, - R: Read + ?Sized, + R: BufRead + ?Sized, { self.reader.match_any(reader, query) } @@ -255,7 +255,7 @@ impl BlockFilterReader { where I: Iterator, I::Item: Borrow<[u8]>, - R: Read + ?Sized, + R: BufRead + ?Sized, { self.reader.match_all(reader, query) } @@ -278,7 +278,7 @@ impl GcsFilterReader { where I: Iterator, I::Item: Borrow<[u8]>, - R: Read + ?Sized, + R: BufRead + ?Sized, { let n_elements: VarInt = Decodable::consensus_decode(reader).unwrap_or(VarInt(0)); // map hashes to [0, n_elements << grp] @@ -321,7 +321,7 @@ impl GcsFilterReader { where I: Iterator, I::Item: Borrow<[u8]>, - R: Read + ?Sized, + R: BufRead + ?Sized, { let n_elements: VarInt = Decodable::consensus_decode(reader).unwrap_or(VarInt(0)); // map hashes to [0, n_elements << grp] @@ -447,7 +447,7 @@ impl GcsFilter { /// Golomb-Rice decodes a number from a bit stream (parameter 2^k). fn golomb_rice_decode(&self, reader: &mut BitStreamReader) -> Result where - R: Read + ?Sized, + R: BufRead + ?Sized, { let mut q = 0u64; while reader.read(1)? == 1 { @@ -470,7 +470,7 @@ pub struct BitStreamReader<'a, R: ?Sized> { reader: &'a mut R, } -impl<'a, R: Read + ?Sized> BitStreamReader<'a, R> { +impl<'a, R: BufRead + ?Sized> BitStreamReader<'a, R> { /// Creates a new [`BitStreamReader`] that reads bitwise from a given `reader`. pub fn new(reader: &'a mut R) -> BitStreamReader<'a, R> { BitStreamReader { buffer: [0u8], reader, offset: 8 } diff --git a/bitcoin/src/blockdata/block.rs b/bitcoin/src/blockdata/block.rs index e66d5f22..b8e7f5a8 100644 --- a/bitcoin/src/blockdata/block.rs +++ b/bitcoin/src/blockdata/block.rs @@ -11,7 +11,7 @@ use core::fmt; use hashes::{sha256d, Hash, HashEngine}; -use io::{Read, Write}; +use io::{BufRead, Write}; use super::Weight; use crate::blockdata::script; @@ -207,7 +207,7 @@ impl Encodable for Version { } impl Decodable for Version { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Decodable::consensus_decode(r).map(Version) } } diff --git a/bitcoin/src/blockdata/locktime/absolute.rs b/bitcoin/src/blockdata/locktime/absolute.rs index 4099c2b9..efeaa428 100644 --- a/bitcoin/src/blockdata/locktime/absolute.rs +++ b/bitcoin/src/blockdata/locktime/absolute.rs @@ -10,7 +10,7 @@ use core::cmp::{Ordering, PartialOrd}; use core::{fmt, mem}; use internals::write_err; -use io::{Read, Write}; +use io::{BufRead, Write}; #[cfg(all(test, mutate))] use mutagen::mutate; @@ -345,7 +345,7 @@ impl Encodable for LockTime { impl Decodable for LockTime { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { u32::consensus_decode(r).map(LockTime::from_consensus) } } diff --git a/bitcoin/src/blockdata/script/mod.rs b/bitcoin/src/blockdata/script/mod.rs index c48e9a57..d79a58fd 100644 --- a/bitcoin/src/blockdata/script/mod.rs +++ b/bitcoin/src/blockdata/script/mod.rs @@ -66,7 +66,7 @@ use core::fmt; use core::ops::{Deref, DerefMut}; use hashes::{hash160, sha256}; -use io::{Read, Write}; +use io::{BufRead, Write}; #[cfg(feature = "serde")] use serde; @@ -594,7 +594,7 @@ impl Encodable for ScriptBuf { impl Decodable for ScriptBuf { #[inline] - fn consensus_decode_from_finite_reader( + fn consensus_decode_from_finite_reader( r: &mut R, ) -> Result { Ok(ScriptBuf(Decodable::consensus_decode_from_finite_reader(r)?)) diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs index 44b3f32f..d956108b 100644 --- a/bitcoin/src/blockdata/transaction.rs +++ b/bitcoin/src/blockdata/transaction.rs @@ -16,7 +16,7 @@ use core::{cmp, fmt, str}; use hashes::{self, sha256d, Hash}; use internals::write_err; -use io::{Read, Write}; +use io::{BufRead, Write}; use super::Weight; use crate::blockdata::fee_rate::FeeRate; @@ -1025,7 +1025,7 @@ impl Encodable for Version { } impl Decodable for Version { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Decodable::consensus_decode(r).map(Version) } } @@ -1039,7 +1039,7 @@ impl Encodable for OutPoint { } } impl Decodable for OutPoint { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(OutPoint { txid: Decodable::consensus_decode(r)?, vout: Decodable::consensus_decode(r)?, @@ -1058,7 +1058,7 @@ impl Encodable for TxIn { } impl Decodable for TxIn { #[inline] - fn consensus_decode_from_finite_reader( + fn consensus_decode_from_finite_reader( r: &mut R, ) -> Result { Ok(TxIn { @@ -1077,7 +1077,7 @@ impl Encodable for Sequence { } impl Decodable for Sequence { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Decodable::consensus_decode(r).map(Sequence) } } @@ -1107,7 +1107,7 @@ impl Encodable for Transaction { } impl Decodable for Transaction { - fn consensus_decode_from_finite_reader( + fn consensus_decode_from_finite_reader( r: &mut R, ) -> Result { let version = Version::consensus_decode_from_finite_reader(r)?; diff --git a/bitcoin/src/blockdata/witness.rs b/bitcoin/src/blockdata/witness.rs index b7011638..777452c9 100644 --- a/bitcoin/src/blockdata/witness.rs +++ b/bitcoin/src/blockdata/witness.rs @@ -8,7 +8,7 @@ use core::fmt; use core::ops::Index; -use io::{Read, Write}; +use io::{BufRead, Write}; use crate::consensus::encode::{Error, MAX_VEC_SIZE}; use crate::consensus::{Decodable, Encodable, WriteExt}; @@ -124,7 +124,7 @@ pub struct Iter<'a> { } impl Decodable for Witness { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let witness_elements = VarInt::consensus_decode(r)?.0 as usize; // Minimum size of witness element is 1 byte, so if the count is // greater than MAX_VEC_SIZE we must return an error. diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index 0e3e43d8..6017300c 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -20,7 +20,7 @@ use core::{fmt, mem, u32}; use hashes::{sha256, sha256d, Hash}; use internals::write_err; -use io::{Cursor, Read, Write}; +use io::{Cursor, BufRead, Read, Write}; use crate::bip152::{PrefilledTransaction, ShortId}; use crate::bip158::{FilterHash, FilterHeader}; @@ -301,7 +301,7 @@ 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( + fn consensus_decode_from_finite_reader( reader: &mut R, ) -> Result { // This method is always strictly less general than, `consensus_decode`, so it's safe and @@ -319,7 +319,7 @@ pub trait Decodable: Sized { /// for types that override [`Self::consensus_decode_from_finite_reader`] /// instead. #[inline] - fn consensus_decode(reader: &mut R) -> Result { + fn consensus_decode(reader: &mut R) -> Result { Self::consensus_decode_from_finite_reader(&mut reader.take(MAX_VEC_SIZE as u64)) } } @@ -357,7 +357,7 @@ macro_rules! impl_int_encodable { ($ty:ident, $meth_dec:ident, $meth_enc:ident) => { impl Decodable for $ty { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { ReadExt::$meth_dec(r) } } @@ -440,7 +440,7 @@ impl Encodable for VarInt { impl Decodable for VarInt { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let n = ReadExt::read_u8(r)?; match n { 0xFF => { @@ -482,7 +482,7 @@ impl Encodable for bool { impl Decodable for bool { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { ReadExt::read_bool(r) } } @@ -499,7 +499,7 @@ impl Encodable for String { impl Decodable for String { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { String::from_utf8(Decodable::consensus_decode(r)?) .map_err(|_| self::Error::ParseFailed("String was not valid UTF8")) } @@ -517,7 +517,7 @@ impl Encodable for Cow<'static, str> { impl Decodable for Cow<'static, str> { #[inline] - fn consensus_decode(r: &mut R) -> Result, Error> { + fn consensus_decode(r: &mut R) -> Result, Error> { String::from_utf8(Decodable::consensus_decode(r)?) .map_err(|_| self::Error::ParseFailed("String was not valid UTF8")) .map(Cow::Owned) @@ -539,7 +539,7 @@ macro_rules! impl_array { impl Decodable for [u8; $size] { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let mut ret = [0; $size]; r.read_slice(&mut ret)?; Ok(ret) @@ -560,7 +560,7 @@ impl_array!(33); impl Decodable for [u16; 8] { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let mut res = [0; 8]; for item in &mut res { *item = Decodable::consensus_decode(r)?; @@ -595,7 +595,7 @@ macro_rules! impl_vec { impl Decodable for Vec<$type> { #[inline] - fn consensus_decode_from_finite_reader( + fn consensus_decode_from_finite_reader( r: &mut R, ) -> Result { let len = VarInt::consensus_decode_from_finite_reader(r)?.0; @@ -685,7 +685,7 @@ impl Encodable for Vec { impl Decodable for Vec { #[inline] - fn consensus_decode_from_finite_reader(r: &mut R) -> Result { + fn consensus_decode_from_finite_reader(r: &mut R) -> Result { let len = VarInt::consensus_decode(r)?.0 as usize; // most real-world vec of bytes data, wouldn't be larger than 128KiB let opts = ReadBytesFromFiniteReaderOpts { len, chunk_size: 128 * 1024 }; @@ -702,7 +702,7 @@ impl Encodable for Box<[u8]> { impl Decodable for Box<[u8]> { #[inline] - fn consensus_decode_from_finite_reader(r: &mut R) -> Result { + fn consensus_decode_from_finite_reader(r: &mut R) -> Result { >::consensus_decode_from_finite_reader(r).map(From::from) } } @@ -727,7 +727,7 @@ impl Encodable for CheckedData { impl Decodable for CheckedData { #[inline] - fn consensus_decode_from_finite_reader(r: &mut R) -> Result { + fn consensus_decode_from_finite_reader(r: &mut R) -> Result { let len = u32::consensus_decode_from_finite_reader(r)? as usize; let checksum = <[u8; 4]>::consensus_decode_from_finite_reader(r)?; @@ -787,7 +787,7 @@ macro_rules! tuple_encode { impl<$($x: Decodable),*> Decodable for ($($x),*) { #[inline] #[allow(non_snake_case)] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(($({let $x = Decodable::consensus_decode(r)?; $x }),*)) } } @@ -809,7 +809,7 @@ impl Encodable for sha256d::Hash { } impl Decodable for sha256d::Hash { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(Self::from_byte_array(<::Bytes>::consensus_decode(r)?)) } } @@ -821,7 +821,7 @@ impl Encodable for sha256::Hash { } impl Decodable for sha256::Hash { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(Self::from_byte_array(<::Bytes>::consensus_decode(r)?)) } } @@ -833,7 +833,7 @@ impl Encodable for TapLeafHash { } impl Decodable for TapLeafHash { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(Self::from_byte_array(<::Bytes>::consensus_decode(r)?)) } } diff --git a/bitcoin/src/consensus/serde.rs b/bitcoin/src/consensus/serde.rs index 7f94341b..9a8d66cc 100644 --- a/bitcoin/src/consensus/serde.rs +++ b/bitcoin/src/consensus/serde.rs @@ -12,7 +12,7 @@ use core::fmt; use core::marker::PhantomData; -use io::{Read, Write}; +use io::{BufRead, Read, Write}; use serde::de::{SeqAccess, Unexpected, Visitor}; use serde::ser::SerializeSeq; use serde::{Deserializer, Serializer}; @@ -420,11 +420,12 @@ where struct IterReader>> { iterator: core::iter::Fuse, + buf: Option, error: Option, } impl>> IterReader { - fn new(iterator: I) -> Self { IterReader { iterator: iterator.fuse(), error: None } } + fn new(iterator: I) -> Self { IterReader { iterator: iterator.fuse(), buf: None, error: None } } fn decode(mut self) -> Result> { let result = T::consensus_decode(&mut self); @@ -443,8 +444,17 @@ impl>> IterReader { } impl>> Read for IterReader { - fn read(&mut self, buf: &mut [u8]) -> io::Result { + fn read(&mut self, mut buf: &mut [u8]) -> io::Result { let mut count = 0; + if buf.is_empty() { + return Ok(0); + } + + if let Some(first) = self.buf.take() { + buf[0] = first; + buf = &mut buf[1..]; + count += 1; + } for (dst, src) in buf.iter_mut().zip(&mut self.iterator) { match src { Ok(byte) => *dst = byte, @@ -460,6 +470,34 @@ impl>> Read for IterReader } } +impl>> BufRead for IterReader { + fn fill_buf(&mut self) -> Result<&[u8], io::Error> { + // matching on reference rather than using `ref` confuses borrow checker + if let Some(ref byte) = self.buf { + Ok(core::slice::from_ref(byte)) + } else { + match self.iterator.next() { + Some(Ok(byte)) => { + self.buf = Some(byte); + Ok(core::slice::from_ref(self.buf.as_ref().expect("we've just filled it"))) + }, + Some(Err(error)) => { + self.error = Some(error); + Err(io::ErrorKind::Other.into()) + }, + None => Ok(&[]), + } + } + } + + fn consume(&mut self, len: usize) { + debug_assert!(len <= 1); + if len > 0 { + self.buf = None; + } + } +} + /// Helper for `#[serde(with = "")]`. /// /// To (de)serialize a field using consensus encoding you can write e.g.: diff --git a/bitcoin/src/internal_macros.rs b/bitcoin/src/internal_macros.rs index 669c3ff6..62b67aa3 100644 --- a/bitcoin/src/internal_macros.rs +++ b/bitcoin/src/internal_macros.rs @@ -22,7 +22,7 @@ macro_rules! impl_consensus_encoding { impl $crate::consensus::Decodable for $thing { #[inline] - fn consensus_decode_from_finite_reader( + fn consensus_decode_from_finite_reader( r: &mut R, ) -> Result<$thing, $crate::consensus::encode::Error> { Ok($thing { @@ -31,7 +31,7 @@ macro_rules! impl_consensus_encoding { } #[inline] - fn consensus_decode( + fn consensus_decode( r: &mut R, ) -> Result<$thing, $crate::consensus::encode::Error> { let mut r = r.take($crate::consensus::encode::MAX_VEC_SIZE as u64); @@ -202,7 +202,7 @@ macro_rules! impl_hashencode { } impl $crate::consensus::Decodable for $hashtype { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { use $crate::hashes::Hash; Ok(Self::from_byte_array(<<$hashtype as $crate::hashes::Hash>::Bytes>::consensus_decode(r)?)) } diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index 0ebbe5a2..7411bc53 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -165,7 +165,7 @@ pub mod amount { //! We refer to the documentation on the types for more information. use crate::consensus::{encode, Decodable, Encodable}; - use crate::io; + use crate::io::{BufRead, Write}; #[rustfmt::skip] // Keep public re-exports separate. #[doc(inline)] @@ -177,14 +177,14 @@ pub mod amount { impl Decodable for Amount { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(Amount::from_sat(Decodable::consensus_decode(r)?)) } } impl Encodable for Amount { #[inline] - fn consensus_encode(&self, w: &mut W) -> Result { + fn consensus_encode(&self, w: &mut W) -> Result { self.to_sat().consensus_encode(w) } } diff --git a/bitcoin/src/merkle_tree/block.rs b/bitcoin/src/merkle_tree/block.rs index 3194454a..402ffaab 100644 --- a/bitcoin/src/merkle_tree/block.rs +++ b/bitcoin/src/merkle_tree/block.rs @@ -41,7 +41,7 @@ use core::fmt; use hashes::Hash; -use io::{Read, Write}; +use io::{BufRead, Write}; use self::MerkleBlockError::*; use crate::blockdata::block::{self, Block, TxMerkleNode}; @@ -151,7 +151,7 @@ impl Encodable for MerkleBlock { } impl Decodable for MerkleBlock { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(MerkleBlock { header: Decodable::consensus_decode(r)?, txn: Decodable::consensus_decode(r)?, @@ -452,7 +452,7 @@ impl Encodable for PartialMerkleTree { } impl Decodable for PartialMerkleTree { - fn consensus_decode_from_finite_reader( + fn consensus_decode_from_finite_reader( r: &mut R, ) -> Result { let num_transactions: u32 = Decodable::consensus_decode(r)?; diff --git a/bitcoin/src/p2p/address.rs b/bitcoin/src/p2p/address.rs index 014cadd4..e1a69d61 100644 --- a/bitcoin/src/p2p/address.rs +++ b/bitcoin/src/p2p/address.rs @@ -9,7 +9,7 @@ use core::{fmt, iter}; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; -use io::{Read, Write}; +use io::{BufRead, Read, Write}; use crate::consensus::encode::{self, Decodable, Encodable, ReadExt, VarInt, WriteExt}; use crate::p2p::ServiceFlags; @@ -75,7 +75,7 @@ impl Encodable for Address { impl Decodable for Address { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(Address { services: Decodable::consensus_decode(r)?, address: read_be_address(r)?, @@ -167,7 +167,7 @@ impl Encodable for AddrV2 { } impl Decodable for AddrV2 { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let network_id = u8::consensus_decode(r)?; let len = VarInt::consensus_decode(r)?.0; if len > 512 { @@ -285,7 +285,7 @@ impl Encodable for AddrV2Message { } impl Decodable for AddrV2Message { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(AddrV2Message { time: Decodable::consensus_decode(r)?, services: ServiceFlags::from(VarInt::consensus_decode(r)?.0), diff --git a/bitcoin/src/p2p/message.rs b/bitcoin/src/p2p/message.rs index 2c8dc699..a4343d1f 100644 --- a/bitcoin/src/p2p/message.rs +++ b/bitcoin/src/p2p/message.rs @@ -9,7 +9,7 @@ use core::{fmt, iter}; use hashes::{sha256d, Hash}; -use io::{Read, Write}; +use io::{BufRead, Write}; use crate::blockdata::{block, transaction}; use crate::consensus::encode::{self, CheckedData, Decodable, Encodable, VarInt}; @@ -110,7 +110,7 @@ impl Encodable for CommandString { impl Decodable for CommandString { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let rawbytes: [u8; 12] = Decodable::consensus_decode(r)?; let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| { if u > 0 { @@ -407,7 +407,7 @@ struct HeaderDeserializationWrapper(Vec); impl Decodable for HeaderDeserializationWrapper { #[inline] - fn consensus_decode_from_finite_reader( + fn consensus_decode_from_finite_reader( r: &mut R, ) -> Result { let len = VarInt::consensus_decode(r)?.0; @@ -426,13 +426,13 @@ impl Decodable for HeaderDeserializationWrapper { } #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Self::consensus_decode_from_finite_reader(&mut r.take(MAX_MSG_SIZE as u64)) } } impl Decodable for RawNetworkMessage { - fn consensus_decode_from_finite_reader( + fn consensus_decode_from_finite_reader( r: &mut R, ) -> Result { let magic = Decodable::consensus_decode_from_finite_reader(r)?; @@ -442,7 +442,7 @@ impl Decodable for RawNetworkMessage { let raw_payload = checked_data.into_data(); let payload_len = raw_payload.len() as u32; - let mut mem_d = io::Cursor::new(raw_payload); + let mut mem_d = raw_payload.as_slice(); let payload = match &cmd.0[..] { "version" => NetworkMessage::Version(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), @@ -525,13 +525,13 @@ impl Decodable for RawNetworkMessage { "addrv2" => NetworkMessage::AddrV2(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?), "sendaddrv2" => NetworkMessage::SendAddrV2, - _ => NetworkMessage::Unknown { command: cmd, payload: mem_d.into_inner() }, + _ => NetworkMessage::Unknown { command: cmd, payload: raw_payload }, }; Ok(RawNetworkMessage { magic, payload, payload_len, checksum }) } #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Self::consensus_decode_from_finite_reader(&mut r.take(MAX_MSG_SIZE as u64)) } } diff --git a/bitcoin/src/p2p/message_blockdata.rs b/bitcoin/src/p2p/message_blockdata.rs index 550029d1..f1a142d5 100644 --- a/bitcoin/src/p2p/message_blockdata.rs +++ b/bitcoin/src/p2p/message_blockdata.rs @@ -7,7 +7,7 @@ //! use hashes::{sha256d, Hash as _}; -use io::{Read, Write}; +use io::{BufRead, Write}; use crate::blockdata::block::BlockHash; use crate::blockdata::transaction::{Txid, Wtxid}; @@ -83,7 +83,7 @@ impl Encodable for Inventory { impl Decodable for Inventory { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let inv_type: u32 = Decodable::consensus_decode(r)?; Ok(match inv_type { 0 => Inventory::Error, diff --git a/bitcoin/src/p2p/message_bloom.rs b/bitcoin/src/p2p/message_bloom.rs index 3e89c933..cb04fca7 100644 --- a/bitcoin/src/p2p/message_bloom.rs +++ b/bitcoin/src/p2p/message_bloom.rs @@ -5,7 +5,7 @@ //! This module describes BIP37 Connection Bloom filtering network messages. //! -use io::{Read, Write}; +use io::{BufRead, Write}; use crate::consensus::{encode, Decodable, Encodable, ReadExt}; use crate::internal_macros::impl_consensus_encoding; @@ -48,7 +48,7 @@ impl Encodable for BloomFlags { } impl Decodable for BloomFlags { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(match r.read_u8()? { 0 => BloomFlags::None, 1 => BloomFlags::All, diff --git a/bitcoin/src/p2p/message_network.rs b/bitcoin/src/p2p/message_network.rs index f957a4a3..6ad59b5b 100644 --- a/bitcoin/src/p2p/message_network.rs +++ b/bitcoin/src/p2p/message_network.rs @@ -7,7 +7,7 @@ //! use hashes::sha256d; -use io::{Read, Write}; +use io::{BufRead, Write}; use crate::consensus::{encode, Decodable, Encodable, ReadExt}; use crate::internal_macros::impl_consensus_encoding; @@ -110,7 +110,7 @@ impl Encodable for RejectReason { } impl Decodable for RejectReason { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(match r.read_u8()? { 0x01 => RejectReason::Malformed, 0x10 => RejectReason::Invalid, diff --git a/bitcoin/src/p2p/mod.rs b/bitcoin/src/p2p/mod.rs index 0c0381fe..1a450375 100644 --- a/bitcoin/src/p2p/mod.rs +++ b/bitcoin/src/p2p/mod.rs @@ -25,7 +25,7 @@ use core::{fmt, ops}; use hex::FromHex; use internals::{debug_from_display, write_err}; -use io::{Read, Write}; +use io::{BufRead, Write}; use crate::consensus::encode::{self, Decodable, Encodable}; use crate::prelude::{Borrow, BorrowMut, String, ToOwned}; @@ -198,7 +198,7 @@ impl Encodable for ServiceFlags { impl Decodable for ServiceFlags { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { Ok(ServiceFlags(Decodable::consensus_decode(r)?)) } } @@ -290,7 +290,7 @@ impl Encodable for Magic { } impl Decodable for Magic { - fn consensus_decode(reader: &mut R) -> Result { + fn consensus_decode(reader: &mut R) -> Result { Ok(Magic(Decodable::consensus_decode(reader)?)) } } diff --git a/bitcoin/src/pow.rs b/bitcoin/src/pow.rs index 24772b68..20bab1db 100644 --- a/bitcoin/src/pow.rs +++ b/bitcoin/src/pow.rs @@ -9,7 +9,7 @@ use core::fmt::{self, LowerHex, UpperHex}; use core::ops::{Add, Div, Mul, Not, Rem, Shl, Shr, Sub}; -use io::{Read, Write}; +use io::{BufRead, Write}; #[cfg(all(test, mutate))] use mutagen::mutate; @@ -301,7 +301,7 @@ impl Encodable for CompactTarget { impl Decodable for CompactTarget { #[inline] - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { u32::consensus_decode(r).map(CompactTarget) } } diff --git a/bitcoin/src/psbt/macros.rs b/bitcoin/src/psbt/macros.rs index f07e5bbc..33deb634 100644 --- a/bitcoin/src/psbt/macros.rs +++ b/bitcoin/src/psbt/macros.rs @@ -56,7 +56,7 @@ macro_rules! impl_psbtmap_deserialize { macro_rules! impl_psbtmap_decoding { ($thing:ty) => { impl $thing { - pub(crate) fn decode( + pub(crate) fn decode( r: &mut R, ) -> Result { let mut rv: Self = core::default::Default::default(); diff --git a/bitcoin/src/psbt/map/global.rs b/bitcoin/src/psbt/map/global.rs index 7803df2b..8de2ea4b 100644 --- a/bitcoin/src/psbt/map/global.rs +++ b/bitcoin/src/psbt/map/global.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: CC0-1.0 -use io::{Cursor, Read}; +use io::{Cursor, BufRead, Read}; use crate::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpub}; use crate::blockdata::transaction::Transaction; @@ -70,7 +70,7 @@ impl Map for Psbt { } impl Psbt { - pub(crate) fn decode_global(r: &mut R) -> Result { + pub(crate) fn decode_global(r: &mut R) -> Result { let mut r = r.take(MAX_VEC_SIZE as u64); let mut tx: Option = None; let mut version: Option = None; diff --git a/bitcoin/src/psbt/raw.rs b/bitcoin/src/psbt/raw.rs index db4af227..eec5cf5a 100644 --- a/bitcoin/src/psbt/raw.rs +++ b/bitcoin/src/psbt/raw.rs @@ -8,7 +8,7 @@ use core::fmt; -use io::{Read, Write}; +use io::{BufRead, Read, Write}; use super::serialize::{Deserialize, Serialize}; use crate::consensus::encode::{ @@ -74,7 +74,7 @@ impl fmt::Display for Key { } impl Key { - pub(crate) fn decode(r: &mut R) -> Result { + pub(crate) fn decode(r: &mut R) -> Result { let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?; if byte_size == 0 { @@ -137,7 +137,7 @@ impl Deserialize for Pair { } impl Pair { - pub(crate) fn decode(r: &mut R) -> Result { + pub(crate) fn decode(r: &mut R) -> Result { Ok(Pair { key: Key::decode(r)?, value: Decodable::consensus_decode(r)? }) } } @@ -159,7 +159,7 @@ impl Decodable for ProprietaryKey where Subtype: Copy + From + Into, { - fn consensus_decode(r: &mut R) -> Result { + fn consensus_decode(r: &mut R) -> Result { let prefix = Vec::::consensus_decode(r)?; let subtype = Subtype::from(r.read_u8()?); let key = read_to_end(r)?;