Change the signature of consensus_encode to return io::Error's

This is instead of encode::Errors because the encoders should
not be allowed to return errors that don't originate in the writer
they are writing into.

This is a part of the method definition that has been relied upon for a
while already.
This commit is contained in:
Steven Roose 2020-10-09 17:04:10 +02:00
parent 026f2dd4d9
commit 61918dfe81
No known key found for this signature in database
GPG Key ID: 2F2A88D7F8D68E87
19 changed files with 78 additions and 73 deletions

View File

@ -831,7 +831,7 @@ impl Encodable for Script {
fn consensus_encode<S: io::Write>(
&self,
s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
self.0.consensus_encode(s)
}
}

View File

@ -490,7 +490,7 @@ impl Encodable for OutPoint {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let len = self.txid.consensus_encode(&mut s)?;
Ok(len + self.vout.consensus_encode(s)?)
}
@ -508,7 +508,7 @@ impl Encodable for TxIn {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let mut len = 0;
len += self.previous_output.consensus_encode(&mut s)?;
len += self.script_sig.consensus_encode(&mut s)?;
@ -531,7 +531,7 @@ impl Encodable for Transaction {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let mut len = 0;
len += self.version.consensus_encode(&mut s)?;
let mut have_witness = self.input.is_empty();

View File

@ -176,28 +176,28 @@ pub fn deserialize_partial<T: Decodable>(
/// Extensions of `Write` to encode data as per Bitcoin consensus
pub trait WriteExt {
/// Output a 64-bit uint
fn emit_u64(&mut self, v: u64) -> Result<(), Error>;
fn emit_u64(&mut self, v: u64) -> Result<(), io::Error>;
/// Output a 32-bit uint
fn emit_u32(&mut self, v: u32) -> Result<(), Error>;
fn emit_u32(&mut self, v: u32) -> Result<(), io::Error>;
/// Output a 16-bit uint
fn emit_u16(&mut self, v: u16) -> Result<(), Error>;
fn emit_u16(&mut self, v: u16) -> Result<(), io::Error>;
/// Output a 8-bit uint
fn emit_u8(&mut self, v: u8) -> Result<(), Error>;
fn emit_u8(&mut self, v: u8) -> Result<(), io::Error>;
/// Output a 64-bit int
fn emit_i64(&mut self, v: i64) -> Result<(), Error>;
fn emit_i64(&mut self, v: i64) -> Result<(), io::Error>;
/// Output a 32-bit int
fn emit_i32(&mut self, v: i32) -> Result<(), Error>;
fn emit_i32(&mut self, v: i32) -> Result<(), io::Error>;
/// Output a 16-bit int
fn emit_i16(&mut self, v: i16) -> Result<(), Error>;
fn emit_i16(&mut self, v: i16) -> Result<(), io::Error>;
/// Output a 8-bit int
fn emit_i8(&mut self, v: i8) -> Result<(), Error>;
fn emit_i8(&mut self, v: i8) -> Result<(), io::Error>;
/// Output a boolean
fn emit_bool(&mut self, v: bool) -> Result<(), Error>;
fn emit_bool(&mut self, v: bool) -> Result<(), io::Error>;
/// Output a byte slice
fn emit_slice(&mut self, v: &[u8]) -> Result<(), Error>;
fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error>;
}
/// Extensions of `Read` to decode data as per Bitcoin consensus
@ -230,8 +230,8 @@ pub trait ReadExt {
macro_rules! encoder_fn {
($name:ident, $val_type:ty, $writefn:ident) => {
#[inline]
fn $name(&mut self, v: $val_type) -> Result<(), Error> {
self.write_all(&endian::$writefn(v)).map_err(Error::Io)
fn $name(&mut self, v: $val_type) -> Result<(), io::Error> {
self.write_all(&endian::$writefn(v))
}
}
}
@ -257,20 +257,20 @@ impl<W: Write> WriteExt for W {
encoder_fn!(emit_i16, i16, i16_to_array_le);
#[inline]
fn emit_i8(&mut self, v: i8) -> Result<(), Error> {
self.write_all(&[v as u8]).map_err(Error::Io)
fn emit_i8(&mut self, v: i8) -> Result<(), io::Error> {
self.write_all(&[v as u8])
}
#[inline]
fn emit_u8(&mut self, v: u8) -> Result<(), Error> {
self.write_all(&[v]).map_err(Error::Io)
fn emit_u8(&mut self, v: u8) -> Result<(), io::Error> {
self.write_all(&[v])
}
#[inline]
fn emit_bool(&mut self, v: bool) -> Result<(), Error> {
self.write_all(&[v as u8]).map_err(Error::Io)
fn emit_bool(&mut self, v: bool) -> Result<(), io::Error> {
self.write_all(&[v as u8])
}
#[inline]
fn emit_slice(&mut self, v: &[u8]) -> Result<(), Error> {
self.write_all(v).map_err(Error::Io)
fn emit_slice(&mut self, v: &[u8]) -> Result<(), io::Error> {
self.write_all(v)
}
}
@ -309,10 +309,11 @@ pub const MAX_VEC_SIZE: usize = 4_000_000;
/// Data which can be encoded in a consensus-consistent way
pub trait Encodable {
/// Encode an object with a well-defined format, should only ever error if
/// the underlying `Write` errors. Returns the number of bytes written on
/// success
fn consensus_encode<W: io::Write>(&self, e: W) -> Result<usize, Error>;
/// Encode an object with a well-defined format.
/// Returns the number of bytes written on success.
///
/// The only errors returned are errors propagated from the writer.
fn consensus_encode<W: io::Write>(&self, writer: W) -> Result<usize, io::Error>;
}
/// Data which can be encoded in a consensus-consistent way
@ -343,7 +344,7 @@ macro_rules! impl_int_encodable{
fn consensus_encode<S: WriteExt>(
&self,
mut s: S,
) -> Result<usize, self::Error> {
) -> Result<usize, io::Error> {
s.$meth_enc(self.to_le())?;
Ok(mem::size_of::<$ty>())
}
@ -377,7 +378,7 @@ impl VarInt {
impl Encodable for VarInt {
#[inline]
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, io::Error> {
match self.0 {
0..=0xFC => {
(self.0 as u8).consensus_encode(s)?;
@ -440,7 +441,7 @@ impl Decodable for VarInt {
// Booleans
impl Encodable for bool {
#[inline]
fn consensus_encode<S: WriteExt>(&self, mut s: S) -> Result<usize, Error> {
fn consensus_encode<S: WriteExt>(&self, mut s: S) -> Result<usize, io::Error> {
s.emit_bool(*self)?;
Ok(1)
}
@ -456,7 +457,7 @@ impl Decodable for bool {
// Strings
impl Encodable for String {
#[inline]
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, io::Error> {
let b = self.as_bytes();
let vi_len = VarInt(b.len() as u64).consensus_encode(&mut s)?;
s.emit_slice(&b)?;
@ -475,7 +476,7 @@ impl Decodable for String {
// Cow<'static, str>
impl Encodable for Cow<'static, str> {
#[inline]
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, io::Error> {
let b = self.as_bytes();
let vi_len = VarInt(b.len() as u64).consensus_encode(&mut s)?;
s.emit_slice(&b)?;
@ -501,7 +502,7 @@ macro_rules! impl_array {
fn consensus_encode<S: WriteExt>(
&self,
mut s: S,
) -> Result<usize, Error> {
) -> Result<usize, io::Error> {
s.emit_slice(&self[..])?;
Ok(self.len())
}
@ -540,7 +541,7 @@ impl Decodable for [u16; 8] {
impl Encodable for [u16; 8] {
#[inline]
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, io::Error> {
for c in self.iter() { c.consensus_encode(&mut s)?; }
Ok(16)
}
@ -554,7 +555,7 @@ macro_rules! impl_vec {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, Error> {
) -> Result<usize, io::Error> {
let mut len = 0;
len += VarInt(self.len() as u64).consensus_encode(&mut s)?;
for c in self.iter() {
@ -595,7 +596,7 @@ impl_vec!((u32, Address));
impl_vec!(u64);
impl_vec!(AddrV2Message);
fn consensus_encode_with_size<S: io::Write>(data: &[u8], mut s: S) -> Result<usize, Error> {
fn consensus_encode_with_size<S: io::Write>(data: &[u8], mut s: S) -> Result<usize, io::Error> {
let vi_len = VarInt(data.len() as u64).consensus_encode(&mut s)?;
s.emit_slice(&data)?;
Ok(vi_len + data.len())
@ -604,7 +605,7 @@ fn consensus_encode_with_size<S: io::Write>(data: &[u8], mut s: S) -> Result<usi
impl Encodable for Vec<u8> {
#[inline]
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, io::Error> {
consensus_encode_with_size(self, s)
}
}
@ -624,7 +625,7 @@ impl Decodable for Vec<u8> {
impl Encodable for Box<[u8]> {
#[inline]
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, io::Error> {
consensus_encode_with_size(self, s)
}
}
@ -646,7 +647,7 @@ fn sha2_checksum(data: &[u8]) -> [u8; 4] {
// Checked data
impl Encodable for CheckedData {
#[inline]
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, io::Error> {
(self.0.len() as u32).consensus_encode(&mut s)?;
sha2_checksum(&self.0).consensus_encode(&mut s)?;
s.emit_slice(&self.0)?;
@ -681,25 +682,25 @@ impl Decodable for CheckedData {
// References
impl<'a, T: Encodable> Encodable for &'a T {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, io::Error> {
(&**self).consensus_encode(s)
}
}
impl<'a, T: Encodable> Encodable for &'a mut T {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, io::Error> {
(&**self).consensus_encode(s)
}
}
impl<T: Encodable> Encodable for ::std::rc::Rc<T> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, io::Error> {
(&**self).consensus_encode(s)
}
}
impl<T: Encodable> Encodable for ::std::sync::Arc<T> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, io::Error> {
(&**self).consensus_encode(s)
}
}
@ -713,7 +714,7 @@ macro_rules! tuple_encode {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, self::Error> {
) -> Result<usize, io::Error> {
let &($(ref $x),*) = self;
let mut len = 0;
$(len += $x.consensus_encode(&mut s)?;)*
@ -740,7 +741,7 @@ tuple_encode!(T0, T1, T2, T3, T4, T5, T6);
tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
impl Encodable for sha256d::Hash {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, Error> {
fn consensus_encode<S: io::Write>(&self, s: S) -> Result<usize, io::Error> {
self.into_inner().consensus_encode(s)
}
}

View File

@ -21,7 +21,7 @@ use hashes::{Hash, sha256, sha256d, hash160};
macro_rules! impl_hashencode {
($hashtype:ident) => {
impl $crate::consensus::Encodable for $hashtype {
fn consensus_encode<S: ::std::io::Write>(&self, s: S) -> Result<usize, $crate::consensus::encode::Error> {
fn consensus_encode<S: ::std::io::Write>(&self, s: S) -> Result<usize, ::std::io::Error> {
self.0.consensus_encode(s)
}
}

View File

@ -23,7 +23,7 @@ macro_rules! impl_consensus_encoding {
fn consensus_encode<S: ::std::io::Write>(
&self,
mut s: S,
) -> Result<usize, $crate::consensus::encode::Error> {
) -> Result<usize, ::std::io::Error> {
let mut len = 0;
$(len += self.$field.consensus_encode(&mut s)?;)+
Ok(len)

View File

@ -77,7 +77,7 @@ impl Encodable for Address {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let len = self.services.consensus_encode(&mut s)?
+ addr_to_be(self.address).consensus_encode(&mut s)?
+ self.port.to_be().consensus_encode(s)?;
@ -136,8 +136,8 @@ pub enum AddrV2 {
}
impl Encodable for AddrV2 {
fn consensus_encode<W: io::Write>(&self, e: W) -> Result<usize, encode::Error> {
fn encode_addr<W: io::Write>(mut e: W, network: u8, bytes: &[u8]) -> Result<usize, encode::Error> {
fn consensus_encode<W: io::Write>(&self, e: W) -> Result<usize, io::Error> {
fn encode_addr<W: io::Write>(mut e: W, network: u8, bytes: &[u8]) -> Result<usize, io::Error> {
let len =
network.consensus_encode(&mut e)? +
VarInt(bytes.len() as u64).consensus_encode(&mut e)? +
@ -261,7 +261,7 @@ impl AddrV2Message {
}
impl Encodable for AddrV2Message {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, encode::Error> {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, io::Error> {
let mut len = 0;
len += self.time.consensus_encode(&mut e)?;
len += VarInt(self.services.as_u64()).consensus_encode(&mut e)?;

View File

@ -276,7 +276,7 @@ impl Encodable for ServiceFlags {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
self.0.consensus_encode(&mut s)
}
}

View File

@ -78,7 +78,7 @@ impl Encodable for CommandString {
fn consensus_encode<S: io::Write>(
&self,
s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let mut rawbytes = [0u8; 12];
let strbytes = self.0.as_bytes();
debug_assert!(strbytes.len() <= 12);
@ -255,7 +255,7 @@ impl<'a> Encodable for HeaderSerializationWrapper<'a> {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let mut len = 0;
len += VarInt(self.0.len() as u64).consensus_encode(&mut s)?;
for header in self.0.iter() {
@ -270,7 +270,7 @@ impl Encodable for RawNetworkMessage {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let mut len = 0;
len += self.magic.consensus_encode(&mut s)?;
len += self.command().consensus_encode(&mut s)?;

View File

@ -55,7 +55,7 @@ impl Encodable for Inventory {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
macro_rules! encode_inv {
($code:expr, $item:expr) => {
u32::consensus_encode(&$code, &mut s)? +

View File

@ -106,7 +106,7 @@ pub enum RejectReason {
}
impl Encodable for RejectReason {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, encode::Error> {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, io::Error> {
e.write_all(&[*self as u8])?;
Ok(1)
}

View File

@ -350,7 +350,7 @@ impl Encodable for PartialMerkleTree {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let ret = self.num_transactions.consensus_encode(&mut s)?
+ self.hashes.consensus_encode(&mut s)?;
let mut bytes: Vec<u8> = vec![0; (self.bits.len() + 7) / 8];
@ -478,7 +478,7 @@ impl Encodable for MerkleBlock {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let len = self.header.consensus_encode(&mut s)?
+ self.txn.consensus_encode(s)?;
Ok(len)

View File

@ -58,7 +58,7 @@ macro_rules! impl_psbtmap_consensus_encoding {
fn consensus_encode<S: ::std::io::Write>(
&self,
mut s: S,
) -> Result<usize, $crate::consensus::encode::Error> {
) -> Result<usize, ::std::io::Error> {
let mut len = 0;
for pair in $crate::util::psbt::Map::get_pairs(self)? {
len += $crate::consensus::Encodable::consensus_encode(

View File

@ -100,7 +100,7 @@ impl Map for Global {
Ok(())
}
fn get_pairs(&self) -> Result<Vec<raw::Pair>, encode::Error> {
fn get_pairs(&self) -> Result<Vec<raw::Pair>, io::Error> {
let mut rv: Vec<raw::Pair> = Default::default();
rv.push(raw::Pair {

View File

@ -12,7 +12,8 @@
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//
use std::collections::btree_map::{Entry, BTreeMap};
use std::io;
use std::collections::btree_map::{BTreeMap, Entry};
use blockdata::script::Script;
use blockdata::transaction::{SigHashType, Transaction, TxOut};
@ -180,10 +181,10 @@ impl Map for Input {
::std::collections::btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key).into()),
}
_ => match self.unknown.entry(raw_key) {
::std::collections::btree_map::Entry::Vacant(empty_key) => {
Entry::Vacant(empty_key) => {
empty_key.insert(raw_value);
}
::std::collections::btree_map::Entry::Occupied(k) => {
Entry::Occupied(k) => {
return Err(Error::DuplicateKey(k.key().clone()).into())
}
},
@ -192,7 +193,7 @@ impl Map for Input {
Ok(())
}
fn get_pairs(&self) -> Result<Vec<raw::Pair>, encode::Error> {
fn get_pairs(&self) -> Result<Vec<raw::Pair>, io::Error> {
let mut rv: Vec<raw::Pair> = Default::default();
impl_psbt_get_pair! {

View File

@ -12,6 +12,8 @@
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//
use std::io;
use consensus::encode;
use util::psbt;
use util::psbt::raw;
@ -22,7 +24,7 @@ pub trait Map {
fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), encode::Error>;
/// Attempt to get all key-value pairs.
fn get_pairs(&self) -> Result<Vec<raw::Pair>, encode::Error>;
fn get_pairs(&self) -> Result<Vec<raw::Pair>, io::Error>;
/// Attempt to merge with another key-value map of the same type.
fn merge(&mut self, other: Self) -> Result<(), psbt::Error>;

View File

@ -12,6 +12,7 @@
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//
use std::io;
use std::collections::BTreeMap;
use std::collections::btree_map::Entry;
@ -90,7 +91,7 @@ impl Map for Output {
Ok(())
}
fn get_pairs(&self) -> Result<Vec<raw::Pair>, encode::Error> {
fn get_pairs(&self) -> Result<Vec<raw::Pair>, io::Error> {
let mut rv: Vec<raw::Pair> = Default::default();
impl_psbt_get_pair! {

View File

@ -95,7 +95,7 @@ impl Encodable for PartiallySignedTransaction {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let mut len = 0;
len += b"psbt".consensus_encode(&mut s)?;

View File

@ -106,7 +106,7 @@ impl Encodable for Key {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let mut len = 0;
len += VarInt((self.key.len() + 1) as u64).consensus_encode(&mut s)?;
@ -124,7 +124,7 @@ impl Encodable for Pair {
fn consensus_encode<S: io::Write>(
&self,
mut s: S,
) -> Result<usize, encode::Error> {
) -> Result<usize, io::Error> {
let len = self.key.consensus_encode(&mut s)?;
Ok(len + self.value.consensus_encode(s)?)
}
@ -140,7 +140,7 @@ impl Decodable for Pair {
}
impl<Subtype> Encodable for ProprietaryKey<Subtype> where Subtype: Copy + From<u8> + Into<u8> {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, encode::Error> {
fn consensus_encode<W: io::Write>(&self, mut e: W) -> Result<usize, io::Error> {
let mut len = self.prefix.consensus_encode(&mut e)? + 1;
e.emit_u8(self.subtype.into())?;
len += e.write(&self.key)?;

View File

@ -381,7 +381,7 @@ macro_rules! construct_uint {
fn consensus_encode<S: ::std::io::Write>(
&self,
mut s: S,
) -> Result<usize, $crate::consensus::encode::Error> {
) -> Result<usize, ::std::io::Error> {
let &$name(ref data) = self;
let mut len = 0;
for word in data.iter() {