From 3b9a94a17818d1949c48324af12e00ac6d9d7533 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 11 Jul 2019 17:06:42 +0000 Subject: [PATCH] eliminate type parameter from the `Decodable` trait --- src/blockdata/script.rs | 6 +- src/blockdata/transaction.rs | 34 ++++++------ src/consensus/encode.rs | 95 ++++++++++++++++---------------- src/internal_macros.rs | 8 ++- src/network/address.rs | 11 ++-- src/network/message.rs | 42 +++++++------- src/network/message_blockdata.rs | 9 ++- src/util/address.rs | 8 +-- src/util/merkleblock.rs | 27 +++++---- src/util/psbt/macros.rs | 8 ++- src/util/psbt/map/global.rs | 10 ++-- src/util/psbt/mod.rs | 16 +++--- src/util/psbt/raw.rs | 24 ++++---- src/util/psbt/serialize.rs | 16 ++---- src/util/uint.rs | 8 ++- 15 files changed, 166 insertions(+), 156 deletions(-) diff --git a/src/blockdata/script.rs b/src/blockdata/script.rs index 116c2bd..a87cb17 100644 --- a/src/blockdata/script.rs +++ b/src/blockdata/script.rs @@ -30,7 +30,7 @@ use std::{error, fmt, io}; #[cfg(feature = "serde")] use serde; use blockdata::opcodes; -use consensus::{encode, Decodable, Encodable, ReadExt}; +use consensus::{encode, Decodable, Encodable}; use bitcoin_hashes::{hash160, sha256, Hash}; #[cfg(feature="bitcoinconsensus")] use bitcoinconsensus; #[cfg(feature="bitcoinconsensus")] use std::convert; @@ -735,9 +735,9 @@ impl Encodable for Script { } } -impl Decodable for Script { +impl Decodable for Script { #[inline] - fn consensus_decode(d: &mut D) -> Result { + fn consensus_decode(d: D) -> Result { Ok(Script(Decodable::consensus_decode(d)?)) } } diff --git a/src/blockdata/transaction.rs b/src/blockdata/transaction.rs index 3d83d06..cd15963 100644 --- a/src/blockdata/transaction.rs +++ b/src/blockdata/transaction.rs @@ -34,7 +34,7 @@ use bitcoin_hashes::hex::FromHex; use util::hash::BitcoinHash; #[cfg(feature="bitcoinconsensus")] use blockdata::script; use blockdata::script::Script; -use consensus::{encode, serialize, Decodable, Encodable, ReadExt}; +use consensus::{encode, serialize, Decodable, Encodable}; use VarInt; /// A reference to a transaction output @@ -448,10 +448,10 @@ impl Encodable for OutPoint { Ok(len + self.vout.consensus_encode(s)?) } } -impl Decodable for OutPoint { - fn consensus_decode(d: &mut D) -> Result { +impl Decodable for OutPoint { + fn consensus_decode(mut d: D) -> Result { Ok(OutPoint { - txid: Decodable::consensus_decode(d)?, + txid: Decodable::consensus_decode(&mut d)?, vout: Decodable::consensus_decode(d)?, }) } @@ -469,11 +469,11 @@ impl Encodable for TxIn { Ok(len) } } -impl Decodable for TxIn { - fn consensus_decode(d: &mut D) -> Result { +impl Decodable for TxIn { + fn consensus_decode(mut d: D) -> Result { Ok(TxIn { - previous_output: Decodable::consensus_decode(d)?, - script_sig: Decodable::consensus_decode(d)?, + previous_output: Decodable::consensus_decode(&mut d)?, + script_sig: Decodable::consensus_decode(&mut d)?, sequence: Decodable::consensus_decode(d)?, witness: vec![], }) @@ -511,20 +511,20 @@ impl Encodable for Transaction { } } -impl Decodable for Transaction { - fn consensus_decode(d: &mut D) -> Result { - let version: u32 = Decodable::consensus_decode(d)?; - let input: Vec = Decodable::consensus_decode(d)?; +impl Decodable for Transaction { + fn consensus_decode(mut d: D) -> Result { + let version = u32::consensus_decode(&mut d)?; + let input = Vec::::consensus_decode(&mut d)?; // segwit if input.is_empty() { - let segwit_flag: u8 = Decodable::consensus_decode(d)?; + let segwit_flag = u8::consensus_decode(&mut d)?; match segwit_flag { // BIP144 input witnesses 1 => { - let mut input: Vec = Decodable::consensus_decode(d)?; - let output: Vec = Decodable::consensus_decode(d)?; + let mut input = Vec::::consensus_decode(&mut d)?; + let output = Vec::::consensus_decode(&mut d)?; 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()) { Err(encode::Error::ParseFailed("witness flag set but no witnesses present")) @@ -547,7 +547,7 @@ impl Decodable for Transaction { Ok(Transaction { version: version, input: input, - output: Decodable::consensus_decode(d)?, + output: Decodable::consensus_decode(&mut d)?, lock_time: Decodable::consensus_decode(d)?, }) } diff --git a/src/consensus/encode.rs b/src/consensus/encode.rs index a1e8822..87b0a45 100644 --- a/src/consensus/encode.rs +++ b/src/consensus/encode.rs @@ -212,9 +212,7 @@ pub fn serialize_hex(data: &T) -> String { /// Deserialize an object from a vector, will error if said deserialization /// doesn't consume the entire vector. -pub fn deserialize<'a, T>(data: &'a [u8]) -> Result - where T: Decodable> -{ +pub fn deserialize<'a, T: Decodable>(data: &'a [u8]) -> Result { let (rv, consumed) = deserialize_partial(data)?; // Fail if data are not consumed entirely. @@ -227,9 +225,9 @@ pub fn deserialize<'a, T>(data: &'a [u8]) -> Result /// Deserialize an object from a vector, but will not report an error if said deserialization /// doesn't consume the entire vector. -pub fn deserialize_partial<'a, T>(data: &'a [u8]) -> Result<(T, usize), Error> - where T: Decodable> -{ +pub fn deserialize_partial<'a, T: Decodable>( + data: &'a [u8], +) -> Result<(T, usize), Error> { let mut decoder = Cursor::new(data); let rv = Decodable::consensus_decode(&mut decoder)?; let consumed = decoder.position() as usize; @@ -374,9 +372,9 @@ pub trait Encodable { } /// Data which can be encoded in a consensus-consistent way -pub trait Decodable: Sized { +pub trait Decodable: Sized { /// Decode an object with a well-defined format - fn consensus_decode(d: &mut D) -> Result; + fn consensus_decode(d: D) -> Result; } /// A variable-length unsigned integer @@ -390,9 +388,11 @@ pub struct CheckedData(pub Vec); // Primitive types macro_rules! impl_int_encodable{ ($ty:ident, $meth_dec:ident, $meth_enc:ident) => ( - impl Decodable for $ty { + impl Decodable for $ty { #[inline] - fn consensus_decode(d: &mut D) -> Result<$ty, self::Error> { d.$meth_dec().map($ty::from_le) } + fn consensus_decode(mut d: D) -> Result { + ReadExt::$meth_dec(&mut d).map($ty::from_le) + } } impl Encodable for $ty { @@ -459,13 +459,13 @@ impl Encodable for VarInt { } } -impl Decodable for VarInt { +impl Decodable for VarInt { #[inline] - fn consensus_decode(d: &mut D) -> Result { - let n = d.read_u8()?; + fn consensus_decode(mut d: D) -> Result { + let n = ReadExt::read_u8(&mut d)?; match n { 0xFF => { - let x = d.read_u64()?; + let x = ReadExt::read_u64(&mut d)?; if x < 0x100000000 { Err(self::Error::ParseFailed("non-minimal varint")) } else { @@ -473,7 +473,7 @@ impl Decodable for VarInt { } } 0xFE => { - let x = d.read_u32()?; + let x = ReadExt::read_u32(&mut d)?; if x < 0x10000 { Err(self::Error::ParseFailed("non-minimal varint")) } else { @@ -481,7 +481,7 @@ impl Decodable for VarInt { } } 0xFD => { - let x = d.read_u16()?; + let x = ReadExt::read_u16(&mut d)?; if x < 0xFD { Err(self::Error::ParseFailed("non-minimal varint")) } else { @@ -503,9 +503,11 @@ impl Encodable for bool { } } -impl Decodable for bool { +impl Decodable for bool { #[inline] - fn consensus_decode(d: &mut D) -> Result { d.read_u8().map(|n| n != 0) } + fn consensus_decode(mut d: D) -> Result { + ReadExt::read_u8(&mut d).map(|n| n != 0) + } } // Strings @@ -519,9 +521,9 @@ impl Encodable for String { } } -impl Decodable for String { +impl Decodable for String { #[inline] - fn consensus_decode(d: &mut D) -> Result { + fn consensus_decode(d: D) -> Result { String::from_utf8(Decodable::consensus_decode(d)?) .map_err(|_| self::Error::ParseFailed("String was not valid UTF8")) } @@ -542,9 +544,9 @@ macro_rules! impl_array { } } - impl Decodable for [u8; $size] { + impl Decodable for [u8; $size] { #[inline] - fn consensus_decode(d: &mut D) -> Result<[u8; $size], self::Error> { + fn consensus_decode(mut d: D) -> Result { let mut ret = [0; $size]; d.read_slice(&mut ret)?; Ok(ret) @@ -561,12 +563,12 @@ impl_array!(16); impl_array!(32); impl_array!(33); -impl Decodable for [u16; 8] { +impl Decodable for [u16; 8] { #[inline] - fn consensus_decode(d: &mut D) -> Result<[u16; 8], self::Error> { + fn consensus_decode(mut d: D) -> Result { let mut res = [0; 8]; for i in 0..8 { - res[i] = Decodable::consensus_decode(d)?; + res[i] = Decodable::consensus_decode(&mut d)?; } Ok(res) } @@ -598,10 +600,10 @@ macro_rules! impl_vec { } } - impl Decodable for Vec<$type> { + impl Decodable for Vec<$type> { #[inline] - fn consensus_decode(d: &mut D) -> Result, self::Error> { - let len = VarInt::consensus_decode(d)?.0; + fn consensus_decode(mut d: D) -> Result { + let len = VarInt::consensus_decode(&mut d)?.0; let byte_size = (len as usize) .checked_mul(mem::size_of::<$type>()) .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 }) } 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) } } @@ -633,11 +637,10 @@ impl Encodable for Vec { } } -impl Decodable for Vec { +impl Decodable for Vec { #[inline] - fn consensus_decode(d: &mut D) -> Result, self::Error> { - let len = VarInt::consensus_decode(d)?.0; - let len = len as usize; + fn consensus_decode(mut d: D) -> Result { + let len = VarInt::consensus_decode(&mut d)?.0 as usize; if len > MAX_VEC_SIZE { return Err(self::Error::OversizedVectorAllocation { requested: len, max: MAX_VEC_SIZE }) } @@ -657,10 +660,10 @@ impl Encodable for Box<[u8]> { } } -impl Decodable for Box<[u8]> { +impl Decodable for Box<[u8]> { #[inline] - fn consensus_decode(d: &mut D) -> Result, self::Error> { - let len = VarInt::consensus_decode(d)?.0; + fn consensus_decode(mut d: D) -> Result { + let len = VarInt::consensus_decode(&mut d)?.0; let len = len as usize; if len > MAX_VEC_SIZE { return Err(self::Error::OversizedVectorAllocation { requested: len, max: MAX_VEC_SIZE }) @@ -690,17 +693,17 @@ impl Encodable for CheckedData { } } -impl Decodable for CheckedData { +impl Decodable for CheckedData { #[inline] - fn consensus_decode(d: &mut D) -> Result { - let len: u32 = Decodable::consensus_decode(d)?; + fn consensus_decode(mut d: D) -> Result { + let len = u32::consensus_decode(&mut d)?; if len > MAX_VEC_SIZE as u32 { return Err(self::Error::OversizedVectorAllocation { requested: len as usize, 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); ret.resize(len as usize, 0); d.read_slice(&mut ret)?; @@ -733,11 +736,11 @@ macro_rules! tuple_encode { } } - impl),*> Decodable for ($($x),*) { + impl<$($x: Decodable),*> Decodable for ($($x),*) { #[inline] #[allow(non_snake_case)] - fn consensus_decode(d: &mut D) -> Result<($($x),*), self::Error> { - Ok(($({let $x = Decodable::consensus_decode(d)?; $x }),*)) + fn consensus_decode(mut d: D) -> Result { + Ok(($({let $x = Decodable::consensus_decode(&mut d)?; $x }),*)) } } ); @@ -754,9 +757,9 @@ impl Encodable for sha256d::Hash { } } -impl Decodable for sha256d::Hash { - fn consensus_decode(d: &mut D) -> Result { - let inner: [u8; 32] = Decodable::consensus_decode(d)?; +impl Decodable for sha256d::Hash { + fn consensus_decode(d: D) -> Result { + let inner = <[u8; 32]>::consensus_decode(d)?; Ok(sha256d::Hash::from_slice(&inner).unwrap()) } } diff --git a/src/internal_macros.rs b/src/internal_macros.rs index 30fe0bb..b712162 100644 --- a/src/internal_macros.rs +++ b/src/internal_macros.rs @@ -30,11 +30,13 @@ macro_rules! impl_consensus_encoding { } } - impl ::consensus::Decodable for $thing { + impl ::consensus::Decodable for $thing { #[inline] - fn consensus_decode(d: &mut D) -> Result<$thing, ::consensus::encode::Error> { + fn consensus_decode( + mut d: D, + ) -> Result<$thing, ::consensus::encode::Error> { Ok($thing { - $( $field: ::consensus::Decodable::consensus_decode(d)?, )+ + $($field: ::consensus::Decodable::consensus_decode(&mut d)?),+ }) } } diff --git a/src/network/address.rs b/src/network/address.rs index 87a9156..ff84124 100644 --- a/src/network/address.rs +++ b/src/network/address.rs @@ -22,8 +22,7 @@ use std::io; use std::fmt; use std::net::{SocketAddr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; -use consensus::{encode, ReadExt}; -use consensus::encode::{Decodable, Encodable}; +use consensus::encode::{self, Decodable, Encodable}; /// A message which can be sent on the Bitcoin network pub struct Address { @@ -85,12 +84,12 @@ impl Encodable for Address { } } -impl Decodable for Address { +impl Decodable for Address { #[inline] - fn consensus_decode(d: &mut D) -> Result { + fn consensus_decode(mut d: D) -> Result { Ok(Address { - services: Decodable::consensus_decode(d)?, - address: addr_to_be(Decodable::consensus_decode(d)?), + services: Decodable::consensus_decode(&mut d)?, + address: addr_to_be(Decodable::consensus_decode(&mut d)?), port: u16::from_be(Decodable::consensus_decode(d)?) }) } diff --git a/src/network/message.rs b/src/network/message.rs index de00d78..7f15ae9 100644 --- a/src/network/message.rs +++ b/src/network/message.rs @@ -28,9 +28,8 @@ use network::address::Address; use network::message_network; use network::message_blockdata; use network::message_filter; -use consensus::encode::{Decodable, Encodable}; -use consensus::encode::{CheckedData, VarInt}; -use consensus::{encode, serialize, ReadExt}; +use consensus::encode::{CheckedData, Decodable, Encodable, VarInt}; +use consensus::{encode, serialize}; use consensus::encode::MAX_VEC_SIZE; /// Serializer for command string @@ -56,11 +55,15 @@ impl Encodable for CommandString { } } -impl Decodable for CommandString { +impl Decodable for CommandString { #[inline] - fn consensus_decode(d: &mut D) -> Result { + fn consensus_decode(d: D) -> Result { 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)) } } @@ -218,10 +221,11 @@ impl Encodable for RawNetworkMessage { } struct HeaderDeserializationWrapper(Vec); -impl Decodable for HeaderDeserializationWrapper { + +impl Decodable for HeaderDeserializationWrapper { #[inline] - fn consensus_decode(d: &mut D) -> Result { - let len = VarInt::consensus_decode(d)?.0; + fn consensus_decode(mut d: D) -> Result { + let len = VarInt::consensus_decode(&mut d)?.0; let byte_size = (len as usize) .checked_mul(mem::size_of::()) .ok_or(encode::Error::ParseFailed("Invalid length"))?; @@ -230,8 +234,8 @@ impl Decodable for HeaderDeserializationWrapper { } let mut ret = Vec::with_capacity(len as usize); for _ in 0..len { - ret.push(Decodable::consensus_decode(d)?); - if >::consensus_decode(d)? != 0u8 { + ret.push(Decodable::consensus_decode(&mut d)?); + if u8::consensus_decode(&mut d)? != 0u8 { return Err(encode::Error::ParseFailed("Headers message should not contain transactions")); } } @@ -239,11 +243,11 @@ impl Decodable for HeaderDeserializationWrapper { } } -impl Decodable for RawNetworkMessage { - fn consensus_decode(d: &mut D) -> Result { - let magic = Decodable::consensus_decode(d)?; - let CommandString(cmd): CommandString= Decodable::consensus_decode(d)?; - let CheckedData(raw_payload): CheckedData = Decodable::consensus_decode(d)?; +impl Decodable for RawNetworkMessage { + fn consensus_decode(mut d: D) -> Result { + let magic = Decodable::consensus_decode(&mut d)?; + let cmd = CommandString::consensus_decode(&mut d)?.0; + let raw_payload = CheckedData::consensus_decode(&mut d)?.0; let mut mem_d = Cursor::new(raw_payload); let payload = match &cmd[..] { @@ -257,9 +261,9 @@ impl Decodable for RawNetworkMessage { "getheaders" => NetworkMessage::GetHeaders(Decodable::consensus_decode(&mut mem_d)?), "mempool" => NetworkMessage::MemPool, "block" => NetworkMessage::Block(Decodable::consensus_decode(&mut mem_d)?), - "headers" => - NetworkMessage::Headers(>>> - ::consensus_decode(&mut mem_d)?.0), + "headers" => NetworkMessage::Headers( + HeaderDeserializationWrapper::consensus_decode(&mut mem_d)?.0 + ), "sendheaders" => NetworkMessage::SendHeaders, "getaddr" => NetworkMessage::GetAddr, "ping" => NetworkMessage::Ping(Decodable::consensus_decode(&mut mem_d)?), diff --git a/src/network/message_blockdata.rs b/src/network/message_blockdata.rs index 7d3a770..6b5243a 100644 --- a/src/network/message_blockdata.rs +++ b/src/network/message_blockdata.rs @@ -19,8 +19,7 @@ //! use network::constants; -use consensus::encode::{Decodable, Encodable}; -use consensus::{encode, ReadExt}; +use consensus::encode::{self, Decodable, Encodable}; use bitcoin_hashes::sha256d; use std::io; @@ -120,10 +119,10 @@ impl Encodable for Inventory { } } -impl Decodable for Inventory { +impl Decodable for Inventory { #[inline] - fn consensus_decode(d: &mut D) -> Result { - let int_type: u32 = Decodable::consensus_decode(d)?; + fn consensus_decode(mut d: D) -> Result { + let int_type: u32 = Decodable::consensus_decode(&mut d)?; Ok(Inventory { inv_type: match int_type { 0 => InvType::Error, diff --git a/src/util/address.rs b/src/util/address.rs index 2449945..909cb78 100644 --- a/src/util/address.rs +++ b/src/util/address.rs @@ -20,13 +20,13 @@ //! ```rust //! extern crate secp256k1; //! extern crate bitcoin; -//! +//! //! use bitcoin::network::constants::Network; //! use bitcoin::util::address::Address; //! use bitcoin::util::key; //! use secp256k1::Secp256k1; //! use secp256k1::rand::thread_rng; -//! +//! //! fn main() { //! // Generate random key pair //! let s = Secp256k1::new(); @@ -34,7 +34,7 @@ //! compressed: true, //! key: s.generate_keypair(&mut thread_rng()).1, //! }; -//! +//! //! // Generate pay-to-pubkey-hash address //! let address = Address::p2pkh(&public_key, Network::Bitcoin); //! } @@ -427,7 +427,6 @@ mod tests { assert_eq!(&addr.to_string(), "bc1qvzvkjn4q3nszqxrv3nraga2r822xjty3ykvkuw"); } - #[test] fn test_p2wsh () { // stolen from Bitcoin transaction 5df912fda4becb1c29e928bec8d64d93e9ba8efa9b5b405bd683c86fd2c65667 @@ -436,7 +435,6 @@ mod tests { assert_eq!(&addr.to_string(), "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej"); } - #[test] fn test_bip173_vectors() { let addrstr = "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4"; diff --git a/src/util/merkleblock.rs b/src/util/merkleblock.rs index bd42d60..aa76479 100644 --- a/src/util/merkleblock.rs +++ b/src/util/merkleblock.rs @@ -62,8 +62,7 @@ use std::io; use bitcoin_hashes::{sha256d, Hash}; use blockdata::constants::{MAX_BLOCK_WEIGHT, MIN_TRANSACTION_WEIGHT}; -use consensus::encode::{Encodable, Error}; -use consensus::{Decodable, ReadExt}; +use consensus::encode::{self, Decodable, Encodable}; use util::hash::BitcoinHash; use util::merkleblock::MerkleBlockError::*; use {Block, BlockHeader}; @@ -355,7 +354,10 @@ impl PartialMerkleTree { } impl Encodable for PartialMerkleTree { - fn consensus_encode(&self, mut s: S) -> Result { + fn consensus_encode( + &self, + mut s: S, + ) -> Result { let ret = self.num_transactions.consensus_encode(&mut s)? + self.hashes.consensus_encode(&mut s)?; let mut bytes: Vec = vec![0; (self.bits.len() + 7) / 8]; @@ -366,10 +368,10 @@ impl Encodable for PartialMerkleTree { } } -impl Decodable for PartialMerkleTree { - fn consensus_decode(d: &mut D) -> Result { - let num_transactions: u32 = Decodable::consensus_decode(d)?; - let hashes: Vec = Decodable::consensus_decode(d)?; +impl Decodable for PartialMerkleTree { + fn consensus_decode(mut d: D) -> Result { + let num_transactions: u32 = Decodable::consensus_decode(&mut d)?; + let hashes: Vec = Decodable::consensus_decode(&mut d)?; let bytes: Vec = Decodable::consensus_decode(d)?; let mut bits: Vec = vec![false; bytes.len() * 8]; @@ -473,17 +475,20 @@ impl MerkleBlock { } impl Encodable for MerkleBlock { - fn consensus_encode(&self, mut s: S) -> Result { + fn consensus_encode( + &self, + mut s: S, + ) -> Result { let len = self.header.consensus_encode(&mut s)? + self.txn.consensus_encode(s)?; Ok(len) } } -impl Decodable for MerkleBlock { - fn consensus_decode(d: &mut D) -> Result { +impl Decodable for MerkleBlock { + fn consensus_decode(mut d: D) -> Result { Ok(MerkleBlock { - header: Decodable::consensus_decode(d)?, + header: Decodable::consensus_decode(&mut d)?, txn: Decodable::consensus_decode(d)?, }) } diff --git a/src/util/psbt/macros.rs b/src/util/psbt/macros.rs index 3531da6..020f1ff 100644 --- a/src/util/psbt/macros.rs +++ b/src/util/psbt/macros.rs @@ -75,12 +75,14 @@ macro_rules! impl_psbtmap_consensus_encoding { macro_rules! impl_psbtmap_consensus_decoding { ($thing:ty) => { - impl ::consensus::Decodable for $thing { - fn consensus_decode(d: &mut D) -> Result { + impl ::consensus::Decodable for $thing { + fn consensus_decode( + mut d: D, + ) -> Result { let mut rv: Self = ::std::default::Default::default(); loop { - match ::consensus::Decodable::consensus_decode(d) { + match ::consensus::Decodable::consensus_decode(&mut d) { Ok(pair) => ::util::psbt::Map::insert_pair(&mut rv, pair)?, Err(::consensus::encode::Error::Psbt(::util::psbt::Error::NoMorePairs)) => return Ok(rv), Err(e) => return Err(e), diff --git a/src/util/psbt/map/global.rs b/src/util/psbt/map/global.rs index 9e14bd6..81fc3f5 100644 --- a/src/util/psbt/map/global.rs +++ b/src/util/psbt/map/global.rs @@ -13,10 +13,10 @@ // use std::collections::HashMap; -use std::io::Cursor; +use std::io::{self, Cursor}; use blockdata::transaction::Transaction; -use consensus::{encode, Encodable, Decodable, ReadExt}; +use consensus::{encode, Encodable, Decodable}; use util::psbt::map::Map; use util::psbt::raw; use util::psbt; @@ -120,14 +120,14 @@ impl Map for Global { impl_psbtmap_consensus_encoding!(Global); -impl Decodable for Global { - fn consensus_decode(d: &mut D) -> Result { +impl Decodable for Global { + fn consensus_decode(mut d: D) -> Result { let mut tx: Option = None; let mut unknowns: HashMap> = Default::default(); loop { - match raw::Pair::consensus_decode(d) { + match raw::Pair::consensus_decode(&mut d) { Ok(pair) => { match pair.key.type_value { 0u8 => { diff --git a/src/util/psbt/mod.rs b/src/util/psbt/mod.rs index 342265c..53b8508 100644 --- a/src/util/psbt/mod.rs +++ b/src/util/psbt/mod.rs @@ -20,7 +20,7 @@ use blockdata::script::Script; use blockdata::transaction::Transaction; -use consensus::{encode, Encodable, Decodable, ReadExt}; +use consensus::{encode, Encodable, Decodable}; use std::io; @@ -114,19 +114,19 @@ impl Encodable for PartiallySignedTransaction { } } -impl Decodable for PartiallySignedTransaction { - fn consensus_decode(d: &mut D) -> Result { - let magic: [u8; 4] = Decodable::consensus_decode(d)?; +impl Decodable for PartiallySignedTransaction { + fn consensus_decode(mut d: D) -> Result { + let magic: [u8; 4] = Decodable::consensus_decode(&mut d)?; if *b"psbt" != magic { 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()); } - let global: Global = Decodable::consensus_decode(d)?; + let global: Global = Decodable::consensus_decode(&mut d)?; let inputs: Vec = { let inputs_len: usize = (&global.unsigned_tx.input).len(); @@ -134,7 +134,7 @@ impl Decodable for PartiallySignedTransaction { let mut inputs: Vec = Vec::with_capacity(inputs_len); for _ in 0..inputs_len { - inputs.push(Decodable::consensus_decode(d)?); + inputs.push(Decodable::consensus_decode(&mut d)?); } inputs @@ -146,7 +146,7 @@ impl Decodable for PartiallySignedTransaction { let mut outputs: Vec = Vec::with_capacity(outputs_len); for _ in 0..outputs_len { - outputs.push(Decodable::consensus_decode(d)?); + outputs.push(Decodable::consensus_decode(&mut d)?); } outputs diff --git a/src/util/psbt/raw.rs b/src/util/psbt/raw.rs index 808f23b..42c52e4 100644 --- a/src/util/psbt/raw.rs +++ b/src/util/psbt/raw.rs @@ -19,8 +19,7 @@ use std::{fmt, io}; -use consensus::encode::{Decodable, Encodable, VarInt, MAX_VEC_SIZE}; -use consensus::{encode, ReadExt}; +use consensus::encode::{self, Decodable, Encodable, VarInt, MAX_VEC_SIZE}; use util::psbt::Error; /// A PSBT key in its raw byte form. @@ -52,9 +51,9 @@ impl fmt::Display for Key { } } -impl Decodable for Key { - fn consensus_decode(d: &mut D) -> Result { - let VarInt(byte_size): VarInt = Decodable::consensus_decode(d)?; +impl Decodable for Key { + fn consensus_decode(mut d: D) -> Result { + let VarInt(byte_size): VarInt = Decodable::consensus_decode(&mut d)?; if byte_size == 0 { return Err(Error::NoMorePairs.into()); @@ -63,14 +62,17 @@ impl Decodable for Key { let key_byte_size: u64 = byte_size - 1; 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); for _ in 0..key_byte_size { - key.push(Decodable::consensus_decode(d)?); + key.push(Decodable::consensus_decode(&mut d)?); } Ok(Key { @@ -108,10 +110,10 @@ impl Encodable for Pair { } } -impl Decodable for Pair { - fn consensus_decode(d: &mut D) -> Result { +impl Decodable for Pair { + fn consensus_decode(mut d: D) -> Result { Ok(Pair { - key: Decodable::consensus_decode(d)?, + key: Decodable::consensus_decode(&mut d)?, value: Decodable::consensus_decode(d)?, }) } diff --git a/src/util/psbt/serialize.rs b/src/util/psbt/serialize.rs index 762d189..8ecd2f3 100644 --- a/src/util/psbt/serialize.rs +++ b/src/util/psbt/serialize.rs @@ -17,7 +17,7 @@ //! Defines traits used for (de)serializing PSBT values into/from raw //! bytes in PSBT key-value pairs. -use std::io::{self, Cursor}; +use std::io; use blockdata::script::Script; use blockdata::transaction::{SigHashType, Transaction, TxOut}; @@ -93,16 +93,10 @@ impl Deserialize for (Fingerprint, DerivationPath) { let fprint: Fingerprint = Fingerprint::from(&bytes[0..4]); let mut dpath: Vec = Default::default(); - let d = &mut Cursor::new(&bytes[4..]); - loop { - match Decodable::consensus_decode(d) { - Ok(index) => { - dpath.push(>::from(index)); - - if d.position() == (bytes.len() - 4) as u64 { - break; - } - }, + let mut d = &bytes[4..]; + while !d.is_empty() { + match u32::consensus_decode(&mut d) { + Ok(index) => dpath.push(index.into()), Err(e) => return Err(e), } } diff --git a/src/util/uint.rs b/src/util/uint.rs index b1856a9..2e26f97 100644 --- a/src/util/uint.rs +++ b/src/util/uint.rs @@ -351,12 +351,14 @@ macro_rules! construct_uint { } } - impl ::consensus::Decodable for $name { - fn consensus_decode(d: &mut D) -> Result<$name, encode::Error> { + impl ::consensus::Decodable for $name { + fn consensus_decode( + mut d: D, + ) -> Result<$name, encode::Error> { use consensus::Decodable; let mut ret: [u64; $n_words] = [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)) }