diff --git a/src/chainfilter.rs b/src/chainfilter.rs index 076263fbb..e1804c191 100644 --- a/src/chainfilter.rs +++ b/src/chainfilter.rs @@ -18,7 +18,7 @@ //! let filter = ChainFilter::new(&cache, index_size, bloom_levels); //! let block_number = 39; //! let mut bloom = H2048::new(); -//! bloom.shift_bloom(&address.sha3()); +//! bloom.shift_bloomed(&address.sha3()); //! filter.add_bloom(&bloom, block_number) //! }; //! @@ -296,14 +296,14 @@ impl<'a, D> ChainFilter<'a, D> where D: FilterDataSource /// Returns numbers of blocks that may contain Address. pub fn blocks_with_address(&self, address: &Address, from_block: usize, to_block: usize) -> Vec { let mut bloom = H2048::new(); - bloom.shift_bloom(&address.sha3()); + bloom.shift_bloomed(&address.sha3()); self.blocks_with_bloom(&bloom, from_block, to_block) } /// Returns numbers of blocks that may contain Topic. pub fn blocks_with_topic(&self, topic: &H256, from_block: usize, to_block: usize) -> Vec { let mut bloom = H2048::new(); - bloom.shift_bloom(&topic.sha3()); + bloom.shift_bloomed(&topic.sha3()); self.blocks_with_bloom(&bloom, from_block, to_block) } @@ -415,7 +415,7 @@ mod tests { let filter = ChainFilter::new(&cache, index_size, bloom_levels); let block_number = 23; let mut bloom = H2048::new(); - bloom.shift_bloom(&topic.sha3()); + bloom.shift_bloomed(&topic.sha3()); filter.add_bloom(&bloom, block_number) }; diff --git a/src/common.rs b/src/common.rs new file mode 100644 index 000000000..39294155c --- /dev/null +++ b/src/common.rs @@ -0,0 +1,7 @@ +pub use standard::*; +pub use error::*; +pub use hash::*; +pub use uint::*; +pub use bytes::*; +pub use vector::*; +pub use sha3::*; diff --git a/src/error.rs b/src/error.rs index 24b0cc87e..fbe57a98b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,8 @@ //! General error types for use in ethcore. -use rustc_serialize::hex::*; +use rustc_serialize::hex::FromHexError; +use network::NetworkError; +use rlp::DecoderError; #[derive(Debug)] pub enum BaseDataError { @@ -9,22 +11,58 @@ pub enum BaseDataError { #[derive(Debug)] /// General error type which should be capable of representing all errors in ethcore. -pub enum EthcoreError { +pub enum UtilError { + Crypto(::crypto::CryptoError), + Io(::std::io::Error), + AddressParse(::std::net::AddrParseError), + AddressResolve(Option<::std::io::Error>), FromHex(FromHexError), BaseData(BaseDataError), + Network(NetworkError), + Decoder(DecoderError), BadSize, UnknownName, } -impl From for EthcoreError { - fn from(err: FromHexError) -> EthcoreError { - EthcoreError::FromHex(err) +impl From for UtilError { + fn from(err: FromHexError) -> UtilError { + UtilError::FromHex(err) } } -impl From for EthcoreError { - fn from(err: BaseDataError) -> EthcoreError { - EthcoreError::BaseData(err) +impl From for UtilError { + fn from(err: BaseDataError) -> UtilError { + UtilError::BaseData(err) + } +} + +impl From for UtilError { + fn from(err: NetworkError) -> UtilError { + UtilError::Network(err) + } +} + +impl From<::std::io::Error> for UtilError { + fn from(err: ::std::io::Error) -> UtilError { + UtilError::Io(err) + } +} + +impl From<::crypto::CryptoError> for UtilError { + fn from(err: ::crypto::CryptoError) -> UtilError { + UtilError::Crypto(err) + } +} + +impl From<::std::net::AddrParseError> for UtilError { + fn from(err: ::std::net::AddrParseError) -> UtilError { + UtilError::AddressParse(err) + } +} + +impl From<::rlp::DecoderError> for UtilError { + fn from(err: ::rlp::DecoderError) -> UtilError { + UtilError::Decoder(err) } } @@ -32,9 +70,9 @@ impl From for EthcoreError { /*#![feature(concat_idents)] macro_rules! assimilate { ($name:ident) => ( - impl From for EthcoreError { - fn from(err: concat_idents!($name, Error)) -> EthcoreError { - EthcoreError:: $name (err) + impl From for Error { + fn from(err: concat_idents!($name, Error)) -> Error { + Error:: $name (err) } } ) diff --git a/src/hash.rs b/src/hash.rs index 9eafa5dfb..087454ceb 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -4,10 +4,10 @@ use std::str::FromStr; use std::fmt; use std::ops; use std::hash::{Hash, Hasher}; -use std::ops::{Index, IndexMut, Deref, DerefMut, BitOr, BitAnd, BitXor}; +use std::ops::{Index, IndexMut, Deref, DerefMut, BitOr, BitOrAssign, BitAnd, BitXor}; use std::cmp::{PartialOrd, Ordering}; use rustc_serialize::hex::*; -use error::EthcoreError; +use error::UtilError; use rand::Rng; use rand::os::OsRng; use bytes::{BytesConvertable,Populatable}; @@ -19,15 +19,18 @@ use uint::U256; /// Note: types implementing `FixedHash` must be also `BytesConvertable`. pub trait FixedHash: Sized + BytesConvertable + Populatable { fn new() -> Self; + /// Synonym for `new()`. Prefer to new as it's more readable. + fn zero() -> Self; fn random() -> Self; fn randomize(&mut self); fn size() -> usize; fn from_slice(src: &[u8]) -> Self; fn clone_from_slice(&mut self, src: &[u8]) -> usize; fn copy_to(&self, dest: &mut [u8]); - fn shift_bloom<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash; + fn shift_bloomed<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash; + fn with_bloomed(mut self, b: &T) -> Self where T: FixedHash { self.shift_bloomed(b); self } fn bloom_part(&self, m: usize) -> T where T: FixedHash; - fn contains_bloom(&self, b: &T) -> bool where T: FixedHash; + fn contains_bloomed(&self, b: &T) -> bool where T: FixedHash; fn contains<'a>(&'a self, b: &'a Self) -> bool; fn is_zero(&self) -> bool; } @@ -64,6 +67,10 @@ macro_rules! impl_hash { $from([0; $size]) } + fn zero() -> $from { + $from([0; $size]) + } + fn random() -> $from { let mut hash = $from::new(); hash.randomize(); @@ -103,11 +110,12 @@ macro_rules! impl_hash { } } - fn shift_bloom<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash { + fn shift_bloomed<'a, T>(&'a mut self, b: &T) -> &'a mut Self where T: FixedHash { let bp: Self = b.bloom_part($size); let new_self = &bp | self; // impl |= instead + // TODO: that's done now! unsafe { use std::{mem, ptr}; @@ -153,7 +161,7 @@ macro_rules! impl_hash { ret } - fn contains_bloom(&self, b: &T) -> bool where T: FixedHash { + fn contains_bloomed(&self, b: &T) -> bool where T: FixedHash { let bp: Self = b.bloom_part($size); self.contains(&bp) } @@ -168,11 +176,10 @@ macro_rules! impl_hash { } impl FromStr for $from { - type Err = EthcoreError; - - fn from_str(s: &str) -> Result<$from, EthcoreError> { + type Err = UtilError; + fn from_str(s: &str) -> Result<$from, UtilError> { let a = try!(s.from_hex()); - if a.len() != $size { return Err(EthcoreError::BadSize); } + if a.len() != $size { return Err(UtilError::BadSize); } let mut ret = $from([0;$size]); for i in 0..$size { ret.0[i] = a[i]; @@ -299,6 +306,15 @@ macro_rules! impl_hash { } } + /// Moving BitOrAssign + impl<'a> BitOrAssign<&'a $from> for $from { + fn bitor_assign(&mut self, rhs: &'a Self) { + for i in 0..$size { + self.0[i] = self.0[i] | rhs.0[i]; + } + } + } + /// BitAnd on references impl <'a> BitAnd for &'a $from { type Output = $from; @@ -352,6 +368,8 @@ macro_rules! impl_hash { pub fn hex(&self) -> String { format!("{}", self) } + + pub fn from_bloomed(b: &T) -> Self where T: FixedHash { b.bloom_part($size) } } } } @@ -417,6 +435,11 @@ impl_hash!(H520, 65); impl_hash!(H1024, 128); impl_hash!(H2048, 256); +/// Constant address for point 0. Often used as a default. +pub static ZERO_ADDRESS: Address = Address([0x00; 20]); +/// Constant 256-bit datum for 0. Often used as a default. +pub static ZERO_H256: H256 = H256([0x00; 32]); + #[cfg(test)] mod tests { use hash::*; @@ -448,7 +471,7 @@ mod tests { } #[test] - fn shift_bloom() { + fn shift_bloomed() { use sha3::Hashable; let bloom = H2048::from_str("00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); @@ -456,17 +479,17 @@ mod tests { let topic = H256::from_str("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); let mut my_bloom = H2048::new(); - assert!(!my_bloom.contains_bloom(&address.sha3())); - assert!(!my_bloom.contains_bloom(&topic.sha3())); + assert!(!my_bloom.contains_bloomed(&address.sha3())); + assert!(!my_bloom.contains_bloomed(&topic.sha3())); - my_bloom.shift_bloom(&address.sha3()); - assert!(my_bloom.contains_bloom(&address.sha3())); - assert!(!my_bloom.contains_bloom(&topic.sha3())); + my_bloom.shift_bloomed(&address.sha3()); + assert!(my_bloom.contains_bloomed(&address.sha3())); + assert!(!my_bloom.contains_bloomed(&topic.sha3())); - my_bloom.shift_bloom(&topic.sha3()); + my_bloom.shift_bloomed(&topic.sha3()); assert_eq!(my_bloom, bloom); - assert!(my_bloom.contains_bloom(&address.sha3())); - assert!(my_bloom.contains_bloom(&topic.sha3())); + assert!(my_bloom.contains_bloomed(&address.sha3())); + assert!(my_bloom.contains_bloomed(&topic.sha3())); } #[test] diff --git a/src/lib.rs b/src/lib.rs index a061a72cd..de2cdbdf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(op_assign_traits)] //! Ethcore-util library //! //! ### Rust version: @@ -48,6 +49,8 @@ extern crate secp256k1; extern crate arrayvec; extern crate elastic_array; +pub mod standard; +pub mod common; pub mod error; pub mod hash; pub mod uint; @@ -67,6 +70,20 @@ pub mod nibbleslice; pub mod heapsizeof; pub mod squeeze; pub mod semantic_version; - pub mod network; +pub use common::*; +pub use rlp::*; +pub use hashdb::*; +pub use memorydb::*; +pub use overlaydb::*; +pub use math::*; +pub use chainfilter::*; +pub use crypto::*; +pub use triehash::*; +pub use trie::*; +pub use nibbleslice::*; +pub use heapsizeof::*; +pub use squeeze::*; +pub use semantic_version::*; +pub use network::*; diff --git a/src/network/connection.rs b/src/network/connection.rs index 131aae318..efa0059eb 100644 --- a/src/network/connection.rs +++ b/src/network/connection.rs @@ -7,7 +7,8 @@ use bytes::*; use rlp::*; use std::io::{self, Cursor, Read}; use network::host::{Host}; -use network::Error; +use error::*; +use network::NetworkError; use network::handshake::Handshake; use crypto; use rcrypto::blockmodes::*; @@ -158,7 +159,7 @@ pub struct EncryptedConnection { } impl EncryptedConnection { - pub fn new(handshake: Handshake) -> Result { + pub fn new(handshake: Handshake) -> Result { let shared = try!(crypto::ecdh::agree(handshake.ecdhe.secret(), &handshake.remote_public)); let mut nonce_material = H512::new(); if handshake.originated { @@ -207,7 +208,7 @@ impl EncryptedConnection { }) } - pub fn send_packet(&mut self, payload: &[u8]) -> Result<(), Error> { + pub fn send_packet(&mut self, payload: &[u8]) -> Result<(), UtilError> { let mut header = RlpStream::new(); let len = payload.len() as usize; header.append_raw(&[(len >> 16) as u8, (len >> 8) as u8, len as u8], 1); @@ -233,16 +234,16 @@ impl EncryptedConnection { Ok(()) } - fn read_header(&mut self, header: &[u8]) -> Result<(), Error> { + fn read_header(&mut self, header: &[u8]) -> Result<(), UtilError> { if header.len() != ENCRYPTED_HEADER_LEN { - return Err(Error::Auth); + return Err(From::from(NetworkError::Auth)); } EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &header[0..16]); let mac = &header[16..]; let mut expected = H256::new(); self.ingress_mac.clone().finalize(&mut expected); if mac != &expected[0..16] { - return Err(Error::Auth); + return Err(From::from(NetworkError::Auth)); } let mut hdec = H128::new(); @@ -262,11 +263,11 @@ impl EncryptedConnection { Ok(()) } - fn read_payload(&mut self, payload: &[u8]) -> Result { + fn read_payload(&mut self, payload: &[u8]) -> Result { let padding = (16 - (self.payload_len % 16)) % 16; let full_length = self.payload_len + padding + 16; if payload.len() != full_length { - return Err(Error::Auth); + return Err(From::from(NetworkError::Auth)); } self.ingress_mac.update(&payload[0..payload.len() - 16]); EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]); @@ -274,7 +275,7 @@ impl EncryptedConnection { let mut expected = H128::new(); self.ingress_mac.clone().finalize(&mut expected); if mac != &expected[..] { - return Err(Error::Auth); + return Err(From::from(NetworkError::Auth)); } let mut packet = vec![0u8; self.payload_len]; @@ -298,7 +299,7 @@ impl EncryptedConnection { mac.update(&enc); } - pub fn readable(&mut self, event_loop: &mut EventLoop) -> Result, Error> { + pub fn readable(&mut self, event_loop: &mut EventLoop) -> Result, UtilError> { self.idle_timeout.map(|t| event_loop.clear_timeout(t)); match self.read_state { EncryptedConnectionState::Header => { @@ -323,13 +324,13 @@ impl EncryptedConnection { } } - pub fn writable(&mut self, event_loop: &mut EventLoop) -> Result<(), Error> { + pub fn writable(&mut self, event_loop: &mut EventLoop) -> Result<(), UtilError> { self.idle_timeout.map(|t| event_loop.clear_timeout(t)); try!(self.connection.writable()); Ok(()) } - pub fn register(&mut self, event_loop: &mut EventLoop) -> Result<(), Error> { + pub fn register(&mut self, event_loop: &mut EventLoop) -> Result<(), UtilError> { self.connection.expect(ENCRYPTED_HEADER_LEN); self.idle_timeout.map(|t| event_loop.clear_timeout(t)); self.idle_timeout = event_loop.timeout_ms(self.connection.token, 1800).ok(); @@ -337,7 +338,7 @@ impl EncryptedConnection { Ok(()) } - pub fn reregister(&mut self, event_loop: &mut EventLoop) -> Result<(), Error> { + pub fn reregister(&mut self, event_loop: &mut EventLoop) -> Result<(), UtilError> { try!(self.connection.reregister(event_loop)); Ok(()) } diff --git a/src/network/handshake.rs b/src/network/handshake.rs index 4df8cbe8b..d9e280bfe 100644 --- a/src/network/handshake.rs +++ b/src/network/handshake.rs @@ -7,7 +7,8 @@ use crypto::*; use crypto; use network::connection::{Connection}; use network::host::{NodeId, Host, HostInfo}; -use network::Error; +use error::*; +use network::NetworkError; #[derive(PartialEq, Eq, Debug)] enum HandshakeState { @@ -35,7 +36,7 @@ const AUTH_PACKET_SIZE: usize = 307; const ACK_PACKET_SIZE: usize = 210; impl Handshake { - pub fn new(token: Token, id: &NodeId, socket: TcpStream, nonce: &H256) -> Result { + pub fn new(token: Token, id: &NodeId, socket: TcpStream, nonce: &H256) -> Result { Ok(Handshake { id: id.clone(), connection: Connection::new(token, socket), @@ -51,7 +52,7 @@ impl Handshake { }) } - pub fn start(&mut self, host: &HostInfo, originated: bool) -> Result<(), Error> { + pub fn start(&mut self, host: &HostInfo, originated: bool) -> Result<(), UtilError> { self.originated = originated; if originated { try!(self.write_auth(host)); @@ -67,7 +68,7 @@ impl Handshake { self.state == HandshakeState::StartSession } - pub fn readable(&mut self, event_loop: &mut EventLoop, host: &HostInfo) -> Result<(), Error> { + pub fn readable(&mut self, event_loop: &mut EventLoop, host: &HostInfo) -> Result<(), UtilError> { self.idle_timeout.map(|t| event_loop.clear_timeout(t)); match self.state { HandshakeState::ReadingAuth => { @@ -96,7 +97,7 @@ impl Handshake { Ok(()) } - pub fn writable(&mut self, event_loop: &mut EventLoop, _host: &HostInfo) -> Result<(), Error> { + pub fn writable(&mut self, event_loop: &mut EventLoop, _host: &HostInfo) -> Result<(), UtilError> { self.idle_timeout.map(|t| event_loop.clear_timeout(t)); try!(self.connection.writable()); if self.state != HandshakeState::StartSession { @@ -105,14 +106,14 @@ impl Handshake { Ok(()) } - pub fn register(&mut self, event_loop: &mut EventLoop) -> Result<(), Error> { + pub fn register(&mut self, event_loop: &mut EventLoop) -> Result<(), UtilError> { self.idle_timeout.map(|t| event_loop.clear_timeout(t)); self.idle_timeout = event_loop.timeout_ms(self.connection.token, 1800).ok(); try!(self.connection.register(event_loop)); Ok(()) } - fn read_auth(&mut self, host: &HostInfo, data: &[u8]) -> Result<(), Error> { + fn read_auth(&mut self, host: &HostInfo, data: &[u8]) -> Result<(), UtilError> { trace!(target:"net", "Received handshake auth to {:?}", self.connection.socket.peer_addr()); assert!(data.len() == AUTH_PACKET_SIZE); self.auth_cipher = data.to_vec(); @@ -128,12 +129,12 @@ impl Handshake { let spub = try!(ec::recover(&signature, &(&shared ^ &self.remote_nonce))); if &spub.sha3()[..] != hepubk { trace!(target:"net", "Handshake hash mismath with {:?}", self.connection.socket.peer_addr()); - return Err(Error::Auth); + return Err(From::from(NetworkError::Auth)); }; self.write_ack() } - fn read_ack(&mut self, host: &HostInfo, data: &[u8]) -> Result<(), Error> { + fn read_ack(&mut self, host: &HostInfo, data: &[u8]) -> Result<(), UtilError> { trace!(target:"net", "Received handshake auth to {:?}", self.connection.socket.peer_addr()); assert!(data.len() == ACK_PACKET_SIZE); self.ack_cipher = data.to_vec(); @@ -143,7 +144,7 @@ impl Handshake { Ok(()) } - fn write_auth(&mut self, host: &HostInfo) -> Result<(), Error> { + fn write_auth(&mut self, host: &HostInfo) -> Result<(), UtilError> { trace!(target:"net", "Sending handshake auth to {:?}", self.connection.socket.peer_addr()); let mut data = [0u8; /*Signature::SIZE*/ 65 + /*H256::SIZE*/ 32 + /*Public::SIZE*/ 64 + /*H256::SIZE*/ 32 + 1]; //TODO: use associated constants let len = data.len(); @@ -169,7 +170,7 @@ impl Handshake { Ok(()) } - fn write_ack(&mut self) -> Result<(), Error> { + fn write_ack(&mut self) -> Result<(), UtilError> { trace!(target:"net", "Sending handshake ack to {:?}", self.connection.socket.peer_addr()); let mut data = [0u8; 1 + /*Public::SIZE*/ 64 + /*H256::SIZE*/ 32]; //TODO: use associated constants let len = data.len(); diff --git a/src/network/host.rs b/src/network/host.rs index b9ca0152b..f48b9eb2d 100644 --- a/src/network/host.rs +++ b/src/network/host.rs @@ -13,7 +13,8 @@ use rlp::*; use time::Tm; use network::handshake::Handshake; use network::session::{Session, SessionData}; -use network::{Error, ProtocolHandler}; +use error::*; +use network::ProtocolHandler; const _DEFAULT_PORT: u16 = 30304; @@ -53,7 +54,7 @@ pub struct NodeEndpoint { } impl NodeEndpoint { - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { let address = s.to_socket_addrs().map(|mut i| i.next()); match address { Ok(Some(a)) => Ok(NodeEndpoint { @@ -61,8 +62,8 @@ impl NodeEndpoint { address_str: s.to_string(), udp_port: a.port() }), - Ok(_) => Err(Error::AddressResolve(None)), - Err(e) => Err(Error::AddressResolve(Some(e))) + Ok(_) => Err(UtilError::AddressResolve(None)), + Err(e) => Err(UtilError::AddressResolve(Some(e))) } } } @@ -81,7 +82,7 @@ struct Node { } impl FromStr for Node { - type Err = Error; + type Err = UtilError; fn from_str(s: &str) -> Result { let (id, endpoint) = if &s[0..8] == "enode://" && s.len() > 136 && &s[136..137] == "@" { (try!(NodeId::from_str(&s[8..136])), try!(NodeEndpoint::from_str(&s[137..]))) @@ -189,7 +190,7 @@ impl<'s> HostIo<'s> { } /// Send a packet over the network to another peer. - pub fn send(&mut self, peer: PeerId, packet_id: PacketId, data: Vec) -> Result<(), Error> { + pub fn send(&mut self, peer: PeerId, packet_id: PacketId, data: Vec) -> Result<(), UtilError> { match self.connections.get_mut(Token(peer)) { Some(&mut ConnectionEntry::Session(ref mut s)) => { s.send_packet(self.protocol, packet_id as u8, &data).unwrap_or_else(|e| { @@ -204,7 +205,7 @@ impl<'s> HostIo<'s> { } /// Respond to a current network message. Panics if no there is no packet in the context. - pub fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), Error> { + pub fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), UtilError> { match self.session { Some(session) => self.send(session.as_usize(), packet_id, data), None => { @@ -214,7 +215,7 @@ impl<'s> HostIo<'s> { } /// Register a new IO timer. Returns a new timer toke. 'ProtocolHandler::timeout' will be called with the token. - pub fn register_timer(&mut self, ms: u64) -> Result{ + pub fn register_timer(&mut self, ms: u64) -> Result{ match self.timers.insert(UserTimer { delay: ms, protocol: self.protocol, @@ -292,7 +293,7 @@ pub struct Host { } impl Host { - pub fn start(event_loop: &mut EventLoop) -> Result<(), Error> { + pub fn start(event_loop: &mut EventLoop) -> Result<(), UtilError> { let config = NetworkConfiguration::new(); /* match ::ifaces::Interface::get_all().unwrap().into_iter().filter(|x| x.kind == ::ifaces::Kind::Packet && x.addr.is_some()).next() { diff --git a/src/network/mod.rs b/src/network/mod.rs index df0da2c13..cdce08d00 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -69,49 +69,23 @@ pub enum DisconnectReason } #[derive(Debug)] -pub enum Error { - Crypto(::crypto::CryptoError), - Io(::std::io::Error), +pub enum NetworkError { Auth, BadProtocol, - AddressParse(::std::net::AddrParseError), - AddressResolve(Option<::std::io::Error>), - NodeIdParse(::error::EthcoreError), PeerNotFound, - Disconnect(DisconnectReason) + Disconnect(DisconnectReason), + Mio(::std::io::Error), } -impl From<::std::io::Error> for Error { - fn from(err: ::std::io::Error) -> Error { - Error::Io(err) +impl From<::rlp::DecoderError> for NetworkError { + fn from(_err: ::rlp::DecoderError) -> NetworkError { + NetworkError::Auth } } -impl From<::crypto::CryptoError> for Error { - fn from(err: ::crypto::CryptoError) -> Error { - Error::Crypto(err) - } -} - -impl From<::std::net::AddrParseError> for Error { - fn from(err: ::std::net::AddrParseError) -> Error { - Error::AddressParse(err) - } -} -impl From<::error::EthcoreError> for Error { - fn from(err: ::error::EthcoreError) -> Error { - Error::NodeIdParse(err) - } -} -impl From<::rlp::DecoderError> for Error { - fn from(_err: ::rlp::DecoderError) -> Error { - Error::Auth - } -} - -impl From<::mio::NotifyError> for Error { - fn from(_err: ::mio::NotifyError) -> Error { - Error::Io(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error")) +impl From<::mio::NotifyError> for NetworkError { + fn from(_err: ::mio::NotifyError) -> NetworkError { + NetworkError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error")) } } diff --git a/src/network/service.rs b/src/network/service.rs index 7598ffdd6..23cbb57d9 100644 --- a/src/network/service.rs +++ b/src/network/service.rs @@ -1,6 +1,7 @@ use std::thread::{self, JoinHandle}; use mio::*; -use network::{Error, ProtocolHandler}; +use error::*; +use network::{NetworkError, ProtocolHandler}; use network::host::{Host, HostMessage, PeerId, PacketId, ProtocolId}; /// IO Service with networking @@ -11,7 +12,7 @@ pub struct NetworkService { impl NetworkService { /// Starts IO event loop - pub fn start() -> Result { + pub fn start() -> Result { let mut event_loop = EventLoop::new().unwrap(); let channel = event_loop.channel(); let thread = thread::spawn(move || { @@ -24,7 +25,7 @@ impl NetworkService { } /// Send a message over the network. Normaly `HostIo::send` should be used. This can be used from non-io threads. - pub fn send(&mut self, peer: &PeerId, packet_id: PacketId, protocol: ProtocolId, data: &[u8]) -> Result<(), Error> { + pub fn send(&mut self, peer: &PeerId, packet_id: PacketId, protocol: ProtocolId, data: &[u8]) -> Result<(), NetworkError> { try!(self.host_channel.send(HostMessage::Send { peer: *peer, packet_id: packet_id, @@ -35,7 +36,7 @@ impl NetworkService { } /// Regiter a new protocol handler with the event loop. - pub fn register_protocol(&mut self, handler: Box, protocol: ProtocolId, versions: &[u8]) -> Result<(), Error> { + pub fn register_protocol(&mut self, handler: Box, protocol: ProtocolId, versions: &[u8]) -> Result<(), NetworkError> { try!(self.host_channel.send(HostMessage::AddHandler { handler: handler, protocol: protocol, diff --git a/src/network/session.rs b/src/network/session.rs index 8e89ff2c4..141898e24 100644 --- a/src/network/session.rs +++ b/src/network/session.rs @@ -3,7 +3,8 @@ use hash::*; use rlp::*; use network::connection::{EncryptedConnection, Packet}; use network::handshake::Handshake; -use network::{Error, DisconnectReason}; +use error::*; +use network::{NetworkError, DisconnectReason}; use network::host::*; pub struct Session { @@ -64,7 +65,7 @@ const PACKET_USER: u8 = 0x10; const PACKET_LAST: u8 = 0x7f; impl Session { - pub fn new(h: Handshake, event_loop: &mut EventLoop, host: &HostInfo) -> Result { + pub fn new(h: Handshake, event_loop: &mut EventLoop, host: &HostInfo) -> Result { let id = h.id.clone(); let connection = try!(EncryptedConnection::new(h)); let mut session = Session { @@ -87,14 +88,14 @@ impl Session { self.had_hello } - pub fn readable(&mut self, event_loop: &mut EventLoop, host: &HostInfo) -> Result { + pub fn readable(&mut self, event_loop: &mut EventLoop, host: &HostInfo) -> Result { match try!(self.connection.readable(event_loop)) { - Some(data) => self.read_packet(data, host), + Some(data) => Ok(try!(self.read_packet(data, host))), None => Ok(SessionData::None) } } - pub fn writable(&mut self, event_loop: &mut EventLoop, _host: &HostInfo) -> Result<(), Error> { + pub fn writable(&mut self, event_loop: &mut EventLoop, _host: &HostInfo) -> Result<(), UtilError> { self.connection.writable(event_loop) } @@ -102,11 +103,11 @@ impl Session { self.info.capabilities.iter().any(|c| c.protocol == protocol) } - pub fn reregister(&mut self, event_loop: &mut EventLoop) -> Result<(), Error> { + pub fn reregister(&mut self, event_loop: &mut EventLoop) -> Result<(), UtilError> { self.connection.reregister(event_loop) } - pub fn send_packet(&mut self, protocol: &str, packet_id: u8, data: &[u8]) -> Result<(), Error> { + pub fn send_packet(&mut self, protocol: &str, packet_id: u8, data: &[u8]) -> Result<(), UtilError> { let mut i = 0usize; while protocol != self.info.capabilities[i].protocol { i += 1; @@ -122,13 +123,13 @@ impl Session { self.connection.send_packet(&rlp.out()) } - fn read_packet(&mut self, packet: Packet, host: &HostInfo) -> Result { + fn read_packet(&mut self, packet: Packet, host: &HostInfo) -> Result { if packet.data.len() < 2 { - return Err(Error::BadProtocol); + return Err(From::from(NetworkError::BadProtocol)); } let packet_id = packet.data[0]; if packet_id != PACKET_HELLO && packet_id != PACKET_DISCONNECT && !self.had_hello { - return Err(Error::BadProtocol); + return Err(From::from(NetworkError::BadProtocol)); } match packet_id { PACKET_HELLO => { @@ -136,7 +137,7 @@ impl Session { try!(self.read_hello(&rlp, host)); Ok(SessionData::Ready) }, - PACKET_DISCONNECT => Err(Error::Disconnect(DisconnectReason::DisconnectRequested)), + PACKET_DISCONNECT => Err(From::from(NetworkError::Disconnect(DisconnectReason::DisconnectRequested))), PACKET_PING => { try!(self.write_pong()); Ok(SessionData::None) @@ -165,7 +166,7 @@ impl Session { } } - fn write_hello(&mut self, host: &HostInfo) -> Result<(), Error> { + fn write_hello(&mut self, host: &HostInfo) -> Result<(), UtilError> { let mut rlp = RlpStream::new(); rlp.append_raw(&[PACKET_HELLO as u8], 0); rlp.append_list(5) @@ -177,7 +178,7 @@ impl Session { self.connection.send_packet(&rlp.out()) } - fn read_hello(&mut self, rlp: &UntrustedRlp, host: &HostInfo) -> Result<(), Error> { + fn read_hello(&mut self, rlp: &UntrustedRlp, host: &HostInfo) -> Result<(), UtilError> { let protocol = try!(rlp.val_at::(0)); let client_version = try!(rlp.val_at::(1)); let peer_caps = try!(rlp.val_at::>(2)); @@ -218,37 +219,37 @@ impl Session { trace!(target: "net", "Hello: {} v{} {} {:?}", client_version, protocol, id, caps); self.info.capabilities = caps; if protocol != host.protocol_version { - return Err(self.disconnect(DisconnectReason::UselessPeer)); + return Err(From::from(self.disconnect(DisconnectReason::UselessPeer))); } self.had_hello = true; Ok(()) } - fn write_ping(&mut self) -> Result<(), Error> { + fn write_ping(&mut self) -> Result<(), UtilError> { self.send(try!(Session::prepare(PACKET_PING))) } - fn write_pong(&mut self) -> Result<(), Error> { + fn write_pong(&mut self) -> Result<(), UtilError> { self.send(try!(Session::prepare(PACKET_PONG))) } - fn disconnect(&mut self, reason: DisconnectReason) -> Error { + fn disconnect(&mut self, reason: DisconnectReason) -> NetworkError { let mut rlp = RlpStream::new(); rlp.append(&(PACKET_DISCONNECT as u32)); rlp.append_list(1); rlp.append(&(reason.clone() as u32)); self.connection.send_packet(&rlp.out()).ok(); - Error::Disconnect(reason) + NetworkError::Disconnect(reason) } - fn prepare(packet_id: u8) -> Result { + fn prepare(packet_id: u8) -> Result { let mut rlp = RlpStream::new(); rlp.append(&(packet_id as u32)); rlp.append_list(0); Ok(rlp) } - fn send(&mut self, rlp: RlpStream) -> Result<(), Error> { + fn send(&mut self, rlp: RlpStream) -> Result<(), UtilError> { self.connection.send_packet(&rlp.out()) } } diff --git a/src/overlaydb.rs b/src/overlaydb.rs index b5bbf4299..5539a8893 100644 --- a/src/overlaydb.rs +++ b/src/overlaydb.rs @@ -66,7 +66,7 @@ impl OverlayDB { /// assert!(m.exists(&key)); // key now still exists. /// } /// ``` - pub fn commit(&mut self) -> Result { + pub fn commit(&mut self) -> Result { let mut ret = 0u32; for i in self.overlay.drain().into_iter() { let (key, (value, rc)) = i; diff --git a/src/rlp/mod.rs b/src/rlp/mod.rs index 8aa816c04..fc0a4d288 100644 --- a/src/rlp/mod.rs +++ b/src/rlp/mod.rs @@ -32,7 +32,7 @@ pub mod rlptraits; pub mod rlperrors; -pub mod rlp; +pub mod rlpin; pub mod untrusted_rlp; pub mod rlpstream; @@ -42,8 +42,8 @@ mod tests; pub use self::rlperrors::DecoderError; pub use self::rlptraits::{Decoder, Decodable, View, Stream, Encodable, Encoder}; pub use self::untrusted_rlp::{UntrustedRlp, UntrustedRlpIterator, PayloadInfo, Prototype}; -pub use self::rlp::{Rlp, RlpIterator}; -pub use self::rlpstream::{RlpStream}; +pub use self::rlpin::{Rlp, RlpIterator}; +pub use self::rlpstream::{RlpStream,RlpStandard}; use super::hash::H256; pub const NULL_RLP: [u8; 1] = [0x80; 1]; diff --git a/src/rlp/rlp.rs b/src/rlp/rlpin.rs similarity index 100% rename from src/rlp/rlp.rs rename to src/rlp/rlpin.rs diff --git a/src/rlp/rlpstream.rs b/src/rlp/rlpstream.rs index 97ae1b484..b8954ae6f 100644 --- a/src/rlp/rlpstream.rs +++ b/src/rlp/rlpstream.rs @@ -1,6 +1,8 @@ use elastic_array::*; -use bytes::ToBytes; +use bytes::{Bytes, ToBytes}; use rlp::{Stream, Encoder, Encodable}; +use hash::H256; +use sha3::*; #[derive(Debug, Copy, Clone)] struct ListInfo { @@ -213,6 +215,20 @@ impl Encoder for BasicEncoder { } } +pub trait RlpStandard { + fn rlp_append(&self, s: &mut RlpStream); + + fn rlp_bytes(&self) -> Bytes { + let mut s = RlpStream::new(); + self.rlp_append(&mut s); + s.out() + } + + fn rlp_sha3(&self) -> H256 { self.rlp_bytes().sha3() } +} + +// @debris TODO: implement Encoder for RlpStandard. + impl Encodable for T where T: ToBytes { fn encode(&self, encoder: &mut E) where E: Encoder { encoder.emit_value(&self.to_bytes()) diff --git a/src/standard.rs b/src/standard.rs new file mode 100644 index 000000000..b591220f3 --- /dev/null +++ b/src/standard.rs @@ -0,0 +1,21 @@ +pub use std::io; +pub use std::str; +pub use std::fmt; +pub use std::slice; + +pub use std::path::Path; +pub use std::str::{FromStr}; +pub use std::io::{Read,Write}; +pub use std::hash::{Hash, Hasher}; +pub use std::error::Error as StdError; + +pub use std::ops::*; +pub use std::cmp::*; +pub use std::cell::*; +pub use std::collections::*; + +pub use rustc_serialize::json::Json; +pub use rustc_serialize::base64::FromBase64; +pub use rustc_serialize::hex::FromHex; + +pub use heapsize::HeapSizeOf; diff --git a/src/triehash.rs b/src/triehash.rs index de54bb3a7..66f9072b8 100644 --- a/src/triehash.rs +++ b/src/triehash.rs @@ -29,11 +29,8 @@ pub fn ordered_trie_root(input: Vec>) -> H256 { // first put elements into btree to sort them by nibbles // optimize it later .into_iter() - .fold(BTreeMap::new(), | mut acc, vec | { - let len = acc.len(); - acc.insert(rlp::encode(&len), vec); - acc - }) + .enumerate() + .fold(BTreeMap::new(), | mut acc, (i, vec) | { acc.insert(rlp::encode(&i), vec); acc }) // then move them to a vector .into_iter() .map(|(k, v)| (as_nibbles(&k), v) ) diff --git a/src/uint.rs b/src/uint.rs index 7fc11e2df..6fc8d19e1 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -424,6 +424,17 @@ macro_rules! construct_uint { } } + impl fmt::Display for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let &$name(ref data) = self; + try!(write!(f, "0x")); + for ch in data.iter().rev() { + try!(write!(f, "{:02x}", ch)); + } + Ok(()) + } + } + impl Hash for $name { fn hash(&self, state: &mut H) where H: Hasher { unsafe { state.write(::std::slice::from_raw_parts(self.0.as_ptr() as *mut u8, self.0.len() * 8)); }