From 19b982284b479cb8acb2f5297c5687c25891e950 Mon Sep 17 00:00:00 2001 From: Peter van Nostrand Date: Sun, 20 May 2018 07:51:33 -0400 Subject: [PATCH 1/3] Added error-chain error handling. --- Cargo.toml | 4 ++- examples/network/commst.rs | 2 +- src/agreement.rs | 37 +++++++++++--------- src/broadcast.rs | 71 +++++++++++++++++++------------------- src/common_subset.rs | 66 +++++++++++++++++------------------ src/honey_badger.rs | 58 +++++++++++++++---------------- src/lib.rs | 2 ++ src/proto_io.rs | 49 ++++++++++++-------------- 8 files changed, 144 insertions(+), 145 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5026ec8..403b249 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,12 +7,14 @@ authors = ["Vladimir Komendantskiy "] bincode = "1.0.0" derive_deref = "1.0.1" env_logger = "0.5.10" +error-chain = "0.11.0" itertools = "0.7" log = "0.4.1" merkle = { git = "https://github.com/afck/merkle.rs", branch = "public-proof" } protobuf = { version = "2.0.0", optional = true } rand = "0.4.2" -reed-solomon-erasure = "3.0" +# reed-solomon-erasure = "3.0" +reed-solomon-erasure = { git = "https://github.com/darrenldl/reed-solomon-erasure.git", branch = "dev" } ring = "^0.12" serde = "1.0.55" serde_derive = { version = "1.0.55", optional = true } diff --git a/examples/network/commst.rs b/examples/network/commst.rs index cd4b0a5..90192c5 100644 --- a/examples/network/commst.rs +++ b/examples/network/commst.rs @@ -85,7 +85,7 @@ impl<'a, P: Message + 'a, M: Into

+ From

+ Send + 'a> CommsTask<'a, P, M> message: message.into(), }).unwrap(); } - Err(proto_io::Error::ProtobufError(e)) => { + Err(proto_io::Error::Protobuf(e)) => { warn!("Node {} - Protobuf error {}", node_index, e) } Err(e) => { diff --git a/src/agreement.rs b/src/agreement.rs index 7a24c1f..bf6cd8e 100644 --- a/src/agreement.rs +++ b/src/agreement.rs @@ -8,6 +8,17 @@ use std::mem; use messaging::{DistAlgorithm, Target, TargetedMessage}; +error_chain!{ + types { + Error, ErrorKind, ResultExt, AgreementResult; + } + + errors { + InputNotAccepted + Terminated + } +} + /// Messages sent during the binary Byzantine agreement stage. #[cfg_attr(feature = "serialization-serde", derive(Serialize))] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -74,7 +85,7 @@ impl DistAlgorithm for Agreement Result<(), Self::Error> { + fn input(&mut self, input: Self::Input) -> AgreementResult<()> { self.set_input(input) } @@ -83,9 +94,9 @@ impl DistAlgorithm for Agreement Result<(), Self::Error> { + ) -> AgreementResult<()> { if self.terminated { - return Err(Error::Terminated); + return Err(ErrorKind::Terminated.into()); } if message.epoch() < self.epoch { return Ok(()); // Message is obsolete: We are already in a later epoch. @@ -146,9 +157,9 @@ impl Agreement { } /// Sets the input value for agreement. - pub fn set_input(&mut self, input: bool) -> Result<(), Error> { + pub fn set_input(&mut self, input: bool) -> AgreementResult<()> { if self.epoch != 0 || self.estimated.is_some() { - return Err(Error::InputNotAccepted); + return Err(ErrorKind::InputNotAccepted.into()); } if self.num_nodes == 1 { self.decision = Some(input); @@ -167,7 +178,7 @@ impl Agreement { self.epoch == 0 && self.estimated.is_none() } - fn handle_bval(&mut self, sender_id: &NodeUid, b: bool) -> Result<(), Error> { + fn handle_bval(&mut self, sender_id: &NodeUid, b: bool) -> AgreementResult<()> { self.received_bval .entry(sender_id.clone()) .or_insert_with(BTreeSet::new) @@ -197,7 +208,7 @@ impl Agreement { Ok(()) } - fn send_bval(&mut self, b: bool) -> Result<(), Error> { + fn send_bval(&mut self, b: bool) -> AgreementResult<()> { // Record the value `b` as sent. self.sent_bval.insert(b); // Multicast BVAL. @@ -208,12 +219,12 @@ impl Agreement { self.handle_bval(&our_uid, b) } - fn handle_aux(&mut self, sender_id: &NodeUid, b: bool) -> Result<(), Error> { + fn handle_aux(&mut self, sender_id: &NodeUid, b: bool) -> AgreementResult<()> { self.received_aux.insert(sender_id.clone(), b); self.try_coin() } - fn send_aux(&mut self, b: bool) -> Result<(), Error> { + fn send_aux(&mut self, b: bool) -> AgreementResult<()> { // Multicast AUX. self.messages .push_back(AgreementMessage::Aux(self.epoch, b)); @@ -251,7 +262,7 @@ impl Agreement { /// to compute the next decision estimate and outputs the optional decision /// value. The function may start the next epoch. In that case, it also /// returns a message for broadcast. - fn try_coin(&mut self) -> Result<(), Error> { + fn try_coin(&mut self) -> AgreementResult<()> { if self.bin_values.is_empty() { return Ok(()); } @@ -311,9 +322,3 @@ impl Agreement { Ok(()) } } - -#[derive(Clone, Debug)] -pub enum Error { - Terminated, - InputNotAccepted, -} diff --git a/src/broadcast.rs b/src/broadcast.rs index 4b68b39..2f40eb4 100644 --- a/src/broadcast.rs +++ b/src/broadcast.rs @@ -9,6 +9,25 @@ use std::iter; use messaging::{DistAlgorithm, Target, TargetedMessage}; +error_chain!{ + types { + Error, ErrorKind, ResultExt, BroadcastResult; + } + + foreign_links { + ReedSolomon(rse::Error); + } + + errors { + InstanceCannotPropose + NotImplemented + ProofConstructionFailed + RootHashMismatch + Threading + UnknownSender + } +} + /// The three kinds of message sent during the reliable broadcast stage of the /// consensus algorithm. #[cfg_attr(feature = "serialization-serde", derive(Serialize, Deserialize))] @@ -105,9 +124,9 @@ impl DistAlgorithm for Broadcast { type Message = BroadcastMessage; type Error = Error; - fn input(&mut self, input: Self::Input) -> Result<(), Self::Error> { + fn input(&mut self, input: Self::Input) -> BroadcastResult<()> { if self.our_id != self.proposer_id { - return Err(Error::InstanceCannotPropose); + return Err(ErrorKind::InstanceCannotPropose.into()); } // Split the value into chunks/shards, encode them with erasure codes. // Assemble a Merkle tree from data and parity shards. Take all proofs @@ -119,9 +138,9 @@ impl DistAlgorithm for Broadcast { self.handle_value(&our_id, proof) } - fn handle_message(&mut self, sender_id: &N, message: Self::Message) -> Result<(), Self::Error> { + fn handle_message(&mut self, sender_id: &N, message: Self::Message) -> BroadcastResult<()> { if !self.all_uids.contains(sender_id) { - return Err(Error::UnknownSender); + return Err(ErrorKind::UnknownSender.into()); } match message { BroadcastMessage::Value(p) => self.handle_value(sender_id, p), @@ -150,7 +169,7 @@ impl DistAlgorithm for Broadcast { impl Broadcast { /// Creates a new broadcast instance to be used by node `our_id` which expects a value proposal /// from node `proposer_id`. - pub fn new(our_id: N, proposer_id: N, all_uids: BTreeSet) -> Result { + pub fn new(our_id: N, proposer_id: N, all_uids: BTreeSet) -> BroadcastResult { let num_nodes = all_uids.len(); let num_faulty_nodes = (num_nodes - 1) / 3; let parity_shard_num = 2 * num_faulty_nodes; @@ -180,7 +199,7 @@ impl Broadcast { /// scheme. The returned value contains the shard assigned to this /// node. That shard doesn't need to be sent anywhere. It gets recorded in /// the broadcast instance. - fn send_shards(&mut self, mut value: Vec) -> Result>, Error> { + fn send_shards(&mut self, mut value: Vec) -> BroadcastResult>> { let data_shard_num = self.coding.data_shard_count(); let parity_shard_num = self.coding.parity_shard_count(); @@ -229,14 +248,14 @@ impl Broadcast { let mtree = MerkleTree::from_vec(&digest::SHA256, shards_t); // Default result in case of `gen_proof` error. - let mut result = Err(Error::ProofConstructionFailed); + let mut result = Err(ErrorKind::ProofConstructionFailed.into()); assert_eq!(self.num_nodes, mtree.iter().count()); // Send each proof to a node. for (leaf_value, uid) in mtree.iter().zip(&self.all_uids) { let proof = mtree .gen_proof(leaf_value.to_vec()) - .ok_or(Error::ProofConstructionFailed)?; + .ok_or(ErrorKind::ProofConstructionFailed)?; if *uid == self.our_id { // The proof is addressed to this node. result = Ok(proof); @@ -251,7 +270,7 @@ impl Broadcast { } /// Handles a received echo and verifies the proof it contains. - fn handle_value(&mut self, sender_id: &N, p: Proof>) -> Result<(), Error> { + fn handle_value(&mut self, sender_id: &N, p: Proof>) -> BroadcastResult<()> { // If the sender is not the proposer, this is not the first `Value` or the proof is invalid, // ignore. if *sender_id != self.proposer_id { @@ -279,7 +298,7 @@ impl Broadcast { } /// Handles a received `Echo` message. - fn handle_echo(&mut self, sender_id: &N, p: Proof>) -> Result<(), Error> { + fn handle_echo(&mut self, sender_id: &N, p: Proof>) -> BroadcastResult<()> { // If the proof is invalid or the sender has already sent `Echo`, ignore. if self.echos.contains_key(sender_id) { info!( @@ -310,7 +329,7 @@ impl Broadcast { } /// Handles a received `Ready` message. - fn handle_ready(&mut self, sender_id: &N, hash: &[u8]) -> Result<(), Error> { + fn handle_ready(&mut self, sender_id: &N, hash: &[u8]) -> BroadcastResult<()> { // If the sender has already sent a `Ready` before, ignore. if self.readys.contains_key(sender_id) { info!( @@ -335,7 +354,7 @@ impl Broadcast { /// Checks whether the condition for output are met for this hash, and if so, sets the output /// value. - fn compute_output(&mut self, hash: &[u8]) -> Result<(), Error> { + fn compute_output(&mut self, hash: &[u8]) -> BroadcastResult<()> { if self.decided || self.count_readys(hash) <= 2 * self.num_faulty_nodes || self.count_echos(hash) <= self.num_faulty_nodes { @@ -417,7 +436,7 @@ enum Coding { impl Coding { /// Creates a new `Coding` instance with the given number of shards. - fn new(data_shard_num: usize, parity_shard_num: usize) -> Result { + fn new(data_shard_num: usize, parity_shard_num: usize) -> BroadcastResult { Ok(if parity_shard_num > 0 { let rs = ReedSolomon::new(data_shard_num, parity_shard_num)?; Coding::ReedSolomon(Box::new(rs)) @@ -443,7 +462,7 @@ impl Coding { } /// Constructs (and overwrites) the parity shards. - fn encode(&self, slices: &mut [&mut [u8]]) -> Result<(), Error> { + fn encode(&self, slices: &mut [&mut [u8]]) -> BroadcastResult<()> { match *self { Coding::ReedSolomon(ref rs) => rs.encode(slices)?, Coding::Trivial(_) => (), @@ -452,7 +471,7 @@ impl Coding { } /// If enough shards are present, reconstructs the missing ones. - fn reconstruct_shards(&self, shards: &mut [Option>]) -> Result<(), Error> { + fn reconstruct_shards(&self, shards: &mut [Option>]) -> BroadcastResult<()> { match *self { Coding::ReedSolomon(ref rs) => rs.reconstruct_shards(shards)?, Coding::Trivial(_) => { @@ -465,30 +484,12 @@ impl Coding { } } -/// Errors returned by the broadcast instance. -#[derive(Debug, Clone)] -pub enum Error { - RootHashMismatch, - Threading, - ProofConstructionFailed, - ReedSolomon(rse::Error), - InstanceCannotPropose, - NotImplemented, - UnknownSender, -} - -impl From for Error { - fn from(err: rse::Error) -> Error { - Error::ReedSolomon(err) - } -} - fn decode_from_shards( leaf_values: &mut [Option>], coding: &Coding, data_shard_num: usize, root_hash: &[u8], -) -> Result +) -> BroadcastResult where T: From>, { @@ -513,7 +514,7 @@ where // NOTE: The paper does not define the meaning of *abort*. But it is // sensible not to continue trying to reconstruct the tree after this // point. This instance must have received incorrect shards. - Err(Error::RootHashMismatch) + Err(ErrorKind::RootHashMismatch.into()) } else { // Reconstruct the value from the data shards. Ok(glue_shards(mtree, data_shard_num)) diff --git a/src/common_subset.rs b/src/common_subset.rs index 93e0cad..68887c8 100644 --- a/src/common_subset.rs +++ b/src/common_subset.rs @@ -14,6 +14,25 @@ use broadcast::{Broadcast, BroadcastMessage}; use fmt::HexBytes; use messaging::{DistAlgorithm, Target, TargetedMessage}; +error_chain!{ + types { + Error, ErrorKind, ResultExt, CommonSubsetResult; + } + + links { + Agreement(agreement::Error, agreement::ErrorKind); + Broadcast(broadcast::Error, broadcast::ErrorKind); + } + + errors { + MultipleAgreementResults + NoSuchAgreementInstance + NoSuchBroadcastInstance + NotImplemented + UnexpectedMessage + } +} + // TODO: Make this a generic argument of `Broadcast`. type ProposedValue = Vec; // Type of output from the Common Subset message handler. @@ -98,7 +117,7 @@ impl DistAlgorithm for CommonSubset; type Error = Error; - fn input(&mut self, input: Self::Input) -> Result<(), Self::Error> { + fn input(&mut self, input: Self::Input) -> CommonSubsetResult<()> { self.send_proposed_value(input) } @@ -106,7 +125,7 @@ impl DistAlgorithm for CommonSubset Result<(), Self::Error> { + ) -> CommonSubsetResult<()> { match message { Message::Broadcast(p_id, b_msg) => self.handle_broadcast(sender_id, &p_id, b_msg), Message::Agreement(p_id, a_msg) => self.handle_agreement(sender_id, &p_id, a_msg), @@ -131,7 +150,7 @@ impl DistAlgorithm for CommonSubset CommonSubset { - pub fn new(uid: NodeUid, all_uids: &BTreeSet) -> Result { + pub fn new(uid: NodeUid, all_uids: &BTreeSet) -> CommonSubsetResult { let num_nodes = all_uids.len(); let num_faulty_nodes = (num_nodes - 1) / 3; @@ -170,7 +189,7 @@ impl CommonSubset { /// Common Subset input message handler. It receives a value for broadcast /// and redirects it to the corresponding broadcast instance. - pub fn send_proposed_value(&mut self, value: ProposedValue) -> Result<(), Error> { + pub fn send_proposed_value(&mut self, value: ProposedValue) -> CommonSubsetResult<()> { let uid = self.uid.clone(); // Upon receiving input v_i , input v_i to RBC_i. See Figure 2. self.process_broadcast(&uid, |bc| bc.input(value)) @@ -183,7 +202,7 @@ impl CommonSubset { sender_id: &NodeUid, proposer_id: &NodeUid, bmessage: BroadcastMessage, - ) -> Result<(), Error> { + ) -> CommonSubsetResult<()> { self.process_broadcast(proposer_id, |bc| bc.handle_message(sender_id, bmessage)) } @@ -194,7 +213,7 @@ impl CommonSubset { sender_id: &NodeUid, proposer_id: &NodeUid, amessage: AgreementMessage, - ) -> Result<(), Error> { + ) -> CommonSubsetResult<()> { // Send the message to the local instance of Agreement self.process_agreement(proposer_id, |agreement| { agreement.handle_message(sender_id, amessage) @@ -203,14 +222,14 @@ impl CommonSubset { /// Upon delivery of v_j from RBC_j, if input has not yet been provided to /// BA_j, then provide input 1 to BA_j. See Figure 11. - fn process_broadcast(&mut self, proposer_id: &NodeUid, f: F) -> Result<(), Error> + fn process_broadcast(&mut self, proposer_id: &NodeUid, f: F) -> CommonSubsetResult<()> where F: FnOnce(&mut Broadcast) -> Result<(), broadcast::Error>, { let value = { let broadcast = self.broadcast_instances .get_mut(proposer_id) - .ok_or(Error::NoSuchBroadcastInstance)?; + .ok_or(ErrorKind::NoSuchBroadcastInstance)?; f(broadcast)?; self.messages.extend_broadcast(&proposer_id, broadcast); if let Some(output) = broadcast.next_output() { @@ -231,14 +250,14 @@ impl CommonSubset { /// Callback to be invoked on receipt of the decision value of the Agreement /// instance `uid`. - fn process_agreement(&mut self, proposer_id: &NodeUid, f: F) -> Result<(), Error> + fn process_agreement(&mut self, proposer_id: &NodeUid, f: F) -> CommonSubsetResult<()> where F: FnOnce(&mut Agreement) -> Result<(), agreement::Error>, { let value = { let agreement = self.agreement_instances .get_mut(proposer_id) - .ok_or(Error::NoSuchAgreementInstance)?; + .ok_or(ErrorKind::NoSuchAgreementInstance)?; if agreement.terminated() { return Ok(()); } @@ -254,7 +273,7 @@ impl CommonSubset { .insert(proposer_id.clone(), value) .is_some() { - return Err(Error::MultipleAgreementResults); + return Err(ErrorKind::MultipleAgreementResults.into()); } debug!( "{:?} Updated Agreement results: {:?}", @@ -270,7 +289,7 @@ impl CommonSubset { self.messages.extend_agreement(uid, agreement); if let Some(output) = agreement.next_output() { if self.agreement_results.insert(uid.clone(), output).is_some() { - return Err(Error::MultipleAgreementResults); + return Err(ErrorKind::MultipleAgreementResults.into()); } } } @@ -321,26 +340,3 @@ impl CommonSubset { } } } - -#[derive(Clone, Debug)] -pub enum Error { - UnexpectedMessage, - NotImplemented, - NoSuchBroadcastInstance, - NoSuchAgreementInstance, - MultipleAgreementResults, - Broadcast(broadcast::Error), - Agreement(agreement::Error), -} - -impl From for Error { - fn from(err: broadcast::Error) -> Error { - Error::Broadcast(err) - } -} - -impl From for Error { - fn from(err: agreement::Error) -> Error { - Error::Agreement(err) - } -} diff --git a/src/honey_badger.rs b/src/honey_badger.rs index db33fe8..f0e3668 100644 --- a/src/honey_badger.rs +++ b/src/honey_badger.rs @@ -12,6 +12,25 @@ use serde::Serialize; use common_subset::{self, CommonSubset}; use messaging::{DistAlgorithm, TargetedMessage}; +error_chain!{ + types { + Error, ErrorKind, ResultExt, HoneyBadgerResult; + } + + links { + CommonSubset(common_subset::Error, common_subset::ErrorKind); + } + + foreign_links { + Bincode(Box); + } + + errors { + OwnIdMissing + UnknownSender + } +} + /// An instance of the Honey Badger Byzantine fault tolerant consensus algorithm. pub struct HoneyBadger { /// The buffer of transactions that have not yet been included in any output batch. @@ -46,13 +65,13 @@ where type Message = Message; type Error = Error; - fn input(&mut self, input: Self::Input) -> Result<(), Self::Error> { + fn input(&mut self, input: Self::Input) -> HoneyBadgerResult<()> { self.add_transactions(iter::once(input)) } - fn handle_message(&mut self, sender_id: &N, message: Self::Message) -> Result<(), Self::Error> { + fn handle_message(&mut self, sender_id: &N, message: Self::Message) -> HoneyBadgerResult<()> { if !self.all_uids.contains(sender_id) { - return Err(Error::UnknownSender); + return Err(ErrorKind::UnknownSender.into()); } match message { Message::CommonSubset(epoch, cs_msg) => { @@ -85,14 +104,14 @@ where N: Eq + Hash + Ord + Clone + Debug, { /// Returns a new Honey Badger instance with the given parameters, starting at epoch `0`. - pub fn new(id: N, all_uids_iter: I, batch_size: usize, txs: TI) -> Result + pub fn new(id: N, all_uids_iter: I, batch_size: usize, txs: TI) -> HoneyBadgerResult where I: IntoIterator, TI: IntoIterator, { let all_uids: BTreeSet = all_uids_iter.into_iter().collect(); if !all_uids.contains(&id) { - return Err(Error::OwnIdMissing); + return Err(ErrorKind::OwnIdMissing.into()); } let mut honey_badger = HoneyBadger { buffer: txs.into_iter().collect(), @@ -109,13 +128,13 @@ where } /// Adds transactions into the buffer. - pub fn add_transactions>(&mut self, txs: I) -> Result<(), Error> { + pub fn add_transactions>(&mut self, txs: I) -> HoneyBadgerResult<()> { self.buffer.extend(txs); Ok(()) } /// Proposes a new batch in the current epoch. - fn propose(&mut self) -> Result<(), Error> { + fn propose(&mut self) -> HoneyBadgerResult<()> { let proposal = self.choose_transactions()?; let cs = match self.common_subsets.entry(self.epoch) { Entry::Occupied(entry) => entry.into_mut(), @@ -130,7 +149,7 @@ where /// Returns a random choice of `batch_size / all_uids.len()` buffered transactions, and /// serializes them. - fn choose_transactions(&self) -> Result, Error> { + fn choose_transactions(&self) -> HoneyBadgerResult> { let mut rng = rand::thread_rng(); let amount = cmp::max(1, self.batch_size / self.all_uids.len()); let batch_size = cmp::min(self.batch_size, self.buffer.len()); @@ -151,7 +170,7 @@ where sender_id: &N, epoch: u64, message: common_subset::Message, - ) -> Result<(), Error> { + ) -> HoneyBadgerResult<()> { { // Borrow the instance for `epoch`, or create it. let cs = match self.common_subsets.entry(epoch) { @@ -259,24 +278,3 @@ impl MessageQueue { self.extend(cs.message_iter().map(convert)); } } - -/// A Honey Badger error. -#[derive(Debug)] -pub enum Error { - OwnIdMissing, - UnknownSender, - CommonSubset(common_subset::Error), - Bincode(Box), -} - -impl From for Error { - fn from(err: common_subset::Error) -> Error { - Error::CommonSubset(err) - } -} - -impl From> for Error { - fn from(err: Box) -> Error { - Error::Bincode(err) - } -} diff --git a/src/lib.rs b/src/lib.rs index 20d9525..bb5144a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,8 @@ extern crate bincode; #[macro_use(Deref, DerefMut)] extern crate derive_deref; #[macro_use] +extern crate error_chain; +#[macro_use] extern crate log; extern crate itertools; extern crate merkle; diff --git a/src/proto_io.rs b/src/proto_io.rs index edaa484..7ea093f 100644 --- a/src/proto_io.rs +++ b/src/proto_io.rs @@ -1,6 +1,6 @@ //! Protobuf message IO task structure. -use protobuf::{self, Message}; +use protobuf::{self, Message, ProtobufError}; use std::io::{Read, Write}; use std::marker::PhantomData; use std::net::TcpStream; @@ -12,31 +12,26 @@ use std::{cmp, io}; /// TODO: Replace it with a proper handshake at connection initiation. const FRAME_START: u32 = 0x2C0F_FEE5; -#[derive(Debug)] -pub enum Error { - IoError(io::Error), - EncodeError, - DecodeError, - FrameStartMismatch, - // ProtocolError, - ProtobufError(protobuf::ProtobufError), -} +error_chain!{ + types { + Error, ErrorKind, ResultExt, ProtoIoResult; + } -impl From for Error { - fn from(err: io::Error) -> Error { - Error::IoError(err) + foreign_links { + Io(io::Error); + Protobuf(ProtobufError); + } + + errors { + Decode + Encode + FrameStartMismatch } } -impl From for Error { - fn from(err: protobuf::ProtobufError) -> Error { - Error::ProtobufError(err) - } -} - -fn encode_u32_to_be(value: u32, buffer: &mut [u8]) -> Result<(), Error> { +fn encode_u32_to_be(value: u32, buffer: &mut [u8]) -> ProtoIoResult<()> { if buffer.len() < 4 { - return Err(Error::EncodeError); + return Err(ErrorKind::Encode.into()); } let value = value.to_le(); buffer[0] = ((value & 0xFF00_0000) >> 24) as u8; @@ -46,9 +41,9 @@ fn encode_u32_to_be(value: u32, buffer: &mut [u8]) -> Result<(), Error> { Ok(()) } -fn decode_u32_from_be(buffer: &[u8]) -> Result { +fn decode_u32_from_be(buffer: &[u8]) -> ProtoIoResult { if buffer.len() < 4 { - return Err(Error::DecodeError); + return Err(ErrorKind::Decode.into()); } let mut result = u32::from(buffer[0]); result <<= 8; @@ -88,11 +83,11 @@ impl ProtoIo } } - pub fn recv(&mut self) -> Result { + pub fn recv(&mut self) -> ProtoIoResult { self.stream.read_exact(&mut self.buffer[0..4])?; let frame_start = decode_u32_from_be(&self.buffer[0..4])?; if frame_start != FRAME_START { - return Err(Error::FrameStartMismatch); + return Err(ErrorKind::FrameStartMismatch.into()); }; self.stream.read_exact(&mut self.buffer[0..4])?; let size = decode_u32_from_be(&self.buffer[0..4])? as usize; @@ -106,10 +101,10 @@ impl ProtoIo message_v.extend_from_slice(slice); } - protobuf::parse_from_bytes(&message_v).map_err(Error::ProtobufError) + protobuf::parse_from_bytes(&message_v).map_err(|e| e.into()) } - pub fn send(&mut self, message: &M) -> Result<(), Error> { + pub fn send(&mut self, message: &M) -> ProtoIoResult<()> { let mut buffer: [u8; 4] = [0; 4]; // Wrap stream let mut stream = protobuf::CodedOutputStream::new(&mut self.stream); From 465f17d9a598ac66a68f53170df91d3e5a9122e7 Mon Sep 17 00:00:00 2001 From: Peter van Nostrand Date: Sun, 20 May 2018 19:39:47 -0400 Subject: [PATCH 2/3] Bumped reed-solomon-erasure crate version, fixed Protobuf error in example. --- Cargo.toml | 3 +-- examples/network/commst.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 403b249..110353e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,7 @@ log = "0.4.1" merkle = { git = "https://github.com/afck/merkle.rs", branch = "public-proof" } protobuf = { version = "2.0.0", optional = true } rand = "0.4.2" -# reed-solomon-erasure = "3.0" -reed-solomon-erasure = { git = "https://github.com/darrenldl/reed-solomon-erasure.git", branch = "dev" } +reed-solomon-erasure = "3.1.0" ring = "^0.12" serde = "1.0.55" serde_derive = { version = "1.0.55", optional = true } diff --git a/examples/network/commst.rs b/examples/network/commst.rs index 90192c5..0773394 100644 --- a/examples/network/commst.rs +++ b/examples/network/commst.rs @@ -85,7 +85,7 @@ impl<'a, P: Message + 'a, M: Into

+ From

+ Send + 'a> CommsTask<'a, P, M> message: message.into(), }).unwrap(); } - Err(proto_io::Error::Protobuf(e)) => { + Err(proto_io::Error(proto_io::ErrorKind::Protobuf(e), _)) { warn!("Node {} - Protobuf error {}", node_index, e) } Err(e) => { From 1930ea8b7d7bc7edd5af3bf2c9f4c15ae7bf1b3a Mon Sep 17 00:00:00 2001 From: Peter van Nostrand Date: Sun, 20 May 2018 19:52:18 -0400 Subject: [PATCH 3/3] Fixed a typo commst.rs. --- examples/network/commst.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/network/commst.rs b/examples/network/commst.rs index 0773394..de9d348 100644 --- a/examples/network/commst.rs +++ b/examples/network/commst.rs @@ -85,7 +85,7 @@ impl<'a, P: Message + 'a, M: Into

+ From

+ Send + 'a> CommsTask<'a, P, M> message: message.into(), }).unwrap(); } - Err(proto_io::Error(proto_io::ErrorKind::Protobuf(e), _)) { + Err(proto_io::Error(proto_io::ErrorKind::Protobuf(e), _)) => { warn!("Node {} - Protobuf error {}", node_index, e) } Err(e) => {