From a04c5b180a821c709b0ea24c7d4f21c9c2511839 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 16 Apr 2018 14:52:12 +0100 Subject: [PATCH] Replace legacy Rlp with UntrustedRlp and use in ethcore rlp views (#8316) * WIP * Replace Rlp with UntrustedRlp in views, explicity unwrap with expect First pass to get it to compile. Need to figure out whether to do this or to propogate Errors upstream, which would require many more changes to dependent code. If we do this way we are assuming that the views are always used in a context where the rlp is trusted to be valid e.g. when reading from our own DB. So need to fid out whether views are used with data received from an untrusted (e.g. extrernal peer). * Remove original Rlp impl, rename UntrustedRlp -> Rlp * Create rlp views with view! macro to record debug info Views are assumed to be over valid rlp, so if there is a decoding error we record where the view was created in the first place and report it in the expect * Use $crate in view! macro to avoid import, fix tests * Expect valid rlp in decode functions for now * Replace spaces with tabs in new file * Add doc tests for creating views with macro * Update rlp docs to reflect removing of UntrustedRlp * Replace UntrustedRlp usages in private-tx merge --- ethcore/light/src/cht.rs | 4 +- ethcore/light/src/client/header_chain.rs | 6 +- ethcore/light/src/net/mod.rs | 20 +- ethcore/light/src/net/request_credits.rs | 4 +- ethcore/light/src/net/status.rs | 30 +- ethcore/light/src/net/tests/mod.rs | 8 +- ethcore/light/src/on_demand/request.rs | 4 +- ethcore/light/src/types/request/mod.rs | 36 +- ethcore/private-tx/src/lib.rs | 6 +- ethcore/src/block.rs | 14 +- ethcore/src/blockchain/blockchain.rs | 32 +- ethcore/src/blockchain/generator.rs | 2 +- ethcore/src/client/client.rs | 10 +- ethcore/src/client/test_client.rs | 14 +- ethcore/src/encoded.rs | 18 +- ethcore/src/engines/authority_round/mod.rs | 18 +- ethcore/src/engines/basic_authority.rs | 4 +- ethcore/src/engines/epoch.rs | 6 +- ethcore/src/engines/tendermint/message.rs | 18 +- ethcore/src/engines/tendermint/mod.rs | 11 +- .../engines/validator_set/safe_contract.rs | 10 +- ethcore/src/ethereum/ethash.rs | 6 +- ethcore/src/ethereum/mod.rs | 4 +- ethcore/src/header.rs | 6 +- ethcore/src/json_tests/transaction.rs | 4 +- ethcore/src/lib.rs | 4 +- ethcore/src/snapshot/account.rs | 18 +- ethcore/src/snapshot/block.rs | 10 +- ethcore/src/snapshot/consensus/authority.rs | 6 +- ethcore/src/snapshot/consensus/work.rs | 6 +- ethcore/src/snapshot/io.rs | 4 +- ethcore/src/snapshot/mod.rs | 6 +- ethcore/src/spec/spec.rs | 2 +- ethcore/src/test_helpers.rs | 2 +- ethcore/src/tests/client.rs | 12 +- ethcore/src/tests/trace.rs | 4 +- ethcore/src/trace/types/error.rs | 4 +- ethcore/src/trace/types/flat.rs | 4 +- ethcore/src/trace/types/trace.rs | 10 +- ethcore/src/verification/queue/kind.rs | 2 +- ethcore/src/verification/queue/mod.rs | 6 +- ethcore/src/verification/verification.rs | 28 +- ethcore/src/views/block.rs | 59 ++- ethcore/src/views/body.rs | 56 +- ethcore/src/views/header.rs | 42 +- ethcore/src/views/mod.rs | 14 + ethcore/src/views/transaction.rs | 35 +- ethcore/src/views/view_rlp.rs | 130 +++++ ethcore/sync/src/block_sync.rs | 12 +- ethcore/sync/src/blocks.rs | 25 +- ethcore/sync/src/chain.rs | 96 ++-- ethcore/sync/src/lib.rs | 1 + ethcore/transaction/src/transaction.rs | 6 +- ethcore/types/src/receipt.rs | 4 +- ethcore/types/src/snapshot_manifest.rs | 4 +- ethcore/vm/src/call_type.rs | 4 +- local-store/src/lib.rs | 4 +- parity/blockchain.rs | 2 +- rpc/src/lib.rs | 1 + rpc/src/v1/impls/eth.rs | 4 +- rpc/src/v1/impls/light/eth.rs | 4 +- rpc/src/v1/impls/private.rs | 6 +- rpc/src/v1/impls/signer.rs | 4 +- rpc/src/v1/impls/traces.rs | 4 +- rpc/src/v1/tests/eth.rs | 2 +- util/journaldb/src/overlaydb.rs | 4 +- util/journaldb/src/overlayrecentdb.rs | 4 +- util/journaldb/src/util.rs | 6 +- util/network-devp2p/src/connection.rs | 4 +- util/network-devp2p/src/discovery.rs | 16 +- util/network-devp2p/src/handshake.rs | 6 +- util/network-devp2p/src/node_table.rs | 4 +- util/network-devp2p/src/session.rs | 8 +- util/network/src/lib.rs | 4 +- util/patricia_trie/src/node.rs | 6 +- util/patricia_trie/src/triedbmut.rs | 4 +- util/rlp/src/impls.rs | 20 +- util/rlp/src/lib.rs | 14 +- util/rlp/src/rlpin.rs | 487 +++++++++++------- util/rlp/src/traits.rs | 4 +- util/rlp/src/untrusted_rlp.rs | 406 --------------- util/rlp/tests/tests.rs | 18 +- util/rlp_compress/src/lib.rs | 8 +- util/rlp_derive/src/de.rs | 4 +- whisper/src/message.rs | 18 +- whisper/src/net/mod.rs | 12 +- 86 files changed, 944 insertions(+), 1055 deletions(-) create mode 100644 ethcore/src/views/view_rlp.rs delete mode 100644 util/rlp/src/untrusted_rlp.rs diff --git a/ethcore/light/src/cht.rs b/ethcore/light/src/cht.rs index 6f5ebf808..ffb7841f4 100644 --- a/ethcore/light/src/cht.rs +++ b/ethcore/light/src/cht.rs @@ -26,7 +26,7 @@ use hashdb::HashDB; use memorydb::MemoryDB; use bytes::Bytes; use trie::{self, TrieMut, TrieDBMut, Trie, TrieDB, Recorder}; -use rlp::{RlpStream, UntrustedRlp}; +use rlp::{RlpStream, Rlp}; // encode a key. macro_rules! key { @@ -150,7 +150,7 @@ pub fn check_proof(proof: &[Bytes], num: u64, root: H256) -> Option<(H256, U256) let res = match TrieDB::new(&db, &root) { Err(_) => return None, Ok(trie) => trie.get_with(&key!(num), |val: &[u8]| { - let rlp = UntrustedRlp::new(val); + let rlp = Rlp::new(val); rlp.val_at::(0) .and_then(|h| rlp.val_at::(1).map(|td| (h, td))) .ok() diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index 84b7916ee..7bd13a6c0 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -41,7 +41,7 @@ use ethcore::engines::epoch::{ PendingTransition as PendingEpochTransition }; -use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; +use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; use heapsize::HeapSizeOf; use ethereum_types::{H256, H264, U256}; use plain_hasher::H256FastMap; @@ -125,7 +125,7 @@ impl Encodable for Entry { } impl Decodable for Entry { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let mut candidates = SmallVec::<[Candidate; 3]>::new(); for item in rlp.iter() { @@ -186,7 +186,7 @@ fn encode_canonical_transition(header: &Header, proof: &[u8]) -> Vec { // decode last canonical transition entry. fn decode_canonical_transition(t: &[u8]) -> Result<(Header, &[u8]), DecoderError> { - let rlp = UntrustedRlp::new(t); + let rlp = Rlp::new(t); Ok((rlp.val_at(0)?, rlp.at(1)?.data()?)) } diff --git a/ethcore/light/src/net/mod.rs b/ethcore/light/src/net/mod.rs index 829977323..d58d90fac 100644 --- a/ethcore/light/src/net/mod.rs +++ b/ethcore/light/src/net/mod.rs @@ -22,7 +22,7 @@ use transaction::UnverifiedTransaction; use io::TimerToken; use network::{HostInfo, NetworkProtocolHandler, NetworkContext, PeerId}; -use rlp::{RlpStream, UntrustedRlp}; +use rlp::{RlpStream, Rlp}; use ethereum_types::{H256, U256}; use kvdb::DBValue; use parking_lot::{Mutex, RwLock}; @@ -528,7 +528,7 @@ impl LightProtocol { // - check whether peer exists // - check whether request was made // - check whether request kinds match - fn pre_verify_response(&self, peer: &PeerId, raw: &UntrustedRlp) -> Result { + fn pre_verify_response(&self, peer: &PeerId, raw: &Rlp) -> Result { let req_id = ReqId(raw.val_at(0)?); let cur_credits: U256 = raw.val_at(1)?; @@ -572,7 +572,7 @@ impl LightProtocol { /// Packet data is _untrusted_, which means that invalid data won't lead to /// issues. pub fn handle_packet(&self, io: &IoContext, peer: &PeerId, packet_id: u8, data: &[u8]) { - let rlp = UntrustedRlp::new(data); + let rlp = Rlp::new(data); trace!(target: "pip", "Incoming packet {} from peer {}", packet_id, peer); @@ -794,7 +794,7 @@ impl LightProtocol { impl LightProtocol { // Handle status message from peer. - fn status(&self, peer: &PeerId, io: &IoContext, data: UntrustedRlp) -> Result<(), Error> { + fn status(&self, peer: &PeerId, io: &IoContext, data: Rlp) -> Result<(), Error> { let pending = match self.pending_peers.write().remove(peer) { Some(pending) => pending, None => { @@ -855,7 +855,7 @@ impl LightProtocol { } // Handle an announcement. - fn announcement(&self, peer: &PeerId, io: &IoContext, data: UntrustedRlp) -> Result<(), Error> { + fn announcement(&self, peer: &PeerId, io: &IoContext, data: Rlp) -> Result<(), Error> { if !self.peers.read().contains_key(peer) { debug!(target: "pip", "Ignoring announcement from unknown peer"); return Ok(()) @@ -900,7 +900,7 @@ impl LightProtocol { } // Receive requests from a peer. - fn request(&self, peer_id: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { + fn request(&self, peer_id: &PeerId, io: &IoContext, raw: Rlp) -> Result<(), Error> { // the maximum amount of requests we'll fill in a single packet. const MAX_REQUESTS: usize = 256; @@ -968,7 +968,7 @@ impl LightProtocol { } // handle a packet with responses. - fn response(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { + fn response(&self, peer: &PeerId, io: &IoContext, raw: Rlp) -> Result<(), Error> { let (req_id, responses) = { let id_guard = self.pre_verify_response(peer, &raw)?; let responses: Vec = raw.list_at(2)?; @@ -987,7 +987,7 @@ impl LightProtocol { } // handle an update of request credits parameters. - fn update_credits(&self, peer_id: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { + fn update_credits(&self, peer_id: &PeerId, io: &IoContext, raw: Rlp) -> Result<(), Error> { let peers = self.peers.read(); let peer = peers.get(peer_id).ok_or(Error::UnknownPeer)?; @@ -1022,7 +1022,7 @@ impl LightProtocol { } // handle an acknowledgement of request credits update. - fn acknowledge_update(&self, peer_id: &PeerId, _io: &IoContext, _raw: UntrustedRlp) -> Result<(), Error> { + fn acknowledge_update(&self, peer_id: &PeerId, _io: &IoContext, _raw: Rlp) -> Result<(), Error> { let peers = self.peers.read(); let peer = peers.get(peer_id).ok_or(Error::UnknownPeer)?; let mut peer = peer.lock(); @@ -1041,7 +1041,7 @@ impl LightProtocol { } // Receive a set of transactions to relay. - fn relay_transactions(&self, peer: &PeerId, io: &IoContext, data: UntrustedRlp) -> Result<(), Error> { + fn relay_transactions(&self, peer: &PeerId, io: &IoContext, data: Rlp) -> Result<(), Error> { const MAX_TRANSACTIONS: usize = 256; let txs: Vec<_> = data.iter() diff --git a/ethcore/light/src/net/request_credits.rs b/ethcore/light/src/net/request_credits.rs index e1b7455cc..abe609dab 100644 --- a/ethcore/light/src/net/request_credits.rs +++ b/ethcore/light/src/net/request_credits.rs @@ -29,7 +29,7 @@ use request::{self, Request}; use super::error::Error; -use rlp::{UntrustedRlp, RlpStream, Decodable, Encodable, DecoderError}; +use rlp::{Rlp, RlpStream, Decodable, Encodable, DecoderError}; use ethereum_types::U256; use std::time::{Duration, Instant}; @@ -162,7 +162,7 @@ impl Encodable for CostTable { } impl Decodable for CostTable { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let base = rlp.val_at(0)?; let mut headers = None; diff --git a/ethcore/light/src/net/status.rs b/ethcore/light/src/net/status.rs index 0f811bbe4..c9ee3d760 100644 --- a/ethcore/light/src/net/status.rs +++ b/ethcore/light/src/net/status.rs @@ -16,7 +16,7 @@ //! Peer status and capabilities. -use rlp::{DecoderError, Encodable, Decodable, RlpStream, UntrustedRlp}; +use rlp::{DecoderError, Encodable, Decodable, RlpStream, Rlp}; use ethereum_types::{H256, U256}; use super::request_credits::FlowParams; @@ -85,7 +85,7 @@ impl Key { // helper for decoding key-value pairs in the handshake or an announcement. struct Parser<'a> { pos: usize, - rlp: UntrustedRlp<'a>, + rlp: Rlp<'a>, } impl<'a> Parser<'a> { @@ -97,7 +97,7 @@ impl<'a> Parser<'a> { // expect a specific next key, and get the value's RLP. // if the key isn't found, the position isn't advanced. - fn expect_raw(&mut self, key: Key) -> Result, DecoderError> { + fn expect_raw(&mut self, key: Key) -> Result, DecoderError> { trace!(target: "les", "Expecting key {}", key.as_str()); let pre_pos = self.pos; if let Some((k, val)) = self.get_next()? { @@ -109,7 +109,7 @@ impl<'a> Parser<'a> { } // get the next key and value RLP. - fn get_next(&mut self) -> Result)>, DecoderError> { + fn get_next(&mut self) -> Result)>, DecoderError> { while self.pos < self.rlp.item_count()? { let pair = self.rlp.at(self.pos)?; let k: String = pair.val_at(0)?; @@ -208,7 +208,7 @@ impl Capabilities { /// - chain status /// - serving capabilities /// - request credit parameters -pub fn parse_handshake(rlp: UntrustedRlp) -> Result<(Status, Capabilities, Option), DecoderError> { +pub fn parse_handshake(rlp: Rlp) -> Result<(Status, Capabilities, Option), DecoderError> { let mut parser = Parser { pos: 0, rlp: rlp, @@ -304,7 +304,7 @@ pub struct Announcement { } /// Parse an announcement. -pub fn parse_announcement(rlp: UntrustedRlp) -> Result { +pub fn parse_announcement(rlp: Rlp) -> Result { let mut last_key = None; let mut announcement = Announcement { @@ -374,7 +374,7 @@ mod tests { use super::*; use super::super::request_credits::FlowParams; use ethereum_types::{U256, H256}; - use rlp::{RlpStream, UntrustedRlp}; + use rlp::{RlpStream, Rlp}; #[test] fn full_handshake() { @@ -404,7 +404,7 @@ mod tests { let handshake = write_handshake(&status, &capabilities, Some(&flow_params)); let (read_status, read_capabilities, read_flow) - = parse_handshake(UntrustedRlp::new(&handshake)).unwrap(); + = parse_handshake(Rlp::new(&handshake)).unwrap(); assert_eq!(read_status, status); assert_eq!(read_capabilities, capabilities); @@ -439,7 +439,7 @@ mod tests { let handshake = write_handshake(&status, &capabilities, Some(&flow_params)); let (read_status, read_capabilities, read_flow) - = parse_handshake(UntrustedRlp::new(&handshake)).unwrap(); + = parse_handshake(Rlp::new(&handshake)).unwrap(); assert_eq!(read_status, status); assert_eq!(read_capabilities, capabilities); @@ -473,7 +473,7 @@ mod tests { let handshake = write_handshake(&status, &capabilities, Some(&flow_params)); let interleaved = { - let handshake = UntrustedRlp::new(&handshake); + let handshake = Rlp::new(&handshake); let mut stream = RlpStream::new_list(handshake.item_count().unwrap_or(0) * 3); for item in handshake.iter() { @@ -489,7 +489,7 @@ mod tests { }; let (read_status, read_capabilities, read_flow) - = parse_handshake(UntrustedRlp::new(&interleaved)).unwrap(); + = parse_handshake(Rlp::new(&interleaved)).unwrap(); assert_eq!(read_status, status); assert_eq!(read_capabilities, capabilities); @@ -510,7 +510,7 @@ mod tests { }; let serialized = write_announcement(&announcement); - let read = parse_announcement(UntrustedRlp::new(&serialized)).unwrap(); + let read = parse_announcement(Rlp::new(&serialized)).unwrap(); assert_eq!(read, announcement); } @@ -529,7 +529,7 @@ mod tests { .append_raw(&encode_flag(Key::ServeHeaders), 1); let out = stream.drain(); - assert!(parse_announcement(UntrustedRlp::new(&out)).is_err()); + assert!(parse_announcement(Rlp::new(&out)).is_err()); let mut stream = RlpStream::new_list(6); stream @@ -541,7 +541,7 @@ mod tests { .append_raw(&encode_pair(Key::ServeStateSince, &44u64), 1); let out = stream.drain(); - assert!(parse_announcement(UntrustedRlp::new(&out)).is_ok()); + assert!(parse_announcement(Rlp::new(&out)).is_ok()); } #[test] @@ -566,7 +566,7 @@ mod tests { let handshake = write_handshake(&status, &capabilities, None); let (read_status, read_capabilities, read_flow) - = parse_handshake(UntrustedRlp::new(&handshake)).unwrap(); + = parse_handshake(Rlp::new(&handshake)).unwrap(); assert_eq!(read_status, status); assert_eq!(read_capabilities, capabilities); diff --git a/ethcore/light/src/net/tests/mod.rs b/ethcore/light/src/net/tests/mod.rs index 397576ae4..3c04c0ffb 100644 --- a/ethcore/light/src/net/tests/mod.rs +++ b/ethcore/light/src/net/tests/mod.rs @@ -31,7 +31,7 @@ use provider::Provider; use request; use request::*; -use rlp::{UntrustedRlp, RlpStream}; +use rlp::{Rlp, RlpStream}; use ethereum_types::{H256, U256, Address}; use std::sync::Arc; @@ -688,7 +688,7 @@ fn id_guard() { stream.begin_list(2).append(&125usize).append(&3usize); let packet = stream.out(); - assert!(proto.response(&peer_id, &Expect::Nothing, UntrustedRlp::new(&packet)).is_err()); + assert!(proto.response(&peer_id, &Expect::Nothing, Rlp::new(&packet)).is_err()); } // next, do an unexpected response. @@ -699,7 +699,7 @@ fn id_guard() { stream.begin_list(0); let packet = stream.out(); - assert!(proto.response(&peer_id, &Expect::Nothing, UntrustedRlp::new(&packet)).is_err()); + assert!(proto.response(&peer_id, &Expect::Nothing, Rlp::new(&packet)).is_err()); } // lastly, do a valid (but empty) response. @@ -710,7 +710,7 @@ fn id_guard() { stream.begin_list(0); let packet = stream.out(); - assert!(proto.response(&peer_id, &Expect::Nothing, UntrustedRlp::new(&packet)).is_ok()); + assert!(proto.response(&peer_id, &Expect::Nothing, Rlp::new(&packet)).is_ok()); } let peers = proto.peers.read(); diff --git a/ethcore/light/src/on_demand/request.rs b/ethcore/light/src/on_demand/request.rs index 8b184cc1d..18a309ae9 100644 --- a/ethcore/light/src/on_demand/request.rs +++ b/ethcore/light/src/on_demand/request.rs @@ -30,7 +30,7 @@ use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY, KECCAK_EMPTY_LIST_RLP, keccak}; use request::{self as net_request, IncompleteRequest, CompleteRequest, Output, OutputKind, Field}; -use rlp::{RlpStream, UntrustedRlp}; +use rlp::{RlpStream, Rlp}; use ethereum_types::{H256, U256, Address}; use parking_lot::Mutex; use hashdb::HashDB; @@ -831,7 +831,7 @@ impl Account { match TrieDB::new(&db, &state_root).and_then(|t| t.get(&keccak(&self.address)))? { Some(val) => { - let rlp = UntrustedRlp::new(&val); + let rlp = Rlp::new(&val); Ok(Some(BasicAccount { nonce: rlp.val_at(0)?, balance: rlp.val_at(1)?, diff --git a/ethcore/light/src/types/request/mod.rs b/ethcore/light/src/types/request/mod.rs index bd68c6a0a..8d911d3f5 100644 --- a/ethcore/light/src/types/request/mod.rs +++ b/ethcore/light/src/types/request/mod.rs @@ -16,7 +16,7 @@ //! Light protocol request types. -use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; +use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; use ethereum_types::H256; mod batch; @@ -148,7 +148,7 @@ impl From for Field { } impl Decodable for Field { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { match rlp.val_at::(0)? { 0 => Ok(Field::Scalar(rlp.val_at::(1)?)), 1 => Ok({ @@ -224,7 +224,7 @@ impl From for HashOrNumber { } impl Decodable for HashOrNumber { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.as_val::().map(HashOrNumber::Hash) .or_else(|_| rlp.as_val().map(HashOrNumber::Number)) } @@ -331,7 +331,7 @@ impl Request { } impl Decodable for Request { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { match rlp.val_at::(0)? { Kind::Headers => Ok(Request::Headers(rlp.val_at(1)?)), Kind::HeaderProof => Ok(Request::HeaderProof(rlp.val_at(1)?)), @@ -493,7 +493,7 @@ pub enum Kind { } impl Decodable for Kind { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { match rlp.as_val::()? { 0 => Ok(Kind::Headers), 1 => Ok(Kind::HeaderProof), @@ -578,7 +578,7 @@ impl Response { } impl Decodable for Response { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { match rlp.val_at::(0)? { Kind::Headers => Ok(Response::Headers(rlp.val_at(1)?)), Kind::HeaderProof => Ok(Response::HeaderProof(rlp.val_at(1)?)), @@ -673,7 +673,7 @@ pub trait ResponseLike { pub mod header { use super::{Field, HashOrNumber, NoSuchOutput, OutputKind, Output}; use ethcore::encoded; - use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; + use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; /// Potentially incomplete headers request. #[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)] @@ -754,7 +754,7 @@ pub mod header { } impl Decodable for Response { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { use ethcore::header::Header as FullHeader; let mut headers = Vec::new(); @@ -785,7 +785,7 @@ pub mod header { /// Request and response for header proofs. pub mod header_proof { use super::{Field, NoSuchOutput, OutputKind, Output}; - use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; + use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; use ethereum_types::{H256, U256}; use bytes::Bytes; @@ -859,7 +859,7 @@ pub mod header_proof { } impl Decodable for Response { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { Ok(Response { proof: rlp.list_at(0)?, hash: rlp.val_at(1)?, @@ -1027,7 +1027,7 @@ pub mod block_receipts { pub mod block_body { use super::{Field, NoSuchOutput, OutputKind, Output}; use ethcore::encoded; - use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; + use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; use ethereum_types::H256; /// Potentially incomplete block body request. @@ -1092,7 +1092,7 @@ pub mod block_body { } impl Decodable for Response { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { use ethcore::header::Header as FullHeader; use transaction::UnverifiedTransaction; @@ -1411,7 +1411,7 @@ pub mod contract_code { pub mod execution { use super::{Field, NoSuchOutput, OutputKind, Output}; use transaction::Action; - use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; + use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; use ethereum_types::{H256, U256, Address}; use kvdb::DBValue; use bytes::Bytes; @@ -1508,7 +1508,7 @@ pub mod execution { } impl Decodable for Response { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let mut items = Vec::new(); for raw_item in rlp.iter() { let mut item = DBValue::new(); @@ -1536,7 +1536,7 @@ pub mod execution { /// A request for epoch signal data. pub mod epoch_signal { use super::{Field, NoSuchOutput, OutputKind, Output}; - use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; + use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; use ethereum_types::H256; use bytes::Bytes; @@ -1548,7 +1548,7 @@ pub mod epoch_signal { } impl Decodable for Incomplete { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { Ok(Incomplete { block_hash: rlp.val_at(0)?, }) @@ -1617,7 +1617,7 @@ pub mod epoch_signal { } impl Decodable for Response { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { Ok(Response { signal: rlp.as_val()?, @@ -1891,7 +1891,7 @@ mod tests { stream.append(&100usize).append_list(&reqs); let out = stream.out(); - let rlp = UntrustedRlp::new(&out); + let rlp = Rlp::new(&out); assert_eq!(rlp.val_at::(0).unwrap(), 100usize); assert_eq!(rlp.list_at::(1).unwrap(), reqs); } diff --git a/ethcore/private-tx/src/lib.rs b/ethcore/private-tx/src/lib.rs index e28dd7c33..80510938c 100644 --- a/ethcore/private-tx/src/lib.rs +++ b/ethcore/private-tx/src/lib.rs @@ -238,14 +238,14 @@ impl Provider where { fn extract_original_transaction(&self, private: PrivateTransaction, contract: &Address) -> Result { let encrypted_transaction = private.encrypted; let transaction_bytes = self.decrypt(contract, &encrypted_transaction)?; - let original_transaction: UnverifiedTransaction = UntrustedRlp::new(&transaction_bytes).as_val()?; + let original_transaction: UnverifiedTransaction = Rlp::new(&transaction_bytes).as_val()?; Ok(original_transaction) } /// Process received private transaction pub fn import_private_transaction(&self, rlp: &[u8]) -> Result<(), Error> { trace!("Private transaction received"); - let private_tx: PrivateTransaction = UntrustedRlp::new(rlp).as_val()?; + let private_tx: PrivateTransaction = Rlp::new(rlp).as_val()?; let contract = private_tx.contract; let contract_validators = self.get_validators(BlockId::Latest, &contract)?; @@ -356,7 +356,7 @@ impl Provider where { /// Add signed private transaction into the store /// Creates corresponding public transaction if last required singature collected and sends it to the chain pub fn import_signed_private_transaction(&self, rlp: &[u8]) -> Result<(), Error> { - let tx: SignedPrivateTransaction = UntrustedRlp::new(rlp).as_val()?; + let tx: SignedPrivateTransaction = Rlp::new(rlp).as_val()?; trace!("Signature for private transaction received: {:?}", tx); let private_hash = tx.private_transaction_hash(); let desc = match self.transactions_for_signing.lock().get(&private_hash) { diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 4cbc0bac9..e3622c293 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -22,7 +22,7 @@ use std::collections::HashSet; use hash::{keccak, KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use triehash::ordered_trie_root; -use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError, encode_list}; +use rlp::{Rlp, RlpStream, Encodable, Decodable, DecoderError, encode_list}; use ethereum_types::{H256, U256, Address, Bloom}; use bytes::Bytes; use unexpected::{Mismatch, OutOfBounds}; @@ -54,7 +54,7 @@ pub struct Block { impl Block { /// Returns true if the given bytes form a valid encoding of a block in RLP. pub fn is_good(b: &[u8]) -> bool { - UntrustedRlp::new(b).as_val::().is_ok() + Rlp::new(b).as_val::().is_ok() } /// Get the RLP-encoding of the block with the seal. @@ -68,7 +68,7 @@ impl Block { } impl Decodable for Block { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { if rlp.as_raw().len() != rlp.payload_info()?.total() { return Err(DecoderError::RlpIsTooBig); } @@ -622,7 +622,7 @@ pub fn enact_verified( // Remove state root from transaction receipts to make them EIP-98 compatible. strip_receipts: bool, ) -> Result { - let view = BlockView::new(&block.bytes); + let view = view!(BlockView, &block.bytes); enact( block.header, @@ -664,7 +664,7 @@ mod tests { last_hashes: Arc, factories: Factories, ) -> Result { - let block = BlockView::new(block_bytes); + let block = view!(BlockView, block_bytes); let header = block.header(); let transactions: Result, Error> = block .transactions() @@ -715,7 +715,7 @@ mod tests { last_hashes: Arc, factories: Factories, ) -> Result { - let header = BlockView::new(block_bytes).header_view(); + let header = view!(BlockView, block_bytes).header_view(); Ok(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, factories)?.seal(engine, header.seal())?) } @@ -781,7 +781,7 @@ mod tests { let bytes = e.rlp_bytes(); assert_eq!(bytes, orig_bytes); - let uncles = BlockView::new(&bytes).uncles(); + let uncles = view!(BlockView, &bytes).uncles(); assert_eq!(uncles[1].extra_data(), b"uncle2"); let db = e.drain(); diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 5dffc9ec3..6ad8bf811 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -25,11 +25,11 @@ use heapsize::HeapSizeOf; use ethereum_types::{H256, Bloom, U256}; use parking_lot::{Mutex, RwLock}; use bytes::Bytes; -use rlp::{Rlp, RlpStream}; +use rlp::RlpStream; use rlp_compress::{compress, decompress, blocks_swapper}; use header::*; use transaction::*; -use views::*; +use views::{BlockView, HeaderView}; use log_entry::{LogEntry, LocalizedLogEntry}; use receipt::Receipt; use blooms::{BloomGroup, GroupPosition}; @@ -231,13 +231,7 @@ impl BlockProvider for BlockChain { fn block(&self, hash: &H256) -> Option { let header = self.block_header_data(hash)?; let body = self.block_body(hash)?; - - let mut block = RlpStream::new_list(3); - let body_rlp = body.rlp(); - block.append_raw(header.rlp().as_raw(), 1); - block.append_raw(body_rlp.at(0).as_raw(), 1); - block.append_raw(body_rlp.at(1).as_raw(), 1); - Some(encoded::Block::new(block.out())) + Some(encoded::Block::new_from_header_and_body(&header.view(), &body.view())) } /// Get block header data @@ -499,7 +493,7 @@ impl BlockChain { None => { // best block does not exist // we need to insert genesis into the cache - let block = BlockView::new(genesis); + let block = view!(BlockView, genesis); let header = block.header_view(); let hash = block.hash(); @@ -701,7 +695,7 @@ impl BlockChain { /// Supply a dummy parent total difficulty when the parent block may not be in the chain. /// Returns true if the block is disconnected. pub fn insert_unordered_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec, parent_td: Option, is_best: bool, is_ancient: bool) -> bool { - let block = BlockView::new(bytes); + let block = view!(BlockView, bytes); let header = block.header_view(); let hash = header.hash(); @@ -898,7 +892,7 @@ impl BlockChain { /// If the block is already known, does nothing. pub fn insert_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec) -> ImportRoute { // create views onto rlp - let block = BlockView::new(bytes); + let block = view!(BlockView, bytes); let header = block.header_view(); let hash = header.hash(); @@ -1138,7 +1132,7 @@ impl BlockChain { /// This function returns modified block hashes. fn prepare_block_hashes_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap { let mut block_hashes = HashMap::new(); - let block = BlockView::new(block_bytes); + let block = view!(BlockView, block_bytes); let header = block.header_view(); let number = header.number(); @@ -1165,7 +1159,7 @@ impl BlockChain { /// This function returns modified block details. /// Uses the given parent details or attempts to load them from the database. fn prepare_block_details_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap { - let block = BlockView::new(block_bytes); + let block = view!(BlockView, block_bytes); let header = block.header_view(); let parent_hash = header.parent_hash(); @@ -1197,7 +1191,7 @@ impl BlockChain { /// This function returns modified transaction addresses. fn prepare_transaction_addresses_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap> { - let block = BlockView::new(block_bytes); + let block = view!(BlockView, block_bytes); let transaction_hashes = block.transaction_hashes(); match info.location { @@ -1265,7 +1259,7 @@ impl BlockChain { /// to bloom location in database (BlocksBloomLocation). /// fn prepare_block_blooms_update(&self, block_bytes: &[u8], info: &BlockInfo) -> HashMap { - let block = BlockView::new(block_bytes); + let block = view!(BlockView, block_bytes); let header = block.header_view(); let log_blooms = match info.location { @@ -1384,9 +1378,9 @@ impl BlockChain { /// Create a block body from a block. pub fn block_to_body(block: &[u8]) -> Bytes { let mut body = RlpStream::new_list(2); - let block_rlp = Rlp::new(block); - body.append_raw(block_rlp.at(1).as_raw(), 1); - body.append_raw(block_rlp.at(2).as_raw(), 1); + let block_view = view!(BlockView, block); + body.append_raw(block_view.transactions_rlp().as_raw(), 1); + body.append_raw(block_view.uncles_rlp().as_raw(), 1); body.out() } diff --git a/ethcore/src/blockchain/generator.rs b/ethcore/src/blockchain/generator.rs index 5f990a4d9..e767f2211 100644 --- a/ethcore/src/blockchain/generator.rs +++ b/ethcore/src/blockchain/generator.rs @@ -41,7 +41,7 @@ impl Block { #[inline] pub fn hash(&self) -> H256 { - BlockView::new(&self.encoded()).header_view().hash() + view!(BlockView, &self.encoded()).header_view().hash() } #[inline] diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index fb3f07e41..d2b63b6cd 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -62,7 +62,7 @@ use ethcore_miner::pool::VerifiedTransaction; use parking_lot::{Mutex, RwLock}; use rand::OsRng; use receipt::{Receipt, LocalizedReceipt}; -use rlp::UntrustedRlp; +use rlp::Rlp; use snapshot::{self, io as snapshot_io}; use spec::Spec; use state_db::StateDB; @@ -446,7 +446,7 @@ impl Importer { /// The block is guaranteed to be the next best blocks in the /// first block sequence. Does no sealing or transaction validation. fn import_old_block(&self, block_bytes: Bytes, receipts_bytes: Bytes, db: &KeyValueDB, chain: &BlockChain) -> Result { - let block = BlockView::new(&block_bytes); + let block = view!(BlockView, &block_bytes); let header = block.header(); let receipts = ::rlp::decode_list(&receipts_bytes); let hash = header.hash(); @@ -514,7 +514,7 @@ impl Importer { let receipts = block.receipts().to_owned(); let traces = block.traces().clone().drain(); - assert_eq!(header.hash(), BlockView::new(block_data).header_view().hash()); + assert_eq!(header.hash(), view!(BlockView, block_data).header_view().hash()); //let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new)); @@ -988,7 +988,7 @@ impl Client { let txs: Vec = transactions .iter() - .filter_map(|bytes| UntrustedRlp::new(bytes).as_val().ok()) + .filter_map(|bytes| Rlp::new(bytes).as_val().ok()) .collect(); self.notify(|notify| { @@ -1423,7 +1423,7 @@ impl ImportBlock for Client { fn import_block_with_receipts(&self, block_bytes: Bytes, receipts_bytes: Bytes) -> Result { { // check block order - let header = BlockView::new(&block_bytes).header_view(); + let header = view!(BlockView, &block_bytes).header_view(); if self.chain.read().is_known(&header.hash()) { return Err(BlockImportError::Import(ImportError::AlreadyInChain)); } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 02067afd0..c2e06009b 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -29,7 +29,7 @@ use journaldb; use kvdb::DBValue; use kvdb_memorydb; use bytes::Bytes; -use rlp::{UntrustedRlp, RlpStream}; +use rlp::{Rlp, RlpStream}; use ethkey::{Generator, Random}; use ethcore_miner::pool::VerifiedTransaction; use transaction::{self, Transaction, LocalizedTransaction, SignedTransaction, Action}; @@ -471,7 +471,7 @@ impl ChainInfo for TestBlockChainClient { impl BlockInfo for TestBlockChainClient { fn block_header(&self, id: BlockId) -> Option { self.block_hash(id) - .and_then(|hash| self.blocks.read().get(&hash).map(|r| BlockView::new(r).header_rlp().as_raw().to_vec())) + .and_then(|hash| self.blocks.read().get(&hash).map(|r| view!(BlockView, r).header_rlp().as_raw().to_vec())) .map(encoded::Header::new) } @@ -513,7 +513,7 @@ impl RegistryInfo for TestBlockChainClient { impl ImportBlock for TestBlockChainClient { fn import_block(&self, b: Bytes) -> Result { - let header = BlockView::new(&b).header(); + let header = view!(BlockView, &b).header(); let h = header.hash(); let number: usize = header.number() as usize; if number > self.blocks.read().len() { @@ -522,7 +522,7 @@ impl ImportBlock for TestBlockChainClient { if number > 0 { match self.blocks.read().get(header.parent_hash()) { Some(parent) => { - let parent = BlockView::new(parent).header(); + let parent = view!(BlockView, parent).header(); if parent.number() != (header.number() - 1) { panic!("Unexpected block parent"); } @@ -547,7 +547,7 @@ impl ImportBlock for TestBlockChainClient { while n > 0 && self.numbers.read()[&n] != parent_hash { *self.numbers.write().get_mut(&n).unwrap() = parent_hash.clone(); n -= 1; - parent_hash = BlockView::new(&self.blocks.read()[&parent_hash]).header().parent_hash().clone(); + parent_hash = view!(BlockView, &self.blocks.read()[&parent_hash]).header().parent_hash().clone(); } } } @@ -692,7 +692,7 @@ impl BlockChainClient for TestBlockChainClient { fn block_body(&self, id: BlockId) -> Option { self.block_hash(id).and_then(|hash| self.blocks.read().get(&hash).map(|r| { - let block = BlockView::new(r); + let block = view!(BlockView, r); let mut stream = RlpStream::new_list(2); stream.append_raw(block.transactions_rlp().as_raw(), 1); stream.append_raw(block.uncles_rlp().as_raw(), 1); @@ -811,7 +811,7 @@ impl BlockChainClient for TestBlockChainClient { fn queue_transactions(&self, transactions: Vec, _peer_id: usize) { // import right here - let txs = transactions.into_iter().filter_map(|bytes| UntrustedRlp::new(&bytes).as_val().ok()).collect(); + let txs = transactions.into_iter().filter_map(|bytes| Rlp::new(&bytes).as_val().ok()).collect(); self.miner.import_external_transactions(self, txs); } diff --git a/ethcore/src/encoded.rs b/ethcore/src/encoded.rs index 5d3d31606..1f627666a 100644 --- a/ethcore/src/encoded.rs +++ b/ethcore/src/encoded.rs @@ -26,12 +26,12 @@ use block::Block as FullBlock; use header::{BlockNumber, Header as FullHeader}; use transaction::UnverifiedTransaction; -use views; use hash::keccak; use heapsize::HeapSizeOf; use ethereum_types::{H256, Bloom, U256, Address}; use rlp::{Rlp, RlpStream}; +use views::{self, BlockView, HeaderView, BodyView}; /// Owning header view. #[derive(Debug, Clone, PartialEq, Eq)] @@ -52,7 +52,7 @@ impl Header { /// Get a borrowed header view onto the data. #[inline] - pub fn view(&self) -> views::HeaderView { views::HeaderView::new(&self.0) } + pub fn view(&self) -> HeaderView { view!(HeaderView, &self.0) } /// Get the rlp of the header. #[inline] @@ -125,7 +125,7 @@ impl Body { /// Get a borrowed view of the data within. #[inline] - pub fn view(&self) -> views::BodyView { views::BodyView::new(&self.0) } + pub fn view(&self) -> BodyView { view!(BodyView, &self.0) } /// Fully decode this block body. pub fn decode(&self) -> (Vec, Vec) { @@ -145,7 +145,7 @@ impl Body { // forwarders to borrowed view. impl Body { /// Get raw rlp of transactions - pub fn transactions_rlp(&self) -> Rlp { self.view().transactions_rlp() } + pub fn transactions_rlp(&self) -> Rlp { self.view().transactions_rlp().rlp } /// Get a vector of all transactions. pub fn transactions(&self) -> Vec { self.view().transactions() } @@ -160,7 +160,7 @@ impl Body { pub fn transaction_hashes(&self) -> Vec { self.view().transaction_hashes() } /// Get raw rlp of uncle headers - pub fn uncles_rlp(&self) -> Rlp { self.view().uncles_rlp() } + pub fn uncles_rlp(&self) -> Rlp { self.view().uncles_rlp().rlp } /// Decode uncle headers. pub fn uncles(&self) -> Vec { self.view().uncles() } @@ -198,20 +198,20 @@ impl Block { /// Get a borrowed view of the whole block. #[inline] - pub fn view(&self) -> views::BlockView { views::BlockView::new(&self.0) } + pub fn view(&self) -> BlockView { view!(BlockView, &self.0) } /// Get a borrowed view of the block header. #[inline] - pub fn header_view(&self) -> views::HeaderView { self.view().header_view() } + pub fn header_view(&self) -> HeaderView { self.view().header_view() } /// Decode to a full block. pub fn decode(&self) -> FullBlock { ::rlp::decode(&self.0) } /// Decode the header. - pub fn decode_header(&self) -> FullHeader { self.rlp().val_at(0) } + pub fn decode_header(&self) -> FullHeader { self.view().rlp().val_at(0) } /// Clone the encoded header. - pub fn header(&self) -> Header { Header(self.rlp().at(0).as_raw().to_vec()) } + pub fn header(&self) -> Header { Header(self.view().rlp().at(0).as_raw().to_vec()) } /// Get the rlp of this block. #[inline] diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index b8b9ab8b3..013445ba3 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -41,7 +41,7 @@ use self::finality::RollingFinality; use ethkey::{self, Signature}; use io::{IoContext, IoHandler, TimerToken, IoService}; use itertools::{self, Itertools}; -use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp}; +use rlp::{encode, Decodable, DecoderError, Encodable, RlpStream, Rlp}; use ethereum_types::{H256, H520, Address, U128, U256}; use parking_lot::{Mutex, RwLock}; use unexpected::{Mismatch, OutOfBounds}; @@ -325,7 +325,7 @@ impl Encodable for EmptyStep { } impl Decodable for EmptyStep { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let signature = rlp.val_at(0)?; let empty_step_rlp = rlp.at(1)?; @@ -366,7 +366,7 @@ impl Encodable for SealedEmptyStep { } impl Decodable for SealedEmptyStep { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let signature = rlp.val_at(0)?; let step = rlp.val_at(1)?; @@ -415,7 +415,7 @@ impl super::EpochVerifier for EpochVerifier { let mut finality_checker = RollingFinality::blank(self.subchain_validators.clone().into_inner()); let mut finalized = Vec::new(); - let headers: Vec
= UntrustedRlp::new(proof).as_list().ok()?; + let headers: Vec
= Rlp::new(proof).as_list().ok()?; { let mut push_header = |parent_header: &Header, header: Option<&Header>| { @@ -479,13 +479,13 @@ fn header_expected_seal_fields(header: &Header, empty_steps_transition: u64) -> fn header_step(header: &Header, empty_steps_transition: u64) -> Result { let expected_seal_fields = header_expected_seal_fields(header, empty_steps_transition); - UntrustedRlp::new(&header.seal().get(0).expect( + Rlp::new(&header.seal().get(0).expect( &format!("was either checked with verify_block_basic or is genesis; has {} fields; qed (Make sure the spec file has a correct genesis seal)", expected_seal_fields))).as_val() } fn header_signature(header: &Header, empty_steps_transition: u64) -> Result { let expected_seal_fields = header_expected_seal_fields(header, empty_steps_transition); - UntrustedRlp::new(&header.seal().get(1).expect( + Rlp::new(&header.seal().get(1).expect( &format!("was checked with verify_block_basic; has {} fields; qed", expected_seal_fields))).as_val::().map(Into::into) } @@ -498,7 +498,7 @@ fn header_empty_steps_raw(header: &Header) -> &[u8] { // extracts the empty steps from the header seal. should only be called when there are 3 fields in the seal // (i.e. header.number() >= self.empty_steps_transition). fn header_empty_steps(header: &Header) -> Result, ::rlp::DecoderError> { - let empty_steps = UntrustedRlp::new(header_empty_steps_raw(header)).as_list::()?; + let empty_steps = Rlp::new(header_empty_steps_raw(header)).as_list::()?; Ok(empty_steps.into_iter().map(|s| EmptyStep::from_sealed(s, header.parent_hash())).collect()) } @@ -575,7 +575,7 @@ fn combine_proofs(signal_number: BlockNumber, set_proof: &[u8], finality_proof: } fn destructure_proofs(combined: &[u8]) -> Result<(BlockNumber, &[u8], &[u8]), Error> { - let rlp = UntrustedRlp::new(combined); + let rlp = Rlp::new(combined); Ok(( rlp.at(0)?.as_val()?, rlp.at(1)?.data()?, @@ -801,7 +801,7 @@ impl Engine for AuthorityRound { EngineError::MalformedMessage(format!("{:?}", x)) } - let rlp = UntrustedRlp::new(rlp); + let rlp = Rlp::new(rlp); let empty_step: EmptyStep = rlp.as_val().map_err(fmt_err)?;; if empty_step.verify(&*self.validators).unwrap_or(false) { diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 768cde3d5..bbefddccb 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -57,10 +57,10 @@ impl super::EpochVerifier for EpochVerifier { } fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Error> { - use rlp::UntrustedRlp; + use rlp::Rlp; // Check if the signature belongs to a validator, can depend on parent state. - let sig = UntrustedRlp::new(&header.seal()[0]).as_val::()?; + let sig = Rlp::new(&header.seal()[0]).as_val::()?; let signer = ethkey::public_to_address(ðkey::recover(&sig.into(), &header.bare_hash())?); if *header.author() != signer { diff --git a/ethcore/src/engines/epoch.rs b/ethcore/src/engines/epoch.rs index dffc822cb..6975e8898 100644 --- a/ethcore/src/engines/epoch.rs +++ b/ethcore/src/engines/epoch.rs @@ -18,7 +18,7 @@ use ethereum_types::H256; -use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; +use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; /// A full epoch transition. #[derive(Debug, Clone)] @@ -41,7 +41,7 @@ impl Encodable for Transition { } impl Decodable for Transition { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { Ok(Transition { block_hash: rlp.val_at(0)?, block_number: rlp.val_at(1)?, @@ -64,7 +64,7 @@ impl Encodable for PendingTransition { } impl Decodable for PendingTransition { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { Ok(PendingTransition { proof: rlp.as_val()?, }) diff --git a/ethcore/src/engines/tendermint/message.rs b/ethcore/src/engines/tendermint/message.rs index eac08df9b..17b79a80b 100644 --- a/ethcore/src/engines/tendermint/message.rs +++ b/ethcore/src/engines/tendermint/message.rs @@ -23,7 +23,7 @@ use bytes::Bytes; use super::{Height, View, BlockHash, Step}; use error::Error; use header::Header; -use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError}; +use rlp::{Rlp, RlpStream, Encodable, Decodable, DecoderError}; use ethkey::{recover, public_to_address}; use super::super::vote_collector::Message; @@ -61,12 +61,12 @@ impl VoteStep { /// Header consensus view. pub fn consensus_view(header: &Header) -> Result { let view_rlp = header.seal().get(0).expect("seal passed basic verification; seal has 3 fields; qed"); - UntrustedRlp::new(view_rlp.as_slice()).as_val() + Rlp::new(view_rlp.as_slice()).as_val() } /// Proposal signature. pub fn proposal_signature(header: &Header) -> Result { - UntrustedRlp::new(header.seal().get(1).expect("seal passed basic verification; seal has 3 fields; qed").as_slice()).as_val() + Rlp::new(header.seal().get(1).expect("seal passed basic verification; seal has 3 fields; qed").as_slice()).as_val() } impl Message for ConsensusMessage { @@ -100,7 +100,7 @@ impl ConsensusMessage { pub fn verify(&self) -> Result { let full_rlp = ::rlp::encode(self); - let block_info = UntrustedRlp::new(&full_rlp).at(1)?; + let block_info = Rlp::new(&full_rlp).at(1)?; let public_key = recover(&self.signature.into(), &keccak(block_info.as_raw()))?; Ok(public_to_address(&public_key)) } @@ -142,7 +142,7 @@ impl Step { } impl Decodable for Step { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { match rlp.as_val()? { 0u8 => Ok(Step::Propose), 1 => Ok(Step::Prevote), @@ -160,7 +160,7 @@ impl Encodable for Step { /// (signature, (height, view, step, block_hash)) impl Decodable for ConsensusMessage { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let m = rlp.at(1)?; let block_message: H256 = m.val_at(3)?; Ok(ConsensusMessage { @@ -234,7 +234,7 @@ mod tests { }; let raw_rlp = ::rlp::encode(&message).into_vec(); let rlp = Rlp::new(&raw_rlp); - assert_eq!(message, rlp.as_val()); + assert_eq!(Ok(message), rlp.as_val()); let message = ConsensusMessage { signature: H520::default(), @@ -247,7 +247,7 @@ mod tests { }; let raw_rlp = ::rlp::encode(&message); let rlp = Rlp::new(&raw_rlp); - assert_eq!(message, rlp.as_val()); + assert_eq!(Ok(message), rlp.as_val()); } #[test] @@ -260,7 +260,7 @@ mod tests { let raw_rlp = message_full_rlp(&tap.sign(addr, None, keccak(&mi)).unwrap().into(), &mi); - let rlp = UntrustedRlp::new(&raw_rlp); + let rlp = Rlp::new(&raw_rlp); let message: ConsensusMessage = rlp.as_val().unwrap(); match message.verify() { Ok(a) if a == addr => {}, _ => panic!(), }; } diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 14d1ebd58..5021ef986 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -36,7 +36,7 @@ use client::EngineClient; use bytes::Bytes; use error::{Error, BlockError}; use header::{Header, BlockNumber}; -use rlp::UntrustedRlp; +use rlp::Rlp; use ethkey::{self, Message, Signature}; use account_provider::AccountProvider; use block::*; @@ -118,7 +118,7 @@ impl super::EpochVerifier for EpochVerifier let mut addresses = HashSet::new(); let ref header_signatures_field = header.seal().get(2).ok_or(BlockError::InvalidSeal)?; - for rlp in UntrustedRlp::new(header_signatures_field).iter() { + for rlp in Rlp::new(header_signatures_field).iter() { let signature: H520 = rlp.as_val()?; let address = (self.recover)(&signature.into(), &message)?; @@ -154,7 +154,7 @@ fn combine_proofs(signal_number: BlockNumber, set_proof: &[u8], finality_proof: } fn destructure_proofs(combined: &[u8]) -> Result<(BlockNumber, &[u8], &[u8]), Error> { - let rlp = UntrustedRlp::new(combined); + let rlp = Rlp::new(combined); Ok(( rlp.at(0)?.as_val()?, rlp.at(1)?.data()?, @@ -503,7 +503,8 @@ impl Engine for Tendermint { fn fmt_err(x: T) -> EngineError { EngineError::MalformedMessage(format!("{:?}", x)) } - let rlp = UntrustedRlp::new(rlp); + + let rlp = Rlp::new(rlp); let message: ConsensusMessage = rlp.as_val().map_err(fmt_err)?; if !self.votes.is_old_or_known(&message) { let msg_hash = keccak(rlp.at(1).map_err(fmt_err)?.as_raw()); @@ -595,7 +596,7 @@ impl Engine for Tendermint { let precommit_hash = message_hash(vote_step.clone(), header.bare_hash()); let ref signatures_field = header.seal().get(2).expect("block went through verify_block_basic; block has .seal_fields() fields; qed"); let mut origins = HashSet::new(); - for rlp in UntrustedRlp::new(signatures_field).iter() { + for rlp in Rlp::new(signatures_field).iter() { let precommit = ConsensusMessage { signature: rlp.as_val()?, block_hash: Some(header.bare_hash()), diff --git a/ethcore/src/engines/validator_set/safe_contract.rs b/ethcore/src/engines/validator_set/safe_contract.rs index 5c73cb28d..f132a0bf9 100644 --- a/ethcore/src/engines/validator_set/safe_contract.rs +++ b/ethcore/src/engines/validator_set/safe_contract.rs @@ -25,7 +25,7 @@ use parking_lot::RwLock; use bytes::Bytes; use memory_cache::MemoryLruCache; use unexpected::Mismatch; -use rlp::{UntrustedRlp, RlpStream}; +use rlp::{Rlp, RlpStream}; use kvdb::DBValue; use client::EngineClient; @@ -63,7 +63,7 @@ impl ::engines::StateDependentProof for StateProof { } fn check_proof(&self, machine: &EthereumMachine, proof: &[u8]) -> Result<(), String> { - let (header, state_items) = decode_first_proof(&UntrustedRlp::new(proof)) + let (header, state_items) = decode_first_proof(&Rlp::new(proof)) .map_err(|e| format!("proof incorrectly encoded: {}", e))?; if &header != &self.header { return Err("wrong header in proof".into()); @@ -145,7 +145,7 @@ fn check_first_proof(machine: &EthereumMachine, provider: &validator_set::Valida }).map_err(|err| err.to_string()) } -fn decode_first_proof(rlp: &UntrustedRlp) -> Result<(Header, Vec), ::error::Error> { +fn decode_first_proof(rlp: &Rlp) -> Result<(Header, Vec), ::error::Error> { let header = rlp.val_at(0)?; let state_items = rlp.at(1)?.iter().map(|x| { let mut val = DBValue::new(); @@ -165,7 +165,7 @@ fn encode_proof(header: &Header, receipts: &[Receipt]) -> Bytes { stream.drain().into_vec() } -fn decode_proof(rlp: &UntrustedRlp) -> Result<(Header, Vec), ::error::Error> { +fn decode_proof(rlp: &Rlp) -> Result<(Header, Vec), ::error::Error> { Ok((rlp.val_at(0)?, rlp.list_at(1)?)) } @@ -357,7 +357,7 @@ impl ValidatorSet for ValidatorSafeContract { fn epoch_set(&self, first: bool, machine: &EthereumMachine, _number: ::header::BlockNumber, proof: &[u8]) -> Result<(SimpleList, Option), ::error::Error> { - let rlp = UntrustedRlp::new(proof); + let rlp = Rlp::new(proof); if first { trace!(target: "engine", "Recovering initial epoch set"); diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 41ab777d4..7d4339528 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -27,7 +27,7 @@ use error::{BlockError, Error}; use header::{Header, BlockNumber}; use engines::{self, Engine}; use ethjson; -use rlp::UntrustedRlp; +use rlp::Rlp; use machine::EthereumMachine; /// Number of blocks in an ethash snapshot. @@ -59,8 +59,8 @@ impl Seal { ).into()); } - let mix_hash = UntrustedRlp::new(seal[0].as_ref()).as_val::()?; - let nonce = UntrustedRlp::new(seal[1].as_ref()).as_val::()?; + let mix_hash = Rlp::new(seal[0].as_ref()).as_val::()?; + let nonce = Rlp::new(seal[1].as_ref()).as_val::()?; let seal = Seal { mix_hash, nonce, diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 71cf2e86a..5cf646268 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -174,7 +174,7 @@ mod tests { assert_eq!(morden.state_root(), "f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9".into()); let genesis = morden.genesis_block(); - assert_eq!(BlockView::new(&genesis).header_view().hash(), "0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303".into()); + assert_eq!(view!(BlockView, &genesis).header_view().hash(), "0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303".into()); let _ = morden.engine; } @@ -185,7 +185,7 @@ mod tests { assert_eq!(frontier.state_root(), "d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544".into()); let genesis = frontier.genesis_block(); - assert_eq!(BlockView::new(&genesis).header_view().hash(), "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3".into()); + assert_eq!(view!(BlockView, &genesis).header_view().hash(), "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3".into()); let _ = frontier.engine; } diff --git a/ethcore/src/header.rs b/ethcore/src/header.rs index 50529c720..a31aa029b 100644 --- a/ethcore/src/header.rs +++ b/ethcore/src/header.rs @@ -21,7 +21,7 @@ use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP, keccak}; use heapsize::HeapSizeOf; use ethereum_types::{H256, U256, Address, Bloom}; use bytes::Bytes; -use rlp::{UntrustedRlp, RlpStream, Encodable, DecoderError, Decodable}; +use rlp::{Rlp, RlpStream, Encodable, DecoderError, Decodable}; pub use types::BlockNumber; @@ -177,7 +177,7 @@ impl Header { /// Get the seal field with RLP-decoded values as bytes. pub fn decode_seal<'a, T: ::std::iter::FromIterator<&'a [u8]>>(&'a self) -> Result { self.seal.iter().map(|rlp| { - UntrustedRlp::new(rlp).data() + Rlp::new(rlp).data() }).collect() } @@ -327,7 +327,7 @@ fn change_field(hash: &mut Option, field: &mut T, value: T) where T: Pa impl Decodable for Header { - fn decode(r: &UntrustedRlp) -> Result { + fn decode(r: &Rlp) -> Result { let mut blockheader = Header { parent_hash: r.val_at(0)?, uncles_hash: r.val_at(1)?, diff --git a/ethcore/src/json_tests/transaction.rs b/ethcore/src/json_tests/transaction.rs index b7445c51a..1be4900b1 100644 --- a/ethcore/src/json_tests/transaction.rs +++ b/ethcore/src/json_tests/transaction.rs @@ -17,7 +17,7 @@ use super::test_common::*; use evm; use ethjson; -use rlp::UntrustedRlp; +use rlp::Rlp; use transaction::{Action, UnverifiedTransaction, SignedTransaction}; fn do_json_test(json_data: &[u8]) -> Vec { @@ -40,7 +40,7 @@ fn do_json_test(json_data: &[u8]) -> Vec { let allow_unsigned = number.map_or(false, |n| n >= 3_000_000); let rlp: Vec = test.rlp.into(); - let res = UntrustedRlp::new(&rlp) + let res = Rlp::new(&rlp) .as_val() .map_err(::error::Error::from) .and_then(|t: UnverifiedTransaction| { diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 1b0a1e354..65be24dec 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -127,6 +127,9 @@ extern crate evm; pub extern crate ethstore; +#[macro_use] +pub mod views; + #[cfg(test)] extern crate kvdb_rocksdb; @@ -152,7 +155,6 @@ pub mod state_db; pub mod test_helpers; pub mod trace; pub mod verification; -pub mod views; mod cache_manager; mod blooms; diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index 222875b84..6c9e0f3d6 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -25,7 +25,7 @@ use ethereum_types::{H256, U256}; use hashdb::HashDB; use bytes::Bytes; use trie::{TrieDB, Trie}; -use rlp::{RlpStream, UntrustedRlp}; +use rlp::{RlpStream, Rlp}; use std::collections::HashSet; @@ -148,7 +148,7 @@ pub fn to_fat_rlps(account_hash: &H256, acc: &BasicAccount, acct_db: &AccountDB, // if it exists. pub fn from_fat_rlp( acct_db: &mut AccountDBMut, - rlp: UntrustedRlp, + rlp: Rlp, mut storage_root: H256, ) -> Result<(BasicAccount, Option), Error> { use trie::{TrieDBMut, TrieMut}; @@ -217,7 +217,7 @@ mod tests { use ethereum_types::{H256, Address}; use hashdb::HashDB; use kvdb::DBValue; - use rlp::UntrustedRlp; + use rlp::Rlp; use std::collections::HashSet; @@ -239,7 +239,7 @@ mod tests { assert_eq!(::rlp::decode::(&thin_rlp), account); let fat_rlps = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); - let fat_rlp = UntrustedRlp::new(&fat_rlps[0]).at(1).unwrap(); + let fat_rlp = Rlp::new(&fat_rlps[0]).at(1).unwrap(); assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account); } @@ -264,7 +264,7 @@ mod tests { assert_eq!(::rlp::decode::(&thin_rlp), account); let fat_rlp = to_fat_rlps(&keccak(&addr), &account, &AccountDB::new(db.as_hashdb(), &addr), &mut Default::default(), usize::max_value(), usize::max_value()).unwrap(); - let fat_rlp = UntrustedRlp::new(&fat_rlp[0]).at(1).unwrap(); + let fat_rlp = Rlp::new(&fat_rlp[0]).at(1).unwrap(); assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, H256::zero()).unwrap().0, account); } @@ -292,7 +292,7 @@ mod tests { let mut root = KECCAK_NULL_RLP; let mut restored_account = None; for rlp in fat_rlps { - let fat_rlp = UntrustedRlp::new(&rlp).at(1).unwrap(); + let fat_rlp = Rlp::new(&rlp).at(1).unwrap(); restored_account = Some(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, root).unwrap().0); root = restored_account.as_ref().unwrap().storage_root.clone(); } @@ -336,8 +336,8 @@ mod tests { let fat_rlp2 = to_fat_rlps(&keccak(&addr2), &account2, &AccountDB::new(db.as_hashdb(), &addr2), &mut used_code, usize::max_value(), usize::max_value()).unwrap(); assert_eq!(used_code.len(), 1); - let fat_rlp1 = UntrustedRlp::new(&fat_rlp1[0]).at(1).unwrap(); - let fat_rlp2 = UntrustedRlp::new(&fat_rlp2[0]).at(1).unwrap(); + let fat_rlp1 = Rlp::new(&fat_rlp1[0]).at(1).unwrap(); + let fat_rlp2 = Rlp::new(&fat_rlp2[0]).at(1).unwrap(); let (acc, maybe_code) = from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr2), fat_rlp2, H256::zero()).unwrap(); assert!(maybe_code.is_none()); @@ -351,6 +351,6 @@ mod tests { #[test] fn encoding_empty_acc() { let mut db = get_temp_state_db(); - assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), UntrustedRlp::new(&::rlp::NULL_RLP), H256::zero()).unwrap(), (ACC_EMPTY, None)); + assert_eq!(from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), Rlp::new(&::rlp::NULL_RLP), H256::zero()).unwrap(), (ACC_EMPTY, None)); } } diff --git a/ethcore/src/snapshot/block.rs b/ethcore/src/snapshot/block.rs index aa946fd70..a47c504d8 100644 --- a/ethcore/src/snapshot/block.rs +++ b/ethcore/src/snapshot/block.rs @@ -21,7 +21,7 @@ use header::Header; use hash::keccak; use views::BlockView; -use rlp::{DecoderError, RlpStream, UntrustedRlp}; +use rlp::{DecoderError, RlpStream, Rlp}; use ethereum_types::H256; use bytes::Bytes; use triehash::ordered_trie_root; @@ -89,7 +89,7 @@ impl AbridgedBlock { /// /// Will fail if contains invalid rlp. pub fn to_block(&self, parent_hash: H256, number: u64, receipts_root: H256) -> Result { - let rlp = UntrustedRlp::new(&self.rlp); + let rlp = Rlp::new(&self.rlp); let mut header: Header = Default::default(); header.set_parent_hash(parent_hash); @@ -151,7 +151,7 @@ mod tests { let receipts_root = b.header.receipts_root().clone(); let encoded = encode_block(&b); - let abridged = AbridgedBlock::from_block_view(&BlockView::new(&encoded)); + let abridged = AbridgedBlock::from_block_view(&view!(BlockView, &encoded)); assert_eq!(abridged.to_block(H256::new(), 0, receipts_root).unwrap(), b); } @@ -162,7 +162,7 @@ mod tests { let receipts_root = b.header.receipts_root().clone(); let encoded = encode_block(&b); - let abridged = AbridgedBlock::from_block_view(&BlockView::new(&encoded)); + let abridged = AbridgedBlock::from_block_view(&view!(BlockView, &encoded)); assert_eq!(abridged.to_block(H256::new(), 2, receipts_root).unwrap(), b); } @@ -198,7 +198,7 @@ mod tests { let encoded = encode_block(&b); - let abridged = AbridgedBlock::from_block_view(&BlockView::new(&encoded[..])); + let abridged = AbridgedBlock::from_block_view(&view!(BlockView, &encoded[..])); assert_eq!(abridged.to_block(H256::new(), 0, receipts_root).unwrap(), b); } } diff --git a/ethcore/src/snapshot/consensus/authority.rs b/ethcore/src/snapshot/consensus/authority.rs index d3184a081..474f5d350 100644 --- a/ethcore/src/snapshot/consensus/authority.rs +++ b/ethcore/src/snapshot/consensus/authority.rs @@ -33,7 +33,7 @@ use receipt::Receipt; use snapshot::{Error, ManifestData}; use itertools::{Position, Itertools}; -use rlp::{RlpStream, UntrustedRlp}; +use rlp::{RlpStream, Rlp}; use ethereum_types::{H256, U256}; use kvdb::KeyValueDB; use bytes::Bytes; @@ -182,7 +182,7 @@ impl ChunkRebuilder { fn verify_transition( &mut self, last_verifier: &mut Option>>, - transition_rlp: UntrustedRlp, + transition_rlp: Rlp, engine: &EthEngine, ) -> Result { use engines::ConstructedVerifier; @@ -242,7 +242,7 @@ impl Rebuilder for ChunkRebuilder { engine: &EthEngine, abort_flag: &AtomicBool, ) -> Result<(), ::error::Error> { - let rlp = UntrustedRlp::new(chunk); + let rlp = Rlp::new(chunk); let is_last_chunk: bool = rlp.val_at(0)?; let num_items = rlp.item_count()?; diff --git a/ethcore/src/snapshot/consensus/work.rs b/ethcore/src/snapshot/consensus/work.rs index 7f90e327c..5414ed596 100644 --- a/ethcore/src/snapshot/consensus/work.rs +++ b/ethcore/src/snapshot/consensus/work.rs @@ -33,7 +33,7 @@ use snapshot::block::AbridgedBlock; use ethereum_types::H256; use kvdb::KeyValueDB; use bytes::Bytes; -use rlp::{RlpStream, UntrustedRlp}; +use rlp::{RlpStream, Rlp}; use rand::OsRng; /// Snapshot creation and restoration for PoW chains. @@ -225,7 +225,7 @@ impl Rebuilder for PowRebuilder { use ethereum_types::U256; use triehash::ordered_trie_root; - let rlp = UntrustedRlp::new(chunk); + let rlp = Rlp::new(chunk); let item_count = rlp.item_count()?; let num_blocks = (item_count - 3) as u64; @@ -284,7 +284,7 @@ impl Rebuilder for PowRebuilder { self.db.write_buffered(batch); self.chain.commit(); - parent_hash = BlockView::new(&block_bytes).hash(); + parent_hash = view!(BlockView, &block_bytes).hash(); cur_number += 1; } diff --git a/ethcore/src/snapshot/io.rs b/ethcore/src/snapshot/io.rs index 7e38177ea..84faa19b4 100644 --- a/ethcore/src/snapshot/io.rs +++ b/ethcore/src/snapshot/io.rs @@ -27,7 +27,7 @@ use std::path::{Path, PathBuf}; use bytes::Bytes; use ethereum_types::H256; -use rlp::{RlpStream, UntrustedRlp}; +use rlp::{RlpStream, Rlp}; use super::ManifestData; @@ -238,7 +238,7 @@ impl PackedReader { file.seek(SeekFrom::Start(manifest_off))?; file.read_exact(&mut manifest_buf)?; - let rlp = UntrustedRlp::new(&manifest_buf); + let rlp = Rlp::new(&manifest_buf); let (start, version) = if rlp.item_count()? == 5 { (0, 1) diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 6b751bf2c..fbf0c5ca5 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -39,7 +39,7 @@ use parking_lot::Mutex; use journaldb::{self, Algorithm, JournalDB}; use kvdb::KeyValueDB; use trie::{TrieDB, TrieDBMut, Trie, TrieMut}; -use rlp::{RlpStream, UntrustedRlp}; +use rlp::{RlpStream, Rlp}; use bloom_journal::Bloom; use self::io::SnapshotWriter; @@ -327,7 +327,7 @@ impl StateRebuilder { /// Feed an uncompressed state chunk into the rebuilder. pub fn feed(&mut self, chunk: &[u8], flag: &AtomicBool) -> Result<(), ::error::Error> { - let rlp = UntrustedRlp::new(chunk); + let rlp = Rlp::new(chunk); let empty_rlp = StateAccount::new_basic(U256::zero(), U256::zero()).rlp(); let mut pairs = Vec::with_capacity(rlp.item_count()?); @@ -415,7 +415,7 @@ struct RebuiltStatus { // returns a status detailing newly-loaded code and accounts missing code. fn rebuild_accounts( db: &mut HashDB, - account_fat_rlps: UntrustedRlp, + account_fat_rlps: Rlp, out_chunk: &mut [(H256, Bytes)], known_code: &HashMap, known_storage_roots: &mut HashMap, diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index ec1b5edf3..c1fda8667 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -913,7 +913,7 @@ mod tests { ); let genesis = test_spec.genesis_block(); assert_eq!( - BlockView::new(&genesis).header_view().hash(), + view!(BlockView, &genesis).header_view().hash(), "0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303".into() ); } diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index 692f029c8..32b8beab8 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -171,7 +171,7 @@ pub fn generate_dummy_client_with_spec_accounts_and_data(test_spec: F, accoun panic!("error importing block which is valid by definition: {:?}", e); } - last_header = BlockView::new(&b.rlp_bytes()).header(); + last_header = view!(BlockView, &b.rlp_bytes()).header(); db = b.drain(); } client.flush_queue(); diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index fc5f84bfa..0b8200e93 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -141,7 +141,7 @@ fn query_bad_block() { fn returns_chain_info() { let dummy_block = get_good_dummy_block(); let client = get_test_client_with_blocks(vec![dummy_block.clone()]); - let block = BlockView::new(&dummy_block); + let block = view!(BlockView, &dummy_block); let info = client.chain_info(); assert_eq!(info.best_block_hash, block.header().hash()); } @@ -178,12 +178,12 @@ fn returns_logs_with_limit() { fn returns_block_body() { let dummy_block = get_good_dummy_block(); let client = get_test_client_with_blocks(vec![dummy_block.clone()]); - let block = BlockView::new(&dummy_block); + let block = view!(BlockView, &dummy_block); let body = client.block_body(BlockId::Hash(block.header().hash())).unwrap(); let body = body.rlp(); - assert_eq!(body.item_count(), 2); - assert_eq!(body.at(0).as_raw()[..], block.rlp().at(1).as_raw()[..]); - assert_eq!(body.at(1).as_raw()[..], block.rlp().at(2).as_raw()[..]); + assert_eq!(body.item_count().unwrap(), 2); + assert_eq!(body.at(0).unwrap().as_raw()[..], block.rlp().at(1).as_raw()[..]); + assert_eq!(body.at(1).unwrap().as_raw()[..], block.rlp().at(2).as_raw()[..]); } #[test] @@ -259,7 +259,7 @@ fn can_mine() { let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).close(); - assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().hash()); + assert_eq!(*b.block().header().parent_hash(), view!(BlockView, &dummy_blocks[0]).header_view().hash()); } #[test] diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index 1626e828c..72d0d4737 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -97,7 +97,7 @@ fn can_trace_block_and_uncle_reward() { panic!("error importing block which is valid by definition: {:?}", e); } - last_header = BlockView::new(&root_block.rlp_bytes()).header(); + last_header = view!(BlockView, &root_block.rlp_bytes()).header(); let root_header = last_header.clone(); db = root_block.drain(); @@ -125,7 +125,7 @@ fn can_trace_block_and_uncle_reward() { panic!("error importing block which is valid by definition: {:?}", e); } - last_header = BlockView::new(&parent_block.rlp_bytes()).header(); + last_header = view!(BlockView,&parent_block.rlp_bytes()).header(); db = parent_block.drain(); last_hashes.push(last_header.hash()); diff --git a/ethcore/src/trace/types/error.rs b/ethcore/src/trace/types/error.rs index 70a3c315a..f2fa192d3 100644 --- a/ethcore/src/trace/types/error.rs +++ b/ethcore/src/trace/types/error.rs @@ -17,7 +17,7 @@ //! Trace errors. use std::fmt; -use rlp::{Encodable, RlpStream, Decodable, DecoderError, UntrustedRlp}; +use rlp::{Encodable, RlpStream, Decodable, DecoderError, Rlp}; use vm::Error as VmError; /// Trace evm errors. @@ -115,7 +115,7 @@ impl Encodable for Error { } impl Decodable for Error { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { use self::Error::*; let value: u8 = rlp.as_val()?; match value { diff --git a/ethcore/src/trace/types/flat.rs b/ethcore/src/trace/types/flat.rs index e3f66e170..e2746ca7f 100644 --- a/ethcore/src/trace/types/flat.rs +++ b/ethcore/src/trace/types/flat.rs @@ -17,7 +17,7 @@ //! Flat trace module use std::collections::VecDeque; -use rlp::{UntrustedRlp, RlpStream, Decodable, Encodable, DecoderError}; +use rlp::{Rlp, RlpStream, Decodable, Encodable, DecoderError}; use heapsize::HeapSizeOf; use ethereum_types::Bloom; use super::trace::{Action, Res}; @@ -63,7 +63,7 @@ impl Encodable for FlatTrace { } impl Decodable for FlatTrace { - fn decode(d: &UntrustedRlp) -> Result { + fn decode(d: &Rlp) -> Result { let v: Vec = d.list_at(3)?; let res = FlatTrace { action: d.val_at(0)?, diff --git a/ethcore/src/trace/types/trace.rs b/ethcore/src/trace/types/trace.rs index e6db17603..06f24efac 100644 --- a/ethcore/src/trace/types/trace.rs +++ b/ethcore/src/trace/types/trace.rs @@ -18,7 +18,7 @@ use ethereum_types::{U256, Address, Bloom, BloomInput}; use bytes::Bytes; -use rlp::{UntrustedRlp, RlpStream, Encodable, DecoderError, Decodable}; +use rlp::{Rlp, RlpStream, Encodable, DecoderError, Decodable}; use vm::ActionParams; use evm::CallType; @@ -154,7 +154,7 @@ impl Encodable for RewardType { } impl Decodable for RewardType { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.as_val().and_then(|v| Ok(match v { 0u32 => RewardType::Block, 1 => RewardType::Uncle, @@ -191,7 +191,7 @@ impl Encodable for Reward { } impl Decodable for Reward { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let res = Reward { author: rlp.val_at(0)?, value: rlp.val_at(1)?, @@ -263,7 +263,7 @@ impl Encodable for Action { } impl Decodable for Action { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let action_type: u8 = rlp.val_at(0)?; match action_type { 0 => rlp.val_at(1).map(Action::Call), @@ -334,7 +334,7 @@ impl Encodable for Res { } impl Decodable for Res { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let action_type: u8 = rlp.val_at(0)?; match action_type { 0 => rlp.val_at(1).map(Res::Call), diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 898435eb2..223de30f7 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -122,7 +122,7 @@ pub mod blocks { pub fn new(bytes: Bytes) -> Self { use views::BlockView; - let header = BlockView::new(&bytes).header(); + let header = view!(BlockView, &bytes).header(); Unverified { header: header, bytes: bytes, diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index b6e60d042..d50bd1cb3 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -733,7 +733,7 @@ mod tests { use super::kind::blocks::Unverified; use test_helpers::{get_good_dummy_block_seq, get_good_dummy_block}; use error::*; - use views::*; + use views::BlockView; // create a test block queue. // auto_scaling enables verifier adjustment. @@ -785,7 +785,7 @@ mod tests { fn returns_total_difficulty() { let queue = get_test_queue(false); let block = get_good_dummy_block(); - let hash = BlockView::new(&block).header().hash().clone(); + let hash = view!(BlockView, &block).header().hash().clone(); if let Err(e) = queue.import(Unverified::new(block)) { panic!("error importing block that is valid by definition({:?})", e); } @@ -801,7 +801,7 @@ mod tests { fn returns_ok_for_drained_duplicates() { let queue = get_test_queue(false); let block = get_good_dummy_block(); - let hash = BlockView::new(&block).header().hash().clone(); + let hash = view!(BlockView, &block).header().hash().clone(); if let Err(e) = queue.import(Unverified::new(block)) { panic!("error importing block that is valid by definition({:?})", e); } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 5b0700bfd..d0bfcc0c7 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -28,7 +28,7 @@ use bytes::Bytes; use ethereum_types::H256; use hash::keccak; use heapsize::HeapSizeOf; -use rlp::UntrustedRlp; +use rlp::Rlp; use triehash::ordered_trie_root; use unexpected::{Mismatch, OutOfBounds}; @@ -63,13 +63,13 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &EthEngine) -> verify_header_params(&header, engine, true)?; verify_block_integrity(bytes, &header.transactions_root(), &header.uncles_hash())?; engine.verify_block_basic(&header)?; - for u in UntrustedRlp::new(bytes).at(2)?.iter().map(|rlp| rlp.as_val::
()) { + for u in Rlp::new(bytes).at(2)?.iter().map(|rlp| rlp.as_val::
()) { let u = u?; verify_header_params(&u, engine, false)?; engine.verify_block_basic(&u)?; } - for t in UntrustedRlp::new(bytes).at(1)?.iter().map(|rlp| rlp.as_val::()) { + for t in Rlp::new(bytes).at(1)?.iter().map(|rlp| rlp.as_val::()) { engine.verify_transaction_basic(&t?, &header)?; } Ok(()) @@ -81,7 +81,7 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &EthEngine) -> pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &EthEngine, check_seal: bool) -> Result { if check_seal { engine.verify_block_unordered(&header)?; - for u in UntrustedRlp::new(&bytes).at(2)?.iter().map(|rlp| rlp.as_val::
()) { + for u in Rlp::new(&bytes).at(2)?.iter().map(|rlp| rlp.as_val::
()) { engine.verify_block_unordered(&u?)?; } } @@ -91,7 +91,7 @@ pub fn verify_block_unordered(header: Header, bytes: Bytes, engine: &EthEngine, Some((engine.params().nonce_cap_increment * header.number()).into()) } else { None }; { - let v = BlockView::new(&bytes); + let v = view!(BlockView, &bytes); for t in v.transactions() { let t = engine.verify_transaction_unordered(t, &header)?; if let Some(max_nonce) = nonce_cap { @@ -145,7 +145,7 @@ pub fn verify_block_family(header: &Header, parent: } fn verify_uncles(header: &Header, bytes: &[u8], bc: &BlockProvider, engine: &EthEngine) -> Result<(), Error> { - let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count()?; + let num_uncles = Rlp::new(bytes).at(2)?.item_count()?; let max_uncles = engine.maximum_uncle_count(header.number()); if num_uncles != 0 { if num_uncles > max_uncles { @@ -174,7 +174,7 @@ fn verify_uncles(header: &Header, bytes: &[u8], bc: &BlockProvider, engine: &Eth } let mut verified = HashSet::new(); - for uncle in UntrustedRlp::new(bytes).at(2)?.iter().map(|rlp| rlp.as_val::
()) { + for uncle in Rlp::new(bytes).at(2)?.iter().map(|rlp| rlp.as_val::
()) { let uncle = uncle?; if excluded.contains(&uncle.hash()) { return Err(From::from(BlockError::UncleInChain(uncle.hash()))) @@ -333,7 +333,7 @@ fn verify_parent(header: &Header, parent: &Header, engine: &EthEngine) -> Result /// Verify block data against header: transactions root and uncles hash. fn verify_block_integrity(block: &[u8], transactions_root: &H256, uncles_hash: &H256) -> Result<(), Error> { - let block = UntrustedRlp::new(block); + let block = Rlp::new(block); let tx = block.at(1)?; let expected_root = &ordered_trie_root(tx.iter().map(|r| r.as_raw())); if expected_root != transactions_root { @@ -408,8 +408,8 @@ mod tests { } pub fn insert(&mut self, bytes: Bytes) { - let number = BlockView::new(&bytes).header_view().number(); - let hash = BlockView::new(&bytes).header_view().hash(); + let number = view!(BlockView, &bytes).header_view().number(); + let hash = view!(BlockView, &bytes).header_view().hash(); self.blocks.insert(hash.clone(), bytes); self.numbers.insert(number, hash.clone()); } @@ -448,7 +448,7 @@ mod tests { /// Get the familial details concerning a block. fn block_details(&self, hash: &H256) -> Option { self.blocks.get(hash).map(|bytes| { - let header = BlockView::new(bytes).header(); + let header = view!(BlockView, bytes).header(); BlockDetails { number: header.number(), total_difficulty: header.difficulty().clone(), @@ -482,12 +482,12 @@ mod tests { } fn basic_test(bytes: &[u8], engine: &EthEngine) -> Result<(), Error> { - let header = BlockView::new(bytes).header(); + let header = view!(BlockView, bytes).header(); verify_block_basic(&header, bytes, engine) } fn family_test(bytes: &[u8], engine: &EthEngine, bc: &BC) -> Result<(), Error> where BC: BlockProvider { - let view = BlockView::new(bytes); + let view = view!(BlockView, bytes); let header = view.header(); let transactions: Vec<_> = view.transactions() .into_iter() @@ -514,7 +514,7 @@ mod tests { } fn unordered_test(bytes: &[u8], engine: &EthEngine) -> Result<(), Error> { - let header = BlockView::new(bytes).header(); + let header = view!(BlockView, bytes).header(); verify_block_unordered(header, bytes.to_vec(), engine, false)?; Ok(()) } diff --git a/ethcore/src/views/block.rs b/ethcore/src/views/block.rs index f6bb92873..f610504d8 100644 --- a/ethcore/src/views/block.rs +++ b/ethcore/src/views/block.rs @@ -20,25 +20,34 @@ use bytes::Bytes; use ethereum_types::H256; use hash::keccak; use header::Header; -use rlp::Rlp; use transaction::{UnverifiedTransaction, LocalizedTransaction}; use views::{TransactionView, HeaderView}; +use super::ViewRlp; /// View onto block rlp. pub struct BlockView<'a> { - rlp: Rlp<'a> + rlp: ViewRlp<'a> } -impl<'a> BlockView<'a> { - /// Creates new view onto block from raw bytes. - pub fn new(bytes: &'a [u8]) -> BlockView<'a> { - BlockView { - rlp: Rlp::new(bytes) - } - } +impl<'a> BlockView<'a> { /// Creates new view onto block from rlp. - pub fn new_from_rlp(rlp: Rlp<'a>) -> BlockView<'a> { + /// Use the `view!` macro to create this view in order to capture debugging info. + /// + /// # Example + /// + /// ``` + /// #[macro_use] + /// extern crate ethcore; + /// + /// use ethcore::views::{BlockView}; + /// + /// fn main() { + /// let bytes : &[u8] = &[]; + /// let block_view = view!(BlockView, bytes); + /// } + /// ``` + pub fn new(rlp: ViewRlp<'a>) -> BlockView<'a> { BlockView { rlp: rlp } @@ -50,7 +59,7 @@ impl<'a> BlockView<'a> { } /// Return reference to underlaying rlp. - pub fn rlp(&self) -> &Rlp<'a> { + pub fn rlp(&self) -> &ViewRlp<'a> { &self.rlp } @@ -60,13 +69,13 @@ impl<'a> BlockView<'a> { } /// Return header rlp. - pub fn header_rlp(&self) -> Rlp { + pub fn header_rlp(&self) -> ViewRlp<'a> { self.rlp.at(0) } /// Create new header view obto block head rlp. pub fn header_view(&self) -> HeaderView<'a> { - HeaderView::new_from_rlp(self.rlp.at(0)) + HeaderView::new(self.header_rlp()) } /// Return List of transactions in given block. @@ -92,28 +101,28 @@ impl<'a> BlockView<'a> { } /// Return the raw rlp for the transactions in the given block. - pub fn transactions_rlp(&self) -> Rlp<'a> { + pub fn transactions_rlp(&self) -> ViewRlp<'a> { self.rlp.at(1) } /// Return number of transactions in given block, without deserializing them. pub fn transactions_count(&self) -> usize { - self.rlp.at(1).iter().count() + self.transactions_rlp().iter().count() } /// Return List of transactions in given block. pub fn transaction_views(&self) -> Vec> { - self.rlp.at(1).iter().map(TransactionView::new_from_rlp).collect() + self.transactions_rlp().iter().map(TransactionView::new).collect() } /// Return transaction hashes. pub fn transaction_hashes(&self) -> Vec { - self.rlp.at(1).iter().map(|rlp| keccak(rlp.as_raw())).collect() + self.transactions_rlp().iter().map(|rlp| keccak(rlp.as_raw())).collect() } /// Returns transaction at given index without deserializing unnecessary data. pub fn transaction_at(&self, index: usize) -> Option { - self.rlp.at(1).iter().nth(index).map(|rlp| rlp.as_val()) + self.transactions_rlp().iter().nth(index).map(|rlp| rlp.as_val()) } /// Returns localized transaction at given index. @@ -131,7 +140,7 @@ impl<'a> BlockView<'a> { } /// Returns raw rlp for the uncles in the given block - pub fn uncles_rlp(&self) -> Rlp<'a> { + pub fn uncles_rlp(&self) -> ViewRlp<'a> { self.rlp.at(2) } @@ -142,27 +151,27 @@ impl<'a> BlockView<'a> { /// Return number of uncles in given block, without deserializing them. pub fn uncles_count(&self) -> usize { - self.rlp.at(2).iter().count() + self.uncles_rlp().iter().count() } /// Return List of transactions in given block. pub fn uncle_views(&self) -> Vec> { - self.rlp.at(2).iter().map(HeaderView::new_from_rlp).collect() + self.uncles_rlp().iter().map(HeaderView::new).collect() } /// Return list of uncle hashes of given block. pub fn uncle_hashes(&self) -> Vec { - self.rlp.at(2).iter().map(|rlp| keccak(rlp.as_raw())).collect() + self.uncles_rlp().iter().map(|rlp| keccak(rlp.as_raw())).collect() } /// Return nth uncle. pub fn uncle_at(&self, index: usize) -> Option
{ - self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_val()) + self.uncles_rlp().iter().nth(index).map(|rlp| rlp.as_val()) } /// Return nth uncle rlp. pub fn uncle_rlp_at(&self, index: usize) -> Option { - self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_raw().to_vec()) + self.uncles_rlp().iter().nth(index).map(|rlp| rlp.as_raw().to_vec()) } } @@ -176,7 +185,7 @@ mod tests { // that's rlp of block created with ethash engine. let rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap(); - let view = BlockView::new(&rlp); + let view = view!(BlockView, &rlp); assert_eq!(view.hash(), "2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259".into()); assert_eq!(view.transactions_count(), 1); assert_eq!(view.uncles_count(), 0); diff --git a/ethcore/src/views/body.rs b/ethcore/src/views/body.rs index d23f1a1d7..d2864b972 100644 --- a/ethcore/src/views/body.rs +++ b/ethcore/src/views/body.rs @@ -20,32 +20,40 @@ use bytes::Bytes; use ethereum_types::H256; use hash::keccak; use header::{Header, BlockNumber}; -use rlp::Rlp; use transaction::{LocalizedTransaction, UnverifiedTransaction}; use views::{TransactionView, HeaderView}; +use super::ViewRlp; /// View onto block rlp. pub struct BodyView<'a> { - rlp: Rlp<'a> + rlp: ViewRlp<'a> } impl<'a> BodyView<'a> { - /// Creates new view onto block from raw bytes. - pub fn new(bytes: &'a [u8]) -> BodyView<'a> { - BodyView { - rlp: Rlp::new(bytes) - } - } - - /// Creates new view onto block from rlp. - pub fn new_from_rlp(rlp: Rlp<'a>) -> BodyView<'a> { + /// Creates new view onto block body from rlp. + /// Use the `view!` macro to create this view in order to capture debugging info. + /// + /// # Example + /// + /// ``` + /// #[macro_use] + /// extern crate ethcore; + /// + /// use ethcore::views::{BodyView}; + /// + /// fn main() { + /// let bytes : &[u8] = &[]; + /// let body_view = view!(BodyView, bytes); + /// } + /// ``` + pub fn new(rlp: ViewRlp<'a>) -> BodyView<'a> { BodyView { rlp: rlp } } /// Return reference to underlaying rlp. - pub fn rlp(&self) -> &Rlp<'a> { + pub fn rlp(&self) -> &ViewRlp<'a> { &self.rlp } @@ -69,27 +77,27 @@ impl<'a> BodyView<'a> { } /// Return the raw rlp for the transactions in the given block. - pub fn transactions_rlp(&self) -> Rlp<'a> { + pub fn transactions_rlp(&self) -> ViewRlp<'a> { self.rlp.at(0) } /// Return number of transactions in given block, without deserializing them. pub fn transactions_count(&self) -> usize { - self.rlp.at(0).item_count() + self.transactions_rlp().item_count() } /// Return List of transactions in given block. pub fn transaction_views(&self) -> Vec> { - self.rlp.at(0).iter().map(TransactionView::new_from_rlp).collect() + self.transactions_rlp().iter().map(TransactionView::new).collect() } /// Return transaction hashes. pub fn transaction_hashes(&self) -> Vec { - self.rlp.at(0).iter().map(|rlp| keccak(rlp.as_raw())).collect() + self.transactions_rlp().iter().map(|rlp| keccak(rlp.as_raw())).collect() } /// Returns transaction at given index without deserializing unnecessary data. pub fn transaction_at(&self, index: usize) -> Option { - self.rlp.at(0).iter().nth(index).map(|rlp| rlp.as_val()) + self.transactions_rlp().iter().nth(index).map(|rlp| rlp.as_val()) } /// Returns localized transaction at given index. @@ -104,7 +112,7 @@ impl<'a> BodyView<'a> { } /// Returns raw rlp for the uncles in the given block - pub fn uncles_rlp(&self) -> Rlp<'a> { + pub fn uncles_rlp(&self) -> ViewRlp<'a> { self.rlp.at(1) } @@ -115,27 +123,27 @@ impl<'a> BodyView<'a> { /// Return number of uncles in given block, without deserializing them. pub fn uncles_count(&self) -> usize { - self.rlp.at(1).item_count() + self.uncles_rlp().item_count() } /// Return List of transactions in given block. pub fn uncle_views(&self) -> Vec> { - self.rlp.at(1).iter().map(HeaderView::new_from_rlp).collect() + self.uncles_rlp().iter().map(HeaderView::new).collect() } /// Return list of uncle hashes of given block. pub fn uncle_hashes(&self) -> Vec { - self.rlp.at(1).iter().map(|rlp| keccak(rlp.as_raw())).collect() + self.uncles_rlp().iter().map(|rlp| keccak(rlp.as_raw())).collect() } /// Return nth uncle. pub fn uncle_at(&self, index: usize) -> Option
{ - self.rlp.at(1).iter().nth(index).map(|rlp| rlp.as_val()) + self.uncles_rlp().iter().nth(index).map(|rlp| rlp.as_val()) } /// Return nth uncle rlp. pub fn uncle_rlp_at(&self, index: usize) -> Option { - self.rlp.at(1).iter().nth(index).map(|rlp| rlp.as_raw().to_vec()) + self.uncles_rlp().iter().nth(index).map(|rlp| rlp.as_raw().to_vec()) } } @@ -150,7 +158,7 @@ mod tests { // that's rlp of block created with ethash engine. let rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap(); let body = BlockChain::block_to_body(&rlp); - let view = BodyView::new(&body); + let view = view!(BodyView, &body); assert_eq!(view.transactions_count(), 1); assert_eq!(view.uncles_count(), 0); } diff --git a/ethcore/src/views/header.rs b/ethcore/src/views/header.rs index cce4eee82..8d407f0a1 100644 --- a/ethcore/src/views/header.rs +++ b/ethcore/src/views/header.rs @@ -20,35 +20,44 @@ use bytes::Bytes; use ethereum_types::{H256, Bloom, U256, Address}; use hash::keccak; use header::BlockNumber; -use rlp::{self, Rlp}; +use rlp::{self}; +use super::ViewRlp; /// View onto block header rlp. pub struct HeaderView<'a> { - rlp: Rlp<'a> + rlp: ViewRlp<'a> } impl<'a> HeaderView<'a> { - /// Creates new view onto header from raw bytes. - pub fn new(bytes: &'a [u8]) -> HeaderView<'a> { + /// Creates a new Header view from valid ViewRlp + /// Use the `view!` macro to create this view in order to capture debugging info. + /// + /// # Example + /// + /// ``` + /// #[macro_use] + /// extern crate ethcore; + /// + /// use ethcore::views::{HeaderView}; + /// + /// fn main() { + /// let bytes : &[u8] = &[]; + /// let tx_view = view!(HeaderView, bytes); + /// } + /// ``` + pub fn new(rlp: ViewRlp<'a>) -> HeaderView<'a> { HeaderView { - rlp: Rlp::new(bytes) - } - } - - /// Creates new view onto header from rlp. - pub fn new_from_rlp(rlp: Rlp<'a>) -> HeaderView<'a> { - HeaderView { - rlp: rlp + rlp } } /// Returns header hash. pub fn hash(&self) -> H256 { - keccak(self.rlp.as_raw()) + keccak(self.rlp.rlp.as_raw()) } /// Returns raw rlp. - pub fn rlp(&self) -> &Rlp<'a> { &self.rlp } + pub fn rlp(&self) -> &ViewRlp<'a> { &self.rlp } /// Returns parent hash. pub fn parent_hash(&self) -> H256 { self.rlp.val_at(0) } @@ -102,9 +111,10 @@ impl<'a> HeaderView<'a> { pub fn decode_seal(&self) -> Result, rlp::DecoderError> { let seal = self.seal(); seal.into_iter() - .map(|s| rlp::UntrustedRlp::new(&s).data().map(|x| x.to_vec())) + .map(|s| rlp::Rlp::new(&s).data().map(|x| x.to_vec())) .collect() } + } #[cfg(test)] @@ -120,7 +130,7 @@ mod tests { let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); - let view = HeaderView::new(&rlp); + let view = view!(HeaderView, &rlp); assert_eq!(view.hash(), "2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259".into()); assert_eq!(view.parent_hash(), "d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7".into()); assert_eq!(view.uncles_hash(), "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347".into()); diff --git a/ethcore/src/views/mod.rs b/ethcore/src/views/mod.rs index 5d3cc8cdc..b9cbad888 100644 --- a/ethcore/src/views/mod.rs +++ b/ethcore/src/views/mod.rs @@ -16,12 +16,26 @@ //! Block oriented views onto rlp. +#[macro_use] +mod view_rlp; mod block; mod body; mod header; mod transaction; +pub use self::view_rlp::ViewRlp; pub use self::block::BlockView; pub use self::body::BodyView; pub use self::header::HeaderView; pub use self::transaction::TransactionView; + +#[cfg(test)] +mod tests { + use super::HeaderView; + + #[test] + #[should_panic(expected="View rlp is trusted and should be valid. Constructed in ethcore/src/views/mod.rs on line 39: RlpExpectedToBeList")] + fn should_include_file_line_number_in_panic_for_invalid_rlp() { + let _ = view!(HeaderView, &[]).parent_hash(); + } +} \ No newline at end of file diff --git a/ethcore/src/views/transaction.rs b/ethcore/src/views/transaction.rs index 92bd49c27..5607482b3 100644 --- a/ethcore/src/views/transaction.rs +++ b/ethcore/src/views/transaction.rs @@ -18,30 +18,39 @@ use bytes::Bytes; use ethereum_types::{H256, U256}; use hash::keccak; -use rlp::Rlp; +// use rlp::{Rlp, Decodable}; +use super::ViewRlp; /// View onto transaction rlp. pub struct TransactionView<'a> { - rlp: Rlp<'a> + rlp: ViewRlp<'a> } impl<'a> TransactionView<'a> { - /// Creates new view onto block from raw bytes. - pub fn new(bytes: &'a [u8]) -> TransactionView<'a> { - TransactionView { - rlp: Rlp::new(bytes) - } - } - - /// Creates new view onto block from rlp. - pub fn new_from_rlp(rlp: Rlp<'a>) -> TransactionView<'a> { + /// Creates new view onto valid transaction rlp. + /// Use the `view!` macro to create this view in order to capture debugging info. + /// + /// # Example + /// + /// ``` + /// #[macro_use] + /// extern crate ethcore; + /// + /// use ethcore::views::{TransactionView}; + /// + /// fn main() { + /// let bytes : &[u8] = &[]; + /// let tx_view = view!(TransactionView, bytes); + /// } + /// ``` + pub fn new(rlp: ViewRlp<'a>) -> TransactionView<'a> { TransactionView { rlp: rlp } } /// Return reference to underlaying rlp. - pub fn rlp(&self) -> &Rlp<'a> { + pub fn rlp(&self) -> &ViewRlp<'a> { &self.rlp } @@ -84,7 +93,7 @@ mod tests { fn test_transaction_view() { let rlp = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap(); - let view = TransactionView::new(&rlp); + let view = view!(TransactionView, &rlp); assert_eq!(view.nonce(), 0.into()); assert_eq!(view.gas_price(), 1.into()); assert_eq!(view.gas(), 0x61a8.into()); diff --git a/ethcore/src/views/view_rlp.rs b/ethcore/src/views/view_rlp.rs new file mode 100644 index 000000000..6afdb3af8 --- /dev/null +++ b/ethcore/src/views/view_rlp.rs @@ -0,0 +1,130 @@ +// Copyright 2015-2017 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Wrapper for view rlp expected to be valid with debug info + +use rlp::{Rlp, Decodable, DecoderError}; + +/// Wrapper for trusted rlp, which is expected to be valid, for use in views +/// When created with view!, records the file and line where it was created for debugging +pub struct ViewRlp<'a> { + /// Wrapped Rlp, expected to be valid + pub rlp: Rlp<'a>, + file: &'a str, + line: u32, +} + +impl<'a, 'view> ViewRlp<'a> where 'a : 'view { + #[doc(hidden)] + pub fn new(bytes: &'a [u8], file: &'a str, line: u32) -> Self { + ViewRlp { + rlp: Rlp::new(bytes), + file, + line + } + } + + /// Returns a new instance replacing existing rlp with new rlp, maintaining debug info + fn new_from_rlp(&self, rlp: Rlp<'a>) -> Self { + ViewRlp { + rlp, + file: self.file, + line: self.line + } + } + + fn maybe_at(&self, index: usize) -> Option> { + self.rlp.at(index) + .map(|rlp| self.new_from_rlp(rlp)) + .ok() + } + + fn expect_valid_rlp(&self, r: Result) -> T { + r.expect(&format!("View rlp is trusted and should be valid. Constructed in {} on line {}", self.file, self.line)) + } + + /// Returns rlp at the given index, panics if no rlp at that index + pub fn at(&self, index: usize) -> ViewRlp<'a> { + let rlp = self.expect_valid_rlp(self.rlp.at(index)); + self.new_from_rlp(rlp) + } + + /// Returns an iterator over all rlp values + pub fn iter(&'view self) -> ViewRlpIterator<'a, 'view> { + self.into_iter() + } + + /// Returns decoded value of this rlp, panics if rlp not valid + pub fn as_val(&self) -> T where T: Decodable { + self.expect_valid_rlp(self.rlp.as_val()) + } + + /// Returns decoded value at the given index, panics not present or valid at that index + pub fn val_at(&self, index: usize) -> T where T : Decodable { + self.expect_valid_rlp(self.rlp.val_at(index)) + } + + /// Returns decoded list of values, panics if rlp is invalid + pub fn list_at(&self, index: usize) -> Vec where T: Decodable { + self.expect_valid_rlp(self.rlp.list_at(index)) + } + + /// Returns the number of items in the rlp, panics if it is not a list of rlp values + pub fn item_count(&self) -> usize { + self.expect_valid_rlp(self.rlp.item_count()) + } + + /// Returns raw rlp bytes + pub fn as_raw(&'view self) -> &'a [u8] { + self.rlp.as_raw() + } +} + +/// Iterator over rlp-slice list elements. +pub struct ViewRlpIterator<'a, 'view> where 'a: 'view { + rlp: &'view ViewRlp<'a>, + index: usize, +} + +impl<'a, 'view> IntoIterator for &'view ViewRlp<'a> where 'a: 'view { + type Item = ViewRlp<'a>; + type IntoIter = ViewRlpIterator<'a, 'view>; + + fn into_iter(self) -> Self::IntoIter { + ViewRlpIterator { + rlp: self, + index: 0, + } + } +} + +impl<'a, 'view> Iterator for ViewRlpIterator<'a, 'view> { + type Item = ViewRlp<'a>; + + fn next(&mut self) -> Option> { + let index = self.index; + let result = self.rlp.maybe_at(index); + self.index += 1; + result + } +} + +#[macro_export] +macro_rules! view { + ($view: ident, $bytes: expr) => { + $view::new($crate::views::ViewRlp::new($bytes, file!(), line!())) + }; +} \ No newline at end of file diff --git a/ethcore/sync/src/block_sync.rs b/ethcore/sync/src/block_sync.rs index 5cf81b2e8..f7626b0ef 100644 --- a/ethcore/sync/src/block_sync.rs +++ b/ethcore/sync/src/block_sync.rs @@ -22,8 +22,8 @@ use std::collections::{HashSet, VecDeque}; use std::cmp; use heapsize::HeapSizeOf; use ethereum_types::H256; -use rlp::UntrustedRlp; -use ethcore::views::{BlockView}; +use rlp::Rlp; +use ethcore::views::BlockView; use ethcore::header::{BlockNumber, Header as BlockHeader}; use ethcore::client::{BlockStatus, BlockId, BlockImportError}; use ethcore::block::Block; @@ -216,7 +216,7 @@ impl BlockDownloader { } /// Add new block headers. - pub fn import_headers(&mut self, io: &mut SyncIo, r: &UntrustedRlp, expected_hash: Option) -> Result { + pub fn import_headers(&mut self, io: &mut SyncIo, r: &Rlp, expected_hash: Option) -> Result { let item_count = r.item_count().unwrap_or(0); if self.state == State::Idle { trace!(target: "sync", "Ignored unexpected block headers"); @@ -316,7 +316,7 @@ impl BlockDownloader { } /// Called by peer once it has new block bodies - pub fn import_bodies(&mut self, _io: &mut SyncIo, r: &UntrustedRlp) -> Result<(), BlockDownloaderImportError> { + pub fn import_bodies(&mut self, _io: &mut SyncIo, r: &Rlp) -> Result<(), BlockDownloaderImportError> { let item_count = r.item_count().unwrap_or(0); if item_count == 0 { return Err(BlockDownloaderImportError::Useless); @@ -342,7 +342,7 @@ impl BlockDownloader { } /// Called by peer once it has new block bodies - pub fn import_receipts(&mut self, _io: &mut SyncIo, r: &UntrustedRlp) -> Result<(), BlockDownloaderImportError> { + pub fn import_receipts(&mut self, _io: &mut SyncIo, r: &Rlp) -> Result<(), BlockDownloaderImportError> { let item_count = r.item_count().unwrap_or(0); if item_count == 0 { return Err(BlockDownloaderImportError::Useless); @@ -478,7 +478,7 @@ impl BlockDownloader { let block = block_and_receipts.block; let receipts = block_and_receipts.receipts; let (h, number, parent) = { - let header = BlockView::new(&block).header_view(); + let header = view!(BlockView, &block).header_view(); (header.hash(), header.number(), header.parent_hash()) }; diff --git a/ethcore/sync/src/blocks.rs b/ethcore/sync/src/blocks.rs index 37aa579ef..321c783b4 100644 --- a/ethcore/sync/src/blocks.rs +++ b/ethcore/sync/src/blocks.rs @@ -22,7 +22,7 @@ use heapsize::HeapSizeOf; use ethereum_types::H256; use triehash::ordered_trie_root; use bytes::Bytes; -use rlp::{UntrustedRlp, RlpStream, DecoderError}; +use rlp::{Rlp, RlpStream, DecoderError}; use network; use ethcore::encoded::Block; use ethcore::views::{HeaderView, BodyView}; @@ -292,8 +292,9 @@ impl BlockCollection { } for block in blocks { - let body = BodyView::new(block.body.as_ref().expect("blocks contains only full blocks; qed")); - let block_view = Block::new_from_header_and_body(&HeaderView::new(&block.header), &body); + let body = view!(BodyView, block.body.as_ref().expect("blocks contains only full blocks; qed")); + let header = view!(HeaderView, &block.header); + let block_view = Block::new_from_header_and_body(&header, &body); drained.push(BlockAndReceipts { block: block_view.rlp().as_raw().to_vec(), receipts: block.receipts.clone(), @@ -340,7 +341,7 @@ impl BlockCollection { fn insert_body(&mut self, b: Bytes) -> Result<(), network::Error> { let header_id = { - let body = UntrustedRlp::new(&b); + let body = Rlp::new(&b); let tx = body.at(0)?; let tx_root = ordered_trie_root(tx.iter().map(|r| r.as_raw())); let uncles = keccak(body.at(1)?.as_raw()); @@ -375,7 +376,7 @@ impl BlockCollection { fn insert_receipt(&mut self, r: Bytes) -> Result<(), network::Error> { let receipt_root = { - let receipts = UntrustedRlp::new(&r); + let receipts = Rlp::new(&r); ordered_trie_root(receipts.iter().map(|r| r.as_raw())) }; self.downloading_receipts.remove(&receipt_root); @@ -403,7 +404,7 @@ impl BlockCollection { } fn insert_header(&mut self, header: Bytes) -> Result { - let info: BlockHeader = UntrustedRlp::new(&header).as_val()?; + let info: BlockHeader = Rlp::new(&header).as_val()?; let hash = info.hash(); if self.blocks.contains_key(&hash) { return Ok(hash); @@ -525,8 +526,8 @@ mod test { let blocks: Vec<_> = (0..nblocks) .map(|i| (&client as &BlockChainClient).block(BlockId::Number(i as BlockNumber)).unwrap().into_inner()) .collect(); - let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).as_raw().to_vec()).collect(); - let hashes: Vec<_> = headers.iter().map(|h| HeaderView::new(h).hash()).collect(); + let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).unwrap().as_raw().to_vec()).collect(); + let hashes: Vec<_> = headers.iter().map(|h| view!(HeaderView, h).hash()).collect(); let heads: Vec<_> = hashes.iter().enumerate().filter_map(|(i, h)| if i % 20 == 0 { Some(h.clone()) } else { None }).collect(); bc.reset_to(heads); assert!(!bc.is_empty()); @@ -580,8 +581,8 @@ mod test { let blocks: Vec<_> = (0..nblocks) .map(|i| (&client as &BlockChainClient).block(BlockId::Number(i as BlockNumber)).unwrap().into_inner()) .collect(); - let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).as_raw().to_vec()).collect(); - let hashes: Vec<_> = headers.iter().map(|h| HeaderView::new(h).hash()).collect(); + let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).unwrap().as_raw().to_vec()).collect(); + let hashes: Vec<_> = headers.iter().map(|h| view!(HeaderView, h).hash()).collect(); let heads: Vec<_> = hashes.iter().enumerate().filter_map(|(i, h)| if i % 20 == 0 { Some(h.clone()) } else { None }).collect(); bc.reset_to(heads); @@ -604,8 +605,8 @@ mod test { let blocks: Vec<_> = (0..nblocks) .map(|i| (&client as &BlockChainClient).block(BlockId::Number(i as BlockNumber)).unwrap().into_inner()) .collect(); - let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).as_raw().to_vec()).collect(); - let hashes: Vec<_> = headers.iter().map(|h| HeaderView::new(h).hash()).collect(); + let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).unwrap().as_raw().to_vec()).collect(); + let hashes: Vec<_> = headers.iter().map(|h| view!(HeaderView, h).hash()).collect(); let heads: Vec<_> = hashes.iter().enumerate().filter_map(|(i, h)| if i % 20 == 0 { Some(h.clone()) } else { None }).collect(); bc.reset_to(heads); diff --git a/ethcore/sync/src/chain.rs b/ethcore/sync/src/chain.rs index 014302d7f..bc8e35ed4 100644 --- a/ethcore/sync/src/chain.rs +++ b/ethcore/sync/src/chain.rs @@ -98,7 +98,7 @@ use ethereum_types::{H256, U256}; use plain_hasher::H256FastMap; use parking_lot::RwLock; use bytes::Bytes; -use rlp::{UntrustedRlp, RlpStream, DecoderError, Encodable}; +use rlp::{Rlp, RlpStream, DecoderError, Encodable}; use network::{self, PeerId, PacketId}; use ethcore::header::{BlockNumber, Header as BlockHeader}; use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockImportError, BlockQueueInfo}; @@ -632,7 +632,7 @@ impl ChainSync { } /// Called by peer to report status - fn on_peer_status(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_peer_status(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { self.handshaking_peers.remove(&peer_id); let protocol_version: u8 = r.val_at(0)?; let warp_protocol = io.protocol_version(&WARP_SYNC_PROTOCOL_ID, peer_id) != 0; @@ -702,7 +702,7 @@ impl ChainSync { } /// Called by peer once it has new block headers during sync - fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { let confirmed = match self.peers.get_mut(&peer_id) { Some(ref mut peer) if peer.asking == PeerAsking::ForkHeader => { peer.asking = PeerAsking::Nothing; @@ -803,7 +803,7 @@ impl ChainSync { } /// Called by peer once it has new block bodies - fn on_peer_block_bodies(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_peer_block_bodies(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { self.clear_peer_download(peer_id); let block_set = self.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks); if !self.reset_peer_asking(peer_id, PeerAsking::BlockBodies) { @@ -857,7 +857,7 @@ impl ChainSync { } /// Called by peer once it has new block receipts - fn on_peer_block_receipts(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_peer_block_receipts(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { self.clear_peer_download(peer_id); let block_set = self.peers.get(&peer_id).and_then(|p| p.block_set).unwrap_or(BlockSet::NewBlocks); if !self.reset_peer_asking(peer_id, PeerAsking::BlockReceipts) { @@ -911,7 +911,7 @@ impl ChainSync { } /// Called by peer once it has new block bodies - fn on_peer_new_block(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_peer_new_block(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { trace!(target: "sync", "Ignoring new block from unconfirmed peer {}", peer_id); return Ok(()); @@ -978,7 +978,7 @@ impl ChainSync { } /// Handles `NewHashes` packet. Initiates headers download for any unknown hashes. - fn on_peer_new_hashes(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_peer_new_hashes(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { trace!(target: "sync", "Ignoring new hashes from unconfirmed peer {}", peer_id); return Ok(()); @@ -1053,7 +1053,7 @@ impl ChainSync { } /// Called when snapshot manifest is downloaded from a peer. - fn on_snapshot_manifest(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_snapshot_manifest(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { trace!(target: "sync", "Ignoring snapshot manifest from unconfirmed peer {}", peer_id); return Ok(()); @@ -1097,7 +1097,7 @@ impl ChainSync { } /// Called when snapshot data is downloaded from a peer. - fn on_snapshot_data(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_snapshot_data(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { trace!(target: "sync", "Ignoring snapshot data from unconfirmed peer {}", peer_id); return Ok(()); @@ -1501,7 +1501,7 @@ impl ChainSync { } /// Called when peer sends us new transactions - fn on_peer_transactions(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_peer_transactions(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { // Accept transactions only when fully synced if !io.is_chain_queue_empty() || (self.state != SyncState::Idle && self.state != SyncState::NewBlocks) { trace!(target: "sync", "{} Ignoring transactions while syncing", peer_id); @@ -1555,7 +1555,7 @@ impl ChainSync { } /// Respond to GetBlockHeaders request - fn return_block_headers(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { + fn return_block_headers(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { // Packet layout: // [ block: { P , B_32 }, maxHeaders: P, skip: P, reverse: P in { 0 , 1 } ] let max_headers: usize = r.val_at(1)?; @@ -1628,7 +1628,7 @@ impl ChainSync { } /// Respond to GetBlockBodies request - fn return_block_bodies(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { + fn return_block_bodies(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { let mut count = r.item_count().unwrap_or(0); if count == 0 { debug!(target: "sync", "Empty GetBlockBodies request, ignoring."); @@ -1650,7 +1650,7 @@ impl ChainSync { } /// Respond to GetNodeData request - fn return_node_data(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { + fn return_node_data(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { let mut count = r.item_count().unwrap_or(0); trace!(target: "sync", "{} -> GetNodeData: {} entries", peer_id, count); if count == 0 { @@ -1674,7 +1674,7 @@ impl ChainSync { Ok(Some((NODE_DATA_PACKET, rlp))) } - fn return_receipts(io: &SyncIo, rlp: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { + fn return_receipts(io: &SyncIo, rlp: &Rlp, peer_id: PeerId) -> RlpResponseResult { let mut count = rlp.item_count().unwrap_or(0); trace!(target: "sync", "{} -> GetReceipts: {} entries", peer_id, count); if count == 0 { @@ -1699,7 +1699,7 @@ impl ChainSync { } /// Respond to GetSnapshotManifest request - fn return_snapshot_manifest(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { + fn return_snapshot_manifest(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { let count = r.item_count().unwrap_or(0); trace!(target: "sync", "{} -> GetSnapshotManifest", peer_id); if count != 0 { @@ -1722,7 +1722,7 @@ impl ChainSync { } /// Respond to GetSnapshotData request - fn return_snapshot_data(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { + fn return_snapshot_data(io: &SyncIo, r: &Rlp, peer_id: PeerId) -> RlpResponseResult { let hash: H256 = r.val_at(0)?; trace!(target: "sync", "{} -> GetSnapshotData {:?}", peer_id, hash); let rlp = match io.snapshot_service().chunk(hash) { @@ -1739,8 +1739,8 @@ impl ChainSync { Ok(Some((SNAPSHOT_DATA_PACKET, rlp))) } - fn return_rlp(io: &mut SyncIo, rlp: &UntrustedRlp, peer: PeerId, rlp_func: FRlp, error_func: FError) -> Result<(), PacketDecodeError> - where FRlp : Fn(&SyncIo, &UntrustedRlp, PeerId) -> RlpResponseResult, + fn return_rlp(io: &mut SyncIo, rlp: &Rlp, peer: PeerId, rlp_func: FRlp, error_func: FError) -> Result<(), PacketDecodeError> + where FRlp : Fn(&SyncIo, &Rlp, PeerId) -> RlpResponseResult, FError : FnOnce(network::Error) -> String { let response = rlp_func(io, rlp, peer); @@ -1757,7 +1757,7 @@ impl ChainSync { /// Dispatch incoming requests and responses pub fn dispatch_packet(sync: &RwLock, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { - let rlp = UntrustedRlp::new(data); + let rlp = Rlp::new(data); let result = match packet_id { GET_BLOCK_BODIES_PACKET => ChainSync::return_rlp(io, &rlp, peer, ChainSync::return_block_bodies, @@ -1798,7 +1798,7 @@ impl ChainSync { debug!(target:"sync", "Unexpected packet {} from unregistered peer: {}:{}", packet_id, peer, io.peer_info(peer)); return; } - let rlp = UntrustedRlp::new(data); + let rlp = Rlp::new(data); let result = match packet_id { STATUS_PACKET => self.on_peer_status(io, peer, &rlp), TRANSACTIONS_PACKET => self.on_peer_transactions(io, peer, &rlp), @@ -2233,7 +2233,7 @@ impl ChainSync { } /// Called when peer sends us new consensus packet - fn on_consensus_packet(io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_consensus_packet(io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { trace!(target: "sync", "Received consensus packet from {:?}", peer_id); io.chain().queue_consensus_message(r.as_raw().to_vec()); Ok(()) @@ -2249,7 +2249,7 @@ impl ChainSync { } /// Called when peer sends us new private transaction packet - fn on_private_transaction(&self, _io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_private_transaction(&self, _io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { trace!(target: "sync", "{} Ignoring packet from unconfirmed/unknown peer", peer_id); return Ok(()); @@ -2273,7 +2273,7 @@ impl ChainSync { } /// Called when peer sends us signed private transaction packet - fn on_signed_private_transaction(&self, _io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { + fn on_signed_private_transaction(&self, _io: &mut SyncIo, peer_id: PeerId, r: &Rlp) -> Result<(), PacketDecodeError> { if !self.peers.get(&peer_id).map_or(false, |p| p.can_sync()) { trace!(target: "sync", "{} Ignoring packet from unconfirmed/unknown peer", peer_id); return Ok(()); @@ -2324,7 +2324,7 @@ mod tests { use ethereum_types::{H256, U256, Address}; use parking_lot::RwLock; use bytes::Bytes; - use rlp::{Rlp, RlpStream, UntrustedRlp}; + use rlp::{Rlp, RlpStream}; use super::*; use ::SyncConfig; use super::{PeerInfo, PeerAsking}; @@ -2421,7 +2421,7 @@ mod tests { let ss = TestSnapshotService::new(); let io = TestIo::new(&mut client, &ss, &queue, None); - let result = ChainSync::return_receipts(&io, &UntrustedRlp::new(&[0xc0]), 0); + let result = ChainSync::return_receipts(&io, &Rlp::new(&[0xc0]), 0); assert!(result.is_ok()); } @@ -2442,7 +2442,7 @@ mod tests { let receipts_request = receipt_list.out(); // it returns rlp ONLY for hashes started with "f" - let result = ChainSync::return_receipts(&io, &UntrustedRlp::new(&receipts_request.clone()), 0); + let result = ChainSync::return_receipts(&io, &Rlp::new(&receipts_request.clone()), 0); assert!(result.is_ok()); let rlp_result = result.unwrap(); @@ -2484,41 +2484,41 @@ mod tests { client.add_blocks(100, EachBlockWith::Nothing); let blocks: Vec<_> = (0 .. 100) .map(|i| (&client as &BlockChainClient).block(BlockId::Number(i as BlockNumber)).map(|b| b.into_inner()).unwrap()).collect(); - let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).as_raw().to_vec()).collect(); - let hashes: Vec<_> = headers.iter().map(|h| HeaderView::new(h).hash()).collect(); + let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).unwrap().as_raw().to_vec()).collect(); + let hashes: Vec<_> = headers.iter().map(|h| view!(HeaderView, h).hash()).collect(); let queue = RwLock::new(VecDeque::new()); let ss = TestSnapshotService::new(); let io = TestIo::new(&mut client, &ss, &queue, None); let unknown: H256 = H256::new(); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&unknown, 1, 0, false)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&unknown, 1, 0, false)), 0); assert!(to_header_vec(result).is_empty()); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&unknown, 1, 0, true)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&unknown, 1, 0, true)), 0); assert!(to_header_vec(result).is_empty()); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[2], 1, 0, true)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[2], 1, 0, true)), 0); assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[2], 1, 0, false)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[2], 1, 0, false)), 0); assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[50], 3, 5, false)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[50], 3, 5, false)), 0); assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[56].clone(), headers[62].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[50], 3, 5, true)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_hash_req(&hashes[50], 3, 5, true)), 0); assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[44].clone(), headers[38].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(2, 1, 0, true)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_num_req(2, 1, 0, true)), 0); assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(2, 1, 0, false)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_num_req(2, 1, 0, false)), 0); assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(50, 3, 5, false)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_num_req(50, 3, 5, false)), 0); assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[56].clone(), headers[62].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(50, 3, 5, true)), 0); + let result = ChainSync::return_block_headers(&io, &Rlp::new(&make_num_req(50, 3, 5, true)), 0); assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[44].clone(), headers[38].clone()]); } @@ -2537,7 +2537,7 @@ mod tests { let node_request = node_list.out(); // it returns rlp ONLY for hashes started with "f" - let result = ChainSync::return_node_data(&io, &UntrustedRlp::new(&node_request.clone()), 0); + let result = ChainSync::return_node_data(&io, &Rlp::new(&node_request.clone()), 0); assert!(result.is_ok()); let rlp_result = result.unwrap(); @@ -2546,7 +2546,7 @@ mod tests { // the length of one rlp-encoded hashe let rlp = rlp_result.unwrap().1.out(); let rlp = Rlp::new(&rlp); - assert_eq!(1, rlp.item_count()); + assert_eq!(Ok(1), rlp.item_count()); io.sender = Some(2usize); @@ -2891,7 +2891,7 @@ mod tests { return None; } - let rlp = UntrustedRlp::new(&*p.data); + let rlp = Rlp::new(&*p.data); let item_count = rlp.item_count().unwrap_or(0); if item_count != 1 { return None; @@ -2918,7 +2918,7 @@ mod tests { let ss = TestSnapshotService::new(); let mut io = TestIo::new(&mut client, &ss, &queue, None); - let block = UntrustedRlp::new(&block_data); + let block = Rlp::new(&block_data); let result = sync.on_peer_new_block(&mut io, 0, &block); @@ -2937,7 +2937,7 @@ mod tests { let ss = TestSnapshotService::new(); let mut io = TestIo::new(&mut client, &ss, &queue, None); - let block = UntrustedRlp::new(&block_data); + let block = Rlp::new(&block_data); let result = sync.on_peer_new_block(&mut io, 0, &block); @@ -2954,7 +2954,7 @@ mod tests { let mut io = TestIo::new(&mut client, &ss, &queue, None); let empty_data = vec![]; - let block = UntrustedRlp::new(&empty_data); + let block = Rlp::new(&empty_data); let result = sync.on_peer_new_block(&mut io, 0, &block); @@ -2971,7 +2971,7 @@ mod tests { let mut io = TestIo::new(&mut client, &ss, &queue, None); let hashes_data = get_dummy_hashes(); - let hashes_rlp = UntrustedRlp::new(&hashes_data); + let hashes_rlp = Rlp::new(&hashes_data); let result = sync.on_peer_new_hashes(&mut io, 0, &hashes_rlp); @@ -2988,7 +2988,7 @@ mod tests { let mut io = TestIo::new(&mut client, &ss, &queue, None); let empty_hashes_data = vec![]; - let hashes_rlp = UntrustedRlp::new(&empty_hashes_data); + let hashes_rlp = Rlp::new(&empty_hashes_data); let result = sync.on_peer_new_hashes(&mut io, 0, &hashes_rlp); @@ -3011,7 +3011,7 @@ mod tests { sync.propagate_new_hashes(&chain_info, &mut io, &peers); let data = &io.packets[0].data.clone(); - let result = sync.on_peer_new_hashes(&mut io, 0, &UntrustedRlp::new(data)); + let result = sync.on_peer_new_hashes(&mut io, 0, &Rlp::new(data)); assert!(result.is_ok()); } @@ -3031,7 +3031,7 @@ mod tests { sync.propagate_blocks(&chain_info, &mut io, &[], &peers); let data = &io.packets[0].data.clone(); - let result = sync.on_peer_new_block(&mut io, 0, &UntrustedRlp::new(data)); + let result = sync.on_peer_new_block(&mut io, 0, &Rlp::new(data)); assert!(result.is_ok()); } diff --git a/ethcore/sync/src/lib.rs b/ethcore/sync/src/lib.rs index a6e0c7db2..bf3b475fc 100644 --- a/ethcore/sync/src/lib.rs +++ b/ethcore/sync/src/lib.rs @@ -26,6 +26,7 @@ extern crate ethcore_network_devp2p as devp2p; extern crate ethcore_bytes as bytes; extern crate ethcore_io as io; extern crate ethcore_transaction as transaction; +#[macro_use] extern crate ethcore; extern crate ethereum_types; extern crate env_logger; diff --git a/ethcore/transaction/src/transaction.rs b/ethcore/transaction/src/transaction.rs index 6e8e78cc4..571dec3fa 100644 --- a/ethcore/transaction/src/transaction.rs +++ b/ethcore/transaction/src/transaction.rs @@ -24,7 +24,7 @@ use ethkey::{self, Signature, Secret, Public, recover, public_to_address}; use evm::Schedule; use hash::keccak; use heapsize::HeapSizeOf; -use rlp::{self, RlpStream, UntrustedRlp, DecoderError, Encodable}; +use rlp::{self, RlpStream, Rlp, DecoderError, Encodable}; type Bytes = Vec; type BlockNumber = u64; @@ -50,7 +50,7 @@ impl Default for Action { } impl rlp::Decodable for Action { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { if rlp.is_empty() { Ok(Action::Create) } else { @@ -291,7 +291,7 @@ impl Deref for UnverifiedTransaction { } impl rlp::Decodable for UnverifiedTransaction { - fn decode(d: &UntrustedRlp) -> Result { + fn decode(d: &Rlp) -> Result { if d.item_count()? != 9 { return Err(DecoderError::RlpIncorrectListLen); } diff --git a/ethcore/types/src/receipt.rs b/ethcore/types/src/receipt.rs index 8aee99365..c1defbc15 100644 --- a/ethcore/types/src/receipt.rs +++ b/ethcore/types/src/receipt.rs @@ -18,7 +18,7 @@ use ethereum_types::{H256, U256, Address, Bloom}; use heapsize::HeapSizeOf; -use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError}; +use rlp::{Rlp, RlpStream, Encodable, Decodable, DecoderError}; use {BlockNumber}; use log_entry::{LogEntry, LocalizedLogEntry}; @@ -81,7 +81,7 @@ impl Encodable for Receipt { } impl Decodable for Receipt { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { if rlp.item_count()? == 3 { Ok(Receipt { outcome: TransactionOutcome::Unknown, diff --git a/ethcore/types/src/snapshot_manifest.rs b/ethcore/types/src/snapshot_manifest.rs index 7f41f9994..c59402023 100644 --- a/ethcore/types/src/snapshot_manifest.rs +++ b/ethcore/types/src/snapshot_manifest.rs @@ -17,7 +17,7 @@ //! Snapshot manifest type definition use ethereum_types::H256; -use rlp::{UntrustedRlp, RlpStream, DecoderError}; +use rlp::{Rlp, RlpStream, DecoderError}; use bytes::Bytes; /// Manifest data. @@ -53,7 +53,7 @@ impl ManifestData { /// Try to restore manifest data from raw bytes, interpreted as RLP. pub fn from_rlp(raw: &[u8]) -> Result { - let decoder = UntrustedRlp::new(raw); + let decoder = Rlp::new(raw); let (start, version) = if decoder.item_count()? == 5 { (0, 1) } else { diff --git a/ethcore/vm/src/call_type.rs b/ethcore/vm/src/call_type.rs index 08a004053..83260825f 100644 --- a/ethcore/vm/src/call_type.rs +++ b/ethcore/vm/src/call_type.rs @@ -1,6 +1,6 @@ //! EVM call types. -use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; +use rlp::{Encodable, Decodable, DecoderError, RlpStream, Rlp}; /// The type of the call-like instruction. #[derive(Debug, PartialEq, Clone)] @@ -31,7 +31,7 @@ impl Encodable for CallType { } impl Decodable for CallType { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.as_val().and_then(|v| Ok(match v { 0u32 => CallType::None, 1 => CallType::Call, diff --git a/local-store/src/lib.rs b/local-store/src/lib.rs index 2ebc6a69c..078dff36e 100644 --- a/local-store/src/lib.rs +++ b/local-store/src/lib.rs @@ -26,7 +26,7 @@ use transaction::{ }; use ethcore::client::ClientIoMessage; use io::IoHandler; -use rlp::UntrustedRlp; +use rlp::Rlp; use kvdb::KeyValueDB; extern crate ethcore; @@ -103,7 +103,7 @@ struct TransactionEntry { impl TransactionEntry { fn into_pending(self) -> Option { - let tx: UnverifiedTransaction = match UntrustedRlp::new(&self.rlp_bytes).as_val() { + let tx: UnverifiedTransaction = match Rlp::new(&self.rlp_bytes).as_val() { Err(e) => { warn!(target: "local_store", "Invalid persistent transaction stored: {}", e); return None diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 586313ab4..439f13ba3 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -247,7 +247,7 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> { let do_import = |bytes: Vec| { while client.queue_info().is_full() { sleep(Duration::from_secs(1)); } - let header: ::ethcore::header::Header = ::rlp::UntrustedRlp::new(&bytes).val_at(0) + let header: ::ethcore::header::Header = ::rlp::Rlp::new(&bytes).val_at(0) .map_err(|e| format!("Bad block: {}", e))?; if client.best_block_header().number() >= header.number() { return Ok(()) } diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 9d97c3c99..7b5cc3644 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -44,6 +44,7 @@ extern crate jsonrpc_ipc_server as ipc; extern crate jsonrpc_pubsub; extern crate ethash; +#[cfg_attr(test, macro_use)] extern crate ethcore; extern crate ethcore_bytes as bytes; extern crate ethcore_crypto as crypto; diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 37f918466..c894f16df 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -20,7 +20,7 @@ use std::thread; use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH}; use std::sync::Arc; -use rlp::{self, UntrustedRlp}; +use rlp::{self, Rlp}; use ethereum_types::{U256, H64, H160, H256, Address}; use parking_lot::Mutex; @@ -813,7 +813,7 @@ impl Eth for EthClient< } fn send_raw_transaction(&self, raw: Bytes) -> Result { - UntrustedRlp::new(&raw.into_vec()).as_val() + Rlp::new(&raw.into_vec()).as_val() .map_err(errors::rlp) .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction)) .and_then(|signed_transaction| { diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index 73e041aba..eeef12da6 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -36,7 +36,7 @@ use sync::LightSync; use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY_LIST_RLP}; use ethereum_types::U256; use parking_lot::{RwLock, Mutex}; -use rlp::UntrustedRlp; +use rlp::Rlp; use transaction::SignedTransaction; use v1::impls::eth_filter::Filterable; @@ -373,7 +373,7 @@ impl Eth for EthClient { fn send_raw_transaction(&self, raw: Bytes) -> Result { let best_header = self.client.best_block_header().decode(); - UntrustedRlp::new(&raw.into_vec()).as_val() + Rlp::new(&raw.into_vec()).as_val() .map_err(errors::rlp) .and_then(|tx| { self.client.engine().verify_transaction_basic(&tx, &best_header) diff --git a/rpc/src/v1/impls/private.rs b/rpc/src/v1/impls/private.rs index bf797d5a5..ab5866e4a 100644 --- a/rpc/src/v1/impls/private.rs +++ b/rpc/src/v1/impls/private.rs @@ -18,7 +18,7 @@ use std::sync::Arc; -use rlp::UntrustedRlp; +use rlp::Rlp; use ethcore_private_tx::Provider as PrivateTransactionManager; use ethereum_types::Address; @@ -56,7 +56,7 @@ impl Private for PrivateClient { type Metadata = Metadata; fn send_transaction(&self, request: Bytes) -> Result { - let signed_transaction = UntrustedRlp::new(&request.into_vec()).as_val() + let signed_transaction = Rlp::new(&request.into_vec()).as_val() .map_err(errors::rlp) .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))?; let client = self.unwrap_manager()?; @@ -65,7 +65,7 @@ impl Private for PrivateClient { } fn compose_deployment_transaction(&self, block_number: BlockNumber, request: Bytes, validators: Vec, gas_price: U256) -> Result { - let signed_transaction = UntrustedRlp::new(&request.into_vec()).as_val() + let signed_transaction = Rlp::new(&request.into_vec()).as_val() .map_err(errors::rlp) .and_then(|tx| SignedTransaction::new(tx).map_err(errors::transaction))?; let client = self.unwrap_manager()?; diff --git a/rpc/src/v1/impls/signer.rs b/rpc/src/v1/impls/signer.rs index ce3f13b97..2e8d41c4a 100644 --- a/rpc/src/v1/impls/signer.rs +++ b/rpc/src/v1/impls/signer.rs @@ -22,7 +22,7 @@ use ethcore::account_provider::AccountProvider; use ethkey; use parity_reactor::Remote; use parking_lot::Mutex; -use rlp::UntrustedRlp; +use rlp::Rlp; use transaction::{SignedTransaction, PendingTransaction}; use jsonrpc_core::{Result, BoxFuture, Error}; @@ -127,7 +127,7 @@ impl SignerClient { fn verify_transaction(bytes: Bytes, request: FilledTransactionRequest, process: F) -> Result where F: FnOnce(PendingTransaction) -> Result, { - let signed_transaction = UntrustedRlp::new(&bytes.0).as_val().map_err(errors::rlp)?; + let signed_transaction = Rlp::new(&bytes.0).as_val().map_err(errors::rlp)?; let signed_transaction = SignedTransaction::new(signed_transaction).map_err(|e| errors::invalid_params("Invalid signature.", e))?; let sender = signed_transaction.sender(); diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index 06df83b75..bf4dc83be 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -19,7 +19,7 @@ use std::sync::Arc; use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId, StateClient, StateInfo, Call, BlockId}; -use rlp::UntrustedRlp; +use rlp::Rlp; use transaction::SignedTransaction; use jsonrpc_core::Result; @@ -139,7 +139,7 @@ impl Traces for TracesClient where fn raw_transaction(&self, raw_transaction: Bytes, flags: TraceOptions, block: Trailing) -> Result { let block = block.unwrap_or_default(); - let tx = UntrustedRlp::new(&raw_transaction.into_vec()).as_val().map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))?; + let tx = Rlp::new(&raw_transaction.into_vec()).as_val().map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))?; let signed = SignedTransaction::new(tx).map_err(errors::transaction)?; let id = match block { diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 6aacbc865..4b83710bc 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -411,7 +411,7 @@ fn verify_transaction_counts(name: String, chain: BlockChain) { let tester = EthTester::from_chain(&chain); let mut id = 1; - for b in chain.blocks_rlp().iter().filter(|b| Block::is_good(b)).map(|b| BlockView::new(b)) { + for b in chain.blocks_rlp().iter().filter(|b| Block::is_good(b)).map(|b| view!(BlockView, b)) { let count = b.transactions_count(); let hash = b.hash(); diff --git a/util/journaldb/src/overlaydb.rs b/util/journaldb/src/overlaydb.rs index 6ff1b97e8..fa7ff0459 100644 --- a/util/journaldb/src/overlaydb.rs +++ b/util/journaldb/src/overlaydb.rs @@ -21,7 +21,7 @@ use std::collections::HashMap; use std::collections::hash_map::Entry; use error::{Result, BaseDataError}; use ethereum_types::H256; -use rlp::{UntrustedRlp, RlpStream, Encodable, DecoderError, Decodable, encode, decode}; +use rlp::{Rlp, RlpStream, Encodable, DecoderError, Decodable, encode, decode}; use hashdb::*; use memorydb::*; use kvdb::{KeyValueDB, DBTransaction}; @@ -64,7 +64,7 @@ impl Encodable for Payload { } impl Decodable for Payload { - fn decode(rlp: &UntrustedRlp) -> ::std::result::Result { + fn decode(rlp: &Rlp) -> ::std::result::Result { let payload = Payload { count: rlp.val_at(0)?, value: DBValue::from_slice(rlp.at(1)?.data()?), diff --git a/util/journaldb/src/overlayrecentdb.rs b/util/journaldb/src/overlayrecentdb.rs index 9ac8a4e29..fdc178350 100644 --- a/util/journaldb/src/overlayrecentdb.rs +++ b/util/journaldb/src/overlayrecentdb.rs @@ -21,7 +21,7 @@ use std::collections::hash_map::Entry; use std::sync::Arc; use parking_lot::RwLock; use heapsize::HeapSizeOf; -use rlp::{UntrustedRlp, RlpStream, encode, decode, DecoderError, Decodable, Encodable}; +use rlp::{Rlp, RlpStream, encode, decode, DecoderError, Decodable, Encodable}; use hashdb::*; use memorydb::*; use super::{DB_PREFIX_LEN, LATEST_ERA_KEY}; @@ -78,7 +78,7 @@ struct DatabaseValue { } impl Decodable for DatabaseValue { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let id = rlp.val_at(0)?; let inserts = rlp.at(1)?.iter().map(|r| { let k = r.val_at(0)?; diff --git a/util/journaldb/src/util.rs b/util/journaldb/src/util.rs index 52dbad7e1..e99be458e 100644 --- a/util/journaldb/src/util.rs +++ b/util/journaldb/src/util.rs @@ -15,7 +15,7 @@ // along with Parity. If not, see . use ethereum_types::H256; -use rlp::{RlpStream, Encodable, UntrustedRlp, DecoderError}; +use rlp::{RlpStream, Encodable, Rlp, DecoderError}; const PADDING : [u8; 10] = [ 0u8; 10 ]; @@ -34,13 +34,13 @@ impl Encodable for DatabaseKey { } pub struct DatabaseValueView<'a> { - rlp: UntrustedRlp<'a>, + rlp: Rlp<'a>, } impl<'a> DatabaseValueView<'a> { pub fn from_rlp(data: &'a [u8]) -> Self { DatabaseValueView { - rlp: UntrustedRlp::new(data), + rlp: Rlp::new(data), } } diff --git a/util/network-devp2p/src/connection.rs b/util/network-devp2p/src/connection.rs index 12c38b3a2..2b390baf7 100644 --- a/util/network-devp2p/src/connection.rs +++ b/util/network-devp2p/src/connection.rs @@ -24,7 +24,7 @@ use mio::deprecated::{Handler, EventLoop, TryRead, TryWrite}; use mio::tcp::*; use ethereum_types::{H128, H256, H512}; use ethcore_bytes::*; -use rlp::{UntrustedRlp, RlpStream}; +use rlp::{Rlp, RlpStream}; use std::io::{self, Cursor, Read, Write}; use io::{IoContext, StreamToken}; use handshake::Handshake; @@ -391,7 +391,7 @@ impl EncryptedConnection { self.decoder.decrypt(&mut RefReadBuffer::new(&header[0..16]), &mut RefWriteBuffer::new(&mut hdec), false).expect("Invalid length or padding"); let length = ((((hdec[0] as u32) << 8) + (hdec[1] as u32)) << 8) + (hdec[2] as u32); - let header_rlp = UntrustedRlp::new(&hdec[3..6]); + let header_rlp = Rlp::new(&hdec[3..6]); let protocol_id = header_rlp.val_at::(0)?; self.payload_len = length as usize; diff --git a/util/network-devp2p/src/discovery.rs b/util/network-devp2p/src/discovery.rs index 2828b8f19..f14cd5ba6 100644 --- a/util/network-devp2p/src/discovery.rs +++ b/util/network-devp2p/src/discovery.rs @@ -25,7 +25,7 @@ use mio::deprecated::{Handler, EventLoop}; use mio::udp::*; use hash::keccak; use ethereum_types::{H256, H520}; -use rlp::{UntrustedRlp, RlpStream, encode_list}; +use rlp::{Rlp, RlpStream, encode_list}; use node_table::*; use network::{Error, ErrorKind}; use io::{StreamToken, IoContext}; @@ -259,7 +259,7 @@ impl Discovery { fn send_packet(&mut self, packet_id: u8, address: &SocketAddr, payload: &[u8]) -> Result<(), Error> { let mut rlp = RlpStream::new(); rlp.append_raw(&[packet_id], 1); - let source = UntrustedRlp::new(payload); + let source = Rlp::new(payload); rlp.begin_list(source.item_count()? + 1); for i in 0 .. source.item_count()? { rlp.append_raw(source.at(i)?.as_raw(), 1); @@ -382,7 +382,7 @@ impl Discovery { let node_id = recover(&signature.into(), &keccak(signed))?; let packet_id = signed[0]; - let rlp = UntrustedRlp::new(&signed[1..]); + let rlp = Rlp::new(&signed[1..]); match packet_id { PACKET_PING => self.on_ping(&rlp, &node_id, &from, &hash_signed), PACKET_PONG => self.on_pong(&rlp, &node_id, &from), @@ -409,7 +409,7 @@ impl Discovery { entry.endpoint.is_allowed(&self.ip_filter) && entry.id != self.id } - fn on_ping(&mut self, rlp: &UntrustedRlp, node: &NodeId, from: &SocketAddr, echo_hash: &[u8]) -> Result, Error> { + fn on_ping(&mut self, rlp: &Rlp, node: &NodeId, from: &SocketAddr, echo_hash: &[u8]) -> Result, Error> { trace!(target: "discovery", "Got Ping from {:?}", &from); let source = NodeEndpoint::from_rlp(&rlp.at(1)?)?; let dest = NodeEndpoint::from_rlp(&rlp.at(2)?)?; @@ -433,7 +433,7 @@ impl Discovery { Ok(Some(TableUpdates { added: added_map, removed: HashSet::new() })) } - fn on_pong(&mut self, rlp: &UntrustedRlp, node: &NodeId, from: &SocketAddr) -> Result, Error> { + fn on_pong(&mut self, rlp: &Rlp, node: &NodeId, from: &SocketAddr) -> Result, Error> { trace!(target: "discovery", "Got Pong from {:?}", &from); // TODO: validate pong packet in rlp.val_at(1) let dest = NodeEndpoint::from_rlp(&rlp.at(0)?)?; @@ -448,7 +448,7 @@ impl Discovery { Ok(None) } - fn on_find_node(&mut self, rlp: &UntrustedRlp, _node: &NodeId, from: &SocketAddr) -> Result, Error> { + fn on_find_node(&mut self, rlp: &Rlp, _node: &NodeId, from: &SocketAddr) -> Result, Error> { trace!(target: "discovery", "Got FindNode from {:?}", &from); let target: NodeId = rlp.val_at(0)?; let timestamp: u64 = rlp.val_at(1)?; @@ -481,7 +481,7 @@ impl Discovery { packets.collect() } - fn on_neighbours(&mut self, rlp: &UntrustedRlp, _node: &NodeId, from: &SocketAddr) -> Result, Error> { + fn on_neighbours(&mut self, rlp: &Rlp, _node: &NodeId, from: &SocketAddr) -> Result, Error> { // TODO: validate packet let mut added = HashMap::new(); trace!(target: "discovery", "Got {} Neighbours from {:?}", rlp.at(0)?.item_count()?, &from); @@ -725,7 +725,7 @@ mod tests { discovery2.on_packet(&ping_data.payload, ep1.address.clone()).ok(); let pong_data = discovery2.send_queue.pop_front().unwrap(); let data = &pong_data.payload[(32 + 65)..]; - let rlp = UntrustedRlp::new(&data[1..]); + let rlp = Rlp::new(&data[1..]); assert_eq!(ping_data.payload[0..32], rlp.val_at::>(1).unwrap()[..]) } } diff --git a/util/network-devp2p/src/handshake.rs b/util/network-devp2p/src/handshake.rs index d7818b64d..37c39eb61 100644 --- a/util/network-devp2p/src/handshake.rs +++ b/util/network-devp2p/src/handshake.rs @@ -20,7 +20,7 @@ use hash::write_keccak; use mio::tcp::*; use ethereum_types::{H256, H520}; use ethcore_bytes::Bytes; -use rlp::{UntrustedRlp, RlpStream}; +use rlp::{Rlp, RlpStream}; use connection::{Connection}; use node_table::NodeId; use io::{IoContext, StreamToken}; @@ -205,7 +205,7 @@ impl Handshake { trace!(target: "network", "Received EIP8 handshake auth from {:?}", self.connection.remote_addr_str()); self.auth_cipher.extend_from_slice(data); let auth = ecies::decrypt(secret, &self.auth_cipher[0..2], &self.auth_cipher[2..])?; - let rlp = UntrustedRlp::new(&auth); + let rlp = Rlp::new(&auth); let signature: H520 = rlp.val_at(0)?; let remote_public: Public = rlp.val_at(1)?; let remote_nonce: H256 = rlp.val_at(2)?; @@ -248,7 +248,7 @@ impl Handshake { trace!(target: "network", "Received EIP8 handshake auth from {:?}", self.connection.remote_addr_str()); self.ack_cipher.extend_from_slice(data); let ack = ecies::decrypt(secret, &self.ack_cipher[0..2], &self.ack_cipher[2..])?; - let rlp = UntrustedRlp::new(&ack); + let rlp = Rlp::new(&ack); self.remote_ephemeral = rlp.val_at(0)?; self.remote_nonce = rlp.val_at(1)?; self.remote_version = rlp.val_at(2)?; diff --git a/util/network-devp2p/src/node_table.rs b/util/network-devp2p/src/node_table.rs index 470bf5cde..fd18c10a1 100644 --- a/util/network-devp2p/src/node_table.rs +++ b/util/network-devp2p/src/node_table.rs @@ -22,7 +22,7 @@ use std::path::PathBuf; use std::str::FromStr; use std::{fs, mem, slice}; use ethereum_types::H512; -use rlp::{UntrustedRlp, RlpStream, DecoderError}; +use rlp::{Rlp, RlpStream, DecoderError}; use network::{Error, ErrorKind, AllowIP, IpFilter}; use discovery::{TableUpdates, NodeEntry}; use ip_utils::*; @@ -66,7 +66,7 @@ impl NodeEndpoint { } } - pub fn from_rlp(rlp: &UntrustedRlp) -> Result { + pub fn from_rlp(rlp: &Rlp) -> Result { let tcp_port = rlp.val_at::(2)?; let udp_port = rlp.val_at::(1)?; let addr_bytes = rlp.at(0)?.data()?; diff --git a/util/network-devp2p/src/session.rs b/util/network-devp2p/src/session.rs index c1e09a252..47eb2cf72 100644 --- a/util/network-devp2p/src/session.rs +++ b/util/network-devp2p/src/session.rs @@ -23,7 +23,7 @@ use mio::*; use mio::deprecated::{Handler, EventLoop}; use mio::tcp::*; use ethereum_types::H256; -use rlp::{UntrustedRlp, RlpStream, EMPTY_LIST_RLP}; +use rlp::{Rlp, RlpStream, EMPTY_LIST_RLP}; use connection::{EncryptedConnection, Packet, Connection, MAX_PAYLOAD_SIZE}; use handshake::Handshake; use io::{IoContext, StreamToken}; @@ -349,12 +349,12 @@ impl Session { }; match packet_id { PACKET_HELLO => { - let rlp = UntrustedRlp::new(&data); //TODO: validate rlp expected size + let rlp = Rlp::new(&data); //TODO: validate rlp expected size self.read_hello(io, &rlp, host)?; Ok(SessionData::Ready) }, PACKET_DISCONNECT => { - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); let reason: u8 = rlp.val_at(0)?; if self.had_hello { debug!(target:"network", "Disconnected: {}: {:?}", self.token(), DisconnectReason::from_u8(reason)); @@ -419,7 +419,7 @@ impl Session { self.send(io, &rlp.drain()) } - fn read_hello(&mut self, io: &IoContext, rlp: &UntrustedRlp, host: &HostInfo) -> Result<(), Error> + fn read_hello(&mut self, io: &IoContext, rlp: &Rlp, host: &HostInfo) -> Result<(), Error> where Message: Send + Sync + Clone { let protocol = rlp.val_at::(0)?; let client_version = rlp.val_at::(1)?; diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index 1a0c88e4c..5077a953d 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -42,7 +42,7 @@ use ipnetwork::{IpNetwork, IpNetworkError}; use io::IoChannel; use ethkey::Secret; use ethereum_types::{H256, H512}; -use rlp::{Decodable, DecoderError, UntrustedRlp}; +use rlp::{Decodable, DecoderError, Rlp}; /// Protocol handler level packet id pub type PacketId = u8; @@ -118,7 +118,7 @@ pub struct PeerCapabilityInfo { } impl Decodable for PeerCapabilityInfo { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let p: Vec = rlp.val_at(0)?; if p.len() != 3 { return Err(DecoderError::Custom("Invalid subprotocol string length. Should be 3")); diff --git a/util/patricia_trie/src/node.rs b/util/patricia_trie/src/node.rs index 47807940f..0b99acded 100644 --- a/util/patricia_trie/src/node.rs +++ b/util/patricia_trie/src/node.rs @@ -19,7 +19,7 @@ use elastic_array::ElasticArray36; use nibbleslice::NibbleSlice; use nibblevec::NibbleVec; use bytes::*; -use rlp::{UntrustedRlp, RlpStream, Prototype, DecoderError}; +use rlp::{Rlp, RlpStream, Prototype, DecoderError}; use hashdb::DBValue; /// Partial node key type. @@ -41,7 +41,7 @@ pub enum Node<'a> { impl<'a> Node<'a> { /// Decode the `node_rlp` and return the Node. pub fn decoded(node_rlp: &'a [u8]) -> Result { - let r = UntrustedRlp::new(node_rlp); + let r = Rlp::new(node_rlp); match r.prototype()? { // either leaf or extension - decode first item with NibbleSlice::??? // and use is_leaf return to figure out which. @@ -105,7 +105,7 @@ impl<'a> Node<'a> { } pub fn try_decode_hash(node_data: &[u8]) -> Option { - let r = UntrustedRlp::new(node_data); + let r = Rlp::new(node_data); if r.is_data() && r.size() == 32 { Some(r.as_val().expect("Hash is the correct size of 32 bytes; qed")) } else { diff --git a/util/patricia_trie/src/triedbmut.rs b/util/patricia_trie/src/triedbmut.rs index 98215de01..b8d919dee 100644 --- a/util/patricia_trie/src/triedbmut.rs +++ b/util/patricia_trie/src/triedbmut.rs @@ -24,7 +24,7 @@ use super::node::NodeKey; use hashdb::HashDB; use bytes::ToPretty; use nibbleslice::NibbleSlice; -use rlp::{UntrustedRlp, RlpStream}; +use rlp::{Rlp, RlpStream}; use hashdb::DBValue; use std::collections::{HashSet, VecDeque}; @@ -107,7 +107,7 @@ impl Node { RlpNode::Branch(ref children_rlp, val) => { let mut child = |i| { let raw = children_rlp[i]; - let child_rlp = UntrustedRlp::new(raw); + let child_rlp = Rlp::new(raw); if !child_rlp.is_empty() { Some(Self::inline_or_hash(raw, db, storage)) } else { diff --git a/util/rlp/src/impls.rs b/util/rlp/src/impls.rs index 7cb6572fe..573f2c078 100644 --- a/util/rlp/src/impls.rs +++ b/util/rlp/src/impls.rs @@ -11,7 +11,7 @@ use byteorder::{ByteOrder, BigEndian}; use bigint::{U128, U256, H64, H128, H160, H256, H512, H520, Bloom}; use traits::{Encodable, Decodable}; use stream::RlpStream; -use {UntrustedRlp, DecoderError}; +use {Rlp, DecoderError}; pub fn decode_usize(bytes: &[u8]) -> Result { match bytes.len() { @@ -41,7 +41,7 @@ impl Encodable for bool { } impl Decodable for bool { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.decoder().decode_value(|bytes| { match bytes.len() { 0 => Ok(false), @@ -65,7 +65,7 @@ impl Encodable for Vec { } impl Decodable for Vec { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.decoder().decode_value(|bytes| { Ok(bytes.to_vec()) }) @@ -87,7 +87,7 @@ impl Encodable for Option where T: Encodable { } impl Decodable for Option where T: Decodable { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { let items = rlp.item_count()?; match items { 1 => rlp.val_at(0).map(Some), @@ -108,7 +108,7 @@ impl Encodable for u8 { } impl Decodable for u8 { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.decoder().decode_value(|bytes| { match bytes.len() { 1 if bytes[0] != 0 => Ok(bytes[0]), @@ -136,7 +136,7 @@ macro_rules! impl_encodable_for_u { macro_rules! impl_decodable_for_u { ($name: ident) => { impl Decodable for $name { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.decoder().decode_value(|bytes| { match bytes.len() { 0 | 1 => u8::decode(rlp).map(|v| v as $name), @@ -174,7 +174,7 @@ impl Encodable for usize { } impl Decodable for usize { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { u64::decode(rlp).map(|value| value as usize) } } @@ -192,7 +192,7 @@ macro_rules! impl_encodable_for_hash { macro_rules! impl_decodable_for_hash { ($name: ident, $size: expr) => { impl Decodable for $name { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.decoder().decode_value(|bytes| match bytes.len().cmp(&$size) { cmp::Ordering::Less => Err(DecoderError::RlpIsTooShort), cmp::Ordering::Greater => Err(DecoderError::RlpIsTooBig), @@ -239,7 +239,7 @@ macro_rules! impl_encodable_for_uint { macro_rules! impl_decodable_for_uint { ($name: ident, $size: expr) => { impl Decodable for $name { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.decoder().decode_value(|bytes| { if !bytes.is_empty() && bytes[0] == 0 { Err(DecoderError::RlpInvalidIndirection) @@ -273,7 +273,7 @@ impl Encodable for String { } impl Decodable for String { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { rlp.decoder().decode_value(|bytes| { match str::from_utf8(bytes) { Ok(s) => Ok(s.to_owned()), diff --git a/util/rlp/src/lib.rs b/util/rlp/src/lib.rs index a5889a4ef..a6754e22d 100644 --- a/util/rlp/src/lib.rs +++ b/util/rlp/src/lib.rs @@ -27,12 +27,6 @@ //! * You encode a big set of data. //! //!### Use `Rlp` when: -//! * You are working on trusted data (not corrupted). -//! * You want to get view onto rlp-slice. -//! * You don't want to decode whole rlp at once. -//! -//!### Use `UntrustedRlp` when: -//! * You are working on untrusted data (~corrupted). //! * You need to handle data corruption errors. //! * You are working on input data. //! * You want to get view onto rlp-slice. @@ -46,7 +40,6 @@ extern crate rustc_hex; mod traits; mod error; mod rlpin; -mod untrusted_rlp; mod stream; mod impls; @@ -55,8 +48,7 @@ use elastic_array::ElasticArray1024; pub use error::DecoderError; pub use traits::{Decodable, Encodable}; -pub use untrusted_rlp::{UntrustedRlp, UntrustedRlpIterator, PayloadInfo, Prototype}; -pub use rlpin::{Rlp, RlpIterator}; +pub use rlpin::{Rlp, RlpIterator, PayloadInfo, Prototype}; pub use stream::RlpStream; /// The RLP encoded empty data (used to mean "null value"). @@ -77,12 +69,12 @@ pub const EMPTY_LIST_RLP: [u8; 1] = [0xC0; 1]; /// ``` pub fn decode(bytes: &[u8]) -> T where T: Decodable { let rlp = Rlp::new(bytes); - rlp.as_val() + rlp.as_val().expect("trusted rlp should be valid") } pub fn decode_list(bytes: &[u8]) -> Vec where T: Decodable { let rlp = Rlp::new(bytes); - rlp.as_list() + rlp.as_list().expect("trusted rlp should be valid") } /// Shortcut function to encode structure into rlp. diff --git a/util/rlp/src/rlpin.rs b/util/rlp/src/rlpin.rs index c96795913..a55b4f790 100644 --- a/util/rlp/src/rlpin.rs +++ b/util/rlp/src/rlpin.rs @@ -6,246 +6,295 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::cell::Cell; use std::fmt; -use {UntrustedRlp, PayloadInfo, Prototype, Decodable}; +use rustc_hex::ToHex; +use impls::decode_usize; +use {Decodable, DecoderError}; -impl<'a> From> for Rlp<'a> { - fn from(rlp: UntrustedRlp<'a>) -> Rlp<'a> { - Rlp { rlp: rlp } +/// rlp offset +#[derive(Copy, Clone, Debug)] +struct OffsetCache { + index: usize, + offset: usize, +} + +impl OffsetCache { + fn new(index: usize, offset: usize) -> OffsetCache { + OffsetCache { + index: index, + offset: offset, + } } } -/// Data-oriented view onto trusted rlp-slice. +#[derive(Debug)] +/// RLP prototype +pub enum Prototype { + /// Empty + Null, + /// Value + Data(usize), + /// List + List(usize), +} + +/// Stores basic information about item +pub struct PayloadInfo { + /// Header length in bytes + pub header_len: usize, + /// Value length in bytes + pub value_len: usize, +} + +fn calculate_payload_info(header_bytes: &[u8], len_of_len: usize) -> Result { + let header_len = 1 + len_of_len; + match header_bytes.get(1) { + Some(&0) => return Err(DecoderError::RlpDataLenWithZeroPrefix), + None => return Err(DecoderError::RlpIsTooShort), + _ => (), + } + if header_bytes.len() < header_len { return Err(DecoderError::RlpIsTooShort); } + let value_len = decode_usize(&header_bytes[1..header_len])?; + Ok(PayloadInfo::new(header_len, value_len)) +} + +impl PayloadInfo { + fn new(header_len: usize, value_len: usize) -> PayloadInfo { + PayloadInfo { + header_len: header_len, + value_len: value_len, + } + } + + /// Total size of the RLP. + pub fn total(&self) -> usize { self.header_len + self.value_len } + + /// Create a new object from the given bytes RLP. The bytes + pub fn from(header_bytes: &[u8]) -> Result { + match header_bytes.first().cloned() { + None => Err(DecoderError::RlpIsTooShort), + Some(0...0x7f) => Ok(PayloadInfo::new(0, 1)), + Some(l @ 0x80...0xb7) => Ok(PayloadInfo::new(1, l as usize - 0x80)), + Some(l @ 0xb8...0xbf) => { + let len_of_len = l as usize - 0xb7; + calculate_payload_info(header_bytes, len_of_len) + } + Some(l @ 0xc0...0xf7) => Ok(PayloadInfo::new(1, l as usize - 0xc0)), + Some(l @ 0xf8...0xff) => { + let len_of_len = l as usize - 0xf7; + calculate_payload_info(header_bytes, len_of_len) + }, + // we cant reach this place, but rust requires _ to be implemented + _ => { unreachable!(); } + } + } +} + +/// Data-oriented view onto rlp-slice. /// -/// Unlikely to `UntrustedRlp` doesn't bother you with error -/// handling. It assumes that you know what you are doing. +/// This is an immutable structure. No operations change it. +/// +/// Should be used in places where, error handling is required, +/// eg. on input #[derive(Debug)] pub struct Rlp<'a> { - rlp: UntrustedRlp<'a> + bytes: &'a [u8], + offset_cache: Cell, + count_cache: Cell>, +} + +impl<'a> Clone for Rlp<'a> { + fn clone(&self) -> Rlp<'a> { + Rlp { + bytes: self.bytes, + offset_cache: self.offset_cache.clone(), + count_cache: self.count_cache.clone(), + } + } } impl<'a> fmt::Display for Rlp<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "{}", self.rlp) + match self.prototype() { + Ok(Prototype::Null) => write!(f, "null"), + Ok(Prototype::Data(_)) => write!(f, "\"0x{}\"", self.data().unwrap().to_hex()), + Ok(Prototype::List(len)) => { + write!(f, "[")?; + for i in 0..len-1 { + write!(f, "{}, ", self.at(i).unwrap())?; + } + write!(f, "{}", self.at(len - 1).unwrap())?; + write!(f, "]") + }, + Err(err) => write!(f, "{:?}", err) + } } } impl<'a, 'view> Rlp<'a> where 'a: 'view { - /// Create a new instance of `Rlp` pub fn new(bytes: &'a [u8]) -> Rlp<'a> { Rlp { - rlp: UntrustedRlp::new(bytes) + bytes: bytes, + offset_cache: Cell::new(OffsetCache::new(usize::max_value(), 0)), + count_cache: Cell::new(None) } } - /// The raw data of the RLP as slice. - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; - /// let rlp = Rlp::new(&data); - /// let dog = rlp.at(1).as_raw(); - /// assert_eq!(dog, &[0x83, b'd', b'o', b'g']); - /// } - /// ``` pub fn as_raw(&'view self) -> &'a [u8] { - self.rlp.as_raw() + self.bytes } - /// Get the prototype of the RLP. - pub fn prototype(&self) -> Prototype { - self.rlp.prototype().unwrap() + pub fn prototype(&self) -> Result { + // optimize? && return appropriate errors + if self.is_data() { + Ok(Prototype::Data(self.size())) + } else if self.is_list() { + self.item_count().map(Prototype::List) + } else { + Ok(Prototype::Null) + } } - /// Get payload info. - pub fn payload_info(&self) -> PayloadInfo { - self.rlp.payload_info().unwrap() + pub fn payload_info(&self) -> Result { + BasicDecoder::payload_info(self.bytes) } - /// Get underlieing data. - pub fn data(&'view self) -> &'a [u8] { - self.rlp.data().unwrap() + pub fn data(&'view self) -> Result<&'a [u8], DecoderError> { + let pi = BasicDecoder::payload_info(self.bytes)?; + Ok(&self.bytes[pi.header_len..(pi.header_len + pi.value_len)]) } - /// Returns number of RLP items. - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; - /// let rlp = Rlp::new(&data); - /// assert_eq!(rlp.item_count(), 2); - /// let view = rlp.at(1); - /// assert_eq!(view.item_count(), 0); - /// } - /// ``` - pub fn item_count(&self) -> usize { - self.rlp.item_count().unwrap_or(0) + pub fn item_count(&self) -> Result { + match self.is_list() { + true => match self.count_cache.get() { + Some(c) => Ok(c), + None => { + let c = self.iter().count(); + self.count_cache.set(Some(c)); + Ok(c) + } + }, + false => Err(DecoderError::RlpExpectedToBeList), + } } - /// Returns the number of bytes in the data, or zero if it isn't data. - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; - /// let rlp = Rlp::new(&data); - /// assert_eq!(rlp.size(), 0); - /// let view = rlp.at(1); - /// assert_eq!(view.size(), 3); - /// } - /// ``` pub fn size(&self) -> usize { - self.rlp.size() + match self.is_data() { + // TODO: No panic on malformed data, but ideally would Err on no PayloadInfo. + true => BasicDecoder::payload_info(self.bytes).map(|b| b.value_len).unwrap_or(0), + false => 0 + } } - /// Get view onto RLP-slice at index. - /// - /// Caches offset to given index, so access to successive - /// slices is faster. - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; - /// let rlp = Rlp::new(&data); - /// let dog: String = rlp.at(1).as_val(); - /// assert_eq!(dog, "dog".to_string()); - /// } - /// ``` - pub fn at(&'view self, index: usize) -> Rlp<'a> { - From::from(self.rlp.at(index).unwrap()) + pub fn at(&'view self, index: usize) -> Result, DecoderError> { + if !self.is_list() { + return Err(DecoderError::RlpExpectedToBeList); + } + + // move to cached position if its index is less or equal to + // current search index, otherwise move to beginning of list + let c = self.offset_cache.get(); + let (mut bytes, to_skip) = match c.index <= index { + true => (Rlp::consume(self.bytes, c.offset)?, index - c.index), + false => (self.consume_list_payload()?, index), + }; + + // skip up to x items + bytes = Rlp::consume_items(bytes, to_skip)?; + + // update the cache + self.offset_cache.set(OffsetCache::new(index, self.bytes.len() - bytes.len())); + + // construct new rlp + let found = BasicDecoder::payload_info(bytes)?; + Ok(Rlp::new(&bytes[0..found.header_len + found.value_len])) } - /// No value - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![]; - /// let rlp = Rlp::new(&data); - /// assert!(rlp.is_null()); - /// } - /// ``` pub fn is_null(&self) -> bool { - self.rlp.is_null() + self.bytes.len() == 0 } - /// Contains a zero-length string or zero-length list. - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc0]; - /// let rlp = Rlp::new(&data); - /// assert!(rlp.is_empty()); - /// } - /// ``` pub fn is_empty(&self) -> bool { - self.rlp.is_empty() + !self.is_null() && (self.bytes[0] == 0xc0 || self.bytes[0] == 0x80) } - /// List value - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; - /// let rlp = Rlp::new(&data); - /// assert!(rlp.is_list()); - /// } - /// ``` pub fn is_list(&self) -> bool { - self.rlp.is_list() + !self.is_null() && self.bytes[0] >= 0xc0 } - /// String value - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; - /// let rlp = Rlp::new(&data); - /// assert!(rlp.at(1).is_data()); - /// } - /// ``` pub fn is_data(&self) -> bool { - self.rlp.is_data() + !self.is_null() && self.bytes[0] < 0xc0 } - /// Int value - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc1, 0x10]; - /// let rlp = Rlp::new(&data); - /// assert_eq!(rlp.is_int(), false); - /// assert_eq!(rlp.at(0).is_int(), true); - /// } - /// ``` pub fn is_int(&self) -> bool { - self.rlp.is_int() + if self.is_null() { + return false; + } + + match self.bytes[0] { + 0...0x80 => true, + 0x81...0xb7 => self.bytes[1] != 0, + b @ 0xb8...0xbf => self.bytes[1 + b as usize - 0xb7] != 0, + _ => false + } } - /// Get iterator over rlp-slices - /// - /// ```rust - /// extern crate rlp; - /// use rlp::*; - /// - /// fn main () { - /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; - /// let rlp = Rlp::new(&data); - /// let strings: Vec = rlp.iter().map(| i | i.as_val()).collect(); - /// } - /// ``` pub fn iter(&'view self) -> RlpIterator<'a, 'view> { self.into_iter() } - /// Decode data into an object - pub fn as_val(&self) -> T where T: Decodable { - self.rlp.as_val().expect("Unexpected rlp error") + pub fn as_val(&self) -> Result where T: Decodable { + T::decode(self) } - pub fn as_list(&self) -> Vec where T: Decodable { + pub fn as_list(&self) -> Result, DecoderError> where T: Decodable { self.iter().map(|rlp| rlp.as_val()).collect() } - /// Decode data at given list index into an object - pub fn val_at(&self, index: usize) -> T where T: Decodable { - self.at(index).as_val() + pub fn val_at(&self, index: usize) -> Result where T: Decodable { + self.at(index)?.as_val() } - pub fn list_at(&self, index: usize) -> Vec where T: Decodable { - self.at(index).as_list() + pub fn list_at(&self, index: usize) -> Result, DecoderError> where T: Decodable { + self.at(index)?.as_list() + } + + pub fn decoder(&self) -> BasicDecoder { + BasicDecoder::new(self.clone()) + } + + /// consumes first found prefix + fn consume_list_payload(&self) -> Result<&'a [u8], DecoderError> { + let item = BasicDecoder::payload_info(self.bytes)?; + let bytes = Rlp::consume(self.bytes, item.header_len)?; + Ok(bytes) + } + + /// consumes fixed number of items + fn consume_items(bytes: &'a [u8], items: usize) -> Result<&'a [u8], DecoderError> { + let mut result = bytes; + for _ in 0..items { + let i = BasicDecoder::payload_info(result)?; + result = Rlp::consume(result, i.header_len + i.value_len)?; + } + Ok(result) + } + + + /// consumes slice prefix of length `len` + fn consume(bytes: &'a [u8], len: usize) -> Result<&'a [u8], DecoderError> { + match bytes.len() >= len { + true => Ok(&bytes[len..]), + false => Err(DecoderError::RlpIsTooShort), + } } } -/// Iterator over trusted rlp-slice list elements. +/// Iterator over rlp-slice list elements. pub struct RlpIterator<'a, 'view> where 'a: 'view { rlp: &'view Rlp<'a>, - index: usize + index: usize, } impl<'a, 'view> IntoIterator for &'view Rlp<'a> where 'a: 'view { @@ -265,19 +314,93 @@ impl<'a, 'view> Iterator for RlpIterator<'a, 'view> { fn next(&mut self) -> Option> { let index = self.index; - let result = self.rlp.rlp.at(index).ok().map(From::from); + let result = self.rlp.at(index).ok(); self.index += 1; result } } -#[test] -fn break_it() { - use rustc_hex::FromHex; - use bigint::U256; - - let h: Vec = FromHex::from_hex("f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap(); - let r: Rlp = Rlp::new(&h); - let u: U256 = r.val_at(1); - assert_eq!(format!("{}", u), "19526463837540678066"); +pub struct BasicDecoder<'a> { + rlp: Rlp<'a> +} + +impl<'a> BasicDecoder<'a> { + pub fn new(rlp: Rlp<'a>) -> BasicDecoder<'a> { + BasicDecoder { + rlp: rlp + } + } + + /// Return first item info. + fn payload_info(bytes: &[u8]) -> Result { + let item = PayloadInfo::from(bytes)?; + match item.header_len.checked_add(item.value_len) { + Some(x) if x <= bytes.len() => Ok(item), + _ => Err(DecoderError::RlpIsTooShort), + } + } + + pub fn decode_value(&self, f: F) -> Result + where F: Fn(&[u8]) -> Result { + + let bytes = self.rlp.as_raw(); + + match bytes.first().cloned() { + // RLP is too short. + None => Err(DecoderError::RlpIsTooShort), + // Single byte value. + Some(l @ 0...0x7f) => Ok(f(&[l])?), + // 0-55 bytes + Some(l @ 0x80...0xb7) => { + let last_index_of = 1 + l as usize - 0x80; + if bytes.len() < last_index_of { + return Err(DecoderError::RlpInconsistentLengthAndData); + } + let d = &bytes[1..last_index_of]; + if l == 0x81 && d[0] < 0x80 { + return Err(DecoderError::RlpInvalidIndirection); + } + Ok(f(d)?) + }, + // Longer than 55 bytes. + Some(l @ 0xb8...0xbf) => { + let len_of_len = l as usize - 0xb7; + let begin_of_value = 1 as usize + len_of_len; + if bytes.len() < begin_of_value { + return Err(DecoderError::RlpInconsistentLengthAndData); + } + let len = decode_usize(&bytes[1..begin_of_value])?; + + let last_index_of_value = begin_of_value.checked_add(len) + .ok_or(DecoderError::RlpInvalidLength)?; + if bytes.len() < last_index_of_value { + return Err(DecoderError::RlpInconsistentLengthAndData); + } + Ok(f(&bytes[begin_of_value..last_index_of_value])?) + } + // We are reading value, not a list! + _ => Err(DecoderError::RlpExpectedToBeData) + } + } +} + +#[cfg(test)] +mod tests { + use {Rlp, DecoderError}; + + #[test] + fn test_rlp_display() { + use rustc_hex::FromHex; + let data = "f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".from_hex().unwrap(); + let rlp = Rlp::new(&data); + assert_eq!(format!("{}", rlp), "[\"0x05\", \"0x010efbef67941f79b2\", \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\", \"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"]"); + } + + #[test] + fn length_overflow() { + let bs = [0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5]; + let rlp = Rlp::new(&bs); + let res: Result = rlp.as_val(); + assert_eq!(Err(DecoderError::RlpInvalidLength), res); + } } diff --git a/util/rlp/src/traits.rs b/util/rlp/src/traits.rs index 193d0bf84..1596009e7 100644 --- a/util/rlp/src/traits.rs +++ b/util/rlp/src/traits.rs @@ -8,12 +8,12 @@ //! Common RLP traits use elastic_array::ElasticArray1024; -use {DecoderError, UntrustedRlp, RlpStream}; +use {DecoderError, Rlp, RlpStream}; /// RLP decodable trait pub trait Decodable: Sized { /// Decode a value from RLP bytes - fn decode(rlp: &UntrustedRlp) -> Result; + fn decode(rlp: &Rlp) -> Result; } /// Structure encodable to RLP diff --git a/util/rlp/src/untrusted_rlp.rs b/util/rlp/src/untrusted_rlp.rs deleted file mode 100644 index 7f95ce2ef..000000000 --- a/util/rlp/src/untrusted_rlp.rs +++ /dev/null @@ -1,406 +0,0 @@ -// Copyright 2015-2017 Parity Technologies -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::cell::Cell; -use std::fmt; -use rustc_hex::ToHex; -use impls::decode_usize; -use {Decodable, DecoderError}; - -/// rlp offset -#[derive(Copy, Clone, Debug)] -struct OffsetCache { - index: usize, - offset: usize, -} - -impl OffsetCache { - fn new(index: usize, offset: usize) -> OffsetCache { - OffsetCache { - index: index, - offset: offset, - } - } -} - -#[derive(Debug)] -/// RLP prototype -pub enum Prototype { - /// Empty - Null, - /// Value - Data(usize), - /// List - List(usize), -} - -/// Stores basic information about item -pub struct PayloadInfo { - /// Header length in bytes - pub header_len: usize, - /// Value length in bytes - pub value_len: usize, -} - -fn calculate_payload_info(header_bytes: &[u8], len_of_len: usize) -> Result { - let header_len = 1 + len_of_len; - match header_bytes.get(1) { - Some(&0) => return Err(DecoderError::RlpDataLenWithZeroPrefix), - None => return Err(DecoderError::RlpIsTooShort), - _ => (), - } - if header_bytes.len() < header_len { return Err(DecoderError::RlpIsTooShort); } - let value_len = decode_usize(&header_bytes[1..header_len])?; - Ok(PayloadInfo::new(header_len, value_len)) -} - -impl PayloadInfo { - fn new(header_len: usize, value_len: usize) -> PayloadInfo { - PayloadInfo { - header_len: header_len, - value_len: value_len, - } - } - - /// Total size of the RLP. - pub fn total(&self) -> usize { self.header_len + self.value_len } - - /// Create a new object from the given bytes RLP. The bytes - pub fn from(header_bytes: &[u8]) -> Result { - match header_bytes.first().cloned() { - None => Err(DecoderError::RlpIsTooShort), - Some(0...0x7f) => Ok(PayloadInfo::new(0, 1)), - Some(l @ 0x80...0xb7) => Ok(PayloadInfo::new(1, l as usize - 0x80)), - Some(l @ 0xb8...0xbf) => { - let len_of_len = l as usize - 0xb7; - calculate_payload_info(header_bytes, len_of_len) - } - Some(l @ 0xc0...0xf7) => Ok(PayloadInfo::new(1, l as usize - 0xc0)), - Some(l @ 0xf8...0xff) => { - let len_of_len = l as usize - 0xf7; - calculate_payload_info(header_bytes, len_of_len) - }, - // we cant reach this place, but rust requires _ to be implemented - _ => { unreachable!(); } - } - } -} - -/// Data-oriented view onto rlp-slice. -/// -/// This is an immutable structure. No operations change it. -/// -/// Should be used in places where, error handling is required, -/// eg. on input -#[derive(Debug)] -pub struct UntrustedRlp<'a> { - bytes: &'a [u8], - offset_cache: Cell, - count_cache: Cell>, -} - -impl<'a> Clone for UntrustedRlp<'a> { - fn clone(&self) -> UntrustedRlp<'a> { - UntrustedRlp { - bytes: self.bytes, - offset_cache: self.offset_cache.clone(), - count_cache: self.count_cache.clone(), - } - } -} - -impl<'a> fmt::Display for UntrustedRlp<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match self.prototype() { - Ok(Prototype::Null) => write!(f, "null"), - Ok(Prototype::Data(_)) => write!(f, "\"0x{}\"", self.data().unwrap().to_hex()), - Ok(Prototype::List(len)) => { - write!(f, "[")?; - for i in 0..len-1 { - write!(f, "{}, ", self.at(i).unwrap())?; - } - write!(f, "{}", self.at(len - 1).unwrap())?; - write!(f, "]") - }, - Err(err) => write!(f, "{:?}", err) - } - } -} - -impl<'a, 'view> UntrustedRlp<'a> where 'a: 'view { - pub fn new(bytes: &'a [u8]) -> UntrustedRlp<'a> { - UntrustedRlp { - bytes: bytes, - offset_cache: Cell::new(OffsetCache::new(usize::max_value(), 0)), - count_cache: Cell::new(None) - } - } - - pub fn as_raw(&'view self) -> &'a [u8] { - self.bytes - } - - pub fn prototype(&self) -> Result { - // optimize? && return appropriate errors - if self.is_data() { - Ok(Prototype::Data(self.size())) - } else if self.is_list() { - self.item_count().map(Prototype::List) - } else { - Ok(Prototype::Null) - } - } - - pub fn payload_info(&self) -> Result { - BasicDecoder::payload_info(self.bytes) - } - - pub fn data(&'view self) -> Result<&'a [u8], DecoderError> { - let pi = BasicDecoder::payload_info(self.bytes)?; - Ok(&self.bytes[pi.header_len..(pi.header_len + pi.value_len)]) - } - - pub fn item_count(&self) -> Result { - match self.is_list() { - true => match self.count_cache.get() { - Some(c) => Ok(c), - None => { - let c = self.iter().count(); - self.count_cache.set(Some(c)); - Ok(c) - } - }, - false => Err(DecoderError::RlpExpectedToBeList), - } - } - - pub fn size(&self) -> usize { - match self.is_data() { - // TODO: No panic on malformed data, but ideally would Err on no PayloadInfo. - true => BasicDecoder::payload_info(self.bytes).map(|b| b.value_len).unwrap_or(0), - false => 0 - } - } - - pub fn at(&'view self, index: usize) -> Result, DecoderError> { - if !self.is_list() { - return Err(DecoderError::RlpExpectedToBeList); - } - - // move to cached position if its index is less or equal to - // current search index, otherwise move to beginning of list - let c = self.offset_cache.get(); - let (mut bytes, to_skip) = match c.index <= index { - true => (UntrustedRlp::consume(self.bytes, c.offset)?, index - c.index), - false => (self.consume_list_payload()?, index), - }; - - // skip up to x items - bytes = UntrustedRlp::consume_items(bytes, to_skip)?; - - // update the cache - self.offset_cache.set(OffsetCache::new(index, self.bytes.len() - bytes.len())); - - // construct new rlp - let found = BasicDecoder::payload_info(bytes)?; - Ok(UntrustedRlp::new(&bytes[0..found.header_len + found.value_len])) - } - - pub fn is_null(&self) -> bool { - self.bytes.len() == 0 - } - - pub fn is_empty(&self) -> bool { - !self.is_null() && (self.bytes[0] == 0xc0 || self.bytes[0] == 0x80) - } - - pub fn is_list(&self) -> bool { - !self.is_null() && self.bytes[0] >= 0xc0 - } - - pub fn is_data(&self) -> bool { - !self.is_null() && self.bytes[0] < 0xc0 - } - - pub fn is_int(&self) -> bool { - if self.is_null() { - return false; - } - - match self.bytes[0] { - 0...0x80 => true, - 0x81...0xb7 => self.bytes[1] != 0, - b @ 0xb8...0xbf => self.bytes[1 + b as usize - 0xb7] != 0, - _ => false - } - } - - pub fn iter(&'view self) -> UntrustedRlpIterator<'a, 'view> { - self.into_iter() - } - - pub fn as_val(&self) -> Result where T: Decodable { - T::decode(self) - } - - pub fn as_list(&self) -> Result, DecoderError> where T: Decodable { - self.iter().map(|rlp| rlp.as_val()).collect() - } - - pub fn val_at(&self, index: usize) -> Result where T: Decodable { - self.at(index)?.as_val() - } - - pub fn list_at(&self, index: usize) -> Result, DecoderError> where T: Decodable { - self.at(index)?.as_list() - } - - pub fn decoder(&self) -> BasicDecoder { - BasicDecoder::new(self.clone()) - } - - /// consumes first found prefix - fn consume_list_payload(&self) -> Result<&'a [u8], DecoderError> { - let item = BasicDecoder::payload_info(self.bytes)?; - let bytes = UntrustedRlp::consume(self.bytes, item.header_len)?; - Ok(bytes) - } - - /// consumes fixed number of items - fn consume_items(bytes: &'a [u8], items: usize) -> Result<&'a [u8], DecoderError> { - let mut result = bytes; - for _ in 0..items { - let i = BasicDecoder::payload_info(result)?; - result = UntrustedRlp::consume(result, i.header_len + i.value_len)?; - } - Ok(result) - } - - - /// consumes slice prefix of length `len` - fn consume(bytes: &'a [u8], len: usize) -> Result<&'a [u8], DecoderError> { - match bytes.len() >= len { - true => Ok(&bytes[len..]), - false => Err(DecoderError::RlpIsTooShort), - } - } -} - -/// Iterator over rlp-slice list elements. -pub struct UntrustedRlpIterator<'a, 'view> where 'a: 'view { - rlp: &'view UntrustedRlp<'a>, - index: usize, -} - -impl<'a, 'view> IntoIterator for &'view UntrustedRlp<'a> where 'a: 'view { - type Item = UntrustedRlp<'a>; - type IntoIter = UntrustedRlpIterator<'a, 'view>; - - fn into_iter(self) -> Self::IntoIter { - UntrustedRlpIterator { - rlp: self, - index: 0, - } - } -} - -impl<'a, 'view> Iterator for UntrustedRlpIterator<'a, 'view> { - type Item = UntrustedRlp<'a>; - - fn next(&mut self) -> Option> { - let index = self.index; - let result = self.rlp.at(index).ok(); - self.index += 1; - result - } -} - -pub struct BasicDecoder<'a> { - rlp: UntrustedRlp<'a> -} - -impl<'a> BasicDecoder<'a> { - pub fn new(rlp: UntrustedRlp<'a>) -> BasicDecoder<'a> { - BasicDecoder { - rlp: rlp - } - } - - /// Return first item info. - fn payload_info(bytes: &[u8]) -> Result { - let item = PayloadInfo::from(bytes)?; - match item.header_len.checked_add(item.value_len) { - Some(x) if x <= bytes.len() => Ok(item), - _ => Err(DecoderError::RlpIsTooShort), - } - } - - pub fn decode_value(&self, f: F) -> Result - where F: Fn(&[u8]) -> Result { - - let bytes = self.rlp.as_raw(); - - match bytes.first().cloned() { - // RLP is too short. - None => Err(DecoderError::RlpIsTooShort), - // Single byte value. - Some(l @ 0...0x7f) => Ok(f(&[l])?), - // 0-55 bytes - Some(l @ 0x80...0xb7) => { - let last_index_of = 1 + l as usize - 0x80; - if bytes.len() < last_index_of { - return Err(DecoderError::RlpInconsistentLengthAndData); - } - let d = &bytes[1..last_index_of]; - if l == 0x81 && d[0] < 0x80 { - return Err(DecoderError::RlpInvalidIndirection); - } - Ok(f(d)?) - }, - // Longer than 55 bytes. - Some(l @ 0xb8...0xbf) => { - let len_of_len = l as usize - 0xb7; - let begin_of_value = 1 as usize + len_of_len; - if bytes.len() < begin_of_value { - return Err(DecoderError::RlpInconsistentLengthAndData); - } - let len = decode_usize(&bytes[1..begin_of_value])?; - - let last_index_of_value = begin_of_value.checked_add(len) - .ok_or(DecoderError::RlpInvalidLength)?; - if bytes.len() < last_index_of_value { - return Err(DecoderError::RlpInconsistentLengthAndData); - } - Ok(f(&bytes[begin_of_value..last_index_of_value])?) - } - // We are reading value, not a list! - _ => Err(DecoderError::RlpExpectedToBeData) - } - } -} - -#[cfg(test)] -mod tests { - use {UntrustedRlp, DecoderError}; - - #[test] - fn test_rlp_display() { - use rustc_hex::FromHex; - let data = "f84d0589010efbef67941f79b2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470".from_hex().unwrap(); - let rlp = UntrustedRlp::new(&data); - assert_eq!(format!("{}", rlp), "[\"0x05\", \"0x010efbef67941f79b2\", \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\", \"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\"]"); - } - - #[test] - fn length_overflow() { - let bs = [0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5]; - let rlp = UntrustedRlp::new(&bs); - let res: Result = rlp.as_val(); - assert_eq!(Err(DecoderError::RlpInvalidLength), res); - } -} diff --git a/util/rlp/tests/tests.rs b/util/rlp/tests/tests.rs index 03151c5bf..6ff426a77 100644 --- a/util/rlp/tests/tests.rs +++ b/util/rlp/tests/tests.rs @@ -11,13 +11,13 @@ extern crate rlp; use std::{fmt, cmp}; use bigint::{U256, H160}; -use rlp::{Encodable, Decodable, UntrustedRlp, RlpStream, DecoderError}; +use rlp::{Encodable, Decodable, Rlp, RlpStream, DecoderError}; #[test] fn rlp_at() { let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; { - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); assert!(rlp.is_list()); let animals: Vec = rlp.as_list().unwrap(); assert_eq!(animals, vec!["cat".to_owned(), "dog".to_owned()]); @@ -43,7 +43,7 @@ fn rlp_at() { fn rlp_at_err() { let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o']; { - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); assert!(rlp.is_list()); let cat_err = rlp.at(0).unwrap_err(); @@ -58,7 +58,7 @@ fn rlp_at_err() { fn rlp_iter() { let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; { - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); let mut iter = rlp.iter(); let cat = iter.next().unwrap(); @@ -337,7 +337,7 @@ fn decode_untrusted_vector_str() { fn test_rlp_data_length_check() { let data = vec![0x84, b'c', b'a', b't']; - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); let as_val: Result = rlp.as_val(); assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val); @@ -351,7 +351,7 @@ fn test_rlp_long_data_length_check() data.push(b'c'); } - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); let as_val: Result = rlp.as_val(); assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val); @@ -365,7 +365,7 @@ fn test_the_exact_long_string() data.push(b'c'); } - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); let as_val: Result = rlp.as_val(); assert!(as_val.is_ok()); @@ -379,7 +379,7 @@ fn test_rlp_2bytes_data_length_check() data.push(b'c'); } - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); let as_val: Result = rlp.as_val(); assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val); @@ -396,7 +396,7 @@ fn test_rlp_nested_empty_list_encode() { #[test] fn test_rlp_list_length_overflow() { let data: Vec = vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00]; - let rlp = UntrustedRlp::new(&data); + let rlp = Rlp::new(&data); let as_val: Result = rlp.val_at(0); assert_eq!(Err(DecoderError::RlpIsTooShort), as_val); } diff --git a/util/rlp_compress/src/lib.rs b/util/rlp_compress/src/lib.rs index 89c5e8328..b895e1ce1 100644 --- a/util/rlp_compress/src/lib.rs +++ b/util/rlp_compress/src/lib.rs @@ -16,7 +16,7 @@ mod common; use std::cmp; use std::collections::HashMap; use elastic_array::ElasticArray1024; -use rlp::{UntrustedRlp, RlpStream}; +use rlp::{Rlp, RlpStream}; use common::{SNAPSHOT_SWAPPER, BLOCKS_SWAPPER}; pub fn snapshot_swapper() -> &'static Swapper<'static> { @@ -41,7 +41,7 @@ pub trait Decompressor { /// Call this function to compress rlp. pub fn compress(c: &[u8], swapper: &Compressor) -> ElasticArray1024 { - let rlp = UntrustedRlp::new(c); + let rlp = Rlp::new(c); if rlp.is_data() { ElasticArray1024::from_slice(swapper.compressed(rlp.as_raw()).unwrap_or_else(|| rlp.as_raw())) } else { @@ -51,7 +51,7 @@ pub fn compress(c: &[u8], swapper: &Compressor) -> ElasticArray1024 { /// Call this function to decompress rlp. pub fn decompress(c: &[u8], swapper: &Decompressor) -> ElasticArray1024 { - let rlp = UntrustedRlp::new(c); + let rlp = Rlp::new(c); if rlp.is_data() { ElasticArray1024::from_slice(swapper.decompressed(rlp.as_raw()).unwrap_or_else(|| rlp.as_raw())) } else { @@ -59,7 +59,7 @@ pub fn decompress(c: &[u8], swapper: &Decompressor) -> ElasticArray1024 { } } -fn map_rlp ElasticArray1024>(rlp: &UntrustedRlp, f: F) -> ElasticArray1024 { +fn map_rlp ElasticArray1024>(rlp: &Rlp, f: F) -> ElasticArray1024 { let mut stream = RlpStream::new_list(rlp.item_count().unwrap_or_default()); for subrlp in rlp.iter() { stream.append_raw(&f(&subrlp), 1); diff --git a/util/rlp_derive/src/de.rs b/util/rlp_derive/src/de.rs index 7432d3e2e..dac4e34cd 100644 --- a/util/rlp_derive/src/de.rs +++ b/util/rlp_derive/src/de.rs @@ -35,7 +35,7 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> quote::Tokens { let dummy_const: syn::Ident = format!("_IMPL_RLP_DECODABLE_FOR_{}", name).into(); let impl_block = quote! { impl rlp::Decodable for #name { - fn decode(rlp: &rlp::UntrustedRlp) -> Result { + fn decode(rlp: &rlp::Rlp) -> Result { let result = #name { #(#stmts)* }; @@ -75,7 +75,7 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> quote::Tokens { let dummy_const: syn::Ident = format!("_IMPL_RLP_DECODABLE_FOR_{}", name).into(); let impl_block = quote! { impl rlp::Decodable for #name { - fn decode(rlp: &rlp::UntrustedRlp) -> Result { + fn decode(rlp: &rlp::Rlp) -> Result { let result = #name { #stmt }; diff --git a/whisper/src/message.rs b/whisper/src/message.rs index 126acebd2..fbf2faf3f 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -20,7 +20,7 @@ use std::fmt; use std::time::{self, SystemTime, Duration, Instant}; use ethereum_types::{H256, H512}; -use rlp::{self, DecoderError, RlpStream, UntrustedRlp}; +use rlp::{self, DecoderError, RlpStream, Rlp}; use smallvec::SmallVec; use tiny_keccak::{keccak256, Keccak}; @@ -85,7 +85,7 @@ impl rlp::Encodable for Topic { } impl rlp::Decodable for Topic { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { use std::cmp; rlp.decoder().decode_value(|bytes| match bytes.len().cmp(&4) { @@ -145,7 +145,7 @@ fn append_topics<'a>(s: &'a mut RlpStream, topics: &[Topic]) -> &'a mut RlpStrea } } -fn decode_topics(rlp: UntrustedRlp) -> Result, DecoderError> { +fn decode_topics(rlp: Rlp) -> Result, DecoderError> { if rlp.is_list() { rlp.iter().map(|r| r.as_val::()).collect() } else { @@ -212,7 +212,7 @@ impl rlp::Encodable for Envelope { } impl rlp::Decodable for Envelope { - fn decode(rlp: &UntrustedRlp) -> Result { + fn decode(rlp: &Rlp) -> Result { if rlp.item_count()? != 5 { return Err(DecoderError::RlpIncorrectListLen) } Ok(Envelope { @@ -332,7 +332,7 @@ impl Message { } /// Decode message from RLP and check for validity against system time. - pub fn decode(rlp: UntrustedRlp, now: SystemTime) -> Result { + pub fn decode(rlp: Rlp, now: SystemTime) -> Result { let envelope: Envelope = rlp.as_val()?; let encoded_size = rlp.as_raw().len(); let hash = H256(keccak256(rlp.as_raw())); @@ -418,7 +418,7 @@ impl Message { mod tests { use super::*; use std::time::{self, Duration, SystemTime}; - use rlp::UntrustedRlp; + use rlp::Rlp; use smallvec::SmallVec; fn unix_time(x: u64) -> SystemTime { @@ -481,7 +481,7 @@ mod tests { for i in 0..30 { let now = unix_time(100_000 - i); - Message::decode(UntrustedRlp::new(&*encoded), now).unwrap(); + Message::decode(Rlp::new(&*encoded), now).unwrap(); } } @@ -499,7 +499,7 @@ mod tests { let encoded = ::rlp::encode(&envelope); let now = unix_time(100_000 - 1_000); - Message::decode(UntrustedRlp::new(&*encoded), now).unwrap(); + Message::decode(Rlp::new(&*encoded), now).unwrap(); } #[test] @@ -516,6 +516,6 @@ mod tests { let encoded = ::rlp::encode(&envelope); let now = unix_time(95_000); - Message::decode(UntrustedRlp::new(&*encoded), now).unwrap(); + Message::decode(Rlp::new(&*encoded), now).unwrap(); } } diff --git a/whisper/src/net/mod.rs b/whisper/src/net/mod.rs index dd5e345bc..fc6138cf1 100644 --- a/whisper/src/net/mod.rs +++ b/whisper/src/net/mod.rs @@ -26,7 +26,7 @@ use ethereum_types::{H256, H512}; use network::{self, HostInfo, NetworkContext, NodeId, PeerId, ProtocolId, TimerToken}; use ordered_float::OrderedFloat; use parking_lot::{Mutex, RwLock}; -use rlp::{DecoderError, RlpStream, UntrustedRlp}; +use rlp::{DecoderError, RlpStream, Rlp}; use message::{Message, Error as MessageError}; @@ -506,7 +506,7 @@ impl Network { } // handle status packet from peer. - fn on_status(&self, peer: &PeerId, _status: UntrustedRlp) + fn on_status(&self, peer: &PeerId, _status: Rlp) -> Result<(), Error> { let peers = self.peers.read(); @@ -523,7 +523,7 @@ impl Network { } } - fn on_messages(&self, peer: &PeerId, message_packet: UntrustedRlp) + fn on_messages(&self, peer: &PeerId, message_packet: Rlp) -> Result<(), Error> { let mut messages_vec = { @@ -568,7 +568,7 @@ impl Network { Ok(()) } - fn on_pow_requirement(&self, peer: &PeerId, requirement: UntrustedRlp) + fn on_pow_requirement(&self, peer: &PeerId, requirement: Rlp) -> Result<(), Error> { use byteorder::{ByteOrder, BigEndian}; @@ -604,7 +604,7 @@ impl Network { Ok(()) } - fn on_topic_filter(&self, peer: &PeerId, filter: UntrustedRlp) + fn on_topic_filter(&self, peer: &PeerId, filter: Rlp) -> Result<(), Error> { let peers = self.peers.read(); @@ -661,7 +661,7 @@ impl Network { } fn on_packet(&self, io: &C, peer: &PeerId, packet_id: u8, data: &[u8]) { - let rlp = UntrustedRlp::new(data); + let rlp = Rlp::new(data); let res = match packet_id { packet::STATUS => self.on_status(peer, rlp), packet::MESSAGES => self.on_messages(peer, rlp),