Bunch of error type changes

This commit is contained in:
Andrew Poelstra 2015-03-26 11:52:20 -05:00
parent 719f616218
commit 6db25db975
10 changed files with 90 additions and 85 deletions

View File

@ -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);

View File

@ -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<Transaction>, has_txdata: bool) -> BitcoinResult<()> {
fn replace_txdata(&mut self, hash: &Uint256, txdata: Vec<Transaction>, 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<NodePtr> {

View File

@ -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<SocketResponse>, Socket)> {
fn start(&self) -> Result<(Receiver<SocketResponse>, 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();

View File

@ -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<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for RawNetworkMessage {
}
}
impl<D:SimpleDecoder<IoError>> ConsensusDecodable<D, IoError> for RawNetworkMessage {
fn consensus_decode(d: &mut D) -> IoResult<RawNetworkMessage> {
impl<D:SimpleDecoder<io::Error>> ConsensusDecodable<D, io::Error> for RawNetworkMessage {
fn consensus_decode(d: &mut D) -> io::Result<RawNetworkMessage> {
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<D:SimpleDecoder<IoError>> ConsensusDecodable<D, IoError> 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<D:SimpleDecoder<IoError>> ConsensusDecodable<D, IoError> 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<CommandString> = deserialize(vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]);
let cs: io::Result<CommandString> = 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<CommandString> = deserialize(vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0]);
let short_cs: io::Result<CommandString> = deserialize(vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0]);
assert!(short_cs.is_err());
}

View File

@ -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<VersionMessage> {
pub fn new(timestamp: i64, mut socket: Socket, nonce: u64, start_height: i32) -> Result<VersionMessage> {
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<VersionMessage> = deserialize(from_sat.clone());
let decode: Result<VersionMessage> = deserialize(from_sat.clone());
assert!(decode.is_ok());
let real_decode = decode.unwrap();
assert_eq!(real_decode.version, 70002);

View File

@ -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<u8> {
}
/// Encode an object into a vector
pub fn serialize<T: ConsensusEncodable<RawEncoder<MemWriter>, IoError>>(obj: &T) -> IoResult<Vec<u8>> {
pub fn serialize<T: ConsensusEncodable<RawEncoder<MemWriter>, io::Error>>(obj: &T) -> io::Result<Vec<u8>> {
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<T: ConsensusEncodable<RawEncoder<MemWriter>, IoError>>(obj: &T) -> IoResult<String> {
pub fn serialize_hex<T: ConsensusEncodable<RawEncoder<MemWriter>, io::Error>>(obj: &T) -> io::Result<String> {
let serial = try!(serialize(obj));
Ok(serial.as_slice().to_hex())
}
/// Deserialize an object from a vector
pub fn deserialize<T: ConsensusDecodable<RawDecoder<MemReader>, IoError>>(data: Vec<u8>) -> IoResult<T> {
pub fn deserialize<T: ConsensusDecodable<RawDecoder<MemReader>, io::Error>>(data: Vec<u8>) -> io::Result<T> {
let mut decoder = RawDecoder::new(MemReader::new(data));
ConsensusDecodable::consensus_decode(&mut decoder)
}
@ -144,55 +144,55 @@ pub trait SimpleDecoder<E> {
// TODO: trait reform: impl SimpleEncoder for every Encoder, ditto for Decoder
impl<W:Writer> SimpleEncoder<IoError> for RawEncoder<W> {
impl<W:Writer> SimpleEncoder<io::Error> for RawEncoder<W> {
#[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<R:Reader> SimpleDecoder<IoError> for RawDecoder<R> {
impl<R:Reader> SimpleDecoder<io::Error> for RawDecoder<R> {
#[inline]
fn read_u64(&mut self) -> IoResult<u64> { self.reader.read_le_u64() }
fn read_u64(&mut self) -> io::Result<u64> { self.reader.read_le_u64() }
#[inline]
fn read_u32(&mut self) -> IoResult<u32> { self.reader.read_le_u32() }
fn read_u32(&mut self) -> io::Result<u32> { self.reader.read_le_u32() }
#[inline]
fn read_u16(&mut self) -> IoResult<u16> { self.reader.read_le_u16() }
fn read_u16(&mut self) -> io::Result<u16> { self.reader.read_le_u16() }
#[inline]
fn read_u8(&mut self) -> IoResult<u8> { self.reader.read_u8() }
fn read_u8(&mut self) -> io::Result<u8> { self.reader.read_u8() }
#[inline]
fn read_i64(&mut self) -> IoResult<i64> { self.reader.read_le_i64() }
fn read_i64(&mut self) -> io::Result<i64> { self.reader.read_le_i64() }
#[inline]
fn read_i32(&mut self) -> IoResult<i32> { self.reader.read_le_i32() }
fn read_i32(&mut self) -> io::Result<i32> { self.reader.read_le_i32() }
#[inline]
fn read_i16(&mut self) -> IoResult<i16> { self.reader.read_le_i16() }
fn read_i16(&mut self) -> io::Result<i16> { self.reader.read_le_i16() }
#[inline]
fn read_i8(&mut self) -> IoResult<i8> { self.reader.read_i8() }
fn read_i8(&mut self) -> io::Result<i8> { self.reader.read_i8() }
#[inline]
fn read_bool(&mut self) -> IoResult<bool> { self.reader.read_u8().map(|res| res != 0) }
fn read_bool(&mut self) -> io::Result<bool> { 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())
}

View File

@ -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<Address> {
pub fn receiver_address(&mut self) -> Result<Address> {
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<Address> {
pub fn sender_address(&mut self) -> Result<Address> {
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<NetworkMessage> {
pub fn version_message(&mut self, start_height: i32) -> Result<NetworkMessage> {
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<NetworkMessage> {
pub fn receive_message(&mut self) -> Result<NetworkMessage> {
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<RawNetworkMessage> = ConsensusDecodable::consensus_decode(&mut decoder);
let decode: Result<RawNetworkMessage> = 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)),
})

View File

@ -16,16 +16,16 @@
//!
//! Various utility functions
use std::io::IoError;
use std::io;
/// A success/failure return value
pub type BitcoinResult<T> = Result<T, BitcoinError>;
pub type Result<T> = Result<T, Error>;
/// 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

View File

@ -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<Vec<u8>> {
pub fn hex_bytes(s: &str) -> Result<Vec<u8>> {
let mut v = vec![];
let mut iter = s.chars().pair();
// Do the parsing
@ -31,13 +31,13 @@ pub fn hex_bytes(s: &str) -> IoResult<Vec<u8>> {
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<Vec<u8>> {
));
// 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<Vec<u8>> {
}
/// Prepend the detail of an IoResult's error with some text to get poor man's backtracing
pub fn prepend_err<T>(s: &str, res: IoResult<T>) -> IoResult<T> {
pub fn prepend_err<T>(s: &str, res: Result<T>) -> Result<T> {
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<T>(s: &str, res: IoResult<T>) -> IoResult<T> {
}
/// Dump an error message to the screen
pub fn consume_err<T>(s: &str, res: IoResult<T>) {
pub fn consume_err<T>(s: &str, res: Result<T>) {
match res {
Ok(_) => {},
Err(e) => { println!("{}: {}", s, e); }

View File

@ -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)
}
}