eliminate type parameter from the `Decodable` trait

This commit is contained in:
Andrew Poelstra 2019-07-11 17:06:42 +00:00
parent 42960b959f
commit 3b9a94a178
15 changed files with 166 additions and 156 deletions

View File

@ -30,7 +30,7 @@ use std::{error, fmt, io};
#[cfg(feature = "serde")] use serde; #[cfg(feature = "serde")] use serde;
use blockdata::opcodes; use blockdata::opcodes;
use consensus::{encode, Decodable, Encodable, ReadExt}; use consensus::{encode, Decodable, Encodable};
use bitcoin_hashes::{hash160, sha256, Hash}; use bitcoin_hashes::{hash160, sha256, Hash};
#[cfg(feature="bitcoinconsensus")] use bitcoinconsensus; #[cfg(feature="bitcoinconsensus")] use bitcoinconsensus;
#[cfg(feature="bitcoinconsensus")] use std::convert; #[cfg(feature="bitcoinconsensus")] use std::convert;
@ -735,9 +735,9 @@ impl Encodable for Script {
} }
} }
impl<D: ReadExt> Decodable<D> for Script { impl Decodable for Script {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Script, encode::Error> { fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
Ok(Script(Decodable::consensus_decode(d)?)) Ok(Script(Decodable::consensus_decode(d)?))
} }
} }

View File

@ -34,7 +34,7 @@ use bitcoin_hashes::hex::FromHex;
use util::hash::BitcoinHash; use util::hash::BitcoinHash;
#[cfg(feature="bitcoinconsensus")] use blockdata::script; #[cfg(feature="bitcoinconsensus")] use blockdata::script;
use blockdata::script::Script; use blockdata::script::Script;
use consensus::{encode, serialize, Decodable, Encodable, ReadExt}; use consensus::{encode, serialize, Decodable, Encodable};
use VarInt; use VarInt;
/// A reference to a transaction output /// A reference to a transaction output
@ -448,10 +448,10 @@ impl Encodable for OutPoint {
Ok(len + self.vout.consensus_encode(s)?) Ok(len + self.vout.consensus_encode(s)?)
} }
} }
impl<D: ReadExt> Decodable<D> for OutPoint { impl Decodable for OutPoint {
fn consensus_decode(d: &mut D) -> Result<OutPoint, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
Ok(OutPoint { Ok(OutPoint {
txid: Decodable::consensus_decode(d)?, txid: Decodable::consensus_decode(&mut d)?,
vout: Decodable::consensus_decode(d)?, vout: Decodable::consensus_decode(d)?,
}) })
} }
@ -469,11 +469,11 @@ impl Encodable for TxIn {
Ok(len) Ok(len)
} }
} }
impl<D: ReadExt> Decodable<D> for TxIn { impl Decodable for TxIn {
fn consensus_decode(d: &mut D) -> Result<TxIn, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
Ok(TxIn { Ok(TxIn {
previous_output: Decodable::consensus_decode(d)?, previous_output: Decodable::consensus_decode(&mut d)?,
script_sig: Decodable::consensus_decode(d)?, script_sig: Decodable::consensus_decode(&mut d)?,
sequence: Decodable::consensus_decode(d)?, sequence: Decodable::consensus_decode(d)?,
witness: vec![], witness: vec![],
}) })
@ -511,20 +511,20 @@ impl Encodable for Transaction {
} }
} }
impl<D: ReadExt> Decodable<D> for Transaction { impl Decodable for Transaction {
fn consensus_decode(d: &mut D) -> Result<Transaction, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
let version: u32 = Decodable::consensus_decode(d)?; let version = u32::consensus_decode(&mut d)?;
let input: Vec<TxIn> = Decodable::consensus_decode(d)?; let input = Vec::<TxIn>::consensus_decode(&mut d)?;
// segwit // segwit
if input.is_empty() { if input.is_empty() {
let segwit_flag: u8 = Decodable::consensus_decode(d)?; let segwit_flag = u8::consensus_decode(&mut d)?;
match segwit_flag { match segwit_flag {
// BIP144 input witnesses // BIP144 input witnesses
1 => { 1 => {
let mut input: Vec<TxIn> = Decodable::consensus_decode(d)?; let mut input = Vec::<TxIn>::consensus_decode(&mut d)?;
let output: Vec<TxOut> = Decodable::consensus_decode(d)?; let output = Vec::<TxOut>::consensus_decode(&mut d)?;
for txin in input.iter_mut() { for txin in input.iter_mut() {
txin.witness = Decodable::consensus_decode(d)?; txin.witness = Decodable::consensus_decode(&mut d)?;
} }
if !input.is_empty() && input.iter().all(|input| input.witness.is_empty()) { if !input.is_empty() && input.iter().all(|input| input.witness.is_empty()) {
Err(encode::Error::ParseFailed("witness flag set but no witnesses present")) Err(encode::Error::ParseFailed("witness flag set but no witnesses present"))
@ -547,7 +547,7 @@ impl<D: ReadExt> Decodable<D> for Transaction {
Ok(Transaction { Ok(Transaction {
version: version, version: version,
input: input, input: input,
output: Decodable::consensus_decode(d)?, output: Decodable::consensus_decode(&mut d)?,
lock_time: Decodable::consensus_decode(d)?, lock_time: Decodable::consensus_decode(d)?,
}) })
} }

View File

@ -212,9 +212,7 @@ pub fn serialize_hex<T: Encodable + ?Sized>(data: &T) -> String {
/// Deserialize an object from a vector, will error if said deserialization /// Deserialize an object from a vector, will error if said deserialization
/// doesn't consume the entire vector. /// doesn't consume the entire vector.
pub fn deserialize<'a, T>(data: &'a [u8]) -> Result<T, Error> pub fn deserialize<'a, T: Decodable>(data: &'a [u8]) -> Result<T, Error> {
where T: Decodable<Cursor<&'a [u8]>>
{
let (rv, consumed) = deserialize_partial(data)?; let (rv, consumed) = deserialize_partial(data)?;
// Fail if data are not consumed entirely. // Fail if data are not consumed entirely.
@ -227,9 +225,9 @@ pub fn deserialize<'a, T>(data: &'a [u8]) -> Result<T, Error>
/// Deserialize an object from a vector, but will not report an error if said deserialization /// Deserialize an object from a vector, but will not report an error if said deserialization
/// doesn't consume the entire vector. /// doesn't consume the entire vector.
pub fn deserialize_partial<'a, T>(data: &'a [u8]) -> Result<(T, usize), Error> pub fn deserialize_partial<'a, T: Decodable>(
where T: Decodable<Cursor<&'a [u8]>> data: &'a [u8],
{ ) -> Result<(T, usize), Error> {
let mut decoder = Cursor::new(data); let mut decoder = Cursor::new(data);
let rv = Decodable::consensus_decode(&mut decoder)?; let rv = Decodable::consensus_decode(&mut decoder)?;
let consumed = decoder.position() as usize; let consumed = decoder.position() as usize;
@ -374,9 +372,9 @@ pub trait Encodable {
} }
/// Data which can be encoded in a consensus-consistent way /// Data which can be encoded in a consensus-consistent way
pub trait Decodable<D: ReadExt>: Sized { pub trait Decodable: Sized {
/// Decode an object with a well-defined format /// Decode an object with a well-defined format
fn consensus_decode(d: &mut D) -> Result<Self, self::Error>; fn consensus_decode<D: io::Read>(d: D) -> Result<Self, Error>;
} }
/// A variable-length unsigned integer /// A variable-length unsigned integer
@ -390,9 +388,11 @@ pub struct CheckedData(pub Vec<u8>);
// Primitive types // Primitive types
macro_rules! impl_int_encodable{ macro_rules! impl_int_encodable{
($ty:ident, $meth_dec:ident, $meth_enc:ident) => ( ($ty:ident, $meth_dec:ident, $meth_enc:ident) => (
impl<D: ReadExt> Decodable<D> for $ty { impl Decodable for $ty {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<$ty, self::Error> { d.$meth_dec().map($ty::from_le) } fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
ReadExt::$meth_dec(&mut d).map($ty::from_le)
}
} }
impl Encodable for $ty { impl Encodable for $ty {
@ -459,13 +459,13 @@ impl Encodable for VarInt {
} }
} }
impl<D: ReadExt> Decodable<D> for VarInt { impl Decodable for VarInt {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<VarInt, self::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
let n = d.read_u8()?; let n = ReadExt::read_u8(&mut d)?;
match n { match n {
0xFF => { 0xFF => {
let x = d.read_u64()?; let x = ReadExt::read_u64(&mut d)?;
if x < 0x100000000 { if x < 0x100000000 {
Err(self::Error::ParseFailed("non-minimal varint")) Err(self::Error::ParseFailed("non-minimal varint"))
} else { } else {
@ -473,7 +473,7 @@ impl<D: ReadExt> Decodable<D> for VarInt {
} }
} }
0xFE => { 0xFE => {
let x = d.read_u32()?; let x = ReadExt::read_u32(&mut d)?;
if x < 0x10000 { if x < 0x10000 {
Err(self::Error::ParseFailed("non-minimal varint")) Err(self::Error::ParseFailed("non-minimal varint"))
} else { } else {
@ -481,7 +481,7 @@ impl<D: ReadExt> Decodable<D> for VarInt {
} }
} }
0xFD => { 0xFD => {
let x = d.read_u16()?; let x = ReadExt::read_u16(&mut d)?;
if x < 0xFD { if x < 0xFD {
Err(self::Error::ParseFailed("non-minimal varint")) Err(self::Error::ParseFailed("non-minimal varint"))
} else { } else {
@ -503,9 +503,11 @@ impl Encodable for bool {
} }
} }
impl<D: ReadExt> Decodable<D> for bool { impl Decodable for bool {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<bool, self::Error> { d.read_u8().map(|n| n != 0) } fn consensus_decode<D: io::Read>(mut d: D) -> Result<bool, Error> {
ReadExt::read_u8(&mut d).map(|n| n != 0)
}
} }
// Strings // Strings
@ -519,9 +521,9 @@ impl Encodable for String {
} }
} }
impl<D: ReadExt> Decodable<D> for String { impl Decodable for String {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<String, self::Error> { fn consensus_decode<D: io::Read>(d: D) -> Result<String, Error> {
String::from_utf8(Decodable::consensus_decode(d)?) String::from_utf8(Decodable::consensus_decode(d)?)
.map_err(|_| self::Error::ParseFailed("String was not valid UTF8")) .map_err(|_| self::Error::ParseFailed("String was not valid UTF8"))
} }
@ -542,9 +544,9 @@ macro_rules! impl_array {
} }
} }
impl<D: ReadExt> Decodable<D> for [u8; $size] { impl Decodable for [u8; $size] {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<[u8; $size], self::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
let mut ret = [0; $size]; let mut ret = [0; $size];
d.read_slice(&mut ret)?; d.read_slice(&mut ret)?;
Ok(ret) Ok(ret)
@ -561,12 +563,12 @@ impl_array!(16);
impl_array!(32); impl_array!(32);
impl_array!(33); impl_array!(33);
impl<D: ReadExt> Decodable<D> for [u16; 8] { impl Decodable for [u16; 8] {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<[u16; 8], self::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
let mut res = [0; 8]; let mut res = [0; 8];
for i in 0..8 { for i in 0..8 {
res[i] = Decodable::consensus_decode(d)?; res[i] = Decodable::consensus_decode(&mut d)?;
} }
Ok(res) Ok(res)
} }
@ -598,10 +600,10 @@ macro_rules! impl_vec {
} }
} }
impl<D: ReadExt> Decodable<D> for Vec<$type> { impl Decodable for Vec<$type> {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Vec<$type>, self::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
let len = VarInt::consensus_decode(d)?.0; let len = VarInt::consensus_decode(&mut d)?.0;
let byte_size = (len as usize) let byte_size = (len as usize)
.checked_mul(mem::size_of::<$type>()) .checked_mul(mem::size_of::<$type>())
.ok_or(self::Error::ParseFailed("Invalid length"))?; .ok_or(self::Error::ParseFailed("Invalid length"))?;
@ -609,7 +611,9 @@ macro_rules! impl_vec {
return Err(self::Error::OversizedVectorAllocation { requested: byte_size, max: MAX_VEC_SIZE }) return Err(self::Error::OversizedVectorAllocation { requested: byte_size, max: MAX_VEC_SIZE })
} }
let mut ret = Vec::with_capacity(len as usize); let mut ret = Vec::with_capacity(len as usize);
for _ in 0..len { ret.push(Decodable::consensus_decode(d)?); } for _ in 0..len {
ret.push(Decodable::consensus_decode(&mut d)?);
}
Ok(ret) Ok(ret)
} }
} }
@ -633,11 +637,10 @@ impl Encodable for Vec<u8> {
} }
} }
impl<D: ReadExt> Decodable<D> for Vec<u8> { impl Decodable for Vec<u8> {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Vec<u8>, self::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
let len = VarInt::consensus_decode(d)?.0; let len = VarInt::consensus_decode(&mut d)?.0 as usize;
let len = len as usize;
if len > MAX_VEC_SIZE { if len > MAX_VEC_SIZE {
return Err(self::Error::OversizedVectorAllocation { requested: len, max: MAX_VEC_SIZE }) return Err(self::Error::OversizedVectorAllocation { requested: len, max: MAX_VEC_SIZE })
} }
@ -657,10 +660,10 @@ impl Encodable for Box<[u8]> {
} }
} }
impl<D: ReadExt> Decodable<D> for Box<[u8]> { impl Decodable for Box<[u8]> {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Box<[u8]>, self::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
let len = VarInt::consensus_decode(d)?.0; let len = VarInt::consensus_decode(&mut d)?.0;
let len = len as usize; let len = len as usize;
if len > MAX_VEC_SIZE { if len > MAX_VEC_SIZE {
return Err(self::Error::OversizedVectorAllocation { requested: len, max: MAX_VEC_SIZE }) return Err(self::Error::OversizedVectorAllocation { requested: len, max: MAX_VEC_SIZE })
@ -690,17 +693,17 @@ impl Encodable for CheckedData {
} }
} }
impl<D: ReadExt> Decodable<D> for CheckedData { impl Decodable for CheckedData {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<CheckedData, self::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
let len: u32 = Decodable::consensus_decode(d)?; let len = u32::consensus_decode(&mut d)?;
if len > MAX_VEC_SIZE as u32 { if len > MAX_VEC_SIZE as u32 {
return Err(self::Error::OversizedVectorAllocation { return Err(self::Error::OversizedVectorAllocation {
requested: len as usize, requested: len as usize,
max: MAX_VEC_SIZE max: MAX_VEC_SIZE
}); });
} }
let checksum: [u8; 4] = Decodable::consensus_decode(d)?; let checksum = <[u8; 4]>::consensus_decode(&mut d)?;
let mut ret = Vec::with_capacity(len as usize); let mut ret = Vec::with_capacity(len as usize);
ret.resize(len as usize, 0); ret.resize(len as usize, 0);
d.read_slice(&mut ret)?; d.read_slice(&mut ret)?;
@ -733,11 +736,11 @@ macro_rules! tuple_encode {
} }
} }
impl<D: ReadExt, $($x: Decodable<D>),*> Decodable<D> for ($($x),*) { impl<$($x: Decodable),*> Decodable for ($($x),*) {
#[inline] #[inline]
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn consensus_decode(d: &mut D) -> Result<($($x),*), self::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, Error> {
Ok(($({let $x = Decodable::consensus_decode(d)?; $x }),*)) Ok(($({let $x = Decodable::consensus_decode(&mut d)?; $x }),*))
} }
} }
); );
@ -754,9 +757,9 @@ impl Encodable for sha256d::Hash {
} }
} }
impl<D: ReadExt> Decodable<D> for sha256d::Hash { impl Decodable for sha256d::Hash {
fn consensus_decode(d: &mut D) -> Result<sha256d::Hash, self::Error> { fn consensus_decode<D: io::Read>(d: D) -> Result<Self, Error> {
let inner: [u8; 32] = Decodable::consensus_decode(d)?; let inner = <[u8; 32]>::consensus_decode(d)?;
Ok(sha256d::Hash::from_slice(&inner).unwrap()) Ok(sha256d::Hash::from_slice(&inner).unwrap())
} }
} }

View File

@ -30,11 +30,13 @@ macro_rules! impl_consensus_encoding {
} }
} }
impl<D: ::consensus::ReadExt> ::consensus::Decodable<D> for $thing { impl ::consensus::Decodable for $thing {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<$thing, ::consensus::encode::Error> { fn consensus_decode<D: ::std::io::Read>(
mut d: D,
) -> Result<$thing, ::consensus::encode::Error> {
Ok($thing { Ok($thing {
$( $field: ::consensus::Decodable::consensus_decode(d)?, )+ $($field: ::consensus::Decodable::consensus_decode(&mut d)?),+
}) })
} }
} }

View File

@ -22,8 +22,7 @@ use std::io;
use std::fmt; use std::fmt;
use std::net::{SocketAddr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; use std::net::{SocketAddr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
use consensus::{encode, ReadExt}; use consensus::encode::{self, Decodable, Encodable};
use consensus::encode::{Decodable, Encodable};
/// A message which can be sent on the Bitcoin network /// A message which can be sent on the Bitcoin network
pub struct Address { pub struct Address {
@ -85,12 +84,12 @@ impl Encodable for Address {
} }
} }
impl<D: ReadExt> Decodable<D> for Address { impl Decodable for Address {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Address, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
Ok(Address { Ok(Address {
services: Decodable::consensus_decode(d)?, services: Decodable::consensus_decode(&mut d)?,
address: addr_to_be(Decodable::consensus_decode(d)?), address: addr_to_be(Decodable::consensus_decode(&mut d)?),
port: u16::from_be(Decodable::consensus_decode(d)?) port: u16::from_be(Decodable::consensus_decode(d)?)
}) })
} }

View File

@ -28,9 +28,8 @@ use network::address::Address;
use network::message_network; use network::message_network;
use network::message_blockdata; use network::message_blockdata;
use network::message_filter; use network::message_filter;
use consensus::encode::{Decodable, Encodable}; use consensus::encode::{CheckedData, Decodable, Encodable, VarInt};
use consensus::encode::{CheckedData, VarInt}; use consensus::{encode, serialize};
use consensus::{encode, serialize, ReadExt};
use consensus::encode::MAX_VEC_SIZE; use consensus::encode::MAX_VEC_SIZE;
/// Serializer for command string /// Serializer for command string
@ -56,11 +55,15 @@ impl Encodable for CommandString {
} }
} }
impl<D: ReadExt> Decodable<D> for CommandString { impl Decodable for CommandString {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<CommandString, encode::Error> { fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
let rawbytes: [u8; 12] = Decodable::consensus_decode(d)?; let rawbytes: [u8; 12] = Decodable::consensus_decode(d)?;
let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| if u > 0 { Some(u as char) } else { None })); let rv = iter::FromIterator::from_iter(
rawbytes
.iter()
.filter_map(|&u| if u > 0 { Some(u as char) } else { None })
);
Ok(CommandString(rv)) Ok(CommandString(rv))
} }
} }
@ -218,10 +221,11 @@ impl Encodable for RawNetworkMessage {
} }
struct HeaderDeserializationWrapper(Vec<block::BlockHeader>); struct HeaderDeserializationWrapper(Vec<block::BlockHeader>);
impl<D: ReadExt> Decodable<D> for HeaderDeserializationWrapper {
impl Decodable for HeaderDeserializationWrapper {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<HeaderDeserializationWrapper, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
let len = VarInt::consensus_decode(d)?.0; let len = VarInt::consensus_decode(&mut d)?.0;
let byte_size = (len as usize) let byte_size = (len as usize)
.checked_mul(mem::size_of::<block::BlockHeader>()) .checked_mul(mem::size_of::<block::BlockHeader>())
.ok_or(encode::Error::ParseFailed("Invalid length"))?; .ok_or(encode::Error::ParseFailed("Invalid length"))?;
@ -230,8 +234,8 @@ impl<D: ReadExt> Decodable<D> for HeaderDeserializationWrapper {
} }
let mut ret = Vec::with_capacity(len as usize); let mut ret = Vec::with_capacity(len as usize);
for _ in 0..len { for _ in 0..len {
ret.push(Decodable::consensus_decode(d)?); ret.push(Decodable::consensus_decode(&mut d)?);
if <u8 as Decodable<D>>::consensus_decode(d)? != 0u8 { if u8::consensus_decode(&mut d)? != 0u8 {
return Err(encode::Error::ParseFailed("Headers message should not contain transactions")); return Err(encode::Error::ParseFailed("Headers message should not contain transactions"));
} }
} }
@ -239,11 +243,11 @@ impl<D: ReadExt> Decodable<D> for HeaderDeserializationWrapper {
} }
} }
impl<D: ReadExt> Decodable<D> for RawNetworkMessage { impl Decodable for RawNetworkMessage {
fn consensus_decode(d: &mut D) -> Result<RawNetworkMessage, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
let magic = Decodable::consensus_decode(d)?; let magic = Decodable::consensus_decode(&mut d)?;
let CommandString(cmd): CommandString= Decodable::consensus_decode(d)?; let cmd = CommandString::consensus_decode(&mut d)?.0;
let CheckedData(raw_payload): CheckedData = Decodable::consensus_decode(d)?; let raw_payload = CheckedData::consensus_decode(&mut d)?.0;
let mut mem_d = Cursor::new(raw_payload); let mut mem_d = Cursor::new(raw_payload);
let payload = match &cmd[..] { let payload = match &cmd[..] {
@ -257,9 +261,9 @@ impl<D: ReadExt> Decodable<D> for RawNetworkMessage {
"getheaders" => NetworkMessage::GetHeaders(Decodable::consensus_decode(&mut mem_d)?), "getheaders" => NetworkMessage::GetHeaders(Decodable::consensus_decode(&mut mem_d)?),
"mempool" => NetworkMessage::MemPool, "mempool" => NetworkMessage::MemPool,
"block" => NetworkMessage::Block(Decodable::consensus_decode(&mut mem_d)?), "block" => NetworkMessage::Block(Decodable::consensus_decode(&mut mem_d)?),
"headers" => "headers" => NetworkMessage::Headers(
NetworkMessage::Headers(<HeaderDeserializationWrapper as Decodable<Cursor<Vec<u8>>>> HeaderDeserializationWrapper::consensus_decode(&mut mem_d)?.0
::consensus_decode(&mut mem_d)?.0), ),
"sendheaders" => NetworkMessage::SendHeaders, "sendheaders" => NetworkMessage::SendHeaders,
"getaddr" => NetworkMessage::GetAddr, "getaddr" => NetworkMessage::GetAddr,
"ping" => NetworkMessage::Ping(Decodable::consensus_decode(&mut mem_d)?), "ping" => NetworkMessage::Ping(Decodable::consensus_decode(&mut mem_d)?),

View File

@ -19,8 +19,7 @@
//! //!
use network::constants; use network::constants;
use consensus::encode::{Decodable, Encodable}; use consensus::encode::{self, Decodable, Encodable};
use consensus::{encode, ReadExt};
use bitcoin_hashes::sha256d; use bitcoin_hashes::sha256d;
use std::io; use std::io;
@ -120,10 +119,10 @@ impl Encodable for Inventory {
} }
} }
impl<D: ReadExt> Decodable<D> for Inventory { impl Decodable for Inventory {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Inventory, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
let int_type: u32 = Decodable::consensus_decode(d)?; let int_type: u32 = Decodable::consensus_decode(&mut d)?;
Ok(Inventory { Ok(Inventory {
inv_type: match int_type { inv_type: match int_type {
0 => InvType::Error, 0 => InvType::Error,

View File

@ -427,7 +427,6 @@ mod tests {
assert_eq!(&addr.to_string(), "bc1qvzvkjn4q3nszqxrv3nraga2r822xjty3ykvkuw"); assert_eq!(&addr.to_string(), "bc1qvzvkjn4q3nszqxrv3nraga2r822xjty3ykvkuw");
} }
#[test] #[test]
fn test_p2wsh () { fn test_p2wsh () {
// stolen from Bitcoin transaction 5df912fda4becb1c29e928bec8d64d93e9ba8efa9b5b405bd683c86fd2c65667 // stolen from Bitcoin transaction 5df912fda4becb1c29e928bec8d64d93e9ba8efa9b5b405bd683c86fd2c65667
@ -436,7 +435,6 @@ mod tests {
assert_eq!(&addr.to_string(), "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej"); assert_eq!(&addr.to_string(), "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej");
} }
#[test] #[test]
fn test_bip173_vectors() { fn test_bip173_vectors() {
let addrstr = "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4"; let addrstr = "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4";

View File

@ -62,8 +62,7 @@ use std::io;
use bitcoin_hashes::{sha256d, Hash}; use bitcoin_hashes::{sha256d, Hash};
use blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT}; use blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT};
use consensus::encode::{Encodable, Error}; use consensus::encode::{self, Decodable, Encodable};
use consensus::{Decodable, ReadExt};
use util::hash::BitcoinHash; use util::hash::BitcoinHash;
use util::merkleblock::MerkleBlockError::*; use util::merkleblock::MerkleBlockError::*;
use {Block, BlockHeader}; use {Block, BlockHeader};
@ -355,7 +354,10 @@ impl PartialMerkleTree {
} }
impl Encodable for PartialMerkleTree { impl Encodable for PartialMerkleTree {
fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, Error> { fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
let ret = self.num_transactions.consensus_encode(&mut s)? let ret = self.num_transactions.consensus_encode(&mut s)?
+ self.hashes.consensus_encode(&mut s)?; + self.hashes.consensus_encode(&mut s)?;
let mut bytes: Vec<u8> = vec![0; (self.bits.len() + 7) / 8]; let mut bytes: Vec<u8> = vec![0; (self.bits.len() + 7) / 8];
@ -366,10 +368,10 @@ impl Encodable for PartialMerkleTree {
} }
} }
impl<D: ReadExt> Decodable<D> for PartialMerkleTree { impl Decodable for PartialMerkleTree {
fn consensus_decode(d: &mut D) -> Result<Self, Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
let num_transactions: u32 = Decodable::consensus_decode(d)?; let num_transactions: u32 = Decodable::consensus_decode(&mut d)?;
let hashes: Vec<sha256d::Hash> = Decodable::consensus_decode(d)?; let hashes: Vec<sha256d::Hash> = Decodable::consensus_decode(&mut d)?;
let bytes: Vec<u8> = Decodable::consensus_decode(d)?; let bytes: Vec<u8> = Decodable::consensus_decode(d)?;
let mut bits: Vec<bool> = vec![false; bytes.len() * 8]; let mut bits: Vec<bool> = vec![false; bytes.len() * 8];
@ -473,17 +475,20 @@ impl MerkleBlock {
} }
impl Encodable for MerkleBlock { impl Encodable for MerkleBlock {
fn consensus_encode<S: io::Write>(&self, mut s: S) -> Result<usize, Error> { fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
let len = self.header.consensus_encode(&mut s)? let len = self.header.consensus_encode(&mut s)?
+ self.txn.consensus_encode(s)?; + self.txn.consensus_encode(s)?;
Ok(len) Ok(len)
} }
} }
impl<D: ReadExt> Decodable<D> for MerkleBlock { impl Decodable for MerkleBlock {
fn consensus_decode(d: &mut D) -> Result<Self, Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
Ok(MerkleBlock { Ok(MerkleBlock {
header: Decodable::consensus_decode(d)?, header: Decodable::consensus_decode(&mut d)?,
txn: Decodable::consensus_decode(d)?, txn: Decodable::consensus_decode(d)?,
}) })
} }

View File

@ -75,12 +75,14 @@ macro_rules! impl_psbtmap_consensus_encoding {
macro_rules! impl_psbtmap_consensus_decoding { macro_rules! impl_psbtmap_consensus_decoding {
($thing:ty) => { ($thing:ty) => {
impl<D: ::consensus::ReadExt> ::consensus::Decodable<D> for $thing { impl ::consensus::Decodable for $thing {
fn consensus_decode(d: &mut D) -> Result<Self, ::consensus::encode::Error> { fn consensus_decode<D: ::std::io::Read>(
mut d: D,
) -> Result<Self, ::consensus::encode::Error> {
let mut rv: Self = ::std::default::Default::default(); let mut rv: Self = ::std::default::Default::default();
loop { loop {
match ::consensus::Decodable::consensus_decode(d) { match ::consensus::Decodable::consensus_decode(&mut d) {
Ok(pair) => ::util::psbt::Map::insert_pair(&mut rv, pair)?, Ok(pair) => ::util::psbt::Map::insert_pair(&mut rv, pair)?,
Err(::consensus::encode::Error::Psbt(::util::psbt::Error::NoMorePairs)) => return Ok(rv), Err(::consensus::encode::Error::Psbt(::util::psbt::Error::NoMorePairs)) => return Ok(rv),
Err(e) => return Err(e), Err(e) => return Err(e),

View File

@ -13,10 +13,10 @@
// //
use std::collections::HashMap; use std::collections::HashMap;
use std::io::Cursor; use std::io::{self, Cursor};
use blockdata::transaction::Transaction; use blockdata::transaction::Transaction;
use consensus::{encode, Encodable, Decodable, ReadExt}; use consensus::{encode, Encodable, Decodable};
use util::psbt::map::Map; use util::psbt::map::Map;
use util::psbt::raw; use util::psbt::raw;
use util::psbt; use util::psbt;
@ -120,14 +120,14 @@ impl Map for Global {
impl_psbtmap_consensus_encoding!(Global); impl_psbtmap_consensus_encoding!(Global);
impl<D: ReadExt> Decodable<D> for Global { impl Decodable for Global {
fn consensus_decode(d: &mut D) -> Result<Self, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
let mut tx: Option<Transaction> = None; let mut tx: Option<Transaction> = None;
let mut unknowns: HashMap<raw::Key, Vec<u8>> = Default::default(); let mut unknowns: HashMap<raw::Key, Vec<u8>> = Default::default();
loop { loop {
match raw::Pair::consensus_decode(d) { match raw::Pair::consensus_decode(&mut d) {
Ok(pair) => { Ok(pair) => {
match pair.key.type_value { match pair.key.type_value {
0u8 => { 0u8 => {

View File

@ -20,7 +20,7 @@
use blockdata::script::Script; use blockdata::script::Script;
use blockdata::transaction::Transaction; use blockdata::transaction::Transaction;
use consensus::{encode, Encodable, Decodable, ReadExt}; use consensus::{encode, Encodable, Decodable};
use std::io; use std::io;
@ -114,19 +114,19 @@ impl Encodable for PartiallySignedTransaction {
} }
} }
impl<D: ReadExt> Decodable<D> for PartiallySignedTransaction { impl Decodable for PartiallySignedTransaction {
fn consensus_decode(d: &mut D) -> Result<Self, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
let magic: [u8; 4] = Decodable::consensus_decode(d)?; let magic: [u8; 4] = Decodable::consensus_decode(&mut d)?;
if *b"psbt" != magic { if *b"psbt" != magic {
return Err(Error::InvalidMagic.into()); return Err(Error::InvalidMagic.into());
} }
if 0xff_u8 != u8::consensus_decode(d)? { if 0xff_u8 != u8::consensus_decode(&mut d)? {
return Err(Error::InvalidSeparator.into()); return Err(Error::InvalidSeparator.into());
} }
let global: Global = Decodable::consensus_decode(d)?; let global: Global = Decodable::consensus_decode(&mut d)?;
let inputs: Vec<Input> = { let inputs: Vec<Input> = {
let inputs_len: usize = (&global.unsigned_tx.input).len(); let inputs_len: usize = (&global.unsigned_tx.input).len();
@ -134,7 +134,7 @@ impl<D: ReadExt> Decodable<D> for PartiallySignedTransaction {
let mut inputs: Vec<Input> = Vec::with_capacity(inputs_len); let mut inputs: Vec<Input> = Vec::with_capacity(inputs_len);
for _ in 0..inputs_len { for _ in 0..inputs_len {
inputs.push(Decodable::consensus_decode(d)?); inputs.push(Decodable::consensus_decode(&mut d)?);
} }
inputs inputs
@ -146,7 +146,7 @@ impl<D: ReadExt> Decodable<D> for PartiallySignedTransaction {
let mut outputs: Vec<Output> = Vec::with_capacity(outputs_len); let mut outputs: Vec<Output> = Vec::with_capacity(outputs_len);
for _ in 0..outputs_len { for _ in 0..outputs_len {
outputs.push(Decodable::consensus_decode(d)?); outputs.push(Decodable::consensus_decode(&mut d)?);
} }
outputs outputs

View File

@ -19,8 +19,7 @@
use std::{fmt, io}; use std::{fmt, io};
use consensus::encode::{Decodable, Encodable, VarInt, MAX_VEC_SIZE}; use consensus::encode::{self, Decodable, Encodable, VarInt, MAX_VEC_SIZE};
use consensus::{encode, ReadExt};
use util::psbt::Error; use util::psbt::Error;
/// A PSBT key in its raw byte form. /// A PSBT key in its raw byte form.
@ -52,9 +51,9 @@ impl fmt::Display for Key {
} }
} }
impl<D: ReadExt> Decodable<D> for Key { impl Decodable for Key {
fn consensus_decode(d: &mut D) -> Result<Self, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
let VarInt(byte_size): VarInt = Decodable::consensus_decode(d)?; let VarInt(byte_size): VarInt = Decodable::consensus_decode(&mut d)?;
if byte_size == 0 { if byte_size == 0 {
return Err(Error::NoMorePairs.into()); return Err(Error::NoMorePairs.into());
@ -63,14 +62,17 @@ impl<D: ReadExt> Decodable<D> for Key {
let key_byte_size: u64 = byte_size - 1; let key_byte_size: u64 = byte_size - 1;
if key_byte_size > MAX_VEC_SIZE as u64 { if key_byte_size > MAX_VEC_SIZE as u64 {
return Err(encode::Error::OversizedVectorAllocation { requested: key_byte_size as usize, max: MAX_VEC_SIZE } ) return Err(encode::Error::OversizedVectorAllocation {
requested: key_byte_size as usize,
max: MAX_VEC_SIZE,
})
} }
let type_value: u8 = Decodable::consensus_decode(d)?; let type_value: u8 = Decodable::consensus_decode(&mut d)?;
let mut key = Vec::with_capacity(key_byte_size as usize); let mut key = Vec::with_capacity(key_byte_size as usize);
for _ in 0..key_byte_size { for _ in 0..key_byte_size {
key.push(Decodable::consensus_decode(d)?); key.push(Decodable::consensus_decode(&mut d)?);
} }
Ok(Key { Ok(Key {
@ -108,10 +110,10 @@ impl Encodable for Pair {
} }
} }
impl<D: ReadExt> Decodable<D> for Pair { impl Decodable for Pair {
fn consensus_decode(d: &mut D) -> Result<Self, encode::Error> { fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
Ok(Pair { Ok(Pair {
key: Decodable::consensus_decode(d)?, key: Decodable::consensus_decode(&mut d)?,
value: Decodable::consensus_decode(d)?, value: Decodable::consensus_decode(d)?,
}) })
} }

View File

@ -17,7 +17,7 @@
//! Defines traits used for (de)serializing PSBT values into/from raw //! Defines traits used for (de)serializing PSBT values into/from raw
//! bytes in PSBT key-value pairs. //! bytes in PSBT key-value pairs.
use std::io::{self, Cursor}; use std::io;
use blockdata::script::Script; use blockdata::script::Script;
use blockdata::transaction::{SigHashType, Transaction, TxOut}; use blockdata::transaction::{SigHashType, Transaction, TxOut};
@ -93,16 +93,10 @@ impl Deserialize for (Fingerprint, DerivationPath) {
let fprint: Fingerprint = Fingerprint::from(&bytes[0..4]); let fprint: Fingerprint = Fingerprint::from(&bytes[0..4]);
let mut dpath: Vec<ChildNumber> = Default::default(); let mut dpath: Vec<ChildNumber> = Default::default();
let d = &mut Cursor::new(&bytes[4..]); let mut d = &bytes[4..];
loop { while !d.is_empty() {
match Decodable::consensus_decode(d) { match u32::consensus_decode(&mut d) {
Ok(index) => { Ok(index) => dpath.push(index.into()),
dpath.push(<ChildNumber as From<u32>>::from(index));
if d.position() == (bytes.len() - 4) as u64 {
break;
}
},
Err(e) => return Err(e), Err(e) => return Err(e),
} }
} }

View File

@ -351,12 +351,14 @@ macro_rules! construct_uint {
} }
} }
impl<D: ::consensus::ReadExt> ::consensus::Decodable<D> for $name { impl ::consensus::Decodable for $name {
fn consensus_decode(d: &mut D) -> Result<$name, encode::Error> { fn consensus_decode<D: ::std::io::Read>(
mut d: D,
) -> Result<$name, encode::Error> {
use consensus::Decodable; use consensus::Decodable;
let mut ret: [u64; $n_words] = [0; $n_words]; let mut ret: [u64; $n_words] = [0; $n_words];
for i in 0..$n_words { for i in 0..$n_words {
ret[i] = Decodable::consensus_decode(d)?; ret[i] = Decodable::consensus_decode(&mut d)?;
} }
Ok($name(ret)) Ok($name(ret))
} }