Merge pull request #31 from gavofyork/gav

Bloom stuff and RlpStandard
This commit is contained in:
Arkadiy Paronyan 2016-01-10 13:23:04 +01:00
commit 8254b4283b
12 changed files with 162 additions and 126 deletions

View File

@ -18,7 +18,7 @@
//! let filter = ChainFilter::new(&cache, index_size, bloom_levels); //! let filter = ChainFilter::new(&cache, index_size, bloom_levels);
//! let block_number = 39; //! let block_number = 39;
//! let mut bloom = H2048::new(); //! let mut bloom = H2048::new();
//! bloom.shift_bloom(&address.sha3()); //! bloom.shift_bloomed(&address.sha3());
//! filter.add_bloom(&bloom, block_number) //! 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. /// Returns numbers of blocks that may contain Address.
pub fn blocks_with_address(&self, address: &Address, from_block: usize, to_block: usize) -> Vec<usize> { pub fn blocks_with_address(&self, address: &Address, from_block: usize, to_block: usize) -> Vec<usize> {
let mut bloom = H2048::new(); let mut bloom = H2048::new();
bloom.shift_bloom(&address.sha3()); bloom.shift_bloomed(&address.sha3());
self.blocks_with_bloom(&bloom, from_block, to_block) self.blocks_with_bloom(&bloom, from_block, to_block)
} }
/// Returns numbers of blocks that may contain Topic. /// Returns numbers of blocks that may contain Topic.
pub fn blocks_with_topic(&self, topic: &H256, from_block: usize, to_block: usize) -> Vec<usize> { pub fn blocks_with_topic(&self, topic: &H256, from_block: usize, to_block: usize) -> Vec<usize> {
let mut bloom = H2048::new(); let mut bloom = H2048::new();
bloom.shift_bloom(&topic.sha3()); bloom.shift_bloomed(&topic.sha3());
self.blocks_with_bloom(&bloom, from_block, to_block) 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 filter = ChainFilter::new(&cache, index_size, bloom_levels);
let block_number = 23; let block_number = 23;
let mut bloom = H2048::new(); let mut bloom = H2048::new();
bloom.shift_bloom(&topic.sha3()); bloom.shift_bloomed(&topic.sha3());
filter.add_bloom(&bloom, block_number) filter.add_bloom(&bloom, block_number)
}; };

View File

@ -1,6 +1,8 @@
//! General error types for use in ethcore. //! General error types for use in ethcore.
use rustc_serialize::hex::*; use rustc_serialize::hex::FromHexError;
use network::NetworkError;
use rlp::DecoderError;
#[derive(Debug)] #[derive(Debug)]
pub enum BaseDataError { pub enum BaseDataError {
@ -9,22 +11,58 @@ pub enum BaseDataError {
#[derive(Debug)] #[derive(Debug)]
/// General error type which should be capable of representing all errors in ethcore. /// 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), FromHex(FromHexError),
BaseData(BaseDataError), BaseData(BaseDataError),
Network(NetworkError),
Decoder(DecoderError),
BadSize, BadSize,
UnknownName, UnknownName,
} }
impl From<FromHexError> for EthcoreError { impl From<FromHexError> for UtilError {
fn from(err: FromHexError) -> EthcoreError { fn from(err: FromHexError) -> UtilError {
EthcoreError::FromHex(err) UtilError::FromHex(err)
} }
} }
impl From<BaseDataError> for EthcoreError { impl From<BaseDataError> for UtilError {
fn from(err: BaseDataError) -> EthcoreError { fn from(err: BaseDataError) -> UtilError {
EthcoreError::BaseData(err) UtilError::BaseData(err)
}
}
impl From<NetworkError> 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<BaseDataError> for EthcoreError {
/*#![feature(concat_idents)] /*#![feature(concat_idents)]
macro_rules! assimilate { macro_rules! assimilate {
($name:ident) => ( ($name:ident) => (
impl From<concat_idents!($name, Error)> for EthcoreError { impl From<concat_idents!($name, Error)> for Error {
fn from(err: concat_idents!($name, Error)) -> EthcoreError { fn from(err: concat_idents!($name, Error)) -> Error {
EthcoreError:: $name (err) Error:: $name (err)
} }
} }
) )

View File

@ -7,7 +7,7 @@ use std::hash::{Hash, Hasher};
use std::ops::{Index, IndexMut, Deref, DerefMut, BitOr, BitOrAssign, BitAnd, BitXor}; use std::ops::{Index, IndexMut, Deref, DerefMut, BitOr, BitOrAssign, BitAnd, BitXor};
use std::cmp::{PartialOrd, Ordering}; use std::cmp::{PartialOrd, Ordering};
use rustc_serialize::hex::*; use rustc_serialize::hex::*;
use error::EthcoreError; use error::UtilError;
use rand::Rng; use rand::Rng;
use rand::os::OsRng; use rand::os::OsRng;
use bytes::{BytesConvertable,Populatable}; use bytes::{BytesConvertable,Populatable};
@ -27,9 +27,10 @@ pub trait FixedHash: Sized + BytesConvertable + Populatable {
fn from_slice(src: &[u8]) -> Self; fn from_slice(src: &[u8]) -> Self;
fn clone_from_slice(&mut self, src: &[u8]) -> usize; fn clone_from_slice(&mut self, src: &[u8]) -> usize;
fn copy_to(&self, dest: &mut [u8]); 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<T>(mut self, b: &T) -> Self where T: FixedHash { self.shift_bloomed(b); self }
fn bloom_part<T>(&self, m: usize) -> T where T: FixedHash; fn bloom_part<T>(&self, m: usize) -> T where T: FixedHash;
fn contains_bloom<T>(&self, b: &T) -> bool where T: FixedHash; fn contains_bloomed<T>(&self, b: &T) -> bool where T: FixedHash;
fn contains<'a>(&'a self, b: &'a Self) -> bool; fn contains<'a>(&'a self, b: &'a Self) -> bool;
fn is_zero(&self) -> bool; fn is_zero(&self) -> bool;
} }
@ -109,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 bp: Self = b.bloom_part($size);
let new_self = &bp | self; let new_self = &bp | self;
// impl |= instead // impl |= instead
// TODO: that's done now!
unsafe { unsafe {
use std::{mem, ptr}; use std::{mem, ptr};
@ -159,7 +161,7 @@ macro_rules! impl_hash {
ret ret
} }
fn contains_bloom<T>(&self, b: &T) -> bool where T: FixedHash { fn contains_bloomed<T>(&self, b: &T) -> bool where T: FixedHash {
let bp: Self = b.bloom_part($size); let bp: Self = b.bloom_part($size);
self.contains(&bp) self.contains(&bp)
} }
@ -174,11 +176,10 @@ macro_rules! impl_hash {
} }
impl FromStr for $from { impl FromStr for $from {
type Err = EthcoreError; type Err = UtilError;
fn from_str(s: &str) -> Result<$from, UtilError> {
fn from_str(s: &str) -> Result<$from, EthcoreError> {
let a = try!(s.from_hex()); 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]); let mut ret = $from([0;$size]);
for i in 0..$size { for i in 0..$size {
ret.0[i] = a[i]; ret.0[i] = a[i];
@ -367,6 +368,8 @@ macro_rules! impl_hash {
pub fn hex(&self) -> String { pub fn hex(&self) -> String {
format!("{}", self) format!("{}", self)
} }
pub fn from_bloomed<T>(b: &T) -> Self where T: FixedHash { b.bloom_part($size) }
} }
} }
} }
@ -468,7 +471,7 @@ mod tests {
} }
#[test] #[test]
fn shift_bloom() { fn shift_bloomed() {
use sha3::Hashable; use sha3::Hashable;
let bloom = H2048::from_str("00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); let bloom = H2048::from_str("00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
@ -476,17 +479,17 @@ mod tests {
let topic = H256::from_str("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap(); let topic = H256::from_str("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc").unwrap();
let mut my_bloom = H2048::new(); let mut my_bloom = H2048::new();
assert!(!my_bloom.contains_bloom(&address.sha3())); assert!(!my_bloom.contains_bloomed(&address.sha3()));
assert!(!my_bloom.contains_bloom(&topic.sha3())); assert!(!my_bloom.contains_bloomed(&topic.sha3()));
my_bloom.shift_bloom(&address.sha3()); my_bloom.shift_bloomed(&address.sha3());
assert!(my_bloom.contains_bloom(&address.sha3())); assert!(my_bloom.contains_bloomed(&address.sha3()));
assert!(!my_bloom.contains_bloom(&topic.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_eq!(my_bloom, bloom);
assert!(my_bloom.contains_bloom(&address.sha3())); assert!(my_bloom.contains_bloomed(&address.sha3()));
assert!(my_bloom.contains_bloom(&topic.sha3())); assert!(my_bloom.contains_bloomed(&topic.sha3()));
} }
#[test] #[test]

View File

@ -7,7 +7,8 @@ use bytes::*;
use rlp::*; use rlp::*;
use std::io::{self, Cursor, Read}; use std::io::{self, Cursor, Read};
use network::host::{Host}; use network::host::{Host};
use network::Error; use error::*;
use network::NetworkError;
use network::handshake::Handshake; use network::handshake::Handshake;
use crypto; use crypto;
use rcrypto::blockmodes::*; use rcrypto::blockmodes::*;
@ -158,7 +159,7 @@ pub struct EncryptedConnection {
} }
impl EncryptedConnection { impl EncryptedConnection {
pub fn new(handshake: Handshake) -> Result<EncryptedConnection, Error> { pub fn new(handshake: Handshake) -> Result<EncryptedConnection, UtilError> {
let shared = try!(crypto::ecdh::agree(handshake.ecdhe.secret(), &handshake.remote_public)); let shared = try!(crypto::ecdh::agree(handshake.ecdhe.secret(), &handshake.remote_public));
let mut nonce_material = H512::new(); let mut nonce_material = H512::new();
if handshake.originated { 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 mut header = RlpStream::new();
let len = payload.len() as usize; let len = payload.len() as usize;
header.append_raw(&[(len >> 16) as u8, (len >> 8) as u8, len as u8], 1); header.append_raw(&[(len >> 16) as u8, (len >> 8) as u8, len as u8], 1);
@ -233,16 +234,16 @@ impl EncryptedConnection {
Ok(()) 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 { 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]); EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &header[0..16]);
let mac = &header[16..]; let mac = &header[16..];
let mut expected = H256::new(); let mut expected = H256::new();
self.ingress_mac.clone().finalize(&mut expected); self.ingress_mac.clone().finalize(&mut expected);
if mac != &expected[0..16] { if mac != &expected[0..16] {
return Err(Error::Auth); return Err(From::from(NetworkError::Auth));
} }
let mut hdec = H128::new(); let mut hdec = H128::new();
@ -262,11 +263,11 @@ impl EncryptedConnection {
Ok(()) Ok(())
} }
fn read_payload(&mut self, payload: &[u8]) -> Result<Packet, Error> { fn read_payload(&mut self, payload: &[u8]) -> Result<Packet, UtilError> {
let padding = (16 - (self.payload_len % 16)) % 16; let padding = (16 - (self.payload_len % 16)) % 16;
let full_length = (self.payload_len + padding + 16) as usize; let full_length = (self.payload_len + padding + 16) as usize;
if payload.len() != full_length { if payload.len() != full_length {
return Err(Error::Auth); return Err(From::from(NetworkError::Auth));
} }
self.ingress_mac.update(&payload[0..payload.len() - 16]); self.ingress_mac.update(&payload[0..payload.len() - 16]);
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]); EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]);
@ -274,7 +275,7 @@ impl EncryptedConnection {
let mut expected = H128::new(); let mut expected = H128::new();
self.ingress_mac.clone().finalize(&mut expected); self.ingress_mac.clone().finalize(&mut expected);
if mac != &expected[..] { if mac != &expected[..] {
return Err(Error::Auth); return Err(From::from(NetworkError::Auth));
} }
let mut packet = vec![0u8; self.payload_len as usize]; let mut packet = vec![0u8; self.payload_len as usize];
@ -297,7 +298,7 @@ impl EncryptedConnection {
mac.update(&enc); mac.update(&enc);
} }
pub fn readable(&mut self, event_loop: &mut EventLoop<Host>) -> Result<Option<Packet>, Error> { pub fn readable(&mut self, event_loop: &mut EventLoop<Host>) -> Result<Option<Packet>, UtilError> {
self.idle_timeout.map(|t| event_loop.clear_timeout(t)); self.idle_timeout.map(|t| event_loop.clear_timeout(t));
try!(self.connection.reregister(event_loop)); try!(self.connection.reregister(event_loop));
match self.read_state { match self.read_state {
@ -323,14 +324,14 @@ impl EncryptedConnection {
} }
} }
pub fn writable(&mut self, event_loop: &mut EventLoop<Host>) -> Result<(), Error> { pub fn writable(&mut self, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
self.idle_timeout.map(|t| event_loop.clear_timeout(t)); self.idle_timeout.map(|t| event_loop.clear_timeout(t));
try!(self.connection.writable()); try!(self.connection.writable());
try!(self.connection.reregister(event_loop)); try!(self.connection.reregister(event_loop));
Ok(()) Ok(())
} }
pub fn register(&mut self, event_loop: &mut EventLoop<Host>) -> Result<(), Error> { pub fn register(&mut self, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
self.connection.expect(ENCRYPTED_HEADER_LEN); self.connection.expect(ENCRYPTED_HEADER_LEN);
self.idle_timeout.map(|t| event_loop.clear_timeout(t)); self.idle_timeout.map(|t| event_loop.clear_timeout(t));
self.idle_timeout = event_loop.timeout_ms(self.connection.token, 1800).ok(); self.idle_timeout = event_loop.timeout_ms(self.connection.token, 1800).ok();

View File

@ -7,7 +7,8 @@ use crypto::*;
use crypto; use crypto;
use network::connection::{Connection}; use network::connection::{Connection};
use network::host::{NodeId, Host, HostInfo}; use network::host::{NodeId, Host, HostInfo};
use network::Error; use error::*;
use network::NetworkError;
#[derive(PartialEq, Eq, Debug)] #[derive(PartialEq, Eq, Debug)]
enum HandshakeState { enum HandshakeState {
@ -35,7 +36,7 @@ const AUTH_PACKET_SIZE: usize = 307;
const ACK_PACKET_SIZE: usize = 210; const ACK_PACKET_SIZE: usize = 210;
impl Handshake { impl Handshake {
pub fn new(token: Token, id: &NodeId, socket: TcpStream, nonce: &H256) -> Result<Handshake, Error> { pub fn new(token: Token, id: &NodeId, socket: TcpStream, nonce: &H256) -> Result<Handshake, UtilError> {
Ok(Handshake { Ok(Handshake {
id: id.clone(), id: id.clone(),
connection: Connection::new(token, socket), 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; self.originated = originated;
if originated { if originated {
try!(self.write_auth(host)); try!(self.write_auth(host));
@ -67,7 +68,7 @@ impl Handshake {
self.state == HandshakeState::StartSession self.state == HandshakeState::StartSession
} }
pub fn readable(&mut self, event_loop: &mut EventLoop<Host>, host: &HostInfo) -> Result<(), Error> { pub fn readable(&mut self, event_loop: &mut EventLoop<Host>, host: &HostInfo) -> Result<(), UtilError> {
self.idle_timeout.map(|t| event_loop.clear_timeout(t)); self.idle_timeout.map(|t| event_loop.clear_timeout(t));
match self.state { match self.state {
HandshakeState::ReadingAuth => { HandshakeState::ReadingAuth => {
@ -96,7 +97,7 @@ impl Handshake {
Ok(()) Ok(())
} }
pub fn writable(&mut self, event_loop: &mut EventLoop<Host>, _host: &HostInfo) -> Result<(), Error> { pub fn writable(&mut self, event_loop: &mut EventLoop<Host>, _host: &HostInfo) -> Result<(), UtilError> {
self.idle_timeout.map(|t| event_loop.clear_timeout(t)); self.idle_timeout.map(|t| event_loop.clear_timeout(t));
try!(self.connection.writable()); try!(self.connection.writable());
if self.state != HandshakeState::StartSession { if self.state != HandshakeState::StartSession {
@ -105,14 +106,14 @@ impl Handshake {
Ok(()) Ok(())
} }
pub fn register(&mut self, event_loop: &mut EventLoop<Host>) -> Result<(), Error> { pub fn register(&mut self, event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
self.idle_timeout.map(|t| event_loop.clear_timeout(t)); self.idle_timeout.map(|t| event_loop.clear_timeout(t));
self.idle_timeout = event_loop.timeout_ms(self.connection.token, 1800).ok(); self.idle_timeout = event_loop.timeout_ms(self.connection.token, 1800).ok();
try!(self.connection.register(event_loop)); try!(self.connection.register(event_loop));
Ok(()) 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()); trace!(target:"net", "Received handshake auth to {:?}", self.connection.socket.peer_addr());
assert!(data.len() == AUTH_PACKET_SIZE); assert!(data.len() == AUTH_PACKET_SIZE);
self.auth_cipher = data.to_vec(); self.auth_cipher = data.to_vec();
@ -128,12 +129,12 @@ impl Handshake {
let spub = try!(ec::recover(&signature, &(&shared ^ &self.remote_nonce))); let spub = try!(ec::recover(&signature, &(&shared ^ &self.remote_nonce)));
if &spub.sha3()[..] != hepubk { if &spub.sha3()[..] != hepubk {
trace!(target:"net", "Handshake hash mismath with {:?}", self.connection.socket.peer_addr()); 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() 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()); trace!(target:"net", "Received handshake auth to {:?}", self.connection.socket.peer_addr());
assert!(data.len() == ACK_PACKET_SIZE); assert!(data.len() == ACK_PACKET_SIZE);
self.ack_cipher = data.to_vec(); self.ack_cipher = data.to_vec();
@ -143,7 +144,7 @@ impl Handshake {
Ok(()) 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()); 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 mut data = [0u8; /*Signature::SIZE*/ 65 + /*H256::SIZE*/ 32 + /*Public::SIZE*/ 64 + /*H256::SIZE*/ 32 + 1]; //TODO: use associated constants
let len = data.len(); let len = data.len();
@ -169,7 +170,7 @@ impl Handshake {
Ok(()) 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()); 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 mut data = [0u8; 1 + /*Public::SIZE*/ 64 + /*H256::SIZE*/ 32]; //TODO: use associated constants
let len = data.len(); let len = data.len();

View File

@ -13,7 +13,8 @@ use rlp::*;
use time::Tm; use time::Tm;
use network::handshake::Handshake; use network::handshake::Handshake;
use network::session::{Session, SessionData}; use network::session::{Session, SessionData};
use network::{Error, ProtocolHandler}; use error::*;
use network::ProtocolHandler;
const _DEFAULT_PORT: u16 = 30304; const _DEFAULT_PORT: u16 = 30304;
@ -53,7 +54,7 @@ pub struct NodeEndpoint {
} }
impl NodeEndpoint { impl NodeEndpoint {
fn from_str(s: &str) -> Result<NodeEndpoint, Error> { fn from_str(s: &str) -> Result<NodeEndpoint, UtilError> {
let address = s.to_socket_addrs().map(|mut i| i.next()); let address = s.to_socket_addrs().map(|mut i| i.next());
match address { match address {
Ok(Some(a)) => Ok(NodeEndpoint { Ok(Some(a)) => Ok(NodeEndpoint {
@ -61,8 +62,8 @@ impl NodeEndpoint {
address_str: s.to_string(), address_str: s.to_string(),
udp_port: a.port() udp_port: a.port()
}), }),
Ok(_) => Err(Error::AddressResolve(None)), Ok(_) => Err(UtilError::AddressResolve(None)),
Err(e) => Err(Error::AddressResolve(Some(e))) Err(e) => Err(UtilError::AddressResolve(Some(e)))
} }
} }
} }
@ -81,7 +82,7 @@ struct Node {
} }
impl FromStr for Node { impl FromStr for Node {
type Err = Error; type Err = UtilError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let (id, endpoint) = if &s[0..8] == "enode://" && s.len() > 136 && &s[136..137] == "@" { 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..]))) (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. /// Send a packet over the network to another peer.
pub fn send(&mut self, peer: PeerId, packet_id: PacketId, data: Vec<u8>) -> Result<(), Error> { pub fn send(&mut self, peer: PeerId, packet_id: PacketId, data: Vec<u8>) -> Result<(), UtilError> {
match self.connections.get_mut(Token(peer)) { match self.connections.get_mut(Token(peer)) {
Some(&mut ConnectionEntry::Session(ref mut s)) => { Some(&mut ConnectionEntry::Session(ref mut s)) => {
s.send_packet(self.protocol, packet_id as u8, &data).unwrap_or_else(|e| { 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. /// 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<u8>) -> Result<(), Error> { pub fn respond(&mut self, packet_id: PacketId, data: Vec<u8>) -> Result<(), UtilError> {
match self.session { match self.session {
Some(session) => self.send(session.as_usize(), packet_id, data), Some(session) => self.send(session.as_usize(), packet_id, data),
None => { 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. /// 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<TimerToken, Error>{ pub fn register_timer(&mut self, ms: u64) -> Result<TimerToken, UtilError>{
match self.timers.insert(UserTimer { match self.timers.insert(UserTimer {
delay: ms, delay: ms,
protocol: self.protocol, protocol: self.protocol,
@ -292,7 +293,7 @@ pub struct Host {
} }
impl Host { impl Host {
pub fn start(event_loop: &mut EventLoop<Host>) -> Result<(), Error> { pub fn start(event_loop: &mut EventLoop<Host>) -> Result<(), UtilError> {
let config = NetworkConfiguration::new(); let config = NetworkConfiguration::new();
/* /*
match ::ifaces::Interface::get_all().unwrap().into_iter().filter(|x| x.kind == ::ifaces::Kind::Packet && x.addr.is_some()).next() { match ::ifaces::Interface::get_all().unwrap().into_iter().filter(|x| x.kind == ::ifaces::Kind::Packet && x.addr.is_some()).next() {

View File

@ -69,49 +69,23 @@ pub enum DisconnectReason
} }
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum NetworkError {
Crypto(::crypto::CryptoError),
Io(::std::io::Error),
Auth, Auth,
BadProtocol, BadProtocol,
AddressParse(::std::net::AddrParseError),
AddressResolve(Option<::std::io::Error>),
NodeIdParse(::error::EthcoreError),
PeerNotFound, PeerNotFound,
Disconnect(DisconnectReason) Disconnect(DisconnectReason),
Mio(::std::io::Error),
} }
impl From<::std::io::Error> for Error { impl From<::rlp::DecoderError> for NetworkError {
fn from(err: ::std::io::Error) -> Error { fn from(_err: ::rlp::DecoderError) -> NetworkError {
Error::Io(err) NetworkError::Auth
} }
} }
impl From<::crypto::CryptoError> for Error { impl From<::mio::NotifyError<host::HostMessage>> for NetworkError {
fn from(err: ::crypto::CryptoError) -> Error { fn from(_err: ::mio::NotifyError<host::HostMessage>) -> NetworkError {
Error::Crypto(err) NetworkError::Mio(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error"))
}
}
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<host::HostMessage>> for Error {
fn from(_err: ::mio::NotifyError<host::HostMessage>) -> Error {
Error::Io(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, "Network IO notification error"))
} }
} }

View File

@ -1,6 +1,7 @@
use std::thread::{self, JoinHandle}; use std::thread::{self, JoinHandle};
use mio::*; use mio::*;
use network::{Error, ProtocolHandler}; use error::*;
use network::{NetworkError, ProtocolHandler};
use network::host::{Host, HostMessage, PeerId, PacketId, ProtocolId}; use network::host::{Host, HostMessage, PeerId, PacketId, ProtocolId};
/// IO Service with networking /// IO Service with networking
@ -11,7 +12,7 @@ pub struct NetworkService {
impl NetworkService { impl NetworkService {
/// Starts IO event loop /// Starts IO event loop
pub fn start() -> Result<NetworkService, Error> { pub fn start() -> Result<NetworkService, UtilError> {
let mut event_loop = EventLoop::new().unwrap(); let mut event_loop = EventLoop::new().unwrap();
let channel = event_loop.channel(); let channel = event_loop.channel();
let thread = thread::spawn(move || { 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. /// 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 { try!(self.host_channel.send(HostMessage::Send {
peer: *peer, peer: *peer,
packet_id: packet_id, packet_id: packet_id,
@ -35,7 +36,7 @@ impl NetworkService {
} }
/// Regiter a new protocol handler with the event loop. /// Regiter a new protocol handler with the event loop.
pub fn register_protocol(&mut self, handler: Box<ProtocolHandler+Send>, protocol: ProtocolId, versions: &[u8]) -> Result<(), Error> { pub fn register_protocol(&mut self, handler: Box<ProtocolHandler+Send>, protocol: ProtocolId, versions: &[u8]) -> Result<(), NetworkError> {
try!(self.host_channel.send(HostMessage::AddHandler { try!(self.host_channel.send(HostMessage::AddHandler {
handler: handler, handler: handler,
protocol: protocol, protocol: protocol,

View File

@ -3,7 +3,8 @@ use hash::*;
use rlp::*; use rlp::*;
use network::connection::{EncryptedConnection, Packet}; use network::connection::{EncryptedConnection, Packet};
use network::handshake::Handshake; use network::handshake::Handshake;
use network::{Error, DisconnectReason}; use error::*;
use network::{NetworkError, DisconnectReason};
use network::host::*; use network::host::*;
pub struct Session { pub struct Session {
@ -64,7 +65,7 @@ const PACKET_USER: u8 = 0x10;
const PACKET_LAST: u8 = 0x7f; const PACKET_LAST: u8 = 0x7f;
impl Session { impl Session {
pub fn new(h: Handshake, event_loop: &mut EventLoop<Host>, host: &HostInfo) -> Result<Session, Error> { pub fn new(h: Handshake, event_loop: &mut EventLoop<Host>, host: &HostInfo) -> Result<Session, UtilError> {
let id = h.id.clone(); let id = h.id.clone();
let connection = try!(EncryptedConnection::new(h)); let connection = try!(EncryptedConnection::new(h));
let mut session = Session { let mut session = Session {
@ -83,14 +84,14 @@ impl Session {
Ok(session) Ok(session)
} }
pub fn readable(&mut self, event_loop: &mut EventLoop<Host>, host: &HostInfo) -> Result<SessionData, Error> { pub fn readable(&mut self, event_loop: &mut EventLoop<Host>, host: &HostInfo) -> Result<SessionData, UtilError> {
match try!(self.connection.readable(event_loop)) { 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) None => Ok(SessionData::None)
} }
} }
pub fn writable(&mut self, event_loop: &mut EventLoop<Host>, _host: &HostInfo) -> Result<(), Error> { pub fn writable(&mut self, event_loop: &mut EventLoop<Host>, _host: &HostInfo) -> Result<(), UtilError> {
self.connection.writable(event_loop) self.connection.writable(event_loop)
} }
@ -98,7 +99,7 @@ impl Session {
self.info.capabilities.iter().any(|c| c.protocol == protocol) self.info.capabilities.iter().any(|c| c.protocol == protocol)
} }
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; let mut i = 0usize;
while protocol != self.info.capabilities[i].protocol { while protocol != self.info.capabilities[i].protocol {
i += 1; i += 1;
@ -114,13 +115,13 @@ impl Session {
self.connection.send_packet(&rlp.out()) self.connection.send_packet(&rlp.out())
} }
fn read_packet(&mut self, packet: Packet, host: &HostInfo) -> Result<SessionData, Error> { fn read_packet(&mut self, packet: Packet, host: &HostInfo) -> Result<SessionData, UtilError> {
if packet.data.len() < 2 { if packet.data.len() < 2 {
return Err(Error::BadProtocol); return Err(From::from(NetworkError::BadProtocol));
} }
let packet_id = packet.data[0]; let packet_id = packet.data[0];
if packet_id != PACKET_HELLO && packet_id != PACKET_DISCONNECT && !self.had_hello { 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 { match packet_id {
PACKET_HELLO => { PACKET_HELLO => {
@ -128,7 +129,7 @@ impl Session {
try!(self.read_hello(&rlp, host)); try!(self.read_hello(&rlp, host));
Ok(SessionData::Ready) Ok(SessionData::Ready)
}, },
PACKET_DISCONNECT => Err(Error::Disconnect(DisconnectReason::DisconnectRequested)), PACKET_DISCONNECT => Err(From::from(NetworkError::Disconnect(DisconnectReason::DisconnectRequested))),
PACKET_PING => { PACKET_PING => {
try!(self.write_pong()); try!(self.write_pong());
Ok(SessionData::None) Ok(SessionData::None)
@ -157,7 +158,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(); let mut rlp = RlpStream::new();
rlp.append(&(PACKET_HELLO as u32)); rlp.append(&(PACKET_HELLO as u32));
rlp.append_list(5) rlp.append_list(5)
@ -169,7 +170,7 @@ impl Session {
self.connection.send_packet(&rlp.out()) 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::<u32>(0)); let protocol = try!(rlp.val_at::<u32>(0));
let client_version = try!(rlp.val_at::<String>(1)); let client_version = try!(rlp.val_at::<String>(1));
let peer_caps = try!(rlp.val_at::<Vec<PeerCapabilityInfo>>(2)); let peer_caps = try!(rlp.val_at::<Vec<PeerCapabilityInfo>>(2));
@ -210,37 +211,37 @@ impl Session {
trace!(target: "net", "Hello: {} v{} {} {:?}", client_version, protocol, id, caps); trace!(target: "net", "Hello: {} v{} {} {:?}", client_version, protocol, id, caps);
self.info.capabilities = caps; self.info.capabilities = caps;
if protocol != host.protocol_version { if protocol != host.protocol_version {
return Err(self.disconnect(DisconnectReason::UselessPeer)); return Err(From::from(self.disconnect(DisconnectReason::UselessPeer)));
} }
self.had_hello = true; self.had_hello = true;
Ok(()) Ok(())
} }
fn write_ping(&mut self) -> Result<(), Error> { fn write_ping(&mut self) -> Result<(), UtilError> {
self.send(try!(Session::prepare(PACKET_PING, 0))) self.send(try!(Session::prepare(PACKET_PING, 0)))
} }
fn write_pong(&mut self) -> Result<(), Error> { fn write_pong(&mut self) -> Result<(), UtilError> {
self.send(try!(Session::prepare(PACKET_PONG, 0))) self.send(try!(Session::prepare(PACKET_PONG, 0)))
} }
fn disconnect(&mut self, reason: DisconnectReason) -> Error { fn disconnect(&mut self, reason: DisconnectReason) -> NetworkError {
let mut rlp = RlpStream::new(); let mut rlp = RlpStream::new();
rlp.append(&(PACKET_DISCONNECT as u32)); rlp.append(&(PACKET_DISCONNECT as u32));
rlp.append_list(1); rlp.append_list(1);
rlp.append(&(reason.clone() as u32)); rlp.append(&(reason.clone() as u32));
self.connection.send_packet(&rlp.out()).ok(); self.connection.send_packet(&rlp.out()).ok();
Error::Disconnect(reason) NetworkError::Disconnect(reason)
} }
fn prepare(packet_id: u8, items: usize) -> Result<RlpStream, Error> { fn prepare(packet_id: u8, items: usize) -> Result<RlpStream, UtilError> {
let mut rlp = RlpStream::new_list(1); let mut rlp = RlpStream::new_list(1);
rlp.append(&(packet_id as u32)); rlp.append(&(packet_id as u32));
rlp.append_list(items); rlp.append_list(items);
Ok(rlp) Ok(rlp)
} }
fn send(&mut self, rlp: RlpStream) -> Result<(), Error> { fn send(&mut self, rlp: RlpStream) -> Result<(), UtilError> {
self.connection.send_packet(&rlp.out()) self.connection.send_packet(&rlp.out())
} }
} }

View File

@ -66,7 +66,7 @@ impl OverlayDB {
/// assert!(m.exists(&key)); // key now still exists. /// assert!(m.exists(&key)); // key now still exists.
/// } /// }
/// ``` /// ```
pub fn commit(&mut self) -> Result<u32, EthcoreError> { pub fn commit(&mut self) -> Result<u32, UtilError> {
let mut ret = 0u32; let mut ret = 0u32;
for i in self.overlay.drain().into_iter() { for i in self.overlay.drain().into_iter() {
let (key, (value, rc)) = i; let (key, (value, rc)) = i;

View File

@ -43,7 +43,7 @@ pub use self::rlperrors::DecoderError;
pub use self::rlptraits::{Decoder, Decodable, View, Stream, Encodable, Encoder}; pub use self::rlptraits::{Decoder, Decodable, View, Stream, Encodable, Encoder};
pub use self::untrusted_rlp::{UntrustedRlp, UntrustedRlpIterator, PayloadInfo, Prototype}; pub use self::untrusted_rlp::{UntrustedRlp, UntrustedRlpIterator, PayloadInfo, Prototype};
pub use self::rlpin::{Rlp, RlpIterator}; pub use self::rlpin::{Rlp, RlpIterator};
pub use self::rlpstream::{RlpStream}; pub use self::rlpstream::{RlpStream,RlpStandard};
use super::hash::H256; use super::hash::H256;
pub const NULL_RLP: [u8; 1] = [0x80; 1]; pub const NULL_RLP: [u8; 1] = [0x80; 1];

View File

@ -1,6 +1,8 @@
use elastic_array::*; use elastic_array::*;
use bytes::ToBytes; use bytes::{Bytes, ToBytes};
use rlp::{Stream, Encoder, Encodable}; use rlp::{Stream, Encoder, Encodable};
use hash::H256;
use sha3::*;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct ListInfo { 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<T> Encodable for T where T: ToBytes { impl<T> Encodable for T where T: ToBytes {
fn encode<E>(&self, encoder: &mut E) where E: Encoder { fn encode<E>(&self, encoder: &mut E) where E: Encoder {
encoder.emit_value(&self.to_bytes()) encoder.emit_value(&self.to_bytes())