From 6db25db975286716034160b1c1c301f49ff06b1c Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 26 Mar 2015 11:52:20 -0500 Subject: [PATCH] Bunch of error type changes --- src/blockdata/block.rs | 6 ++-- src/blockdata/blockchain.rs | 16 +++++----- src/network/listener.rs | 7 +++-- src/network/message.rs | 18 ++++++------ src/network/message_network.rs | 8 ++--- src/network/serialize.rs | 54 +++++++++++++++++----------------- src/network/socket.rs | 32 +++++++++++--------- src/util/error.rs | 8 ++--- src/util/misc.rs | 22 +++++++------- src/util/uint.rs | 4 +-- 10 files changed, 90 insertions(+), 85 deletions(-) diff --git a/src/blockdata/block.rs b/src/blockdata/block.rs index e0f171e..d4bb8de 100644 --- a/src/blockdata/block.rs +++ b/src/blockdata/block.rs @@ -22,8 +22,8 @@ use std::num::{Zero, from_u64}; -use util::error::{BitcoinResult}; -use util::error::BitcoinError::{SpvBadTarget, SpvBadProofOfWork}; +use util::error; +use util::error::Error::{SpvBadTarget, SpvBadProofOfWork}; use util::hash::Sha256dHash; use util::uint::Uint256; use network::encodable::{ConsensusEncodable, VarInt}; @@ -97,7 +97,7 @@ impl BlockHeader { /// Performs an SPV validation of a block, which confirms that the proof-of-work /// is correct, but does not verify that the transactions are valid or encoded /// correctly. - pub fn spv_validate(&self, required_target: &Uint256) -> BitcoinResult<()> { + pub fn spv_validate(&self, required_target: &Uint256) -> error::Result<()> { let ref target = self.target(); if target != required_target { return Err(SpvBadTarget); diff --git a/src/blockdata/blockchain.rs b/src/blockdata/blockchain.rs index 7493a96..b7d02a8 100644 --- a/src/blockdata/blockchain.rs +++ b/src/blockdata/blockchain.rs @@ -33,8 +33,8 @@ use network::constants::Network::{self, BitcoinTestnet}; use network::encodable::{ConsensusDecodable, ConsensusEncodable}; use network::serialize::{BitcoinHash, SimpleDecoder, SimpleEncoder}; use util::BitArray; -use util::error::BitcoinResult; -use util::error::BitcoinError::{BlockNotFound, DuplicateHash, PrevHashNotFound}; +use util::error; +use util::error::Error::{BlockNotFound, DuplicateHash, PrevHashNotFound}; use util::uint::Uint256; use util::hash::Sha256dHash; use util::patricia_tree::PatriciaTree; @@ -365,7 +365,7 @@ impl Blockchain { } } - fn replace_txdata(&mut self, hash: &Uint256, txdata: Vec, has_txdata: bool) -> BitcoinResult<()> { + fn replace_txdata(&mut self, hash: &Uint256, txdata: Vec, has_txdata: bool) -> error::Result<()> { match self.tree.lookup_mut(hash, 256) { Some(existing_block) => { unsafe { @@ -405,26 +405,26 @@ impl Blockchain { } /// Locates a block in the chain and overwrites its txdata - pub fn add_txdata(&mut self, block: Block) -> BitcoinResult<()> { + pub fn add_txdata(&mut self, block: Block) -> error::Result<()> { self.replace_txdata(&block.header.bitcoin_hash().into_le(), block.txdata, true) } /// Locates a block in the chain and removes its txdata - pub fn remove_txdata(&mut self, hash: Sha256dHash) -> BitcoinResult<()> { + pub fn remove_txdata(&mut self, hash: Sha256dHash) -> error::Result<()> { self.replace_txdata(&hash.into_le(), vec![], false) } /// Adds a block header to the chain - pub fn add_header(&mut self, header: BlockHeader) -> BitcoinResult<()> { + pub fn add_header(&mut self, header: BlockHeader) -> error::Result<()> { self.real_add_block(Block { header: header, txdata: vec![] }, false) } /// Adds a block to the chain - pub fn add_block(&mut self, block: Block) -> BitcoinResult<()> { + pub fn add_block(&mut self, block: Block) -> error::Result<()> { self.real_add_block(block, true) } - fn real_add_block(&mut self, block: Block, has_txdata: bool) -> BitcoinResult<()> { + fn real_add_block(&mut self, block: Block, has_txdata: bool) -> error::Result<()> { // get_prev optimizes the common case where we are extending the best tip #[inline] fn get_prev<'a>(chain: &'a Blockchain, hash: Sha256dHash) -> Option { diff --git a/src/network/listener.rs b/src/network/listener.rs index df01e8c..139c221 100644 --- a/src/network/listener.rs +++ b/src/network/listener.rs @@ -18,7 +18,7 @@ //! to connect to a peer, send network messages, and receive Bitcoin data. //! -use std::io::{IoResult, standard_error, ConnectionFailed}; +use std::io::{Result, Error, ErrorKind}; use network::constants::Network; use network::message; @@ -35,12 +35,13 @@ pub trait Listener { /// Return the network this `Listener` is operating on fn network(&self) -> Network; /// Main listen loop - fn start(&self) -> IoResult<(Receiver, Socket)> { + fn start(&self) -> Result<(Receiver, Socket)> { // Open socket let mut ret_sock = Socket::new(self.network()); match ret_sock.connect(self.peer(), self.port()) { Ok(_) => {}, - Err(_) => return Err(standard_error(ConnectionFailed)) + Err(_) => return Err(Error::new(ErrorKind::ConnectionFailed, + "Listener connection failed", None)) } let mut sock = ret_sock.clone(); diff --git a/src/network/message.rs b/src/network/message.rs index 8632b0f..5beb9de 100644 --- a/src/network/message.rs +++ b/src/network/message.rs @@ -20,7 +20,7 @@ //! use collections::Vec; -use std::io::{IoError, IoResult, OtherIoError}; +use std::io; use std::io::MemReader; use blockdata::block; @@ -69,7 +69,7 @@ pub enum SocketResponse { /// A message was received MessageReceived(NetworkMessage), /// An error occured and the socket needs to close - ConnectionFailed(IoError, Sender<()>) + ConnectionFailed(io::Error, Sender<()>) } #[derive(Clone, PartialEq, Eq, Debug)] @@ -155,8 +155,8 @@ impl, E> ConsensusEncodable for RawNetworkMessage { } } -impl> ConsensusDecodable for RawNetworkMessage { - fn consensus_decode(d: &mut D) -> IoResult { +impl> ConsensusDecodable for RawNetworkMessage { + fn consensus_decode(d: &mut D) -> io::Result { let magic = try!(ConsensusDecodable::consensus_decode(d)); let CommandString(cmd): CommandString= try!(ConsensusDecodable::consensus_decode(d)); let CheckedData(raw_payload): CheckedData = try!(ConsensusDecodable::consensus_decode(d)); @@ -177,8 +177,8 @@ impl> ConsensusDecodable for RawNetworkMess "pong" => Ping(try!(prepend_err("pong", ConsensusDecodable::consensus_decode(&mut mem_d)))), "tx" => Tx(try!(prepend_err("tx", ConsensusDecodable::consensus_decode(&mut mem_d)))), cmd => { - return Err(IoError { - kind: OtherIoError, + return Err(io::Error { + kind: io::ErrorKind::OtherError, desc: "unknown message type", detail: Some(format!("`{}` not recognized", cmd)) }); @@ -195,7 +195,7 @@ impl> ConsensusDecodable for RawNetworkMess mod test { use super::{RawNetworkMessage, CommandString, Verack, Ping}; - use std::io::IoResult; + use std::io::io::Result; use network::serialize::{deserialize, serialize}; @@ -207,11 +207,11 @@ mod test { #[test] fn deserialize_commandstring_test() { - let cs: IoResult = deserialize(vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]); + let cs: io::Result = deserialize(vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]); assert!(cs.is_ok()); assert_eq!(cs.unwrap(), CommandString(String::from_str("Andrew"))); - let short_cs: IoResult = deserialize(vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0]); + let short_cs: io::Result = deserialize(vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0]); assert!(short_cs.is_err()); } diff --git a/src/network/message_network.rs b/src/network/message_network.rs index 4fe3bef..0816e37 100644 --- a/src/network/message_network.rs +++ b/src/network/message_network.rs @@ -18,7 +18,7 @@ //! capabilities //! -use std::io::IoResult; +use std::io::Result; use network::constants; use network::address::Address; @@ -54,7 +54,7 @@ pub struct VersionMessage { impl VersionMessage { // TODO: we have fixed services and relay to 0 /// Constructs a new `version` message - pub fn new(timestamp: i64, mut socket: Socket, nonce: u64, start_height: i32) -> IoResult { + pub fn new(timestamp: i64, mut socket: Socket, nonce: u64, start_height: i32) -> Result { let recv_addr = socket.receiver_address(); let send_addr = socket.sender_address(); // If we are not connected, we might not be able to get these address.s @@ -88,7 +88,7 @@ impl_consensus_encoding!(VersionMessage, version, services, timestamp, mod tests { use super::VersionMessage; - use std::io::IoResult; + use std::io::Result; use serialize::hex::FromHex; use network::serialize::{deserialize, serialize}; @@ -98,7 +98,7 @@ mod tests { // This message is from my satoshi node, morning of May 27 2014 let from_sat = "721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001".from_hex().unwrap(); - let decode: IoResult = deserialize(from_sat.clone()); + let decode: Result = deserialize(from_sat.clone()); assert!(decode.is_ok()); let real_decode = decode.unwrap(); assert_eq!(real_decode.version, 70002); diff --git a/src/network/serialize.rs b/src/network/serialize.rs index 4670fb0..e3ed705 100644 --- a/src/network/serialize.rs +++ b/src/network/serialize.rs @@ -20,7 +20,7 @@ //! use collections::Vec; -use std::io::{IoError, IoResult, OtherIoError, MemReader, MemWriter}; +use std::io::{self, MemReader, MemWriter}; use serialize::hex::ToHex; use network::encodable::{ConsensusDecodable, ConsensusEncodable}; @@ -39,20 +39,20 @@ impl BitcoinHash for Vec { } /// Encode an object into a vector -pub fn serialize, IoError>>(obj: &T) -> IoResult> { +pub fn serialize, io::Error>>(obj: &T) -> io::Result> { let mut encoder = RawEncoder::new(MemWriter::new()); try!(obj.consensus_encode(&mut encoder)); Ok(encoder.unwrap().unwrap()) } /// Encode an object into a hex-encoded string -pub fn serialize_hex, IoError>>(obj: &T) -> IoResult { +pub fn serialize_hex, io::Error>>(obj: &T) -> io::Result { let serial = try!(serialize(obj)); Ok(serial.as_slice().to_hex()) } /// Deserialize an object from a vector -pub fn deserialize, IoError>>(data: Vec) -> IoResult { +pub fn deserialize, io::Error>>(data: Vec) -> io::Result { let mut decoder = RawDecoder::new(MemReader::new(data)); ConsensusDecodable::consensus_decode(&mut decoder) } @@ -144,55 +144,55 @@ pub trait SimpleDecoder { // TODO: trait reform: impl SimpleEncoder for every Encoder, ditto for Decoder -impl SimpleEncoder for RawEncoder { +impl SimpleEncoder for RawEncoder { #[inline] - fn emit_u64(&mut self, v: u64) -> IoResult<()> { self.writer.write_le_u64(v) } + fn emit_u64(&mut self, v: u64) -> io::Result<()> { self.writer.write_le_u64(v) } #[inline] - fn emit_u32(&mut self, v: u32) -> IoResult<()> { self.writer.write_le_u32(v) } + fn emit_u32(&mut self, v: u32) -> io::Result<()> { self.writer.write_le_u32(v) } #[inline] - fn emit_u16(&mut self, v: u16) -> IoResult<()> { self.writer.write_le_u16(v) } + fn emit_u16(&mut self, v: u16) -> io::Result<()> { self.writer.write_le_u16(v) } #[inline] - fn emit_u8(&mut self, v: u8) -> IoResult<()> { self.writer.write_u8(v) } + fn emit_u8(&mut self, v: u8) -> io::Result<()> { self.writer.write_u8(v) } #[inline] - fn emit_i64(&mut self, v: i64) -> IoResult<()> { self.writer.write_le_i64(v) } + fn emit_i64(&mut self, v: i64) -> io::Result<()> { self.writer.write_le_i64(v) } #[inline] - fn emit_i32(&mut self, v: i32) -> IoResult<()> { self.writer.write_le_i32(v) } + fn emit_i32(&mut self, v: i32) -> io::Result<()> { self.writer.write_le_i32(v) } #[inline] - fn emit_i16(&mut self, v: i16) -> IoResult<()> { self.writer.write_le_i16(v) } + fn emit_i16(&mut self, v: i16) -> io::Result<()> { self.writer.write_le_i16(v) } #[inline] - fn emit_i8(&mut self, v: i8) -> IoResult<()> { self.writer.write_i8(v) } + fn emit_i8(&mut self, v: i8) -> io::Result<()> { self.writer.write_i8(v) } #[inline] - fn emit_bool(&mut self, v: bool) -> IoResult<()> { self.writer.write_i8(if v {1} else {0}) } + fn emit_bool(&mut self, v: bool) -> io::Result<()> { self.writer.write_i8(if v {1} else {0}) } } -impl SimpleDecoder for RawDecoder { +impl SimpleDecoder for RawDecoder { #[inline] - fn read_u64(&mut self) -> IoResult { self.reader.read_le_u64() } + fn read_u64(&mut self) -> io::Result { self.reader.read_le_u64() } #[inline] - fn read_u32(&mut self) -> IoResult { self.reader.read_le_u32() } + fn read_u32(&mut self) -> io::Result { self.reader.read_le_u32() } #[inline] - fn read_u16(&mut self) -> IoResult { self.reader.read_le_u16() } + fn read_u16(&mut self) -> io::Result { self.reader.read_le_u16() } #[inline] - fn read_u8(&mut self) -> IoResult { self.reader.read_u8() } + fn read_u8(&mut self) -> io::Result { self.reader.read_u8() } #[inline] - fn read_i64(&mut self) -> IoResult { self.reader.read_le_i64() } + fn read_i64(&mut self) -> io::Result { self.reader.read_le_i64() } #[inline] - fn read_i32(&mut self) -> IoResult { self.reader.read_le_i32() } + fn read_i32(&mut self) -> io::Result { self.reader.read_le_i32() } #[inline] - fn read_i16(&mut self) -> IoResult { self.reader.read_le_i16() } + fn read_i16(&mut self) -> io::Result { self.reader.read_le_i16() } #[inline] - fn read_i8(&mut self) -> IoResult { self.reader.read_i8() } + fn read_i8(&mut self) -> io::Result { self.reader.read_i8() } #[inline] - fn read_bool(&mut self) -> IoResult { self.reader.read_u8().map(|res| res != 0) } + fn read_bool(&mut self) -> io::Result { self.reader.read_u8().map(|res| res != 0) } #[inline] - fn error(&mut self, err: &str) -> IoError { - IoError { - kind: OtherIoError, + fn error(&mut self, err: &str) -> io::Error { + io::Error { + kind: io::ErrorKind::OtherError, desc: "parse error", detail: Some(err.to_string()) } diff --git a/src/network/socket.rs b/src/network/socket.rs index aa1fa15..8ad7f64 100644 --- a/src/network/socket.rs +++ b/src/network/socket.rs @@ -21,7 +21,7 @@ use time::now; use std::rand::task_rng; use rand::Rng; use std::io::{BufferedReader, BufferedWriter}; -use std::io::{IoError, IoResult, NotConnected, OtherIoError, standard_error}; +use std::io::{Error, Result, ErrorKind}; use std::io::net::{ip, tcp}; use std::sync::{Arc, Mutex}; @@ -86,7 +86,7 @@ impl Socket { } /// Connect to the peer - pub fn connect(&mut self, host: &str, port: u16) -> IoResult<()> { + pub fn connect(&mut self, host: &str, port: u16) -> Result<()> { // Boot off any lingering readers or writers if self.socket.is_some() { let _ = self.socket.as_mut().unwrap().close_read(); @@ -107,7 +107,7 @@ impl Socket { } /// Peer address - pub fn receiver_address(&mut self) -> IoResult
{ + pub fn receiver_address(&mut self) -> Result
{ match self.socket { Some(ref mut s) => match s.peer_name() { Ok(addr) => { @@ -119,12 +119,13 @@ impl Socket { } Err(e) => Err(e) }, - None => Err(standard_error(NotConnected)) + None => Err(Error::new(ErrorKind::NotConnected, + "receiver_address: not connected to peer", None)) } } /// Our own address - pub fn sender_address(&mut self) -> IoResult
{ + pub fn sender_address(&mut self) -> Result
{ match self.socket { Some(ref mut s) => match s.socket_name() { Ok(addr) => { @@ -136,12 +137,13 @@ impl Socket { } Err(e) => Err(e) }, - None => Err(standard_error(NotConnected)) + None => Err(Error::new(ErrorKind::NotConnected, + "sender_address: not connected to peer", None)) } } /// Produce a version message appropriate for this socket - pub fn version_message(&mut self, start_height: i32) -> IoResult { + pub fn version_message(&mut self, start_height: i32) -> Result { let timestamp = now().to_timespec().sec; let recv_addr = self.receiver_address(); let send_addr = self.sender_address(); @@ -169,10 +171,11 @@ impl Socket { } /// Send a general message across the line - pub fn send_message(&mut self, payload: NetworkMessage) -> IoResult<()> { + pub fn send_message(&mut self, payload: NetworkMessage) -> Result<()> { let mut writer_lock = self.buffered_writer.lock(); match *writer_lock.deref_mut() { - None => Err(standard_error(NotConnected)), + None => Err(Error::new(ErrorKind::NotConnected, + "send_message: not connected to peer", None)), Some(ref mut writer) => { let message = RawNetworkMessage { magic: self.magic, payload: payload }; try!(message.consensus_encode(&mut RawEncoder::new(writer.by_ref()))); @@ -183,15 +186,16 @@ impl Socket { /// Receive the next message from the peer, decoding the network header /// and verifying its correctness. Returns the undecoded payload. - pub fn receive_message(&mut self) -> IoResult { + pub fn receive_message(&mut self) -> Result { let mut reader_lock = self.buffered_reader.lock(); match *reader_lock.deref_mut() { - None => Err(standard_error(NotConnected)), + None => Err(Error::new(ErrorKind::NotConnected, + "receive_message: not connected to peer", None)), Some(ref mut buf) => { // We need a new scope since the closure in here borrows read_err, // and we try to read it afterward. Letting `iter` go out fixes it. let mut decoder = RawDecoder::new(buf.by_ref()); - let decode: IoResult = ConsensusDecodable::consensus_decode(&mut decoder); + let decode: Result = ConsensusDecodable::consensus_decode(&mut decoder); match decode { // Check for parse errors... Err(e) => { @@ -201,8 +205,8 @@ impl Socket { // Then for magic (this should come before parse error, but we can't // get to it if the deserialization failed). TODO restructure this if ret.magic != self.magic { - Err(IoError { - kind: OtherIoError, + Err(Error { + kind: ErrorKind::OtherError, desc: "bad magic", detail: Some(format!("got magic {:x}, expected {:x}", ret.magic, self.magic)), }) diff --git a/src/util/error.rs b/src/util/error.rs index 35b2c43..56283cc 100644 --- a/src/util/error.rs +++ b/src/util/error.rs @@ -16,16 +16,16 @@ //! //! Various utility functions -use std::io::IoError; +use std::io; /// A success/failure return value -pub type BitcoinResult = Result; +pub type Result = Result; /// A general error code #[derive(PartialEq, Eq, Debug, Clone)] -pub enum BitcoinError { +pub enum Error { /// An I/O error - InputOutput(IoError), + InputOutput(io::Error), /// An object was attempted to be added twice DuplicateHash, /// Some operation was attempted on a block (or blockheader) that doesn't exist diff --git a/src/util/misc.rs b/src/util/misc.rs index 68b970e..3a3ad8c 100644 --- a/src/util/misc.rs +++ b/src/util/misc.rs @@ -16,14 +16,14 @@ //! //! Various utility functions -use std::io::{IoError, IoResult, InvalidInput}; +use std::io::{Error, Result, ErrorKind}; use blockdata::opcodes; use blockdata::opcodes::all::Opcode; use util::iter::Pairable; /// Convert a hexadecimal-encoded string to its corresponding bytes -pub fn hex_bytes(s: &str) -> IoResult> { +pub fn hex_bytes(s: &str) -> Result> { let mut v = vec![]; let mut iter = s.chars().pair(); // Do the parsing @@ -31,13 +31,13 @@ pub fn hex_bytes(s: &str) -> IoResult> { if e.is_err() { return e; } else { match (f.to_digit(16), s.to_digit(16)) { - (None, _) => return Err(IoError { - kind: InvalidInput, + (None, _) => return Err(Error { + kind: ErrorKind::InvalidInput, desc: "invalid hex character", detail: Some(format!("expected hex, got {:}", f)) }), - (_, None) => return Err(IoError { - kind: InvalidInput, + (_, None) => return Err(Error { + kind: ErrorKind::InvalidInput, desc: "invalid hex character", detail: Some(format!("expected hex, got {:}", s)) }), @@ -47,8 +47,8 @@ pub fn hex_bytes(s: &str) -> IoResult> { )); // Check that there was no remainder match iter.remainder() { - Some(_) => Err(IoError { - kind: InvalidInput, + Some(_) => Err(Error { + kind: ErrorKind::InvalidInput, desc: "hexstring of odd length", detail: None }), @@ -57,9 +57,9 @@ pub fn hex_bytes(s: &str) -> IoResult> { } /// Prepend the detail of an IoResult's error with some text to get poor man's backtracing -pub fn prepend_err(s: &str, res: IoResult) -> IoResult { +pub fn prepend_err(s: &str, res: Result) -> Result { res.map_err(|err| { - IoError { + Error { kind: err.kind, desc: err.desc, detail: Some(format!("{}: {}", s, match err.detail { Some(s) => s, None => String::new() })) @@ -68,7 +68,7 @@ pub fn prepend_err(s: &str, res: IoResult) -> IoResult { } /// Dump an error message to the screen -pub fn consume_err(s: &str, res: IoResult) { +pub fn consume_err(s: &str, res: Result) { match res { Ok(_) => {}, Err(e) => { println!("{}: {}", s, e); } diff --git a/src/util/uint.rs b/src/util/uint.rs index f77f610..236394f 100644 --- a/src/util/uint.rs +++ b/src/util/uint.rs @@ -310,10 +310,10 @@ macro_rules! construct_uint { impl fmt::Debug for $name { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use std::fmt::WriteError; + use std::fmt::Error; use network::encodable::ConsensusEncodable; let mut encoder = RawEncoder::new(f.by_ref()); - self.consensus_encode(&mut encoder).map_err(|_| WriteError) + self.consensus_encode(&mut encoder).map_err(|_| Error) } }