Merge rust-bitcoin/rust-bitcoin#2240: Require `BufRead` instead of `Read`
263a8b3603
Require BufRead instead of Read (Tobin C. Harding)32d68fd1fa
io: Add BufRead trait (Tobin C. Harding) Pull request description: Require `BufRead` instead of `Read` for consensus decode trait. ACKs for top commit: Kixunil: ACK263a8b3603
apoelstra: ACK263a8b3603
Tree-SHA512: 58ad04c7267f9091738463331473bd22b61e6b06a13aec38b3602a369cd8e571d7d1388fd81dd7a0a05f2e8d5a9c35270cd8a918a4fafe636506591ed06a4cb2
This commit is contained in:
commit
2073a40c50
|
@ -12,7 +12,7 @@ use std::error;
|
||||||
|
|
||||||
use hashes::{sha256, siphash24, Hash};
|
use hashes::{sha256, siphash24, Hash};
|
||||||
use internals::impl_array_newtype;
|
use internals::impl_array_newtype;
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::consensus::encode::{self, Decodable, Encodable, VarInt};
|
use crate::consensus::encode::{self, Decodable, Encodable, VarInt};
|
||||||
use crate::internal_macros::{impl_bytes_newtype, impl_consensus_encoding};
|
use crate::internal_macros::{impl_bytes_newtype, impl_consensus_encoding};
|
||||||
|
@ -81,7 +81,7 @@ impl Encodable for PrefilledTransaction {
|
||||||
|
|
||||||
impl Decodable for PrefilledTransaction {
|
impl Decodable for PrefilledTransaction {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
let idx = VarInt::consensus_decode(r)?.0;
|
let idx = VarInt::consensus_decode(r)?.0;
|
||||||
let idx = u16::try_from(idx)
|
let idx = u16::try_from(idx)
|
||||||
.map_err(|_| encode::Error::ParseFailed("BIP152 prefilled tx index out of bounds"))?;
|
.map_err(|_| encode::Error::ParseFailed("BIP152 prefilled tx index out of bounds"))?;
|
||||||
|
@ -137,7 +137,7 @@ impl Encodable for ShortId {
|
||||||
|
|
||||||
impl Decodable for ShortId {
|
impl Decodable for ShortId {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<ShortId, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<ShortId, encode::Error> {
|
||||||
Ok(ShortId(Decodable::consensus_decode(r)?))
|
Ok(ShortId(Decodable::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ impl Encodable for BlockTransactionsRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for BlockTransactionsRequest {
|
impl Decodable for BlockTransactionsRequest {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(BlockTransactionsRequest {
|
Ok(BlockTransactionsRequest {
|
||||||
block_hash: BlockHash::consensus_decode(r)?,
|
block_hash: BlockHash::consensus_decode(r)?,
|
||||||
indexes: {
|
indexes: {
|
||||||
|
|
|
@ -43,7 +43,7 @@ use core::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
use hashes::{sha256d, siphash24, Hash};
|
use hashes::{sha256d, siphash24, Hash};
|
||||||
use internals::write_err;
|
use internals::write_err;
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::blockdata::block::{Block, BlockHash};
|
use crate::blockdata::block::{Block, BlockHash};
|
||||||
use crate::blockdata::script::Script;
|
use crate::blockdata::script::Script;
|
||||||
|
@ -245,7 +245,7 @@ impl BlockFilterReader {
|
||||||
where
|
where
|
||||||
I: Iterator,
|
I: Iterator,
|
||||||
I::Item: Borrow<[u8]>,
|
I::Item: Borrow<[u8]>,
|
||||||
R: Read + ?Sized,
|
R: BufRead + ?Sized,
|
||||||
{
|
{
|
||||||
self.reader.match_any(reader, query)
|
self.reader.match_any(reader, query)
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ impl BlockFilterReader {
|
||||||
where
|
where
|
||||||
I: Iterator,
|
I: Iterator,
|
||||||
I::Item: Borrow<[u8]>,
|
I::Item: Borrow<[u8]>,
|
||||||
R: Read + ?Sized,
|
R: BufRead + ?Sized,
|
||||||
{
|
{
|
||||||
self.reader.match_all(reader, query)
|
self.reader.match_all(reader, query)
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ impl GcsFilterReader {
|
||||||
where
|
where
|
||||||
I: Iterator,
|
I: Iterator,
|
||||||
I::Item: Borrow<[u8]>,
|
I::Item: Borrow<[u8]>,
|
||||||
R: Read + ?Sized,
|
R: BufRead + ?Sized,
|
||||||
{
|
{
|
||||||
let n_elements: VarInt = Decodable::consensus_decode(reader).unwrap_or(VarInt(0));
|
let n_elements: VarInt = Decodable::consensus_decode(reader).unwrap_or(VarInt(0));
|
||||||
// map hashes to [0, n_elements << grp]
|
// map hashes to [0, n_elements << grp]
|
||||||
|
@ -321,7 +321,7 @@ impl GcsFilterReader {
|
||||||
where
|
where
|
||||||
I: Iterator,
|
I: Iterator,
|
||||||
I::Item: Borrow<[u8]>,
|
I::Item: Borrow<[u8]>,
|
||||||
R: Read + ?Sized,
|
R: BufRead + ?Sized,
|
||||||
{
|
{
|
||||||
let n_elements: VarInt = Decodable::consensus_decode(reader).unwrap_or(VarInt(0));
|
let n_elements: VarInt = Decodable::consensus_decode(reader).unwrap_or(VarInt(0));
|
||||||
// map hashes to [0, n_elements << grp]
|
// 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).
|
/// Golomb-Rice decodes a number from a bit stream (parameter 2^k).
|
||||||
fn golomb_rice_decode<R>(&self, reader: &mut BitStreamReader<R>) -> Result<u64, io::Error>
|
fn golomb_rice_decode<R>(&self, reader: &mut BitStreamReader<R>) -> Result<u64, io::Error>
|
||||||
where
|
where
|
||||||
R: Read + ?Sized,
|
R: BufRead + ?Sized,
|
||||||
{
|
{
|
||||||
let mut q = 0u64;
|
let mut q = 0u64;
|
||||||
while reader.read(1)? == 1 {
|
while reader.read(1)? == 1 {
|
||||||
|
@ -470,7 +470,7 @@ pub struct BitStreamReader<'a, R: ?Sized> {
|
||||||
reader: &'a mut R,
|
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`.
|
/// Creates a new [`BitStreamReader`] that reads bitwise from a given `reader`.
|
||||||
pub fn new(reader: &'a mut R) -> BitStreamReader<'a, R> {
|
pub fn new(reader: &'a mut R) -> BitStreamReader<'a, R> {
|
||||||
BitStreamReader { buffer: [0u8], reader, offset: 8 }
|
BitStreamReader { buffer: [0u8], reader, offset: 8 }
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use hashes::{sha256d, Hash, HashEngine};
|
use hashes::{sha256d, Hash, HashEngine};
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use super::Weight;
|
use super::Weight;
|
||||||
use crate::blockdata::script;
|
use crate::blockdata::script;
|
||||||
|
@ -207,7 +207,7 @@ impl Encodable for Version {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Version {
|
impl Decodable for Version {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Decodable::consensus_decode(r).map(Version)
|
Decodable::consensus_decode(r).map(Version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use core::cmp::{Ordering, PartialOrd};
|
||||||
use core::{fmt, mem};
|
use core::{fmt, mem};
|
||||||
|
|
||||||
use internals::write_err;
|
use internals::write_err;
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
#[cfg(all(test, mutate))]
|
#[cfg(all(test, mutate))]
|
||||||
use mutagen::mutate;
|
use mutagen::mutate;
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ impl Encodable for LockTime {
|
||||||
|
|
||||||
impl Decodable for LockTime {
|
impl Decodable for LockTime {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
u32::consensus_decode(r).map(LockTime::from_consensus)
|
u32::consensus_decode(r).map(LockTime::from_consensus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ use core::fmt;
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use hashes::{hash160, sha256};
|
use hashes::{hash160, sha256};
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde;
|
use serde;
|
||||||
|
|
||||||
|
@ -594,7 +594,7 @@ impl Encodable for ScriptBuf {
|
||||||
|
|
||||||
impl Decodable for ScriptBuf {
|
impl Decodable for ScriptBuf {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<Self, encode::Error> {
|
) -> Result<Self, encode::Error> {
|
||||||
Ok(ScriptBuf(Decodable::consensus_decode_from_finite_reader(r)?))
|
Ok(ScriptBuf(Decodable::consensus_decode_from_finite_reader(r)?))
|
||||||
|
|
|
@ -16,7 +16,7 @@ use core::{cmp, fmt, str};
|
||||||
|
|
||||||
use hashes::{self, sha256d, Hash};
|
use hashes::{self, sha256d, Hash};
|
||||||
use internals::write_err;
|
use internals::write_err;
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use super::Weight;
|
use super::Weight;
|
||||||
use crate::blockdata::locktime::absolute::{self, Height, Time};
|
use crate::blockdata::locktime::absolute::{self, Height, Time};
|
||||||
|
@ -1030,7 +1030,7 @@ impl Encodable for Version {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Version {
|
impl Decodable for Version {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Decodable::consensus_decode(r).map(Version)
|
Decodable::consensus_decode(r).map(Version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1048,7 +1048,7 @@ impl Encodable for OutPoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Decodable for OutPoint {
|
impl Decodable for OutPoint {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(OutPoint {
|
Ok(OutPoint {
|
||||||
txid: Decodable::consensus_decode(r)?,
|
txid: Decodable::consensus_decode(r)?,
|
||||||
vout: Decodable::consensus_decode(r)?,
|
vout: Decodable::consensus_decode(r)?,
|
||||||
|
@ -1067,7 +1067,7 @@ impl Encodable for TxIn {
|
||||||
}
|
}
|
||||||
impl Decodable for TxIn {
|
impl Decodable for TxIn {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<Self, encode::Error> {
|
) -> Result<Self, encode::Error> {
|
||||||
Ok(TxIn {
|
Ok(TxIn {
|
||||||
|
@ -1086,7 +1086,7 @@ impl Encodable for Sequence {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Sequence {
|
impl Decodable for Sequence {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Decodable::consensus_decode(r).map(Sequence)
|
Decodable::consensus_decode(r).map(Sequence)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1116,7 @@ impl Encodable for Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Transaction {
|
impl Decodable for Transaction {
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<Self, encode::Error> {
|
) -> Result<Self, encode::Error> {
|
||||||
let version = Version::consensus_decode_from_finite_reader(r)?;
|
let version = Version::consensus_decode_from_finite_reader(r)?;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::ops::Index;
|
use core::ops::Index;
|
||||||
|
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::consensus::encode::{Error, MAX_VEC_SIZE};
|
use crate::consensus::encode::{Error, MAX_VEC_SIZE};
|
||||||
use crate::consensus::{Decodable, Encodable, WriteExt};
|
use crate::consensus::{Decodable, Encodable, WriteExt};
|
||||||
|
@ -124,7 +124,7 @@ pub struct Iter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Witness {
|
impl Decodable for Witness {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
let witness_elements = VarInt::consensus_decode(r)?.0 as usize;
|
let witness_elements = VarInt::consensus_decode(r)?.0 as usize;
|
||||||
// Minimum size of witness element is 1 byte, so if the count is
|
// Minimum size of witness element is 1 byte, so if the count is
|
||||||
// greater than MAX_VEC_SIZE we must return an error.
|
// greater than MAX_VEC_SIZE we must return an error.
|
||||||
|
|
|
@ -20,7 +20,7 @@ use core::{fmt, mem, u32};
|
||||||
|
|
||||||
use hashes::{sha256, sha256d, Hash};
|
use hashes::{sha256, sha256d, Hash};
|
||||||
use internals::write_err;
|
use internals::write_err;
|
||||||
use io::{Cursor, Read, Write};
|
use io::{Cursor, BufRead, Read, Write};
|
||||||
|
|
||||||
use crate::bip152::{PrefilledTransaction, ShortId};
|
use crate::bip152::{PrefilledTransaction, ShortId};
|
||||||
use crate::bip158::{FilterHash, FilterHeader};
|
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
|
/// avoid creating redundant `Take` wrappers. Failure to do so might result only in a tiny
|
||||||
/// performance hit.
|
/// performance hit.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
|
||||||
reader: &mut R,
|
reader: &mut R,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
// This method is always strictly less general than, `consensus_decode`, so it's safe and
|
// This method is always strictly less general than, `consensus_decode`, so it's safe and
|
||||||
|
@ -319,7 +319,7 @@ pub trait Decodable: Sized {
|
||||||
/// for types that override [`Self::consensus_decode_from_finite_reader`]
|
/// for types that override [`Self::consensus_decode_from_finite_reader`]
|
||||||
/// instead.
|
/// instead.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(reader: &mut R) -> Result<Self, Error> {
|
||||||
Self::consensus_decode_from_finite_reader(&mut reader.take(MAX_VEC_SIZE as u64))
|
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) => {
|
($ty:ident, $meth_dec:ident, $meth_enc:ident) => {
|
||||||
impl Decodable for $ty {
|
impl Decodable for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
ReadExt::$meth_dec(r)
|
ReadExt::$meth_dec(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -440,7 +440,7 @@ impl Encodable for VarInt {
|
||||||
|
|
||||||
impl Decodable for VarInt {
|
impl Decodable for VarInt {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
let n = ReadExt::read_u8(r)?;
|
let n = ReadExt::read_u8(r)?;
|
||||||
match n {
|
match n {
|
||||||
0xFF => {
|
0xFF => {
|
||||||
|
@ -482,7 +482,7 @@ impl Encodable for bool {
|
||||||
|
|
||||||
impl Decodable for bool {
|
impl Decodable for bool {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<bool, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<bool, Error> {
|
||||||
ReadExt::read_bool(r)
|
ReadExt::read_bool(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,7 +499,7 @@ impl Encodable for String {
|
||||||
|
|
||||||
impl Decodable for String {
|
impl Decodable for String {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<String, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<String, Error> {
|
||||||
String::from_utf8(Decodable::consensus_decode(r)?)
|
String::from_utf8(Decodable::consensus_decode(r)?)
|
||||||
.map_err(|_| self::Error::ParseFailed("String was not valid UTF8"))
|
.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> {
|
impl Decodable for Cow<'static, str> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Cow<'static, str>, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Cow<'static, str>, Error> {
|
||||||
String::from_utf8(Decodable::consensus_decode(r)?)
|
String::from_utf8(Decodable::consensus_decode(r)?)
|
||||||
.map_err(|_| self::Error::ParseFailed("String was not valid UTF8"))
|
.map_err(|_| self::Error::ParseFailed("String was not valid UTF8"))
|
||||||
.map(Cow::Owned)
|
.map(Cow::Owned)
|
||||||
|
@ -539,7 +539,7 @@ macro_rules! impl_array {
|
||||||
|
|
||||||
impl Decodable for [u8; $size] {
|
impl Decodable for [u8; $size] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
let mut ret = [0; $size];
|
let mut ret = [0; $size];
|
||||||
r.read_slice(&mut ret)?;
|
r.read_slice(&mut ret)?;
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
|
@ -560,7 +560,7 @@ impl_array!(33);
|
||||||
|
|
||||||
impl Decodable for [u16; 8] {
|
impl Decodable for [u16; 8] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
let mut res = [0; 8];
|
let mut res = [0; 8];
|
||||||
for item in &mut res {
|
for item in &mut res {
|
||||||
*item = Decodable::consensus_decode(r)?;
|
*item = Decodable::consensus_decode(r)?;
|
||||||
|
@ -595,7 +595,7 @@ macro_rules! impl_vec {
|
||||||
|
|
||||||
impl Decodable for Vec<$type> {
|
impl Decodable for Vec<$type> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let len = VarInt::consensus_decode_from_finite_reader(r)?.0;
|
let len = VarInt::consensus_decode_from_finite_reader(r)?.0;
|
||||||
|
@ -685,7 +685,7 @@ impl Encodable for Vec<u8> {
|
||||||
|
|
||||||
impl Decodable for Vec<u8> {
|
impl Decodable for Vec<u8> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
let len = VarInt::consensus_decode(r)?.0 as usize;
|
let len = VarInt::consensus_decode(r)?.0 as usize;
|
||||||
// most real-world vec of bytes data, wouldn't be larger than 128KiB
|
// most real-world vec of bytes data, wouldn't be larger than 128KiB
|
||||||
let opts = ReadBytesFromFiniteReaderOpts { len, chunk_size: 128 * 1024 };
|
let opts = ReadBytesFromFiniteReaderOpts { len, chunk_size: 128 * 1024 };
|
||||||
|
@ -702,7 +702,7 @@ impl Encodable for Box<[u8]> {
|
||||||
|
|
||||||
impl Decodable for Box<[u8]> {
|
impl Decodable for Box<[u8]> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
<Vec<u8>>::consensus_decode_from_finite_reader(r).map(From::from)
|
<Vec<u8>>::consensus_decode_from_finite_reader(r).map(From::from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -727,7 +727,7 @@ impl Encodable for CheckedData {
|
||||||
|
|
||||||
impl Decodable for CheckedData {
|
impl Decodable for CheckedData {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
let len = u32::consensus_decode_from_finite_reader(r)? as usize;
|
let len = u32::consensus_decode_from_finite_reader(r)? as usize;
|
||||||
|
|
||||||
let checksum = <[u8; 4]>::consensus_decode_from_finite_reader(r)?;
|
let checksum = <[u8; 4]>::consensus_decode_from_finite_reader(r)?;
|
||||||
|
@ -787,7 +787,7 @@ macro_rules! tuple_encode {
|
||||||
impl<$($x: Decodable),*> Decodable for ($($x),*) {
|
impl<$($x: Decodable),*> Decodable for ($($x),*) {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
Ok(($({let $x = Decodable::consensus_decode(r)?; $x }),*))
|
Ok(($({let $x = Decodable::consensus_decode(r)?; $x }),*))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -809,7 +809,7 @@ impl Encodable for sha256d::Hash {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for sha256d::Hash {
|
impl Decodable for sha256d::Hash {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
Ok(Self::from_byte_array(<<Self as Hash>::Bytes>::consensus_decode(r)?))
|
Ok(Self::from_byte_array(<<Self as Hash>::Bytes>::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -821,7 +821,7 @@ impl Encodable for sha256::Hash {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for sha256::Hash {
|
impl Decodable for sha256::Hash {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
Ok(Self::from_byte_array(<<Self as Hash>::Bytes>::consensus_decode(r)?))
|
Ok(Self::from_byte_array(<<Self as Hash>::Bytes>::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,7 +833,7 @@ impl Encodable for TapLeafHash {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for TapLeafHash {
|
impl Decodable for TapLeafHash {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
Ok(Self::from_byte_array(<<Self as Hash>::Bytes>::consensus_decode(r)?))
|
Ok(Self::from_byte_array(<<Self as Hash>::Bytes>::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Read, Write};
|
||||||
use serde::de::{SeqAccess, Unexpected, Visitor};
|
use serde::de::{SeqAccess, Unexpected, Visitor};
|
||||||
use serde::ser::SerializeSeq;
|
use serde::ser::SerializeSeq;
|
||||||
use serde::{Deserializer, Serializer};
|
use serde::{Deserializer, Serializer};
|
||||||
|
@ -420,11 +420,12 @@ where
|
||||||
|
|
||||||
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>,
|
iterator: core::iter::Fuse<I>,
|
||||||
|
buf: Option<u8>,
|
||||||
error: Option<E>,
|
error: Option<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> IterReader<E, I> {
|
impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> IterReader<E, I> {
|
||||||
fn new(iterator: I) -> Self { IterReader { iterator: iterator.fuse(), error: None } }
|
fn new(iterator: I) -> Self { IterReader { iterator: iterator.fuse(), buf: None, error: None } }
|
||||||
|
|
||||||
fn decode<T: Decodable>(mut self) -> Result<T, DecodeError<E>> {
|
fn decode<T: Decodable>(mut self) -> Result<T, DecodeError<E>> {
|
||||||
let result = T::consensus_decode(&mut self);
|
let result = T::consensus_decode(&mut self);
|
||||||
|
@ -443,8 +444,17 @@ impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> IterReader<E, I> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> Read for IterReader<E, I> {
|
impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> Read for IterReader<E, I> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
|
||||||
let mut count = 0;
|
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) {
|
for (dst, src) in buf.iter_mut().zip(&mut self.iterator) {
|
||||||
match src {
|
match src {
|
||||||
Ok(byte) => *dst = byte,
|
Ok(byte) => *dst = byte,
|
||||||
|
@ -460,6 +470,34 @@ impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> Read for IterReader<E, I>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: fmt::Debug, I: Iterator<Item = Result<u8, E>>> BufRead for IterReader<E, I> {
|
||||||
|
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 = "")]`.
|
/// Helper for `#[serde(with = "")]`.
|
||||||
///
|
///
|
||||||
/// To (de)serialize a field using consensus encoding you can write e.g.:
|
/// To (de)serialize a field using consensus encoding you can write e.g.:
|
||||||
|
|
|
@ -22,7 +22,7 @@ macro_rules! impl_consensus_encoding {
|
||||||
impl $crate::consensus::Decodable for $thing {
|
impl $crate::consensus::Decodable for $thing {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: $crate::io::Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: $crate::io::BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<$thing, $crate::consensus::encode::Error> {
|
) -> Result<$thing, $crate::consensus::encode::Error> {
|
||||||
Ok($thing {
|
Ok($thing {
|
||||||
|
@ -31,7 +31,7 @@ macro_rules! impl_consensus_encoding {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: $crate::io::Read + ?Sized>(
|
fn consensus_decode<R: $crate::io::BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<$thing, $crate::consensus::encode::Error> {
|
) -> Result<$thing, $crate::consensus::encode::Error> {
|
||||||
let mut r = r.take($crate::consensus::encode::MAX_VEC_SIZE as u64);
|
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 {
|
impl $crate::consensus::Decodable for $hashtype {
|
||||||
fn consensus_decode<R: $crate::io::Read + ?Sized>(r: &mut R) -> Result<Self, $crate::consensus::encode::Error> {
|
fn consensus_decode<R: $crate::io::BufRead + ?Sized>(r: &mut R) -> Result<Self, $crate::consensus::encode::Error> {
|
||||||
use $crate::hashes::Hash;
|
use $crate::hashes::Hash;
|
||||||
Ok(Self::from_byte_array(<<$hashtype as $crate::hashes::Hash>::Bytes>::consensus_decode(r)?))
|
Ok(Self::from_byte_array(<<$hashtype as $crate::hashes::Hash>::Bytes>::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,7 @@ pub mod amount {
|
||||||
//! We refer to the documentation on the types for more information.
|
//! We refer to the documentation on the types for more information.
|
||||||
|
|
||||||
use crate::consensus::{encode, Decodable, Encodable};
|
use crate::consensus::{encode, Decodable, Encodable};
|
||||||
use crate::io;
|
use crate::io::{BufRead, Write};
|
||||||
|
|
||||||
#[rustfmt::skip] // Keep public re-exports separate.
|
#[rustfmt::skip] // Keep public re-exports separate.
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
|
@ -184,14 +184,14 @@ pub mod amount {
|
||||||
|
|
||||||
impl Decodable for Amount {
|
impl Decodable for Amount {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(Amount::from_sat(Decodable::consensus_decode(r)?))
|
Ok(Amount::from_sat(Decodable::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Encodable for Amount {
|
impl Encodable for Amount {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
|
||||||
self.to_sat().consensus_encode(w)
|
self.to_sat().consensus_encode(w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use hashes::Hash;
|
use hashes::Hash;
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use self::MerkleBlockError::*;
|
use self::MerkleBlockError::*;
|
||||||
use crate::blockdata::block::{self, Block, TxMerkleNode};
|
use crate::blockdata::block::{self, Block, TxMerkleNode};
|
||||||
|
@ -151,7 +151,7 @@ impl Encodable for MerkleBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for MerkleBlock {
|
impl Decodable for MerkleBlock {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(MerkleBlock {
|
Ok(MerkleBlock {
|
||||||
header: Decodable::consensus_decode(r)?,
|
header: Decodable::consensus_decode(r)?,
|
||||||
txn: Decodable::consensus_decode(r)?,
|
txn: Decodable::consensus_decode(r)?,
|
||||||
|
@ -452,7 +452,7 @@ impl Encodable for PartialMerkleTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for PartialMerkleTree {
|
impl Decodable for PartialMerkleTree {
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<Self, encode::Error> {
|
) -> Result<Self, encode::Error> {
|
||||||
let num_transactions: u32 = Decodable::consensus_decode(r)?;
|
let num_transactions: u32 = Decodable::consensus_decode(r)?;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
use core::{fmt, iter};
|
use core::{fmt, iter};
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
|
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::consensus::encode::{self, Decodable, Encodable, ReadExt, VarInt, WriteExt};
|
||||||
use crate::p2p::ServiceFlags;
|
use crate::p2p::ServiceFlags;
|
||||||
|
@ -75,7 +75,7 @@ impl Encodable for Address {
|
||||||
|
|
||||||
impl Decodable for Address {
|
impl Decodable for Address {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(Address {
|
Ok(Address {
|
||||||
services: Decodable::consensus_decode(r)?,
|
services: Decodable::consensus_decode(r)?,
|
||||||
address: read_be_address(r)?,
|
address: read_be_address(r)?,
|
||||||
|
@ -167,7 +167,7 @@ impl Encodable for AddrV2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for AddrV2 {
|
impl Decodable for AddrV2 {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
let network_id = u8::consensus_decode(r)?;
|
let network_id = u8::consensus_decode(r)?;
|
||||||
let len = VarInt::consensus_decode(r)?.0;
|
let len = VarInt::consensus_decode(r)?.0;
|
||||||
if len > 512 {
|
if len > 512 {
|
||||||
|
@ -285,7 +285,7 @@ impl Encodable for AddrV2Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for AddrV2Message {
|
impl Decodable for AddrV2Message {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(AddrV2Message {
|
Ok(AddrV2Message {
|
||||||
time: Decodable::consensus_decode(r)?,
|
time: Decodable::consensus_decode(r)?,
|
||||||
services: ServiceFlags::from(VarInt::consensus_decode(r)?.0),
|
services: ServiceFlags::from(VarInt::consensus_decode(r)?.0),
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
use core::{fmt, iter};
|
use core::{fmt, iter};
|
||||||
|
|
||||||
use hashes::{sha256d, Hash};
|
use hashes::{sha256d, Hash};
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::blockdata::{block, transaction};
|
use crate::blockdata::{block, transaction};
|
||||||
use crate::consensus::encode::{self, CheckedData, Decodable, Encodable, VarInt};
|
use crate::consensus::encode::{self, CheckedData, Decodable, Encodable, VarInt};
|
||||||
|
@ -110,7 +110,7 @@ impl Encodable for CommandString {
|
||||||
|
|
||||||
impl Decodable for CommandString {
|
impl Decodable for CommandString {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
let rawbytes: [u8; 12] = Decodable::consensus_decode(r)?;
|
let rawbytes: [u8; 12] = Decodable::consensus_decode(r)?;
|
||||||
let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| {
|
let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| {
|
||||||
if u > 0 {
|
if u > 0 {
|
||||||
|
@ -407,7 +407,7 @@ struct HeaderDeserializationWrapper(Vec<block::Header>);
|
||||||
|
|
||||||
impl Decodable for HeaderDeserializationWrapper {
|
impl Decodable for HeaderDeserializationWrapper {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<Self, encode::Error> {
|
) -> Result<Self, encode::Error> {
|
||||||
let len = VarInt::consensus_decode(r)?.0;
|
let len = VarInt::consensus_decode(r)?.0;
|
||||||
|
@ -426,13 +426,13 @@ impl Decodable for HeaderDeserializationWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Self::consensus_decode_from_finite_reader(&mut r.take(MAX_MSG_SIZE as u64))
|
Self::consensus_decode_from_finite_reader(&mut r.take(MAX_MSG_SIZE as u64))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for RawNetworkMessage {
|
impl Decodable for RawNetworkMessage {
|
||||||
fn consensus_decode_from_finite_reader<R: Read + ?Sized>(
|
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<Self, encode::Error> {
|
) -> Result<Self, encode::Error> {
|
||||||
let magic = Decodable::consensus_decode_from_finite_reader(r)?;
|
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 raw_payload = checked_data.into_data();
|
||||||
let payload_len = raw_payload.len() as u32;
|
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[..] {
|
let payload = match &cmd.0[..] {
|
||||||
"version" =>
|
"version" =>
|
||||||
NetworkMessage::Version(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
|
NetworkMessage::Version(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
|
||||||
|
@ -525,13 +525,13 @@ impl Decodable for RawNetworkMessage {
|
||||||
"addrv2" =>
|
"addrv2" =>
|
||||||
NetworkMessage::AddrV2(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
|
NetworkMessage::AddrV2(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
|
||||||
"sendaddrv2" => NetworkMessage::SendAddrV2,
|
"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 })
|
Ok(RawNetworkMessage { magic, payload, payload_len, checksum })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Self::consensus_decode_from_finite_reader(&mut r.take(MAX_MSG_SIZE as u64))
|
Self::consensus_decode_from_finite_reader(&mut r.take(MAX_MSG_SIZE as u64))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use hashes::{sha256d, Hash as _};
|
use hashes::{sha256d, Hash as _};
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::blockdata::block::BlockHash;
|
use crate::blockdata::block::BlockHash;
|
||||||
use crate::blockdata::transaction::{Txid, Wtxid};
|
use crate::blockdata::transaction::{Txid, Wtxid};
|
||||||
|
@ -83,7 +83,7 @@ impl Encodable for Inventory {
|
||||||
|
|
||||||
impl Decodable for Inventory {
|
impl Decodable for Inventory {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
let inv_type: u32 = Decodable::consensus_decode(r)?;
|
let inv_type: u32 = Decodable::consensus_decode(r)?;
|
||||||
Ok(match inv_type {
|
Ok(match inv_type {
|
||||||
0 => Inventory::Error,
|
0 => Inventory::Error,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//! This module describes BIP37 Connection Bloom filtering network messages.
|
//! 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::consensus::{encode, Decodable, Encodable, ReadExt};
|
||||||
use crate::internal_macros::impl_consensus_encoding;
|
use crate::internal_macros::impl_consensus_encoding;
|
||||||
|
@ -48,7 +48,7 @@ impl Encodable for BloomFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for BloomFlags {
|
impl Decodable for BloomFlags {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(match r.read_u8()? {
|
Ok(match r.read_u8()? {
|
||||||
0 => BloomFlags::None,
|
0 => BloomFlags::None,
|
||||||
1 => BloomFlags::All,
|
1 => BloomFlags::All,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use hashes::sha256d;
|
use hashes::sha256d;
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::consensus::{encode, Decodable, Encodable, ReadExt};
|
use crate::consensus::{encode, Decodable, Encodable, ReadExt};
|
||||||
use crate::internal_macros::impl_consensus_encoding;
|
use crate::internal_macros::impl_consensus_encoding;
|
||||||
|
@ -117,7 +117,7 @@ impl Encodable for RejectReason {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for RejectReason {
|
impl Decodable for RejectReason {
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(match r.read_u8()? {
|
Ok(match r.read_u8()? {
|
||||||
0x01 => RejectReason::Malformed,
|
0x01 => RejectReason::Malformed,
|
||||||
0x10 => RejectReason::Invalid,
|
0x10 => RejectReason::Invalid,
|
||||||
|
|
|
@ -25,7 +25,7 @@ use core::{fmt, ops};
|
||||||
|
|
||||||
use hex::FromHex;
|
use hex::FromHex;
|
||||||
use internals::{debug_from_display, write_err};
|
use internals::{debug_from_display, write_err};
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
|
|
||||||
use crate::consensus::encode::{self, Decodable, Encodable};
|
use crate::consensus::encode::{self, Decodable, Encodable};
|
||||||
use crate::prelude::{Borrow, BorrowMut, String, ToOwned};
|
use crate::prelude::{Borrow, BorrowMut, String, ToOwned};
|
||||||
|
@ -198,7 +198,7 @@ impl Encodable for ServiceFlags {
|
||||||
|
|
||||||
impl Decodable for ServiceFlags {
|
impl Decodable for ServiceFlags {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(ServiceFlags(Decodable::consensus_decode(r)?))
|
Ok(ServiceFlags(Decodable::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ impl Encodable for Magic {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for Magic {
|
impl Decodable for Magic {
|
||||||
fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(reader: &mut R) -> Result<Self, encode::Error> {
|
||||||
Ok(Magic(Decodable::consensus_decode(reader)?))
|
Ok(Magic(Decodable::consensus_decode(reader)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
use core::fmt::{self, LowerHex, UpperHex};
|
use core::fmt::{self, LowerHex, UpperHex};
|
||||||
use core::ops::{Add, Div, Mul, Not, Rem, Shl, Shr, Sub};
|
use core::ops::{Add, Div, Mul, Not, Rem, Shl, Shr, Sub};
|
||||||
|
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Write};
|
||||||
#[cfg(all(test, mutate))]
|
#[cfg(all(test, mutate))]
|
||||||
use mutagen::mutate;
|
use mutagen::mutate;
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ impl Encodable for CompactTarget {
|
||||||
|
|
||||||
impl Decodable for CompactTarget {
|
impl Decodable for CompactTarget {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
u32::consensus_decode(r).map(CompactTarget)
|
u32::consensus_decode(r).map(CompactTarget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ macro_rules! impl_psbtmap_deserialize {
|
||||||
macro_rules! impl_psbtmap_decoding {
|
macro_rules! impl_psbtmap_decoding {
|
||||||
($thing:ty) => {
|
($thing:ty) => {
|
||||||
impl $thing {
|
impl $thing {
|
||||||
pub(crate) fn decode<R: $crate::io::Read + ?Sized>(
|
pub(crate) fn decode<R: $crate::io::BufRead + ?Sized>(
|
||||||
r: &mut R,
|
r: &mut R,
|
||||||
) -> Result<Self, $crate::psbt::Error> {
|
) -> Result<Self, $crate::psbt::Error> {
|
||||||
let mut rv: Self = core::default::Default::default();
|
let mut rv: Self = core::default::Default::default();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SPDX-License-Identifier: CC0-1.0
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
use io::{Cursor, Read};
|
use io::{Cursor, BufRead, Read};
|
||||||
|
|
||||||
use crate::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpub};
|
use crate::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpub};
|
||||||
use crate::blockdata::transaction::Transaction;
|
use crate::blockdata::transaction::Transaction;
|
||||||
|
@ -70,7 +70,7 @@ impl Map for Psbt {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Psbt {
|
impl Psbt {
|
||||||
pub(crate) fn decode_global<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
pub(crate) fn decode_global<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
let mut r = r.take(MAX_VEC_SIZE as u64);
|
let mut r = r.take(MAX_VEC_SIZE as u64);
|
||||||
let mut tx: Option<Transaction> = None;
|
let mut tx: Option<Transaction> = None;
|
||||||
let mut version: Option<u32> = None;
|
let mut version: Option<u32> = None;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use io::{Read, Write};
|
use io::{BufRead, Read, Write};
|
||||||
|
|
||||||
use super::serialize::{Deserialize, Serialize};
|
use super::serialize::{Deserialize, Serialize};
|
||||||
use crate::consensus::encode::{
|
use crate::consensus::encode::{
|
||||||
|
@ -74,7 +74,7 @@ impl fmt::Display for Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Key {
|
impl Key {
|
||||||
pub(crate) fn decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
pub(crate) fn decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?;
|
let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?;
|
||||||
|
|
||||||
if byte_size == 0 {
|
if byte_size == 0 {
|
||||||
|
@ -137,7 +137,7 @@ impl Deserialize for Pair {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pair {
|
impl Pair {
|
||||||
pub(crate) fn decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
pub(crate) fn decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, Error> {
|
||||||
Ok(Pair { key: Key::decode(r)?, value: Decodable::consensus_decode(r)? })
|
Ok(Pair { key: Key::decode(r)?, value: Decodable::consensus_decode(r)? })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ impl<Subtype> Decodable for ProprietaryKey<Subtype>
|
||||||
where
|
where
|
||||||
Subtype: Copy + From<u8> + Into<u8>,
|
Subtype: Copy + From<u8> + Into<u8>,
|
||||||
{
|
{
|
||||||
fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
|
||||||
let prefix = Vec::<u8>::consensus_decode(r)?;
|
let prefix = Vec::<u8>::consensus_decode(r)?;
|
||||||
let subtype = Subtype::from(r.read_u8()?);
|
let subtype = Subtype::from(r.read_u8()?);
|
||||||
let key = read_to_end(r)?;
|
let key = read_to_end(r)?;
|
||||||
|
|
|
@ -47,6 +47,19 @@ pub trait Read {
|
||||||
fn take(&mut self, limit: u64) -> Take<Self> { Take { reader: self, remaining: limit } }
|
fn take(&mut self, limit: u64) -> Take<Self> { Take { reader: self, remaining: limit } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait describing an input stream that uses an internal buffer when reading.
|
||||||
|
pub trait BufRead: Read {
|
||||||
|
/// Returns data read from this reader, filling the internal buffer if needed.
|
||||||
|
fn fill_buf(&mut self) -> Result<&[u8]>;
|
||||||
|
|
||||||
|
/// Marks the buffered data up to amount as consumed.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// May panic if `amount` is greater than amount of data read by `fill_buf`.
|
||||||
|
fn consume(&mut self, amount: usize);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Take<'a, R: Read + ?Sized> {
|
pub struct Take<'a, R: Read + ?Sized> {
|
||||||
reader: &'a mut R,
|
reader: &'a mut R,
|
||||||
remaining: u64,
|
remaining: u64,
|
||||||
|
@ -62,6 +75,30 @@ impl<'a, R: Read + ?Sized> Read for Take<'a, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Impl copied from Rust stdlib.
|
||||||
|
impl<'a, R: BufRead + ?Sized> BufRead for Take<'a, R> {
|
||||||
|
#[inline]
|
||||||
|
fn fill_buf(&mut self) -> Result<&[u8]> {
|
||||||
|
// Don't call into inner reader at all at EOF because it may still block
|
||||||
|
if self.remaining == 0 {
|
||||||
|
return Ok(&[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let buf = self.reader.fill_buf()?;
|
||||||
|
// Cast length to a u64 instead of casting `remaining` to a `usize`
|
||||||
|
// (in case `remaining > u32::MAX` and we are on a 32 bit machine).
|
||||||
|
let cap = cmp::min(buf.len() as u64, self.remaining) as usize;
|
||||||
|
Ok(&buf[..cap])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn consume(&mut self, amount: usize) {
|
||||||
|
assert!(amount as u64 <= self.remaining);
|
||||||
|
self.remaining -= amount as u64;
|
||||||
|
self.reader.consume(amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<R: std::io::Read> Read for R {
|
impl<R: std::io::Read> Read for R {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -70,6 +107,15 @@ impl<R: std::io::Read> Read for R {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<R: std::io::BufRead + Read + ?Sized> BufRead for R {
|
||||||
|
#[inline]
|
||||||
|
fn fill_buf(&mut self) -> Result<&[u8]> { Ok(std::io::BufRead::fill_buf(self)?) }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn consume(&mut self, amount: usize) { std::io::BufRead::consume(self, amount) }
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
impl Read for &[u8] {
|
impl Read for &[u8] {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -81,6 +127,16 @@ impl Read for &[u8] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "std"))]
|
||||||
|
impl BufRead for &[u8] {
|
||||||
|
#[inline]
|
||||||
|
fn fill_buf(&mut self) -> Result<&[u8]> { Ok(self) }
|
||||||
|
|
||||||
|
// This panics if amount is out of bounds, same as the std version.
|
||||||
|
#[inline]
|
||||||
|
fn consume(&mut self, amount: usize) { *self = &self[amount..] }
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Cursor<T> {
|
pub struct Cursor<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
pos: u64,
|
pos: u64,
|
||||||
|
@ -110,6 +166,20 @@ impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: AsRef<[u8]>> BufRead for Cursor<T> {
|
||||||
|
#[inline]
|
||||||
|
fn fill_buf(&mut self) -> Result<&[u8]> {
|
||||||
|
let inner: &[u8] = self.inner.as_ref();
|
||||||
|
Ok(&inner[self.pos as usize..])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn consume(&mut self, amount: usize) {
|
||||||
|
assert!(amount <= self.inner.as_ref().len());
|
||||||
|
self.pos += amount as u64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A generic trait describing an output stream. See [`std::io::Write`] for more info.
|
/// A generic trait describing an output stream. See [`std::io::Write`] for more info.
|
||||||
pub trait Write {
|
pub trait Write {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize>;
|
fn write(&mut self, buf: &[u8]) -> Result<usize>;
|
||||||
|
@ -197,3 +267,30 @@ impl std::io::Write for Sink {
|
||||||
/// Returns a sink to which all writes succeed. See [`std::io::sink`] for more info.
|
/// Returns a sink to which all writes succeed. See [`std::io::sink`] for more info.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sink() -> Sink { Sink }
|
pub fn sink() -> Sink { Sink }
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn buf_read_fill_and_consume_slice() {
|
||||||
|
let data = [0_u8, 1, 2];
|
||||||
|
|
||||||
|
let mut slice = &data[..];
|
||||||
|
|
||||||
|
let fill = BufRead::fill_buf(&mut slice).unwrap();
|
||||||
|
assert_eq!(fill.len(), 3);
|
||||||
|
assert_eq!(fill, &[0_u8, 1, 2]);
|
||||||
|
slice.consume(2);
|
||||||
|
|
||||||
|
let fill = BufRead::fill_buf(&mut slice).unwrap();
|
||||||
|
assert_eq!(fill.len(), 1);
|
||||||
|
assert_eq!(fill, &[2_u8]);
|
||||||
|
slice.consume(1);
|
||||||
|
|
||||||
|
// checks we can attempt to read from a now-empty reader.
|
||||||
|
let fill = BufRead::fill_buf(&mut slice).unwrap();
|
||||||
|
assert_eq!(fill.len(), 0);
|
||||||
|
assert_eq!(fill, &[]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue