Merge branch 'master' into pip-msg
This commit is contained in:
		
						commit
						a0619fc101
					
				| @ -23,7 +23,7 @@ | ||||
| use ethcore::ids::BlockId; | ||||
| use util::{Bytes, H256, U256, HashDB, MemoryDB}; | ||||
| use util::trie::{self, TrieMut, TrieDBMut, Trie, TrieDB, Recorder}; | ||||
| use rlp::{RlpStream, UntrustedRlp, View}; | ||||
| use rlp::{RlpStream, UntrustedRlp}; | ||||
| 
 | ||||
| // encode a key.
 | ||||
| macro_rules! key { | ||||
|  | ||||
| @ -22,7 +22,7 @@ use ethcore::transaction::UnverifiedTransaction; | ||||
| 
 | ||||
| use io::TimerToken; | ||||
| use network::{NetworkProtocolHandler, NetworkContext, PeerId}; | ||||
| use rlp::{RlpStream, UntrustedRlp, View}; | ||||
| use rlp::{RlpStream, UntrustedRlp}; | ||||
| use util::hash::H256; | ||||
| use util::{DBValue, Mutex, RwLock, U256}; | ||||
| use time::{Duration, SteadyTime}; | ||||
| @ -723,7 +723,7 @@ impl LightProtocol { | ||||
| 	fn response(&self, peer: &PeerId, io: &IoContext, raw: UntrustedRlp) -> Result<(), Error> { | ||||
| 		let (req_id, responses) = { | ||||
| 			let id_guard = self.pre_verify_response(peer, &raw)?; | ||||
| 			let responses: Vec<Response> = raw.val_at(2)?; | ||||
| 			let responses: Vec<Response> = raw.list_at(2)?; | ||||
| 			(id_guard.defuse(), responses) | ||||
| 		}; | ||||
| 
 | ||||
|  | ||||
| @ -127,8 +127,7 @@ impl Encodable for CostTable { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for CostTable { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let base = rlp.val_at(0)?; | ||||
| 
 | ||||
| 		let mut headers = None; | ||||
|  | ||||
| @ -16,7 +16,7 @@ | ||||
| 
 | ||||
| //! Peer status and capabilities.
 | ||||
| 
 | ||||
| use rlp::{DecoderError, RlpDecodable, Encodable, RlpStream, UntrustedRlp, View}; | ||||
| use rlp::{DecoderError, Encodable, Decodable, RlpStream, UntrustedRlp}; | ||||
| use util::{H256, U256}; | ||||
| 
 | ||||
| use super::request_credits::FlowParams; | ||||
| @ -91,7 +91,7 @@ struct Parser<'a> { | ||||
| impl<'a> Parser<'a> { | ||||
| 	// expect a specific next key, and decode the value.
 | ||||
| 	// error on unexpected key or invalid value.
 | ||||
| 	fn expect<T: RlpDecodable>(&mut self, key: Key) -> Result<T, DecoderError> { | ||||
| 	fn expect<T: Decodable>(&mut self, key: Key) -> Result<T, DecoderError> { | ||||
| 		self.expect_raw(key).and_then(|item| item.as_val()) | ||||
| 	} | ||||
| 
 | ||||
| @ -110,7 +110,7 @@ impl<'a> Parser<'a> { | ||||
| 
 | ||||
| 	// get the next key and value RLP.
 | ||||
| 	fn get_next(&mut self) -> Result<Option<(Key, UntrustedRlp<'a>)>, DecoderError> { | ||||
| 		while self.pos < self.rlp.item_count() { | ||||
| 		while self.pos < self.rlp.item_count()? { | ||||
| 			let pair = self.rlp.at(self.pos)?; | ||||
| 			let k: String = pair.val_at(0)?; | ||||
| 
 | ||||
| @ -374,7 +374,7 @@ mod tests { | ||||
| 	use super::*; | ||||
| 	use super::super::request_credits::FlowParams; | ||||
| 	use util::{U256, H256}; | ||||
| 	use rlp::{RlpStream, UntrustedRlp, View}; | ||||
| 	use rlp::{RlpStream, UntrustedRlp}; | ||||
| 
 | ||||
| 	#[test] | ||||
| 	fn full_handshake() { | ||||
| @ -474,7 +474,7 @@ mod tests { | ||||
| 		let handshake = write_handshake(&status, &capabilities, Some(&flow_params)); | ||||
| 		let interleaved = { | ||||
| 			let handshake = UntrustedRlp::new(&handshake); | ||||
| 			let mut stream = RlpStream::new_list(handshake.item_count() * 3); | ||||
| 			let mut stream = RlpStream::new_list(handshake.item_count().unwrap_or(0) * 3); | ||||
| 
 | ||||
| 			for item in handshake.iter() { | ||||
| 				stream.append_raw(item.as_raw(), 1); | ||||
|  | ||||
| @ -26,7 +26,7 @@ use ethcore::receipt::Receipt; | ||||
| use ethcore::state::{self, ProvedExecution}; | ||||
| use ethcore::transaction::SignedTransaction; | ||||
| 
 | ||||
| use rlp::{RlpStream, UntrustedRlp, View}; | ||||
| use rlp::{RlpStream, UntrustedRlp}; | ||||
| use util::{Address, Bytes, DBValue, HashDB, H256, U256}; | ||||
| use util::memorydb::MemoryDB; | ||||
| use util::sha3::Hashable; | ||||
|  | ||||
| @ -153,7 +153,7 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T { | ||||
| 
 | ||||
| 	fn block_receipts(&self, req: request::CompleteReceiptsRequest) -> Option<request::ReceiptsResponse> { | ||||
| 		BlockChainClient::block_receipts(self, &req.hash) | ||||
| 			.map(|x| ::request::ReceiptsResponse { receipts: ::rlp::decode(&x) }) | ||||
| 			.map(|x| ::request::ReceiptsResponse { receipts: ::rlp::decode_list(&x) }) | ||||
| 	} | ||||
| 
 | ||||
| 	fn account_proof(&self, req: request::CompleteAccountRequest) -> Option<request::AccountResponse> { | ||||
|  | ||||
| @ -16,7 +16,7 @@ | ||||
| 
 | ||||
| //! Light protocol request types.
 | ||||
| 
 | ||||
| use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| use util::H256; | ||||
| 
 | ||||
| mod builder; | ||||
| @ -105,9 +105,7 @@ impl<T> From<T> for Field<T> { | ||||
| } | ||||
| 
 | ||||
| impl<T: Decodable> Decodable for Field<T> { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		match rlp.val_at::<u8>(0)? { | ||||
| 			0 => Ok(Field::Scalar(rlp.val_at::<T>(1)?)), | ||||
| 			1 => Ok({ | ||||
| @ -184,9 +182,7 @@ impl From<u64> for HashOrNumber { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for HashOrNumber { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		rlp.as_val::<H256>().map(HashOrNumber::Hash) | ||||
| 			.or_else(|_| rlp.as_val().map(HashOrNumber::Number)) | ||||
| 	} | ||||
| @ -263,9 +259,7 @@ impl Request { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Request { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		match rlp.val_at::<Kind>(0)? { | ||||
| 			Kind::Headers => Ok(Request::Headers(rlp.val_at(1)?)), | ||||
| 			Kind::HeaderProof => Ok(Request::HeaderProof(rlp.val_at(1)?)), | ||||
| @ -382,9 +376,7 @@ pub enum Kind { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Kind { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		match rlp.as_val::<u8>()? { | ||||
| 			0 => Ok(Kind::Headers), | ||||
| 			1 => Ok(Kind::HeaderProof), | ||||
| @ -458,9 +450,7 @@ impl Response { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Response { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		match rlp.val_at::<Kind>(0)? { | ||||
| 			Kind::Headers => Ok(Response::Headers(rlp.val_at(1)?)), | ||||
| 			Kind::HeaderProof => Ok(Response::HeaderProof(rlp.val_at(1)?)), | ||||
| @ -525,7 +515,7 @@ pub trait IncompleteRequest: Sized { | ||||
| pub mod header { | ||||
| 	use super::{Field, HashOrNumber, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::encoded; | ||||
| 	use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| 	use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| 
 | ||||
| 	/// Potentially incomplete headers request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| @ -541,8 +531,7 @@ pub mod header { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Incomplete { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Incomplete { | ||||
| 				start: rlp.val_at(0)?, | ||||
| 				skip: rlp.val_at(1)?, | ||||
| @ -623,9 +612,8 @@ pub mod header { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Response { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			use ethcore::header::Header as FullHeader; | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 			let mut headers = Vec::new(); | ||||
| 
 | ||||
| @ -655,7 +643,7 @@ pub mod header { | ||||
| /// Request and response for header proofs.
 | ||||
| pub mod header_proof { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| 	use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| 	use util::{Bytes, U256, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete header proof request.
 | ||||
| @ -666,8 +654,7 @@ pub mod header_proof { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Incomplete { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Incomplete { | ||||
| 				num: rlp.val_at(0)?, | ||||
| 			}) | ||||
| @ -738,11 +725,10 @@ pub mod header_proof { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Response { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 
 | ||||
| 			Ok(Response { | ||||
| 				proof: rlp.val_at(0)?, | ||||
| 				proof: rlp.list_at(0)?, | ||||
| 				hash: rlp.val_at(1)?, | ||||
| 				td: rlp.val_at(2)?, | ||||
| 			}) | ||||
| @ -765,7 +751,7 @@ pub mod header_proof { | ||||
| pub mod block_receipts { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::receipt::Receipt; | ||||
| 	use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| 	use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| 	use util::H256; | ||||
| 
 | ||||
| 	/// Potentially incomplete block receipts request.
 | ||||
| @ -776,8 +762,7 @@ pub mod block_receipts { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Incomplete { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Incomplete { | ||||
| 				hash: rlp.val_at(0)?, | ||||
| 			}) | ||||
| @ -840,11 +825,10 @@ pub mod block_receipts { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Response { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 
 | ||||
| 			Ok(Response { | ||||
| 				receipts: rlp.as_val()?, | ||||
| 				receipts: rlp.as_list()?, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
| @ -860,7 +844,7 @@ pub mod block_receipts { | ||||
| pub mod block_body { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::encoded; | ||||
| 	use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| 	use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| 	use util::H256; | ||||
| 
 | ||||
| 	/// Potentially incomplete block body request.
 | ||||
| @ -871,8 +855,7 @@ pub mod block_body { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Incomplete { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Incomplete { | ||||
| 				hash: rlp.val_at(0)?, | ||||
| 			}) | ||||
| @ -935,15 +918,13 @@ pub mod block_body { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Response { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			use ethcore::header::Header as FullHeader; | ||||
| 			use ethcore::transaction::UnverifiedTransaction; | ||||
| 
 | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 			// check body validity.
 | ||||
| 			let _: Vec<FullHeader> = rlp.val_at(0)?; | ||||
| 			let _: Vec<UnverifiedTransaction> = rlp.val_at(1)?; | ||||
| 			let _: Vec<FullHeader> = rlp.list_at(0)?; | ||||
| 			let _: Vec<UnverifiedTransaction> = rlp.list_at(1)?; | ||||
| 
 | ||||
| 			Ok(Response { | ||||
| 				body: encoded::Body::new(rlp.as_raw().to_owned()), | ||||
| @ -961,7 +942,7 @@ pub mod block_body { | ||||
| /// A request for an account proof.
 | ||||
| pub mod account { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| 	use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| 	use util::{Bytes, U256, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete request for an account proof.
 | ||||
| @ -974,8 +955,7 @@ pub mod account { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Incomplete { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Incomplete { | ||||
| 				block_hash: rlp.val_at(0)?, | ||||
| 				address_hash: rlp.val_at(1)?, | ||||
| @ -1070,11 +1050,9 @@ pub mod account { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Response { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Response { | ||||
| 				proof: rlp.val_at(0)?, | ||||
| 				proof: rlp.list_at(0)?, | ||||
| 				nonce: rlp.val_at(1)?, | ||||
| 				balance: rlp.val_at(2)?, | ||||
| 				code_hash: rlp.val_at(3)?, | ||||
| @ -1101,7 +1079,7 @@ pub mod account { | ||||
| /// A request for a storage proof.
 | ||||
| pub mod storage { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| 	use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| 	use util::{Bytes, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete request for an storage proof.
 | ||||
| @ -1116,8 +1094,7 @@ pub mod storage { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Incomplete { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Incomplete { | ||||
| 				block_hash: rlp.val_at(0)?, | ||||
| 				address_hash: rlp.val_at(1)?, | ||||
| @ -1220,11 +1197,9 @@ pub mod storage { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Response { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 
 | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Response { | ||||
| 				proof: rlp.val_at(0)?, | ||||
| 				proof: rlp.list_at(0)?, | ||||
| 				value: rlp.val_at(1)?, | ||||
| 			}) | ||||
| 		} | ||||
| @ -1244,7 +1219,7 @@ pub mod storage { | ||||
| /// A request for contract code.
 | ||||
| pub mod contract_code { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| 	use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| 	use util::{Bytes, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete contract code request.
 | ||||
| @ -1257,8 +1232,7 @@ pub mod contract_code { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Incomplete { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Incomplete { | ||||
| 				block_hash: rlp.val_at(0)?, | ||||
| 				code_hash: rlp.val_at(1)?, | ||||
| @ -1338,8 +1312,7 @@ pub mod contract_code { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Response { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 
 | ||||
| 			Ok(Response { | ||||
| 				code: rlp.as_val()?, | ||||
| @ -1358,7 +1331,7 @@ pub mod contract_code { | ||||
| pub mod execution { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::transaction::Action; | ||||
| 	use rlp::{Encodable, Decodable, Decoder, DecoderError, RlpStream, View}; | ||||
| 	use rlp::{Encodable, Decodable, DecoderError, RlpStream, UntrustedRlp}; | ||||
| 	use util::{Bytes, Address, U256, H256, DBValue}; | ||||
| 
 | ||||
| 	/// Potentially incomplete execution proof request.
 | ||||
| @ -1381,8 +1354,7 @@ pub mod execution { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Incomplete { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			Ok(Incomplete { | ||||
| 				block_hash: rlp.val_at(0)?, | ||||
| 				from: rlp.val_at(1)?, | ||||
| @ -1481,8 +1453,7 @@ pub mod execution { | ||||
| 	} | ||||
| 
 | ||||
| 	impl Decodable for Response { | ||||
| 		fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 			let rlp = decoder.as_rlp(); | ||||
| 		fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 			let mut items = Vec::new(); | ||||
| 			for raw_item in rlp.iter() { | ||||
| 				let mut item = DBValue::new(); | ||||
| @ -1734,6 +1705,6 @@ mod tests { | ||||
| 
 | ||||
| 		let rlp = UntrustedRlp::new(&out); | ||||
| 		assert_eq!(rlp.val_at::<usize>(0).unwrap(), 100usize); | ||||
| 		assert_eq!(rlp.val_at::<Vec<Request>>(1).unwrap(), reqs); | ||||
| 		assert_eq!(rlp.list_at::<Request>(1).unwrap(), reqs); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -20,7 +20,7 @@ use std::cmp; | ||||
| use std::sync::Arc; | ||||
| use std::collections::HashSet; | ||||
| 
 | ||||
| use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, Decoder, DecoderError, View}; | ||||
| use rlp::{UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError}; | ||||
| use util::{Bytes, Address, Uint, Hashable, U256, H256, ordered_trie_root, SHA3_NULL_RLP}; | ||||
| use util::error::{Mismatch, OutOfBounds}; | ||||
| 
 | ||||
| @ -67,18 +67,17 @@ impl Block { | ||||
| 
 | ||||
| 
 | ||||
| impl Decodable for Block { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		if decoder.as_raw().len() != decoder.as_rlp().payload_info()?.total() { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		if rlp.as_raw().len() != rlp.payload_info()?.total() { | ||||
| 			return Err(DecoderError::RlpIsTooBig); | ||||
| 		} | ||||
| 		let d = decoder.as_rlp(); | ||||
| 		if d.item_count() != 3 { | ||||
| 		if rlp.item_count()? != 3 { | ||||
| 			return Err(DecoderError::RlpIncorrectListLen); | ||||
| 		} | ||||
| 		Ok(Block { | ||||
| 			header: d.val_at(0)?, | ||||
| 			transactions: d.val_at(1)?, | ||||
| 			uncles: d.val_at(2)?, | ||||
| 			header: rlp.val_at(0)?, | ||||
| 			transactions: rlp.list_at(1)?, | ||||
| 			uncles: rlp.list_at(2)?, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -154,13 +154,12 @@ impl HeapSizeOf for BlockDetails { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for BlockDetails { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let details = BlockDetails { | ||||
| 			number: d.val_at(0)?, | ||||
| 			total_difficulty: d.val_at(1)?, | ||||
| 			parent: d.val_at(2)?, | ||||
| 			children: d.val_at(3)?, | ||||
| 			number: rlp.val_at(0)?, | ||||
| 			total_difficulty: rlp.val_at(1)?, | ||||
| 			parent: rlp.val_at(2)?, | ||||
| 			children: rlp.list_at(3)?, | ||||
| 		}; | ||||
| 		Ok(details) | ||||
| 	} | ||||
| @ -190,11 +189,10 @@ impl HeapSizeOf for TransactionAddress { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for TransactionAddress { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let tx_address = TransactionAddress { | ||||
| 			block_hash: d.val_at(0)?, | ||||
| 			index: d.val_at(1)?, | ||||
| 			block_hash: rlp.val_at(0)?, | ||||
| 			index: rlp.val_at(1)?, | ||||
| 		}; | ||||
| 
 | ||||
| 		Ok(tx_address) | ||||
| @ -224,9 +222,9 @@ impl BlockReceipts { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for BlockReceipts { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		Ok(BlockReceipts { | ||||
| 			receipts: Decodable::decode(decoder)? | ||||
| 			receipts: rlp.as_list()?, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -44,8 +44,8 @@ impl Into<bc::Bloom> for Bloom { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Bloom { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		Decodable::decode(decoder).map(Bloom) | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		LogBloom::decode(rlp).map(Bloom) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -52,8 +52,8 @@ impl Into<bc::BloomGroup> for BloomGroup { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for BloomGroup { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let blooms = Decodable::decode(decoder)?; | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let blooms = rlp.as_list()?; | ||||
| 		let group = BloomGroup { | ||||
| 			blooms: blooms | ||||
| 		}; | ||||
|  | ||||
| @ -66,7 +66,7 @@ use evm::{Factory as EvmFactory, Schedule}; | ||||
| use miner::{Miner, MinerService, TransactionImportResult}; | ||||
| use snapshot::{self, io as snapshot_io}; | ||||
| use factory::Factories; | ||||
| use rlp::{View, UntrustedRlp}; | ||||
| use rlp::UntrustedRlp; | ||||
| use state_db::StateDB; | ||||
| use rand::OsRng; | ||||
| use client::registry::Registry; | ||||
| @ -539,7 +539,7 @@ impl Client { | ||||
| 			)?; | ||||
| 
 | ||||
| 			// Commit results
 | ||||
| 			let receipts = ::rlp::decode(&receipts_bytes); | ||||
| 			let receipts = ::rlp::decode_list(&receipts_bytes); | ||||
| 			let mut batch = DBTransaction::new(); | ||||
| 			chain.insert_unordered_block(&mut batch, &block_bytes, receipts, None, false, true); | ||||
| 			// Final commit to the DB
 | ||||
|  | ||||
| @ -21,7 +21,7 @@ use std::sync::Weak; | ||||
| use std::time::{UNIX_EPOCH, Duration}; | ||||
| use util::*; | ||||
| use ethkey::{verify_address, Signature}; | ||||
| use rlp::{UntrustedRlp, View, encode}; | ||||
| use rlp::{UntrustedRlp, encode}; | ||||
| use account_provider::AccountProvider; | ||||
| use block::*; | ||||
| use spec::CommonParams; | ||||
|  | ||||
| @ -138,7 +138,7 @@ impl Engine for BasicAuthority { | ||||
| 	} | ||||
| 
 | ||||
| 	fn verify_block_family(&self, header: &Header, parent: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> { | ||||
| 		use rlp::{UntrustedRlp, View}; | ||||
| 		use rlp::UntrustedRlp; | ||||
| 		// Check if the signature belongs to a validator, can depend on parent state.
 | ||||
| 		let sig = UntrustedRlp::new(&header.seal()[0]).as_val::<H520>()?; | ||||
| 		let signer = public_to_address(&recover(&sig.into(), &header.bare_hash())?); | ||||
|  | ||||
| @ -20,7 +20,7 @@ use util::*; | ||||
| use super::{Height, View, BlockHash, Step}; | ||||
| use error::Error; | ||||
| use header::Header; | ||||
| use rlp::{Rlp, UntrustedRlp, RlpStream, Encodable, Decodable, Decoder, DecoderError, View as RlpView}; | ||||
| use rlp::{Rlp, UntrustedRlp, RlpStream, Encodable, Decodable, DecoderError}; | ||||
| use ethkey::{recover, public_to_address}; | ||||
| use super::super::vote_collector::Message; | ||||
| 
 | ||||
| @ -150,8 +150,8 @@ impl Step { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Step { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		match decoder.as_rlp().as_val()? { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		match rlp.as_val()? { | ||||
| 			0u8 => Ok(Step::Propose), | ||||
| 			1 => Ok(Step::Prevote), | ||||
| 			2 => Ok(Step::Precommit), | ||||
| @ -168,8 +168,7 @@ impl Encodable for Step { | ||||
| 
 | ||||
| /// (signature, (height, view, step, block_hash))
 | ||||
| impl Decodable for ConsensusMessage { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let m = rlp.at(1)?; | ||||
| 		let block_message: H256 = m.val_at(3)?; | ||||
| 		Ok(ConsensusMessage { | ||||
|  | ||||
| @ -33,7 +33,7 @@ use error::{Error, BlockError}; | ||||
| use header::Header; | ||||
| use builtin::Builtin; | ||||
| use env_info::EnvInfo; | ||||
| use rlp::{UntrustedRlp, View as RlpView}; | ||||
| use rlp::UntrustedRlp; | ||||
| use ethkey::{recover, public_to_address, Signature}; | ||||
| use account_provider::AccountProvider; | ||||
| use block::*; | ||||
|  | ||||
| @ -27,7 +27,7 @@ use transaction::UnverifiedTransaction; | ||||
| use engines::Engine; | ||||
| use evm::Schedule; | ||||
| use ethjson; | ||||
| use rlp::{self, UntrustedRlp, View}; | ||||
| use rlp::{self, UntrustedRlp}; | ||||
| 
 | ||||
| /// Parity tries to round block.gas_limit to multiple of this constant
 | ||||
| pub const PARITY_GAS_LIMIT_DETERMINANT: U256 = U256([37, 0, 0, 0]); | ||||
|  | ||||
| @ -261,9 +261,7 @@ impl Header { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Header { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let r = decoder.as_rlp(); | ||||
| 
 | ||||
| 	fn decode(r: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let mut blockheader = Header { | ||||
| 			parent_hash: r.val_at(0)?, | ||||
| 			uncles_hash: r.val_at(1)?, | ||||
| @ -283,7 +281,7 @@ impl Decodable for Header { | ||||
| 			bare_hash: RefCell::new(None), | ||||
| 		}; | ||||
| 
 | ||||
| 		for i in 13..r.item_count() { | ||||
| 		for i in 13..r.item_count()? { | ||||
| 			blockheader.seal.push(r.at(i)?.as_raw().to_vec()) | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| use super::test_common::*; | ||||
| use evm; | ||||
| use ethjson; | ||||
| use rlp::{UntrustedRlp, View}; | ||||
| use rlp::UntrustedRlp; | ||||
| use transaction::{Action, UnverifiedTransaction}; | ||||
| use ethstore::ethkey::public_to_address; | ||||
| 
 | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| //! This migration compresses the state db.
 | ||||
| 
 | ||||
| use util::migration::{SimpleMigration, Progress}; | ||||
| use rlp::{Compressible, UntrustedRlp, View, RlpType}; | ||||
| use rlp::{Compressible, UntrustedRlp, RlpType}; | ||||
| 
 | ||||
| /// Compressing migration.
 | ||||
| #[derive(Default)] | ||||
|  | ||||
| @ -26,8 +26,7 @@ use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress | ||||
| use util::sha3::Hashable; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| use rlp::{decode, Rlp, RlpStream, View}; | ||||
| 
 | ||||
| use rlp::{decode, Rlp, RlpStream}; | ||||
| 
 | ||||
| // attempt to migrate a key, value pair. None if migration not possible.
 | ||||
| fn attempt_migrate(mut key_h: H256, val: &[u8]) -> Option<H256> { | ||||
| @ -184,7 +183,7 @@ impl OverlayRecentV7 { | ||||
| 						} | ||||
| 
 | ||||
| 						// migrate all deleted keys.
 | ||||
| 						let mut deleted_keys: Vec<H256> = rlp.val_at(2); | ||||
| 						let mut deleted_keys: Vec<H256> = rlp.list_at(2); | ||||
| 						for old_key in &mut deleted_keys { | ||||
| 							if let Some(new) = self.migrated_keys.get(&*old_key) { | ||||
| 								*old_key = new.clone(); | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| 
 | ||||
| //! This migration consolidates all databases into single one using Column Families.
 | ||||
| 
 | ||||
| use rlp::{Rlp, RlpStream, View}; | ||||
| use rlp::{Rlp, RlpStream}; | ||||
| use util::kvdb::Database; | ||||
| use util::migration::{Batch, Config, Error, Migration, Progress}; | ||||
| use std::sync::Arc; | ||||
|  | ||||
| @ -22,7 +22,7 @@ use snapshot::Error; | ||||
| 
 | ||||
| use util::{U256, H256, Bytes, HashDB, SHA3_EMPTY, SHA3_NULL_RLP}; | ||||
| use util::trie::{TrieDB, Trie}; | ||||
| use rlp::{RlpStream, UntrustedRlp, View}; | ||||
| use rlp::{RlpStream, UntrustedRlp}; | ||||
| 
 | ||||
| use std::collections::HashSet; | ||||
| 
 | ||||
| @ -180,7 +180,7 @@ mod tests { | ||||
| 
 | ||||
| 	use util::sha3::{SHA3_EMPTY, SHA3_NULL_RLP}; | ||||
| 	use util::{Address, H256, HashDB, DBValue}; | ||||
| 	use rlp::{UntrustedRlp, View}; | ||||
| 	use rlp::UntrustedRlp; | ||||
| 
 | ||||
| 	use std::collections::HashSet; | ||||
| 
 | ||||
|  | ||||
| @ -20,7 +20,7 @@ use block::Block; | ||||
| use header::Header; | ||||
| 
 | ||||
| use views::BlockView; | ||||
| use rlp::{DecoderError, RlpStream, UntrustedRlp, View}; | ||||
| use rlp::{DecoderError, RlpStream, UntrustedRlp}; | ||||
| use util::{Bytes, Hashable, H256}; | ||||
| use util::triehash::ordered_trie_root; | ||||
| 
 | ||||
| @ -101,8 +101,8 @@ impl AbridgedBlock { | ||||
| 		header.set_timestamp(rlp.val_at(6)?); | ||||
| 		header.set_extra_data(rlp.val_at(7)?); | ||||
| 
 | ||||
| 		let transactions = rlp.val_at(8)?; | ||||
| 		let uncles: Vec<Header> = rlp.val_at(9)?; | ||||
| 		let transactions = rlp.list_at(8)?; | ||||
| 		let uncles: Vec<Header> = rlp.list_at(9)?; | ||||
| 
 | ||||
| 		header.set_transactions_root(ordered_trie_root( | ||||
| 			rlp.at(8)?.iter().map(|r| r.as_raw().to_owned()) | ||||
| @ -114,7 +114,7 @@ impl AbridgedBlock { | ||||
| 		header.set_uncles_hash(uncles_rlp.as_raw().sha3()); | ||||
| 
 | ||||
| 		let mut seal_fields = Vec::new(); | ||||
| 		for i in (HEADER_FIELDS + BLOCK_FIELDS)..rlp.item_count() { | ||||
| 		for i in (HEADER_FIELDS + BLOCK_FIELDS)..rlp.item_count()? { | ||||
| 			let seal_rlp = rlp.at(i)?; | ||||
| 			seal_fields.push(seal_rlp.as_raw().to_owned()); | ||||
| 		} | ||||
|  | ||||
| @ -27,7 +27,7 @@ use std::path::{Path, PathBuf}; | ||||
| 
 | ||||
| use util::Bytes; | ||||
| use util::hash::H256; | ||||
| use rlp::{self, Encodable, RlpStream, UntrustedRlp, View}; | ||||
| use rlp::{self, Encodable, RlpStream, UntrustedRlp}; | ||||
| 
 | ||||
| use super::ManifestData; | ||||
| 
 | ||||
| @ -57,12 +57,10 @@ impl Encodable for ChunkInfo { | ||||
| } | ||||
| 
 | ||||
| impl rlp::Decodable for ChunkInfo { | ||||
| 	fn decode<D: rlp::Decoder>(decoder: &D) -> Result<Self, rlp::DecoderError> { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 
 | ||||
| 		let hash = d.val_at(0)?; | ||||
| 		let len = d.val_at(1)?; | ||||
| 		let off = d.val_at(2)?; | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, rlp::DecoderError> { | ||||
| 		let hash = rlp.val_at(0)?; | ||||
| 		let len = rlp.val_at(1)?; | ||||
| 		let off = rlp.val_at(2)?; | ||||
| 		Ok(ChunkInfo(hash, len, off)) | ||||
| 	} | ||||
| } | ||||
| @ -257,8 +255,8 @@ impl PackedReader { | ||||
| 
 | ||||
| 		let rlp = UntrustedRlp::new(&manifest_buf); | ||||
| 
 | ||||
| 		let state: Vec<ChunkInfo> = rlp.val_at(0)?; | ||||
| 		let blocks: Vec<ChunkInfo> = rlp.val_at(1)?; | ||||
| 		let state: Vec<ChunkInfo> = rlp.list_at(0)?; | ||||
| 		let blocks: Vec<ChunkInfo> = rlp.list_at(1)?; | ||||
| 
 | ||||
| 		let manifest = ManifestData { | ||||
| 			state_hashes: state.iter().map(|c| c.0).collect(), | ||||
|  | ||||
| @ -37,7 +37,7 @@ use util::journaldb::{self, Algorithm, JournalDB}; | ||||
| use util::kvdb::Database; | ||||
| use util::trie::{TrieDB, TrieDBMut, Trie, TrieMut}; | ||||
| use util::sha3::SHA3_NULL_RLP; | ||||
| use rlp::{RlpStream, UntrustedRlp, View}; | ||||
| use rlp::{RlpStream, UntrustedRlp}; | ||||
| use bloom_journal::Bloom; | ||||
| 
 | ||||
| use self::block::AbridgedBlock; | ||||
| @ -408,10 +408,10 @@ impl StateRebuilder { | ||||
| 	pub fn feed(&mut self, chunk: &[u8], flag: &AtomicBool) -> Result<(), ::error::Error> { | ||||
| 		let rlp = UntrustedRlp::new(chunk); | ||||
| 		let empty_rlp = StateAccount::new_basic(U256::zero(), U256::zero()).rlp(); | ||||
| 		let mut pairs = Vec::with_capacity(rlp.item_count()); | ||||
| 		let mut pairs = Vec::with_capacity(rlp.item_count()?); | ||||
| 
 | ||||
| 		// initialize the pairs vector with empty values so we have slots to write into.
 | ||||
| 		pairs.resize(rlp.item_count(), (H256::new(), Vec::new())); | ||||
| 		pairs.resize(rlp.item_count()?, (H256::new(), Vec::new())); | ||||
| 
 | ||||
| 		let status = rebuild_accounts( | ||||
| 			self.db.as_hashdb_mut(), | ||||
| @ -601,7 +601,7 @@ impl BlockRebuilder { | ||||
| 		use util::triehash::ordered_trie_root; | ||||
| 
 | ||||
| 		let rlp = UntrustedRlp::new(chunk); | ||||
| 		let item_count = rlp.item_count(); | ||||
| 		let item_count = rlp.item_count()?; | ||||
| 		let num_blocks = (item_count - 3) as u64; | ||||
| 
 | ||||
| 		trace!(target: "snapshot", "restoring block chunk with {} blocks.", item_count - 3); | ||||
| @ -621,7 +621,7 @@ impl BlockRebuilder { | ||||
| 			let pair = rlp.at(idx)?; | ||||
| 			let abridged_rlp = pair.at(0)?.as_raw().to_owned(); | ||||
| 			let abridged_block = AbridgedBlock::from_raw(abridged_rlp); | ||||
| 			let receipts: Vec<::receipt::Receipt> = pair.val_at(1)?; | ||||
| 			let receipts: Vec<::receipt::Receipt> = pair.list_at(1)?; | ||||
| 			let receipts_root = ordered_trie_root( | ||||
| 				pair.at(1)?.iter().map(|r| r.as_raw().to_owned()) | ||||
| 			); | ||||
|  | ||||
| @ -34,7 +34,7 @@ use super::genesis::Genesis; | ||||
| use super::seal::Generic as GenericSeal; | ||||
| use ethereum; | ||||
| use ethjson; | ||||
| use rlp::{Rlp, RlpStream, View}; | ||||
| use rlp::{Rlp, RlpStream}; | ||||
| 
 | ||||
| /// Parameters common to all engines.
 | ||||
| #[derive(Debug, PartialEq, Clone, Default)] | ||||
|  | ||||
| @ -462,7 +462,7 @@ impl fmt::Debug for Account { | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
| 	use rlp::{UntrustedRlp, RlpType, View, Compressible}; | ||||
| 	use rlp::{UntrustedRlp, RlpType, Compressible}; | ||||
| 	use util::*; | ||||
| 	use super::*; | ||||
| 	use account_db::*; | ||||
|  | ||||
| @ -25,7 +25,6 @@ use types::filter::Filter; | ||||
| use util::*; | ||||
| use devtools::*; | ||||
| use miner::Miner; | ||||
| use rlp::View; | ||||
| use spec::Spec; | ||||
| use views::BlockView; | ||||
| use ethkey::{KeyPair, Secret}; | ||||
|  | ||||
| @ -60,8 +60,8 @@ impl Into<BloomGroup> for BlockTracesBloomGroup { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for BlockTracesBloom { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		Decodable::decode(decoder).map(BlockTracesBloom) | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		LogBloom::decode(rlp).map(BlockTracesBloom) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -72,8 +72,8 @@ impl Encodable for BlockTracesBloom { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for BlockTracesBloomGroup { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let blooms = Decodable::decode(decoder)?; | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let blooms = rlp.as_list()?; | ||||
| 		let group = BlockTracesBloomGroup { | ||||
| 			blooms: blooms | ||||
| 		}; | ||||
|  | ||||
| @ -43,8 +43,7 @@ impl Encodable for BasicAccount { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for BasicAccount { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		Ok(BasicAccount { | ||||
| 			nonce: rlp.val_at(0)?, | ||||
| 			balance: rlp.val_at(1)?, | ||||
|  | ||||
| @ -29,7 +29,7 @@ use transaction::UnverifiedTransaction; | ||||
| use views; | ||||
| 
 | ||||
| use util::{Address, Hashable, H256, H2048, U256, HeapSizeOf}; | ||||
| use rlp::{Rlp, View}; | ||||
| use rlp::Rlp; | ||||
| 
 | ||||
| /// Owning header view.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
|  | ||||
| @ -51,8 +51,8 @@ impl Encodable for CallType { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for CallType { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		decoder.as_rlp().as_val().and_then(|v| Ok(match v { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		rlp.as_val().and_then(|v| Ok(match v { | ||||
| 			0u32 => CallType::None, | ||||
| 			1 => CallType::Call, | ||||
| 			2 => CallType::CallCode, | ||||
|  | ||||
| @ -47,12 +47,11 @@ impl Encodable for LogEntry { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for LogEntry { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let entry = LogEntry { | ||||
| 			address: d.val_at(0)?, | ||||
| 			topics: d.val_at(1)?, | ||||
| 			data: d.val_at(2)?, | ||||
| 			address: rlp.val_at(0)?, | ||||
| 			topics: rlp.list_at(1)?, | ||||
| 			data: rlp.val_at(2)?, | ||||
| 		}; | ||||
| 		Ok(entry) | ||||
| 	} | ||||
|  | ||||
| @ -65,21 +65,20 @@ impl Encodable for Receipt { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Receipt { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 		if d.item_count() == 3 { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		if rlp.item_count()? == 3 { | ||||
| 			Ok(Receipt { | ||||
| 				state_root: None, | ||||
| 				gas_used: d.val_at(0)?, | ||||
| 				log_bloom: d.val_at(1)?, | ||||
| 				logs: d.val_at(2)?, | ||||
| 				gas_used: rlp.val_at(0)?, | ||||
| 				log_bloom: rlp.val_at(1)?, | ||||
| 				logs: rlp.list_at(2)?, | ||||
| 			}) | ||||
| 		} else { | ||||
| 			Ok(Receipt { | ||||
| 				state_root: Some(d.val_at(0)?), | ||||
| 				gas_used: d.val_at(1)?, | ||||
| 				log_bloom: d.val_at(2)?, | ||||
| 				logs: d.val_at(3)?, | ||||
| 				state_root: Some(rlp.val_at(0)?), | ||||
| 				gas_used: rlp.val_at(1)?, | ||||
| 				log_bloom: rlp.val_at(2)?, | ||||
| 				logs: rlp.list_at(3)?, | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -53,8 +53,8 @@ impl ManifestData { | ||||
| 	pub fn from_rlp(raw: &[u8]) -> Result<Self, DecoderError> { | ||||
| 		let decoder = UntrustedRlp::new(raw); | ||||
| 
 | ||||
| 		let state_hashes: Vec<H256> = decoder.val_at(0)?; | ||||
| 		let block_hashes: Vec<H256> = decoder.val_at(1)?; | ||||
| 		let state_hashes: Vec<H256> = decoder.list_at(0)?; | ||||
| 		let block_hashes: Vec<H256> = decoder.list_at(1)?; | ||||
| 		let state_root: H256 = decoder.val_at(2)?; | ||||
| 		let block_number: u64 = decoder.val_at(3)?; | ||||
| 		let block_hash: H256 = decoder.val_at(4)?; | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| //! Trace errors.
 | ||||
| 
 | ||||
| use std::fmt; | ||||
| use rlp::{Encodable, RlpStream, Decodable, Decoder, DecoderError, View}; | ||||
| use rlp::{Encodable, RlpStream, Decodable, DecoderError, UntrustedRlp}; | ||||
| use evm::Error as EvmError; | ||||
| 
 | ||||
| /// Trace evm errors.
 | ||||
| @ -91,9 +91,9 @@ impl Encodable for Error { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Error { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		use self::Error::*; | ||||
| 		let value: u8 = decoder.as_rlp().as_val()?; | ||||
| 		let value: u8 = rlp.as_val()?; | ||||
| 		match value { | ||||
| 			0 => Ok(OutOfGas), | ||||
| 			1 => Ok(BadJumpDestination), | ||||
|  | ||||
| @ -64,9 +64,8 @@ impl Encodable for FlatTrace { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for FlatTrace { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 		let v: Vec<usize> = d.val_at(3)?; | ||||
| 	fn decode(d: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let v: Vec<usize> = d.list_at(3)?; | ||||
| 		let res = FlatTrace { | ||||
| 			action: d.val_at(0)?, | ||||
| 			result: d.val_at(1)?, | ||||
| @ -108,8 +107,8 @@ impl Encodable for FlatTransactionTraces { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for FlatTransactionTraces { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		Ok(FlatTransactionTraces(Decodable::decode(decoder)?)) | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		Ok(FlatTransactionTraces(rlp.as_list()?)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -149,8 +148,8 @@ impl Encodable for FlatBlockTraces { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for FlatBlockTraces { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		Ok(FlatBlockTraces(Decodable::decode(decoder)?)) | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		Ok(FlatBlockTraces(rlp.as_list()?)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -45,11 +45,10 @@ impl Encodable for CallResult { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for CallResult { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let res = CallResult { | ||||
| 			gas_used: d.val_at(0)?, | ||||
| 			output: d.val_at(1)?, | ||||
| 			gas_used: rlp.val_at(0)?, | ||||
| 			output: rlp.val_at(1)?, | ||||
| 		}; | ||||
| 
 | ||||
| 		Ok(res) | ||||
| @ -78,12 +77,11 @@ impl Encodable for CreateResult { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for CreateResult { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let res = CreateResult { | ||||
| 			gas_used: d.val_at(0)?, | ||||
| 			code: d.val_at(1)?, | ||||
| 			address: d.val_at(2)?, | ||||
| 			gas_used: rlp.val_at(0)?, | ||||
| 			code: rlp.val_at(1)?, | ||||
| 			address: rlp.val_at(2)?, | ||||
| 		}; | ||||
| 
 | ||||
| 		Ok(res) | ||||
| @ -141,15 +139,14 @@ impl Encodable for Call { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Call { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let res = Call { | ||||
| 			from: d.val_at(0)?, | ||||
| 			to: d.val_at(1)?, | ||||
| 			value: d.val_at(2)?, | ||||
| 			gas: d.val_at(3)?, | ||||
| 			input: d.val_at(4)?, | ||||
| 			call_type: d.val_at(5)?, | ||||
| 			from: rlp.val_at(0)?, | ||||
| 			to: rlp.val_at(1)?, | ||||
| 			value: rlp.val_at(2)?, | ||||
| 			gas: rlp.val_at(3)?, | ||||
| 			input: rlp.val_at(4)?, | ||||
| 			call_type: rlp.val_at(5)?, | ||||
| 		}; | ||||
| 
 | ||||
| 		Ok(res) | ||||
| @ -201,13 +198,12 @@ impl Encodable for Create { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Create { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let res = Create { | ||||
| 			from: d.val_at(0)?, | ||||
| 			value: d.val_at(1)?, | ||||
| 			gas: d.val_at(2)?, | ||||
| 			init: d.val_at(3)?, | ||||
| 			from: rlp.val_at(0)?, | ||||
| 			value: rlp.val_at(1)?, | ||||
| 			gas: rlp.val_at(2)?, | ||||
| 			init: rlp.val_at(3)?, | ||||
| 		}; | ||||
| 
 | ||||
| 		Ok(res) | ||||
| @ -252,12 +248,11 @@ impl Encodable for Suicide { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Suicide { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let res = Suicide { | ||||
| 			address: d.val_at(0)?, | ||||
| 			refund_address: d.val_at(1)?, | ||||
| 			balance: d.val_at(2)?, | ||||
| 			address: rlp.val_at(0)?, | ||||
| 			refund_address: rlp.val_at(1)?, | ||||
| 			balance: rlp.val_at(2)?, | ||||
| 		}; | ||||
| 
 | ||||
| 		Ok(res) | ||||
| @ -298,13 +293,12 @@ impl Encodable for Action { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Action { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 		let action_type: u8 = d.val_at(0)?; | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let action_type: u8 = rlp.val_at(0)?; | ||||
| 		match action_type { | ||||
| 			0 => d.val_at(1).map(Action::Call), | ||||
| 			1 => d.val_at(1).map(Action::Create), | ||||
| 			2 => d.val_at(1).map(Action::Suicide), | ||||
| 			0 => rlp.val_at(1).map(Action::Call), | ||||
| 			1 => rlp.val_at(1).map(Action::Create), | ||||
| 			2 => rlp.val_at(1).map(Action::Suicide), | ||||
| 			_ => Err(DecoderError::Custom("Invalid action type.")), | ||||
| 		} | ||||
| 	} | ||||
| @ -369,14 +363,13 @@ impl Encodable for Res { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Res { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 		let action_type: u8 = d.val_at(0)?; | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let action_type: u8 = rlp.val_at(0)?; | ||||
| 		match action_type { | ||||
| 			0 => d.val_at(1).map(Res::Call), | ||||
| 			1 => d.val_at(1).map(Res::Create), | ||||
| 			2 => d.val_at(1).map(Res::FailedCall), | ||||
| 			3 => d.val_at(1).map(Res::FailedCreate), | ||||
| 			0 => rlp.val_at(1).map(Res::Call), | ||||
| 			1 => rlp.val_at(1).map(Res::Create), | ||||
| 			2 => rlp.val_at(1).map(Res::FailedCall), | ||||
| 			3 => rlp.val_at(1).map(Res::FailedCreate), | ||||
| 			4 => Ok(Res::None), | ||||
| 			_ => Err(DecoderError::Custom("Invalid result type.")), | ||||
| 		} | ||||
| @ -420,11 +413,10 @@ impl Encodable for MemoryDiff { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for MemoryDiff { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		Ok(MemoryDiff { | ||||
| 			offset: d.val_at(0)?, | ||||
| 			data: d.val_at(1)?, | ||||
| 			offset: rlp.val_at(0)?, | ||||
| 			data: rlp.val_at(1)?, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -448,11 +440,10 @@ impl Encodable for StorageDiff { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for StorageDiff { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		Ok(StorageDiff { | ||||
| 			location: d.val_at(0)?, | ||||
| 			value: d.val_at(1)?, | ||||
| 			location: rlp.val_at(0)?, | ||||
| 			value: rlp.val_at(1)?, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -482,13 +473,12 @@ impl Encodable for VMExecutedOperation { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for VMExecutedOperation { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		Ok(VMExecutedOperation { | ||||
| 			gas_used: d.val_at(0)?, | ||||
| 			stack_push: d.val_at(1)?, | ||||
| 			mem_diff: d.val_at(2)?, | ||||
| 			store_diff: d.val_at(3)?, | ||||
| 			gas_used: rlp.val_at(0)?, | ||||
| 			stack_push: rlp.list_at(1)?, | ||||
| 			mem_diff: rlp.val_at(2)?, | ||||
| 			store_diff: rlp.val_at(3)?, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -518,13 +508,12 @@ impl Encodable for VMOperation { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for VMOperation { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let res = VMOperation { | ||||
| 			pc: d.val_at(0)?, | ||||
| 			instruction: d.val_at(1)?, | ||||
| 			gas_cost: d.val_at(2)?, | ||||
| 			executed: d.val_at(3)?, | ||||
| 			pc: rlp.val_at(0)?, | ||||
| 			instruction: rlp.val_at(1)?, | ||||
| 			gas_cost: rlp.val_at(2)?, | ||||
| 			executed: rlp.val_at(3)?, | ||||
| 		}; | ||||
| 
 | ||||
| 		Ok(res) | ||||
| @ -557,13 +546,12 @@ impl Encodable for VMTrace { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for VMTrace { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let res = VMTrace { | ||||
| 			parent_step: d.val_at(0)?, | ||||
| 			code: d.val_at(1)?, | ||||
| 			operations: d.val_at(2)?, | ||||
| 			subs: d.val_at(3)?, | ||||
| 			parent_step: rlp.val_at(0)?, | ||||
| 			code: rlp.val_at(1)?, | ||||
| 			operations: rlp.list_at(2)?, | ||||
| 			subs: rlp.list_at(3)?, | ||||
| 		}; | ||||
| 
 | ||||
| 		Ok(res) | ||||
|  | ||||
| @ -42,8 +42,7 @@ impl Default for Action { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Action { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let rlp = decoder.as_rlp(); | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		if rlp.is_empty() { | ||||
| 			Ok(Action::Create) | ||||
| 		} else { | ||||
| @ -243,12 +242,11 @@ impl Deref for UnverifiedTransaction { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for UnverifiedTransaction { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let d = decoder.as_rlp(); | ||||
| 		if d.item_count() != 9 { | ||||
| 	fn decode(d: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		if d.item_count()? != 9 { | ||||
| 			return Err(DecoderError::RlpIncorrectListLen); | ||||
| 		} | ||||
| 		let hash = decoder.as_raw().sha3(); | ||||
| 		let hash = d.as_raw().sha3(); | ||||
| 		Ok(UnverifiedTransaction { | ||||
| 			unsigned: Transaction { | ||||
| 				nonce: d.val_at(0)?, | ||||
|  | ||||
| @ -26,7 +26,7 @@ use engines::Engine; | ||||
| use error::{BlockError, Error}; | ||||
| use blockchain::*; | ||||
| use header::{BlockNumber, Header}; | ||||
| use rlp::{UntrustedRlp, View}; | ||||
| use rlp::UntrustedRlp; | ||||
| use transaction::SignedTransaction; | ||||
| use views::BlockView; | ||||
| use time::get_time; | ||||
| @ -101,7 +101,7 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: & | ||||
| 	verify_parent(&header, &parent)?; | ||||
| 	engine.verify_block_family(&header, &parent, Some(bytes))?; | ||||
| 
 | ||||
| 	let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count(); | ||||
| 	let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count()?; | ||||
| 	if num_uncles != 0 { | ||||
| 		if num_uncles > engine.maximum_uncle_count() { | ||||
| 			return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: None, max: Some(engine.maximum_uncle_count()), found: num_uncles }))); | ||||
| @ -264,7 +264,6 @@ mod tests { | ||||
| 	use transaction::*; | ||||
| 	use tests::helpers::*; | ||||
| 	use types::log_entry::{LogEntry, LocalizedLogEntry}; | ||||
| 	use rlp::View; | ||||
| 	use time::get_time; | ||||
| 	use encoded; | ||||
| 
 | ||||
|  | ||||
| @ -20,7 +20,7 @@ use util::*; | ||||
| use header::*; | ||||
| use transaction::*; | ||||
| use super::{TransactionView, HeaderView}; | ||||
| use rlp::{Rlp, View}; | ||||
| use rlp::Rlp; | ||||
| 
 | ||||
| /// View onto block rlp.
 | ||||
| pub struct BlockView<'a> { | ||||
| @ -69,7 +69,7 @@ impl<'a> BlockView<'a> { | ||||
| 
 | ||||
| 	/// Return List of transactions in given block.
 | ||||
| 	pub fn transactions(&self) -> Vec<UnverifiedTransaction> { | ||||
| 		self.rlp.val_at(1) | ||||
| 		self.rlp.list_at(1) | ||||
| 	} | ||||
| 
 | ||||
| 	/// Return List of transactions with additional localization info.
 | ||||
| @ -125,7 +125,7 @@ impl<'a> BlockView<'a> { | ||||
| 
 | ||||
| 	/// Return list of uncles of given block.
 | ||||
| 	pub fn uncles(&self) -> Vec<Header> { | ||||
| 		self.rlp.val_at(2) | ||||
| 		self.rlp.list_at(2) | ||||
| 	} | ||||
| 
 | ||||
| 	/// Return number of uncles in given block, without deserializing them.
 | ||||
|  | ||||
| @ -20,7 +20,7 @@ use util::*; | ||||
| use header::*; | ||||
| use transaction::*; | ||||
| use super::{TransactionView, HeaderView}; | ||||
| use rlp::{Rlp, View}; | ||||
| use rlp::Rlp; | ||||
| 
 | ||||
| /// View onto block rlp.
 | ||||
| pub struct BodyView<'a> { | ||||
| @ -49,7 +49,7 @@ impl<'a> BodyView<'a> { | ||||
| 
 | ||||
| 	/// Return List of transactions in given block.
 | ||||
| 	pub fn transactions(&self) -> Vec<UnverifiedTransaction> { | ||||
| 		self.rlp.val_at(0) | ||||
| 		self.rlp.list_at(0) | ||||
| 	} | ||||
| 
 | ||||
| 	/// Return List of transactions with additional localization info.
 | ||||
| @ -99,7 +99,7 @@ impl<'a> BodyView<'a> { | ||||
| 
 | ||||
| 	/// Return list of uncles of given block.
 | ||||
| 	pub fn uncles(&self) -> Vec<Header> { | ||||
| 		self.rlp.val_at(1) | ||||
| 		self.rlp.list_at(1) | ||||
| 	} | ||||
| 
 | ||||
| 	/// Return number of uncles in given block, without deserializing them.
 | ||||
|  | ||||
| @ -17,7 +17,7 @@ | ||||
| //! View onto block header rlp
 | ||||
| 
 | ||||
| use util::{U256, Bytes, Hashable, H256, Address, H2048}; | ||||
| use rlp::{Rlp, View}; | ||||
| use rlp::Rlp; | ||||
| use header::BlockNumber; | ||||
| 
 | ||||
| /// View onto block header rlp.
 | ||||
|  | ||||
| @ -16,7 +16,7 @@ | ||||
| 
 | ||||
| //! View onto transaction rlp
 | ||||
| use util::{U256, Bytes, Hashable, H256}; | ||||
| use rlp::{Rlp, View}; | ||||
| use rlp::Rlp; | ||||
| 
 | ||||
| /// View onto transaction rlp.
 | ||||
| pub struct TransactionView<'a> { | ||||
|  | ||||
| @ -25,7 +25,7 @@ use ethcore::transaction::{ | ||||
| }; | ||||
| use ethcore::service::ClientIoMessage; | ||||
| use io::IoHandler; | ||||
| use rlp::{UntrustedRlp, View}; | ||||
| use rlp::UntrustedRlp; | ||||
| use util::kvdb::KeyValueDB; | ||||
| 
 | ||||
| extern crate ethcore; | ||||
|  | ||||
| @ -32,7 +32,6 @@ use ethcore::snapshot::{RestorationStatus, SnapshotService as SS}; | ||||
| use number_prefix::{binary_prefix, Standalone, Prefixed}; | ||||
| use ethcore_rpc::{is_major_importing}; | ||||
| use ethcore_rpc::informant::RpcStats; | ||||
| use rlp::View; | ||||
| 
 | ||||
| pub struct Informant { | ||||
| 	report: RwLock<Option<ClientReport>>, | ||||
|  | ||||
| @ -21,7 +21,7 @@ use std::time::{Instant, Duration}; | ||||
| use std::sync::{Arc, Weak}; | ||||
| 
 | ||||
| use futures::{self, future, BoxFuture, Future}; | ||||
| use rlp::{self, UntrustedRlp, View}; | ||||
| use rlp::{self, UntrustedRlp}; | ||||
| use time::get_time; | ||||
| use util::{H160, H256, Address, U256, H64}; | ||||
| use util::sha3::Hashable; | ||||
|  | ||||
| @ -36,7 +36,7 @@ use ethcore::executed::{Executed, ExecutionError}; | ||||
| use ethcore::ids::BlockId; | ||||
| use ethcore::transaction::{Action, SignedTransaction, Transaction as EthTransaction}; | ||||
| use ethsync::LightSync; | ||||
| use rlp::{UntrustedRlp, View}; | ||||
| use rlp::UntrustedRlp; | ||||
| use util::sha3::{SHA3_NULL_RLP, SHA3_EMPTY_LIST_RLP}; | ||||
| use util::{RwLock, Mutex, Uint, U256}; | ||||
| 
 | ||||
|  | ||||
| @ -18,7 +18,7 @@ | ||||
| 
 | ||||
| use std::sync::{Arc, Weak}; | ||||
| 
 | ||||
| use rlp::{UntrustedRlp, View}; | ||||
| use rlp::UntrustedRlp; | ||||
| use ethcore::account_provider::AccountProvider; | ||||
| use ethcore::transaction::{SignedTransaction, PendingTransaction}; | ||||
| use futures::{future, BoxFuture, Future, IntoFuture}; | ||||
|  | ||||
| @ -18,7 +18,7 @@ | ||||
| 
 | ||||
| use std::sync::{Weak, Arc}; | ||||
| 
 | ||||
| use rlp::{UntrustedRlp, View}; | ||||
| use rlp::UntrustedRlp; | ||||
| use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId}; | ||||
| use ethcore::miner::MinerService; | ||||
| use ethcore::transaction::SignedTransaction; | ||||
|  | ||||
| @ -940,7 +940,7 @@ fn rpc_eth_send_raw_transaction_error() { | ||||
| 		], | ||||
| 		"id": 1 | ||||
| 	}"#;
 | ||||
| 	let res = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid RLP.","data":"RlpIncorrectListLen"},"id":1}"#.into(); | ||||
| 	let res = r#"{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid RLP.","data":"RlpExpectedToBeList"},"id":1}"#.into(); | ||||
| 
 | ||||
| 	assert_eq!(tester.io.handle_request_sync(&req), Some(res)); | ||||
| } | ||||
|  | ||||
| @ -214,7 +214,7 @@ impl BlockDownloader { | ||||
| 
 | ||||
| 	/// Add new block headers.
 | ||||
| 	pub fn import_headers(&mut self, io: &mut SyncIo, r: &UntrustedRlp, expected_hash: Option<H256>) -> Result<DownloadAction, BlockDownloaderImportError> { | ||||
| 		let item_count = r.item_count(); | ||||
| 		let item_count = r.item_count().unwrap_or(0); | ||||
| 		if self.state == State::Idle { | ||||
| 			trace!(target: "sync", "Ignored unexpected block headers"); | ||||
| 			return Ok(DownloadAction::None) | ||||
| @ -314,7 +314,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> { | ||||
| 		let item_count = r.item_count(); | ||||
| 		let item_count = r.item_count().unwrap_or(0); | ||||
| 		if item_count == 0 { | ||||
| 			return Err(BlockDownloaderImportError::Useless); | ||||
| 		} | ||||
| @ -340,7 +340,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> { | ||||
| 		let item_count = r.item_count(); | ||||
| 		let item_count = r.item_count().unwrap_or(0); | ||||
| 		if item_count == 0 { | ||||
| 			return Err(BlockDownloaderImportError::Useless); | ||||
| 		} | ||||
|  | ||||
| @ -659,7 +659,7 @@ impl ChainSync { | ||||
| 		let confirmed = match self.peers.get_mut(&peer_id) { | ||||
| 			Some(ref mut peer) if peer.asking == PeerAsking::ForkHeader => { | ||||
| 				peer.asking = PeerAsking::Nothing; | ||||
| 				let item_count = r.item_count(); | ||||
| 				let item_count = r.item_count()?; | ||||
| 				let (fork_number, fork_hash) = self.fork_block.expect("ForkHeader request is sent only fork block is Some; qed").clone(); | ||||
| 				if item_count == 0 || item_count != 1 { | ||||
| 					trace!(target: "sync", "{}: Chain is too short to confirm the block", peer_id); | ||||
| @ -696,7 +696,7 @@ impl ChainSync { | ||||
| 			self.continue_sync(io); | ||||
| 			return Ok(()); | ||||
| 		} | ||||
| 		let item_count = r.item_count(); | ||||
| 		let item_count = r.item_count()?; | ||||
| 		trace!(target: "sync", "{} -> BlockHeaders ({} entries), state = {:?}, set = {:?}", peer_id, item_count, self.state, block_set); | ||||
| 		if (self.state == SyncState::Idle || self.state == SyncState::WaitingPeers) && self.old_blocks.is_none() { | ||||
| 			trace!(target: "sync", "Ignored unexpected block headers"); | ||||
| @ -764,7 +764,7 @@ impl ChainSync { | ||||
| 			self.continue_sync(io); | ||||
| 			return Ok(()); | ||||
| 		} | ||||
| 		let item_count = r.item_count(); | ||||
| 		let item_count = r.item_count()?; | ||||
| 		trace!(target: "sync", "{} -> BlockBodies ({} entries), set = {:?}", peer_id, item_count, block_set); | ||||
| 		if item_count == 0 { | ||||
| 			self.deactivate_peer(io, peer_id); | ||||
| @ -818,7 +818,7 @@ impl ChainSync { | ||||
| 			self.continue_sync(io); | ||||
| 			return Ok(()); | ||||
| 		} | ||||
| 		let item_count = r.item_count(); | ||||
| 		let item_count = r.item_count()?; | ||||
| 		trace!(target: "sync", "{} -> BlockReceipts ({} entries)", peer_id, item_count); | ||||
| 		if item_count == 0 { | ||||
| 			self.deactivate_peer(io, peer_id); | ||||
| @ -954,7 +954,7 @@ impl ChainSync { | ||||
| 			self.continue_sync(io); | ||||
| 			return Ok(()); | ||||
| 		} | ||||
| 		trace!(target: "sync", "{} -> NewHashes ({} entries)", peer_id, r.item_count()); | ||||
| 		trace!(target: "sync", "{} -> NewHashes ({} entries)", peer_id, r.item_count()?); | ||||
| 		let mut max_height: BlockNumber = 0; | ||||
| 		let mut new_hashes = Vec::new(); | ||||
| 		let last_imported_number = self.new_blocks.last_imported_block_number(); | ||||
| @ -1439,7 +1439,7 @@ impl ChainSync { | ||||
| 			trace!(target: "sync", "{} Ignoring transactions from unconfirmed/unknown peer", peer_id); | ||||
| 		} | ||||
| 
 | ||||
| 		let mut item_count = r.item_count(); | ||||
| 		let mut item_count = r.item_count()?; | ||||
| 		trace!(target: "sync", "{:02} -> Transactions ({} entries)", peer_id, item_count); | ||||
| 		item_count = min(item_count, MAX_TX_TO_IMPORT); | ||||
| 		let mut transactions = Vec::with_capacity(item_count); | ||||
| @ -1557,7 +1557,7 @@ impl ChainSync { | ||||
| 
 | ||||
| 	/// Respond to GetBlockBodies request
 | ||||
| 	fn return_block_bodies(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { | ||||
| 		let mut count = r.item_count(); | ||||
| 		let mut count = r.item_count().unwrap_or(0); | ||||
| 		if count == 0 { | ||||
| 			debug!(target: "sync", "Empty GetBlockBodies request, ignoring."); | ||||
| 			return Ok(None); | ||||
| @ -1579,7 +1579,7 @@ impl ChainSync { | ||||
| 
 | ||||
| 	/// Respond to GetNodeData request
 | ||||
| 	fn return_node_data(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { | ||||
| 		let mut count = r.item_count(); | ||||
| 		let mut count = r.item_count().unwrap_or(0); | ||||
| 		trace!(target: "sync", "{} -> GetNodeData: {} entries", peer_id, count); | ||||
| 		if count == 0 { | ||||
| 			debug!(target: "sync", "Empty GetNodeData request, ignoring."); | ||||
| @ -1603,7 +1603,7 @@ impl ChainSync { | ||||
| 	} | ||||
| 
 | ||||
| 	fn return_receipts(io: &SyncIo, rlp: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { | ||||
| 		let mut count = rlp.item_count(); | ||||
| 		let mut count = rlp.item_count().unwrap_or(0); | ||||
| 		trace!(target: "sync", "{} -> GetReceipts: {} entries", peer_id, count); | ||||
| 		if count == 0 { | ||||
| 			debug!(target: "sync", "Empty GetReceipts request, ignoring."); | ||||
| @ -1628,7 +1628,7 @@ impl ChainSync { | ||||
| 
 | ||||
| 	/// Respond to GetSnapshotManifest request
 | ||||
| 	fn return_snapshot_manifest(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { | ||||
| 		let count = r.item_count(); | ||||
| 		let count = r.item_count().unwrap_or(0); | ||||
| 		trace!(target: "sync", "{} -> GetSnapshotManifest", peer_id); | ||||
| 		if count != 0 { | ||||
| 			debug!(target: "sync", "Invalid GetSnapshotManifest request, ignoring."); | ||||
| @ -2177,7 +2177,7 @@ mod tests { | ||||
| 	use util::sha3::Hashable; | ||||
| 	use util::hash::H256; | ||||
| 	use util::bytes::Bytes; | ||||
| 	use rlp::{Rlp, RlpStream, UntrustedRlp, View}; | ||||
| 	use rlp::{Rlp, RlpStream, UntrustedRlp}; | ||||
| 	use super::*; | ||||
| 	use ::SyncConfig; | ||||
| 	use super::{PeerInfo, PeerAsking}; | ||||
| @ -2746,7 +2746,7 @@ mod tests { | ||||
| 				} | ||||
| 
 | ||||
| 				let rlp = UntrustedRlp::new(&*p.data); | ||||
| 				let item_count = rlp.item_count(); | ||||
| 				let item_count = rlp.item_count().unwrap_or(0); | ||||
| 				if item_count != 1 { | ||||
| 					return None; | ||||
| 				} | ||||
|  | ||||
| @ -481,7 +481,7 @@ impl Discovery { | ||||
| 	fn on_neighbours(&mut self, rlp: &UntrustedRlp, _node: &NodeId, from: &SocketAddr) -> Result<Option<TableUpdates>, NetworkError> { | ||||
| 		// TODO: validate packet
 | ||||
| 		let mut added = HashMap::new(); | ||||
| 		trace!(target: "discovery", "Got {} Neighbours from {:?}", rlp.at(0)?.item_count(), &from); | ||||
| 		trace!(target: "discovery", "Got {} Neighbours from {:?}", rlp.at(0)?.item_count()?, &from); | ||||
| 		for r in rlp.at(0)?.iter() { | ||||
| 			let endpoint = NodeEndpoint::from_rlp(&r)?; | ||||
| 			if !endpoint.is_valid() { | ||||
|  | ||||
| @ -116,9 +116,8 @@ pub struct PeerCapabilityInfo { | ||||
| } | ||||
| 
 | ||||
| impl Decodable for PeerCapabilityInfo { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let c = decoder.as_rlp(); | ||||
| 		let p: Vec<u8> = c.val_at(0)?; | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let p: Vec<u8> = rlp.val_at(0)?; | ||||
| 		if p.len() != 3 { | ||||
| 			return Err(DecoderError::Custom("Invalid subprotocol string length. Should be 3")); | ||||
| 		} | ||||
| @ -126,7 +125,7 @@ impl Decodable for PeerCapabilityInfo { | ||||
| 		p2.clone_from_slice(&p); | ||||
| 		Ok(PeerCapabilityInfo { | ||||
| 			protocol: p2, | ||||
| 			version: c.val_at(1)? | ||||
| 			version: rlp.val_at(1)? | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| @ -473,7 +472,7 @@ impl Session { | ||||
| 	where Message: Send + Sync + Clone { | ||||
| 		let protocol = rlp.val_at::<u32>(0)?; | ||||
| 		let client_version = rlp.val_at::<String>(1)?; | ||||
| 		let peer_caps = rlp.val_at::<Vec<PeerCapabilityInfo>>(2)?; | ||||
| 		let peer_caps: Vec<PeerCapabilityInfo> = rlp.list_at(2)?; | ||||
| 		let id = rlp.val_at::<NodeId>(4)?; | ||||
| 
 | ||||
| 		// Intersect with host capabilities
 | ||||
|  | ||||
| @ -23,13 +23,12 @@ | ||||
| #![feature(test)] | ||||
| 
 | ||||
| extern crate test; | ||||
| extern crate ethcore_bigint as bigint; | ||||
| extern crate rlp; | ||||
| extern crate ethcore_util as util; | ||||
| 
 | ||||
| use test::Bencher; | ||||
| use std::str::FromStr; | ||||
| use rlp::*; | ||||
| use util::U256; | ||||
| use bigint::prelude::U256; | ||||
| use rlp::{RlpStream, Rlp}; | ||||
| 
 | ||||
| #[bench] | ||||
| fn bench_stream_u64_value(b: &mut Bencher) { | ||||
| @ -56,9 +55,8 @@ fn bench_stream_u256_value(b: &mut Bencher) { | ||||
| 	b.iter(|| { | ||||
| 		// u256
 | ||||
| 		let mut stream = RlpStream::new(); | ||||
| 		stream.append(&U256::from_str("8090a0b0c0d0e0f009102030405060770000000000000001000000000\ | ||||
| 		                               00012f0")
 | ||||
| 			               .unwrap()); | ||||
| 		let uint: U256 = "8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0".into(); | ||||
| 		stream.append(&uint); | ||||
| 		let _ = stream.out(); | ||||
| 	}); | ||||
| } | ||||
| @ -93,11 +91,11 @@ fn bench_decode_nested_empty_lists(b: &mut Bencher) { | ||||
| 		// [ [], [[]], [ [], [[]] ] ]
 | ||||
| 		let data = vec![0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0]; | ||||
| 		let rlp = Rlp::new(&data); | ||||
| 		let _v0: Vec<u16> = rlp.val_at(0); | ||||
| 		let _v1: Vec<Vec<u16>> = rlp.val_at(1); | ||||
| 		let _v0: Vec<u16> = rlp.at(0).as_list(); | ||||
| 		let _v1: Vec<u16> = rlp.at(1).at(0).as_list(); | ||||
| 		let nested_rlp = rlp.at(2); | ||||
| 		let _v2a: Vec<u16> = nested_rlp.val_at(0); | ||||
| 		let _v2b: Vec<Vec<u16>> = nested_rlp.val_at(1); | ||||
| 		let _v2a: Vec<u16> = nested_rlp.at(0).as_list(); | ||||
| 		let _v2b: Vec<u16> = nested_rlp.at(1).at(0).as_list(); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| @ -1,148 +0,0 @@ | ||||
| // 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 <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| //! Unified interfaces for RLP bytes operations on basic types
 | ||||
| //!
 | ||||
| 
 | ||||
| use std::{mem, fmt, cmp}; | ||||
| use std::error::Error as StdError; | ||||
| use bigint::prelude::{U128, U256, H64, H128, H160, H256, H512, H520, H2048}; | ||||
| 
 | ||||
| /// Error returned when `FromBytes` conversation goes wrong
 | ||||
| #[derive(Debug, PartialEq, Eq)] | ||||
| pub enum FromBytesError { | ||||
| 	/// Expected more RLP data
 | ||||
| 	DataIsTooShort, | ||||
| 	/// Extra bytes after the end of the last item
 | ||||
| 	DataIsTooLong, | ||||
| 	/// Integer-representation is non-canonically prefixed with zero byte(s).
 | ||||
| 	ZeroPrefixedInt, | ||||
| 	/// String representation is not utf-8
 | ||||
| 	InvalidUtf8, | ||||
| } | ||||
| 
 | ||||
| impl StdError for FromBytesError { | ||||
| 	fn description(&self) -> &str { "from_bytes error" } | ||||
| } | ||||
| 
 | ||||
| impl fmt::Display for FromBytesError { | ||||
| 	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
| 		fmt::Debug::fmt(&self, f) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// Alias for the result of `FromBytes` trait
 | ||||
| pub type FromBytesResult<T> = Result<T, FromBytesError>; | ||||
| 
 | ||||
| /// Converts to given type from its bytes representation
 | ||||
| ///
 | ||||
| /// TODO: check size of bytes before conversation and return appropriate error
 | ||||
| pub trait FromBytes: Sized { | ||||
| 	/// Create a value from bytes
 | ||||
| 	fn from_bytes(bytes: &[u8]) -> FromBytesResult<Self>; | ||||
| } | ||||
| 
 | ||||
| impl FromBytes for String { | ||||
| 	fn from_bytes(bytes: &[u8]) -> FromBytesResult<String> { | ||||
| 		::std::str::from_utf8(bytes).map(|s| s.to_owned()).map_err(|_| FromBytesError::InvalidUtf8) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_uint_from_bytes { | ||||
| 	($to: ident) => { | ||||
| 		impl FromBytes for $to { | ||||
| 			fn from_bytes(bytes: &[u8]) -> FromBytesResult<$to> { | ||||
| 				match bytes.len() { | ||||
| 					0 => Ok(0), | ||||
| 					l if l <= mem::size_of::<$to>() => { | ||||
| 						if bytes[0] == 0 { | ||||
| 							return Err(FromBytesError::ZeroPrefixedInt) | ||||
| 						} | ||||
| 						let mut res = 0 as $to; | ||||
| 						for i in 0..l { | ||||
| 							let shift = (l - 1 - i) * 8; | ||||
| 							res = res + ((bytes[i] as $to) << shift); | ||||
| 						} | ||||
| 						Ok(res) | ||||
| 					} | ||||
| 					_ => Err(FromBytesError::DataIsTooLong) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl FromBytes for bool { | ||||
| 	fn from_bytes(bytes: &[u8]) -> FromBytesResult<bool> { | ||||
| 		match bytes.len() { | ||||
| 			0 => Ok(false), | ||||
| 			1 => Ok(bytes[0] != 0), | ||||
| 			_ => Err(FromBytesError::DataIsTooLong), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //impl_uint_from_bytes!(u8);
 | ||||
| impl_uint_from_bytes!(u16); | ||||
| impl_uint_from_bytes!(u32); | ||||
| impl_uint_from_bytes!(u64); | ||||
| impl_uint_from_bytes!(usize); | ||||
| 
 | ||||
| macro_rules! impl_uint_from_bytes { | ||||
| 	($name: ident, $size: expr) => { | ||||
| 		impl FromBytes for $name { | ||||
| 			fn from_bytes(bytes: &[u8]) -> FromBytesResult<$name> { | ||||
| 				if !bytes.is_empty() && bytes[0] == 0 { | ||||
| 					Err(FromBytesError::ZeroPrefixedInt) | ||||
| 				} else if bytes.len() <= $size { | ||||
| 					Ok($name::from(bytes)) | ||||
| 				} else { | ||||
| 					Err(FromBytesError::DataIsTooLong) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl_uint_from_bytes!(U256, 32); | ||||
| impl_uint_from_bytes!(U128, 16); | ||||
| 
 | ||||
| macro_rules! impl_hash_from_bytes { | ||||
| 	($name: ident, $size: expr) => { | ||||
| 		impl FromBytes for $name { | ||||
| 			fn from_bytes(bytes: &[u8]) -> FromBytesResult<$name> { | ||||
| 				match bytes.len().cmp(&$size) { | ||||
| 					cmp::Ordering::Less => Err(FromBytesError::DataIsTooShort), | ||||
| 					cmp::Ordering::Greater => Err(FromBytesError::DataIsTooLong), | ||||
| 					cmp::Ordering::Equal => { | ||||
| 						let mut t = [0u8; $size]; | ||||
| 						t.copy_from_slice(bytes); | ||||
| 						Ok($name(t)) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl_hash_from_bytes!(H64, 8); | ||||
| impl_hash_from_bytes!(H128, 16); | ||||
| impl_hash_from_bytes!(H160, 20); | ||||
| impl_hash_from_bytes!(H256, 32); | ||||
| impl_hash_from_bytes!(H512, 64); | ||||
| impl_hash_from_bytes!(H520, 65); | ||||
| impl_hash_from_bytes!(H2048, 256); | ||||
| 
 | ||||
| @ -17,7 +17,7 @@ | ||||
| use std::collections::HashMap; | ||||
| use elastic_array::ElasticArray1024; | ||||
| use common::{BLOCKS_RLP_SWAPPER, SNAPSHOT_RLP_SWAPPER}; | ||||
| use {UntrustedRlp, View, Compressible, encode, RlpStream}; | ||||
| use {UntrustedRlp, Compressible, encode, RlpStream}; | ||||
| 
 | ||||
| /// Stores RLPs used for compression
 | ||||
| pub struct InvalidRlpSwapper<'a> { | ||||
| @ -69,7 +69,7 @@ fn to_elastic(slice: &[u8]) -> ElasticArray1024<u8> { | ||||
| fn map_rlp<F>(rlp: &UntrustedRlp, f: F) -> Option<ElasticArray1024<u8>> where | ||||
| 	F: Fn(&UntrustedRlp) -> Option<ElasticArray1024<u8>> { | ||||
| 	match rlp.iter() | ||||
| 	.fold((false, RlpStream::new_list(rlp.item_count())), | ||||
| 		.fold((false, RlpStream::new_list(rlp.item_count().unwrap_or(0))), | ||||
| 		|(is_some, mut acc), subrlp| { | ||||
|   		let new = f(&subrlp); | ||||
|   		if let Some(ref insert) = new { | ||||
| @ -138,7 +138,7 @@ fn deep_decompress(rlp: &UntrustedRlp, swapper: &InvalidRlpSwapper) -> Option<El | ||||
| 		swapper.get_valid(rlp.as_raw()).map(to_elastic); | ||||
| 	// Simply decompress data.
 | ||||
| 	if rlp.is_data() { return simple_swap(); } | ||||
| 	match rlp.item_count() { | ||||
| 	match rlp.item_count().unwrap_or(0) { | ||||
| 		// Look for special compressed list, which contains nested data.
 | ||||
| 		2 if rlp.at(0).map(|r| r.as_raw() == &[0x81, 0x7f]).unwrap_or(false) => | ||||
| 			rlp.at(1).ok().map_or(simple_swap(), | ||||
| @ -169,7 +169,7 @@ impl<'a> Compressible for UntrustedRlp<'a> { | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
| 	use compression::InvalidRlpSwapper; | ||||
| 	use {UntrustedRlp, Compressible, View, RlpType}; | ||||
| 	use {UntrustedRlp, Compressible, RlpType}; | ||||
| 
 | ||||
| 	#[test] | ||||
| 	fn invalid_rlp_swapper() { | ||||
|  | ||||
| @ -16,13 +16,10 @@ | ||||
| 
 | ||||
| use std::fmt; | ||||
| use std::error::Error as StdError; | ||||
| use bytes::FromBytesError; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Eq)] | ||||
| /// Error concerning the RLP decoder.
 | ||||
| pub enum DecoderError { | ||||
| 	/// Couldn't convert given bytes to an instance of required type.
 | ||||
| 	FromBytesError(FromBytesError), | ||||
| 	/// Data has additional bytes at the end of the valid RLP fragment.
 | ||||
| 	RlpIsTooBig, | ||||
| 	/// Data has too few bytes for valid RLP.
 | ||||
| @ -56,9 +53,3 @@ impl fmt::Display for DecoderError { | ||||
| 		fmt::Debug::fmt(&self, f) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl From<FromBytesError> for DecoderError { | ||||
| 	fn from(err: FromBytesError) -> DecoderError { | ||||
| 		DecoderError::FromBytesError(err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,26 @@ | ||||
| use std::{cmp, mem, str}; | ||||
| use byteorder::{ByteOrder, BigEndian}; | ||||
| use bigint::prelude::{Uint, U128, U256, H64, H128, H160, H256, H512, H520, H2048}; | ||||
| use traits::Encodable; | ||||
| use traits::{Encodable, Decodable}; | ||||
| use stream::RlpStream; | ||||
| use {UntrustedRlp, DecoderError}; | ||||
| 
 | ||||
| pub fn decode_usize(bytes: &[u8]) -> Result<usize, DecoderError> { | ||||
| 	match bytes.len() { | ||||
| 		l if l <= mem::size_of::<usize>() => { | ||||
| 			if bytes[0] == 0 { | ||||
| 				return Err(DecoderError::RlpInvalidIndirection); | ||||
| 			} | ||||
| 			let mut res = 0usize; | ||||
| 			for i in 0..l { | ||||
| 				let shift = (l - 1 - i) * 8; | ||||
| 				res = res + ((bytes[i] as usize) << shift); | ||||
| 			} | ||||
| 			Ok(res) | ||||
| 		} | ||||
| 		_ => Err(DecoderError::RlpIsTooBig), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Encodable for bool { | ||||
| 	fn rlp_append(&self, s: &mut RlpStream) { | ||||
| @ -13,6 +32,18 @@ impl Encodable for bool { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Decodable for bool { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		rlp.decoder().decode_value(|bytes| { | ||||
| 			match bytes.len() { | ||||
| 				0 => Ok(false), | ||||
| 				1 => Ok(bytes[0] != 0), | ||||
| 				_ => Err(DecoderError::RlpIsTooBig), | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<'a> Encodable for &'a [u8] { | ||||
| 	fn rlp_append(&self, s: &mut RlpStream) { | ||||
| 		s.encoder().encode_value(self); | ||||
| @ -25,6 +56,14 @@ impl Encodable for Vec<u8> { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Vec<u8> { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		rlp.decoder().decode_value(|bytes| { | ||||
| 			Ok(bytes.to_vec()) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<T> Encodable for Option<T> where T: Encodable { | ||||
| 	fn rlp_append(&self, s: &mut RlpStream) { | ||||
| 		match *self { | ||||
| @ -39,6 +78,17 @@ impl<T> Encodable for Option<T> where T: Encodable { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<T> Decodable for Option<T> where T: Decodable { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		let items = rlp.item_count()?; | ||||
| 		match items { | ||||
| 			1 => rlp.val_at(0).map(Some), | ||||
| 			0 => Ok(None), | ||||
| 			_ => Err(DecoderError::RlpIncorrectListLen), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Encodable for u8 { | ||||
| 	fn rlp_append(&self, s: &mut RlpStream) { | ||||
| 		if *self != 0 { | ||||
| @ -49,6 +99,19 @@ impl Encodable for u8 { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Decodable for u8 { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		rlp.decoder().decode_value(|bytes| { | ||||
| 			match bytes.len() { | ||||
| 				1 if bytes[0] != 0 => Ok(bytes[0]), | ||||
| 				0 => Ok(0), | ||||
| 				1 => Err(DecoderError::RlpInvalidIndirection), | ||||
| 				_ => Err(DecoderError::RlpIsTooBig), | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_encodable_for_u { | ||||
| 	($name: ident, $func: ident, $size: expr) => { | ||||
| 		impl Encodable for $name { | ||||
| @ -62,16 +125,52 @@ macro_rules! impl_encodable_for_u { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_decodable_for_u { | ||||
| 	($name: ident) => { | ||||
| 		impl Decodable for $name { | ||||
| 			fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 				rlp.decoder().decode_value(|bytes| { | ||||
| 					match bytes.len() { | ||||
| 						0 | 1 => u8::decode(rlp).map(|v| v as $name), | ||||
| 						l if l <= mem::size_of::<$name>() => { | ||||
| 							if bytes[0] == 0 { | ||||
| 								return Err(DecoderError::RlpInvalidIndirection); | ||||
| 							} | ||||
| 							let mut res = 0 as $name; | ||||
| 							for i in 0..l { | ||||
| 								let shift = (l - 1 - i) * 8; | ||||
| 								res = res + ((bytes[i] as $name) << shift); | ||||
| 							} | ||||
| 							Ok(res) | ||||
| 						} | ||||
| 						_ => Err(DecoderError::RlpIsTooBig), | ||||
| 					} | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl_encodable_for_u!(u16, write_u16, 2); | ||||
| impl_encodable_for_u!(u32, write_u32, 4); | ||||
| impl_encodable_for_u!(u64, write_u64, 8); | ||||
| 
 | ||||
| impl_decodable_for_u!(u16); | ||||
| impl_decodable_for_u!(u32); | ||||
| impl_decodable_for_u!(u64); | ||||
| 
 | ||||
| impl Encodable for usize { | ||||
| 	fn rlp_append(&self, s: &mut RlpStream) { | ||||
| 		(*self as u64).rlp_append(s); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Decodable for usize { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		u64::decode(rlp).map(|value| value as usize) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_encodable_for_hash { | ||||
| 	($name: ident) => { | ||||
| 		impl Encodable for $name { | ||||
| @ -82,6 +181,24 @@ 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<Self, DecoderError> { | ||||
| 				rlp.decoder().decode_value(|bytes| match bytes.len().cmp(&$size) { | ||||
| 					cmp::Ordering::Less => Err(DecoderError::RlpIsTooShort), | ||||
| 					cmp::Ordering::Greater => Err(DecoderError::RlpIsTooBig), | ||||
| 					cmp::Ordering::Equal => { | ||||
| 						let mut t = [0u8; $size]; | ||||
| 						t.copy_from_slice(bytes); | ||||
| 						Ok($name(t)) | ||||
| 					} | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl_encodable_for_hash!(H64); | ||||
| impl_encodable_for_hash!(H128); | ||||
| impl_encodable_for_hash!(H160); | ||||
| @ -90,6 +207,14 @@ impl_encodable_for_hash!(H512); | ||||
| impl_encodable_for_hash!(H520); | ||||
| impl_encodable_for_hash!(H2048); | ||||
| 
 | ||||
| impl_decodable_for_hash!(H64, 8); | ||||
| impl_decodable_for_hash!(H128, 16); | ||||
| impl_decodable_for_hash!(H160, 20); | ||||
| impl_decodable_for_hash!(H256, 32); | ||||
| impl_decodable_for_hash!(H512, 64); | ||||
| impl_decodable_for_hash!(H520, 65); | ||||
| impl_decodable_for_hash!(H2048, 256); | ||||
| 
 | ||||
| macro_rules! impl_encodable_for_uint { | ||||
| 	($name: ident, $size: expr) => { | ||||
| 		impl Encodable for $name { | ||||
| @ -103,9 +228,30 @@ 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<Self, DecoderError> { | ||||
| 				rlp.decoder().decode_value(|bytes| { | ||||
| 					if !bytes.is_empty() && bytes[0] == 0 { | ||||
| 						Err(DecoderError::RlpInvalidIndirection) | ||||
| 					} else if bytes.len() <= $size { | ||||
| 						Ok($name::from(bytes)) | ||||
| 					} else { | ||||
| 						Err(DecoderError::RlpIsTooBig) | ||||
| 					} | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl_encodable_for_uint!(U256, 32); | ||||
| impl_encodable_for_uint!(U128, 16); | ||||
| 
 | ||||
| impl_decodable_for_uint!(U256, 32); | ||||
| impl_decodable_for_uint!(U128, 16); | ||||
| 
 | ||||
| impl<'a> Encodable for &'a str { | ||||
| 	fn rlp_append(&self, s: &mut RlpStream) { | ||||
| 		s.encoder().encode_value(self.as_bytes()); | ||||
| @ -118,3 +264,14 @@ impl Encodable for String { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Decodable for String { | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> { | ||||
| 		rlp.decoder().decode_value(|bytes| { | ||||
| 			match str::from_utf8(bytes) { | ||||
| 				Ok(s) => Ok(s.to_owned()), | ||||
| 				// consider better error type here
 | ||||
| 				Err(_err) => Err(DecoderError::RlpExpectedToBeData), | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -61,17 +61,13 @@ mod untrusted_rlp; | ||||
| mod stream; | ||||
| mod compression; | ||||
| mod common; | ||||
| mod bytes; | ||||
| mod impls; | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests; | ||||
| 
 | ||||
| use std::borrow::Borrow; | ||||
| use elastic_array::ElasticArray1024; | ||||
| 
 | ||||
| pub use error::DecoderError; | ||||
| pub use traits::{Decoder, Decodable, View, Encodable, RlpDecodable, Compressible}; | ||||
| pub use traits::{Decodable, Encodable, Compressible}; | ||||
| pub use untrusted_rlp::{UntrustedRlp, UntrustedRlpIterator, PayloadInfo, Prototype}; | ||||
| pub use rlpin::{Rlp, RlpIterator}; | ||||
| pub use stream::RlpStream; | ||||
| @ -88,16 +84,21 @@ pub const EMPTY_LIST_RLP: [u8; 1] = [0xC0; 1]; | ||||
| /// extern crate rlp;
 | ||||
| ///
 | ||||
| /// fn main () {
 | ||||
| /// 	let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
 | ||||
| /// 	let animals: Vec<String> = rlp::decode(&data);
 | ||||
| /// 	assert_eq!(animals, vec!["cat".to_string(), "dog".to_string()]);
 | ||||
| /// 	let data = vec![0x83, b'c', b'a', b't'];
 | ||||
| /// 	let animal: String = rlp::decode(&data);
 | ||||
| /// 	assert_eq!(animal, "cat".to_owned());
 | ||||
| /// }
 | ||||
| /// ```
 | ||||
| pub fn decode<T>(bytes: &[u8]) -> T where T: RlpDecodable { | ||||
| pub fn decode<T>(bytes: &[u8]) -> T where T: Decodable { | ||||
| 	let rlp = Rlp::new(bytes); | ||||
| 	rlp.as_val() | ||||
| } | ||||
| 
 | ||||
| pub fn decode_list<T>(bytes: &[u8]) -> Vec<T> where T: Decodable { | ||||
| 	let rlp = Rlp::new(bytes); | ||||
| 	rlp.as_list() | ||||
| } | ||||
| 
 | ||||
| /// Shortcut function to encode structure into rlp.
 | ||||
| ///
 | ||||
| /// ```rust
 | ||||
|  | ||||
| @ -15,8 +15,7 @@ | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| use std::fmt; | ||||
| use rustc_serialize::hex::ToHex; | ||||
| use {View, DecoderError, UntrustedRlp, PayloadInfo, Prototype, RlpDecodable}; | ||||
| use {UntrustedRlp, PayloadInfo, Prototype, Decodable}; | ||||
| 
 | ||||
| impl<'a> From<UntrustedRlp<'a>> for Rlp<'a> { | ||||
| 	fn from(rlp: UntrustedRlp<'a>) -> Rlp<'a> { | ||||
| @ -39,95 +38,215 @@ impl<'a> fmt::Display for Rlp<'a> { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'view> View<'a, 'view> for Rlp<'a> where 'a: 'view { | ||||
| 	type Prototype = Prototype; | ||||
| 	type PayloadInfo = PayloadInfo; | ||||
| 	type Data = &'a [u8]; | ||||
| 	type Item = Rlp<'a>; | ||||
| 	type Iter = RlpIterator<'a, 'view>; | ||||
| 
 | ||||
| impl<'a, 'view> Rlp<'a> where 'a: 'view { | ||||
| 	/// Create a new instance of `Rlp`
 | ||||
| 	fn new(bytes: &'a [u8]) -> Rlp<'a> { | ||||
| 	pub fn new(bytes: &'a [u8]) -> Rlp<'a> { | ||||
| 		Rlp { | ||||
| 			rlp: UntrustedRlp::new(bytes) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn as_raw(&'view self) -> &'a [u8] { | ||||
| 	/// 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() | ||||
| 	} | ||||
| 
 | ||||
| 	fn prototype(&self) -> Self::Prototype { | ||||
| 	/// Get the prototype of the RLP.
 | ||||
| 	pub fn prototype(&self) -> Prototype { | ||||
| 		self.rlp.prototype().unwrap() | ||||
| 	} | ||||
| 
 | ||||
| 	fn payload_info(&self) -> Self::PayloadInfo { | ||||
| 	/// Get payload info.
 | ||||
| 	pub fn payload_info(&self) -> PayloadInfo { | ||||
| 		self.rlp.payload_info().unwrap() | ||||
| 	} | ||||
| 
 | ||||
| 	fn data(&'view self) -> Self::Data { | ||||
| 	/// Get underlieing data.
 | ||||
| 	pub fn data(&'view self) -> &'a [u8] { | ||||
| 		self.rlp.data().unwrap() | ||||
| 	} | ||||
| 
 | ||||
| 	fn item_count(&self) -> usize { | ||||
| 		self.rlp.item_count() | ||||
| 	/// 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) | ||||
| 	} | ||||
| 
 | ||||
| 	fn size(&self) -> usize { | ||||
| 	/// 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() | ||||
| 	} | ||||
| 
 | ||||
| 	fn at(&'view self, index: usize) -> Self::Item { | ||||
| 	/// 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()) | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_null(&self) -> bool { | ||||
| 	/// 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() | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_empty(&self) -> bool { | ||||
| 	/// 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() | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_list(&self) -> bool { | ||||
| 	/// 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() | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_data(&self) -> bool { | ||||
| 	/// 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() | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_int(&self) -> bool { | ||||
| 	/// 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() | ||||
| 	} | ||||
| 
 | ||||
| 	fn iter(&'view self) -> Self::Iter { | ||||
| 	/// 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<String> = rlp.iter().map(| i | i.as_val()).collect();
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	pub fn iter(&'view self) -> RlpIterator<'a, 'view> { | ||||
| 		self.into_iter() | ||||
| 	} | ||||
| 
 | ||||
| 	fn as_val<T>(&self) -> Result<T, DecoderError> where T: RlpDecodable { | ||||
| 		self.rlp.as_val() | ||||
| 	/// Decode data into an object
 | ||||
| 	pub fn as_val<T>(&self) -> T where T: Decodable { | ||||
| 		self.rlp.as_val().expect("Unexpected rlp error") | ||||
| 	} | ||||
| 
 | ||||
| 	fn val_at<T>(&self, index: usize) -> Result<T, DecoderError> where T: RlpDecodable { | ||||
| 		self.at(index).rlp.as_val() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl <'a, 'view> Rlp<'a> where 'a: 'view { | ||||
| 	fn view_as_val<T, R>(r: &'view R) -> T where R: View<'a, 'view>, T: RlpDecodable { | ||||
| 		let res: Result<T, DecoderError> = r.as_val(); | ||||
| 		res.unwrap_or_else(|e| panic!("DecodeError: {}, {}", e, r.as_raw().to_hex())) | ||||
| 	pub fn as_list<T>(&self) -> Vec<T> where T: Decodable { | ||||
| 		self.iter().map(|rlp| rlp.as_val()).collect() | ||||
| 	} | ||||
| 
 | ||||
| 	/// Decode into an object
 | ||||
| 	pub fn as_val<T>(&self) -> T where T: RlpDecodable { | ||||
| 		Self::view_as_val(self) | ||||
| 	/// Decode data at given list index into an object
 | ||||
| 	pub fn val_at<T>(&self, index: usize) -> T where T: Decodable { | ||||
| 		self.at(index).as_val() | ||||
| 	} | ||||
| 
 | ||||
| 	/// Decode list item at given index into an object
 | ||||
| 	pub fn val_at<T>(&self, index: usize) -> T where T: RlpDecodable { | ||||
| 		Self::view_as_val(&self.at(index)) | ||||
| 	pub fn list_at<T>(&self, index: usize) -> Vec<T> where T: Decodable { | ||||
| 		self.at(index).as_list() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -16,212 +16,12 @@ | ||||
| 
 | ||||
| //! Common RLP traits
 | ||||
| use elastic_array::ElasticArray1024; | ||||
| use stream::RlpStream; | ||||
| use {DecoderError, UntrustedRlp}; | ||||
| 
 | ||||
| /// Type is able to decode RLP.
 | ||||
| pub trait Decoder: Sized { | ||||
| 	/// Read a value from the RLP into a given type.
 | ||||
| 	fn read_value<T, F>(&self, f: &F) -> Result<T, DecoderError> | ||||
| 		where F: Fn(&[u8]) -> Result<T, DecoderError>; | ||||
| 
 | ||||
| 	/// Get underlying `UntrustedRLP` object.
 | ||||
| 	fn as_rlp(&self) -> &UntrustedRlp; | ||||
| 	/// Get underlying raw bytes slice.
 | ||||
| 	fn as_raw(&self) -> &[u8]; | ||||
| } | ||||
| use {DecoderError, UntrustedRlp, RlpStream}; | ||||
| 
 | ||||
| /// RLP decodable trait
 | ||||
| pub trait Decodable: Sized { | ||||
| 	/// Decode a value from RLP bytes
 | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError>  where D: Decoder; | ||||
| } | ||||
| 
 | ||||
| /// Internal helper trait. Implement `Decodable` for custom types.
 | ||||
| pub trait RlpDecodable: Sized { | ||||
| 	/// Decode a value from RLP bytes
 | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError>  where D: Decoder; | ||||
| } | ||||
| 
 | ||||
| /// A view into RLP encoded data
 | ||||
| pub trait View<'a, 'view>: Sized { | ||||
| 	/// RLP prototype type
 | ||||
| 	type Prototype; | ||||
| 	/// Payload info type
 | ||||
| 	type PayloadInfo; | ||||
| 	/// Data type
 | ||||
| 	type Data; | ||||
| 	/// Item type
 | ||||
| 	type Item; | ||||
| 	/// Iterator type
 | ||||
| 	type Iter; | ||||
| 
 | ||||
| 	/// Creates a new instance of `Rlp` reader
 | ||||
| 	fn new(bytes: &'a [u8]) -> Self; | ||||
| 
 | ||||
| 	/// 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']);
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn as_raw(&'view self) -> &'a [u8]; | ||||
| 
 | ||||
| 	/// Get the prototype of the RLP.
 | ||||
| 	fn prototype(&self) -> Self::Prototype; | ||||
| 
 | ||||
| 	/// Get payload info.
 | ||||
| 	fn payload_info(&self) -> Self::PayloadInfo; | ||||
| 
 | ||||
| 	/// Get underlieing data.
 | ||||
| 	fn data(&'view self) -> Self::Data; | ||||
| 
 | ||||
| 	/// 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);
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn item_count(&self) -> usize; | ||||
| 
 | ||||
| 	/// 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);
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn size(&self) -> usize; | ||||
| 
 | ||||
| 	/// 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());
 | ||||
| 	/// }
 | ||||
| 	fn at(&'view self, index: usize) -> Self::Item; | ||||
| 
 | ||||
| 	/// No value
 | ||||
| 	///
 | ||||
| 	/// ```rust
 | ||||
| 	/// extern crate rlp;
 | ||||
| 	/// use rlp::*;
 | ||||
| 	///
 | ||||
| 	/// fn main () {
 | ||||
| 	/// 	let data = vec![];
 | ||||
| 	/// 	let rlp = Rlp::new(&data);
 | ||||
| 	/// 	assert!(rlp.is_null());
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn is_null(&self) -> bool; | ||||
| 
 | ||||
| 	/// 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());
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn is_empty(&self) -> bool; | ||||
| 
 | ||||
| 	/// 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());
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn is_list(&self) -> bool; | ||||
| 
 | ||||
| 	/// 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());
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn is_data(&self) -> bool; | ||||
| 
 | ||||
| 	/// 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);
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn is_int(&self) -> bool; | ||||
| 
 | ||||
| 	/// 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<String> = rlp.iter().map(| i | i.as_val()).collect();
 | ||||
| 	/// }
 | ||||
| 	/// ```
 | ||||
| 	fn iter(&'view self) -> Self::Iter; | ||||
| 
 | ||||
| 	/// Decode data into an object
 | ||||
| 	fn as_val<T>(&self) -> Result<T, DecoderError> where T: RlpDecodable; | ||||
| 
 | ||||
| 	/// Decode data at given list index into an object
 | ||||
| 	fn val_at<T>(&self, index: usize) -> Result<T, DecoderError> where T: RlpDecodable; | ||||
| 	fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError>; | ||||
| } | ||||
| 
 | ||||
| /// Structure encodable to RLP
 | ||||
|  | ||||
| @ -17,9 +17,8 @@ | ||||
| use std::cell::Cell; | ||||
| use std::fmt; | ||||
| use rustc_serialize::hex::ToHex; | ||||
| 
 | ||||
| use bytes::{FromBytes, FromBytesResult, FromBytesError}; | ||||
| use ::{View, Decoder, Decodable, DecoderError, RlpDecodable}; | ||||
| use impls::decode_usize; | ||||
| use {Decodable, DecoderError}; | ||||
| 
 | ||||
| /// rlp offset
 | ||||
| #[derive(Copy, Clone, Debug)] | ||||
| @ -64,7 +63,7 @@ fn calculate_payload_info(header_bytes: &[u8], len_of_len: usize) -> Result<Payl | ||||
| 		_ => (), | ||||
| 	} | ||||
| 	if header_bytes.len() < header_len { return Err(DecoderError::RlpIsTooShort); } | ||||
| 	let value_len = usize::from_bytes(&header_bytes[1..header_len])?; | ||||
| 	let value_len = decode_usize(&header_bytes[1..header_len])?; | ||||
| 	Ok(PayloadInfo::new(header_len, value_len)) | ||||
| } | ||||
| 
 | ||||
| @ -141,15 +140,8 @@ impl<'a> fmt::Display for UntrustedRlp<'a> { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view { | ||||
| 	type Prototype = Result<Prototype, DecoderError>; | ||||
| 	type PayloadInfo = Result<PayloadInfo, DecoderError>; | ||||
| 	type Data = Result<&'a [u8], DecoderError>; | ||||
| 	type Item = Result<UntrustedRlp<'a>, DecoderError>; | ||||
| 	type Iter = UntrustedRlpIterator<'a, 'view>; | ||||
| 
 | ||||
| 	//returns new instance of `UntrustedRlp`
 | ||||
| 	fn new(bytes: &'a [u8]) -> UntrustedRlp<'a> { | ||||
| 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)), | ||||
| @ -157,45 +149,45 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn as_raw(&'view self) -> &'a [u8] { | ||||
| 	pub fn as_raw(&'view self) -> &'a [u8] { | ||||
| 		self.bytes | ||||
| 	} | ||||
| 
 | ||||
| 	fn prototype(&self) -> Self::Prototype { | ||||
| 	pub fn prototype(&self) -> Result<Prototype, DecoderError> { | ||||
| 		// optimize? && return appropriate errors
 | ||||
| 		if self.is_data() { | ||||
| 			Ok(Prototype::Data(self.size())) | ||||
| 		} else if self.is_list() { | ||||
| 			Ok(Prototype::List(self.item_count())) | ||||
| 			self.item_count().map(Prototype::List) | ||||
| 		} else { | ||||
| 			Ok(Prototype::Null) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn payload_info(&self) -> Self::PayloadInfo { | ||||
| 	pub fn payload_info(&self) -> Result<PayloadInfo, DecoderError> { | ||||
| 		BasicDecoder::payload_info(self.bytes) | ||||
| 	} | ||||
| 
 | ||||
| 	fn data(&'view self) -> Self::Data { | ||||
| 	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)]) | ||||
| 	} | ||||
| 
 | ||||
| 	fn item_count(&self) -> usize { | ||||
| 	pub fn item_count(&self) -> Result<usize, DecoderError> { | ||||
| 		match self.is_list() { | ||||
| 			true => match self.count_cache.get() { | ||||
| 				Some(c) => c, | ||||
| 				Some(c) => Ok(c), | ||||
| 				None => { | ||||
| 					let c = self.iter().count(); | ||||
| 					self.count_cache.set(Some(c)); | ||||
| 					c | ||||
| 					Ok(c) | ||||
| 				} | ||||
| 			}, | ||||
| 			false => 0 | ||||
| 			false => Err(DecoderError::RlpExpectedToBeList), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn size(&self) -> usize { | ||||
| 	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), | ||||
| @ -203,7 +195,7 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn at(&'view self, index: usize) -> Self::Item { | ||||
| 	pub fn at(&'view self, index: usize) -> Result<UntrustedRlp<'a>, DecoderError> { | ||||
| 		if !self.is_list() { | ||||
| 			return Err(DecoderError::RlpExpectedToBeList); | ||||
| 		} | ||||
| @ -213,7 +205,7 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view { | ||||
| 		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_prefix()?, index), | ||||
| 			false => (self.consume_list_payload()?, index), | ||||
| 		}; | ||||
| 
 | ||||
| 		// skip up to x items
 | ||||
| @ -227,23 +219,23 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view { | ||||
| 		Ok(UntrustedRlp::new(&bytes[0..found.header_len + found.value_len])) | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_null(&self) -> bool { | ||||
| 	pub fn is_null(&self) -> bool { | ||||
| 		self.bytes.len() == 0 | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_empty(&self) -> bool { | ||||
| 	pub fn is_empty(&self) -> bool { | ||||
| 		!self.is_null() && (self.bytes[0] == 0xc0 || self.bytes[0] == 0x80) | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_list(&self) -> bool { | ||||
| 	pub fn is_list(&self) -> bool { | ||||
| 		!self.is_null() && self.bytes[0] >= 0xc0 | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_data(&self) -> bool { | ||||
| 	pub fn is_data(&self) -> bool { | ||||
| 		!self.is_null() && self.bytes[0] < 0xc0 | ||||
| 	} | ||||
| 
 | ||||
| 	fn is_int(&self) -> bool { | ||||
| 	pub fn is_int(&self) -> bool { | ||||
| 		if self.is_null() { | ||||
| 			return false; | ||||
| 		} | ||||
| @ -256,23 +248,32 @@ impl<'a, 'view> View<'a, 'view> for UntrustedRlp<'a> where 'a: 'view { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn iter(&'view self) -> Self::Iter { | ||||
| 	pub fn iter(&'view self) -> UntrustedRlpIterator<'a, 'view> { | ||||
| 		self.into_iter() | ||||
| 	} | ||||
| 
 | ||||
| 	fn as_val<T>(&self) -> Result<T, DecoderError> where T: RlpDecodable { | ||||
| 		// optimize, so it doesn't use clone (although This clone is cheap)
 | ||||
| 		T::decode(&BasicDecoder::new(self.clone())) | ||||
| 	pub fn as_val<T>(&self) -> Result<T, DecoderError> where T: Decodable { | ||||
| 		T::decode(self) | ||||
| 	} | ||||
| 
 | ||||
| 	fn val_at<T>(&self, index: usize) -> Result<T, DecoderError> where T: RlpDecodable { | ||||
| 	pub fn as_list<T>(&self) -> Result<Vec<T>, DecoderError> where T: Decodable { | ||||
| 		self.iter().map(|rlp| rlp.as_val()).collect() | ||||
| 	} | ||||
| 
 | ||||
| 	pub fn val_at<T>(&self, index: usize) -> Result<T, DecoderError> where T: Decodable { | ||||
| 		self.at(index)?.as_val() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<'a> UntrustedRlp<'a> { | ||||
| 	pub fn list_at<T>(&self, index: usize) -> Result<Vec<T>, 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_prefix(&self) -> Result<&'a [u8], DecoderError> { | ||||
| 	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) | ||||
| @ -327,7 +328,7 @@ impl<'a, 'view> Iterator for UntrustedRlpIterator<'a, 'view> { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct BasicDecoder<'a> { | ||||
| pub struct BasicDecoder<'a> { | ||||
| 	rlp: UntrustedRlp<'a> | ||||
| } | ||||
| 
 | ||||
| @ -346,10 +347,8 @@ impl<'a> BasicDecoder<'a> { | ||||
| 			_ => Err(DecoderError::RlpIsTooShort), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<'a> Decoder for BasicDecoder<'a> { | ||||
| 	fn read_value<T, F>(&self, f: &F) -> Result<T, DecoderError> | ||||
| 	pub fn decode_value<T, F>(&self, f: F) -> Result<T, DecoderError> | ||||
| 		where F: Fn(&[u8]) -> Result<T, DecoderError> { | ||||
| 
 | ||||
| 		let bytes = self.rlp.as_raw(); | ||||
| @ -378,7 +377,7 @@ impl<'a> Decoder for BasicDecoder<'a> { | ||||
| 				if bytes.len() < begin_of_value { | ||||
| 					return Err(DecoderError::RlpInconsistentLengthAndData); | ||||
| 				} | ||||
| 				let len = usize::from_bytes(&bytes[1..begin_of_value])?; | ||||
| 				let len = decode_usize(&bytes[1..begin_of_value])?; | ||||
| 
 | ||||
| 				let last_index_of_value = begin_of_value + len; | ||||
| 				if bytes.len() < last_index_of_value { | ||||
| @ -390,108 +389,12 @@ impl<'a> Decoder for BasicDecoder<'a> { | ||||
| 			_ => Err(DecoderError::RlpExpectedToBeData) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn as_raw(&self) -> &[u8] { | ||||
| 		self.rlp.as_raw() | ||||
| 	} | ||||
| 
 | ||||
| 	fn as_rlp(&self) -> &UntrustedRlp { | ||||
| 		&self.rlp | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<T> Decodable for T where T: FromBytes { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		decoder.read_value(&|bytes: &[u8]| Ok(T::from_bytes(bytes)?)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<T> Decodable for Vec<T> where T: Decodable { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		decoder.as_rlp().iter().map(|d| T::decode(&BasicDecoder::new(d))).collect() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl<T> Decodable for Option<T> where T: Decodable { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		decoder.as_rlp().iter().map(|d| T::decode(&BasicDecoder::new(d))).collect::<Result<Vec<_>, DecoderError>>().map(|mut a| a.pop()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Decodable for Vec<u8> { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		decoder.read_value(&|bytes: &[u8]| Ok(bytes.to_vec())) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_array_decodable { | ||||
| 	($index_type:ty, $len:expr ) => ( | ||||
| 		impl<T> Decodable for [T; $len] where T: Decodable { | ||||
| 			fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 				let decoders = decoder.as_rlp(); | ||||
| 
 | ||||
| 				let mut result: [T; $len] = unsafe { ::std::mem::uninitialized() }; | ||||
| 				if decoders.item_count() != $len { | ||||
| 					return Err(DecoderError::RlpIncorrectListLen); | ||||
| 				} | ||||
| 
 | ||||
| 				for i in 0..decoders.item_count() { | ||||
| 					result[i] = T::decode(&BasicDecoder::new(decoders.at(i)?))?; | ||||
| 				} | ||||
| 
 | ||||
| 				Ok(result) | ||||
| 			} | ||||
| 		} | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_array_decodable_recursive { | ||||
| 	($index_type:ty, ) => (); | ||||
| 	($index_type:ty, $len:expr, $($more:expr,)*) => ( | ||||
| 		impl_array_decodable!($index_type, $len); | ||||
| 		impl_array_decodable_recursive!($index_type, $($more,)*); | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| impl_array_decodable_recursive!( | ||||
| 	u8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, | ||||
| 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, | ||||
| 	32, 40, 48, 56, 64, 72, 96, 128, 160, 192, 224, | ||||
| ); | ||||
| 
 | ||||
| impl<T> RlpDecodable for T where T: Decodable { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		Decodable::decode(decoder) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct DecodableU8 (u8); | ||||
| 
 | ||||
| impl FromBytes for DecodableU8 { | ||||
| 	fn from_bytes(bytes: &[u8]) -> FromBytesResult<DecodableU8> { | ||||
| 		match bytes.len() { | ||||
| 			0 => Ok(DecodableU8(0u8)), | ||||
| 			1 => { | ||||
| 				if bytes[0] == 0 { | ||||
| 					return Err(FromBytesError::ZeroPrefixedInt) | ||||
| 				} | ||||
| 				Ok(DecodableU8(bytes[0])) | ||||
| 			} | ||||
| 			_ => Err(FromBytesError::DataIsTooLong) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl RlpDecodable for u8 { | ||||
| 	fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { | ||||
| 		let u: DecodableU8 = Decodable::decode(decoder)?; | ||||
| 		Ok(u.0) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
| 	use ::{UntrustedRlp, View}; | ||||
| 	use UntrustedRlp; | ||||
| 
 | ||||
| 	#[test] | ||||
| 	fn test_rlp_display() { | ||||
| 		use rustc_serialize::hex::FromHex; | ||||
|  | ||||
| @ -14,9 +14,12 @@ | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| extern crate ethcore_bigint as bigint; | ||||
| extern crate rlp; | ||||
| 
 | ||||
| use std::{fmt, cmp}; | ||||
| use bigint::prelude::U256; | ||||
| use {Encodable, RlpDecodable, UntrustedRlp, RlpStream, View, DecoderError}; | ||||
| use rlp::{Encodable, Decodable, UntrustedRlp, RlpStream, DecoderError}; | ||||
| 
 | ||||
| #[test] | ||||
| fn rlp_at() { | ||||
| @ -24,7 +27,7 @@ fn rlp_at() { | ||||
| 	{ | ||||
| 		let rlp = UntrustedRlp::new(&data); | ||||
| 		assert!(rlp.is_list()); | ||||
| 		let animals: Vec<String> = rlp.as_val().unwrap(); | ||||
| 		let animals: Vec<String> = rlp.as_list().unwrap(); | ||||
| 		assert_eq!(animals, vec!["cat".to_owned(), "dog".to_owned()]); | ||||
| 
 | ||||
| 		let cat = rlp.at(0).unwrap(); | ||||
| @ -89,7 +92,7 @@ fn run_encode_tests<T>(tests: Vec<ETestPair<T>>) | ||||
| 	where T: Encodable | ||||
| { | ||||
| 	for t in &tests { | ||||
| 		let res = super::encode(&t.0); | ||||
| 		let res = rlp::encode(&t.0); | ||||
| 		assert_eq!(&res[..], &t.1[..]); | ||||
| 	} | ||||
| } | ||||
| @ -100,7 +103,7 @@ fn run_encode_tests_list<T>(tests: Vec<VETestPair<T>>) | ||||
| 	where T: Encodable | ||||
| { | ||||
| 	for t in &tests { | ||||
| 		let res = super::encode_list(&t.0); | ||||
| 		let res = rlp::encode_list(&t.0); | ||||
| 		assert_eq!(&res[..], &t.1[..]); | ||||
| 	} | ||||
| } | ||||
| @ -210,11 +213,20 @@ fn encode_vector_str() { | ||||
| 	run_encode_tests_list(tests); | ||||
| } | ||||
| 
 | ||||
| struct DTestPair<T>(T, Vec<u8>) where T: RlpDecodable + fmt::Debug + cmp::Eq; | ||||
| struct DTestPair<T>(T, Vec<u8>) where T: Decodable + fmt::Debug + cmp::Eq; | ||||
| 
 | ||||
| fn run_decode_tests<T>(tests: Vec<DTestPair<T>>) where T: RlpDecodable + fmt::Debug + cmp::Eq { | ||||
| struct VDTestPair<T>(Vec<T>, Vec<u8>) where T: Decodable + fmt::Debug + cmp::Eq; | ||||
| 
 | ||||
| fn run_decode_tests<T>(tests: Vec<DTestPair<T>>) where T: Decodable + fmt::Debug + cmp::Eq { | ||||
| 	for t in &tests { | ||||
| 		let res: T = super::decode(&t.1); | ||||
| 		let res: T = rlp::decode(&t.1); | ||||
| 		assert_eq!(res, t.0); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn run_decode_tests_list<T>(tests: Vec<VDTestPair<T>>) where T: Decodable + fmt::Debug + cmp::Eq { | ||||
| 	for t in &tests { | ||||
| 		let res: Vec<T> = rlp::decode_list(&t.1); | ||||
| 		assert_eq!(res, t.0); | ||||
| 	} | ||||
| } | ||||
| @ -318,35 +330,19 @@ fn decode_untrusted_address() { | ||||
| #[test] | ||||
| fn decode_untrusted_vector_u64() { | ||||
| 	let tests = vec![ | ||||
| 		DTestPair(vec![], vec![0xc0]), | ||||
| 		DTestPair(vec![15u64], vec![0xc1, 0x0f]), | ||||
| 		DTestPair(vec![1, 2, 3, 7, 0xff], vec![0xc6, 1, 2, 3, 7, 0x81, 0xff]), | ||||
| 		DTestPair(vec![0xffffffff, 1, 2, 3, 7, 0xff], vec![0xcb, 0x84, 0xff, 0xff, 0xff, 0xff,  1, 2, 3, 7, 0x81, 0xff]), | ||||
| 		VDTestPair(vec![], vec![0xc0]), | ||||
| 		VDTestPair(vec![15u64], vec![0xc1, 0x0f]), | ||||
| 		VDTestPair(vec![1, 2, 3, 7, 0xff], vec![0xc6, 1, 2, 3, 7, 0x81, 0xff]), | ||||
| 		VDTestPair(vec![0xffffffff, 1, 2, 3, 7, 0xff], vec![0xcb, 0x84, 0xff, 0xff, 0xff, 0xff,  1, 2, 3, 7, 0x81, 0xff]), | ||||
| 	]; | ||||
| 	run_decode_tests(tests); | ||||
| 	run_decode_tests_list(tests); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn decode_untrusted_vector_str() { | ||||
| 	let tests = vec![DTestPair(vec!["cat".to_owned(), "dog".to_owned()], | ||||
| 	let tests = vec![VDTestPair(vec!["cat".to_owned(), "dog".to_owned()], | ||||
| 							   vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'])]; | ||||
| 	run_decode_tests(tests); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn decode_untrusted_vector_of_vectors_str() { | ||||
| 	let tests = vec![DTestPair(vec![vec!["cat".to_owned()]], | ||||
| 							   vec![0xc5, 0xc4, 0x83, b'c', b'a', b't'])]; | ||||
| 	run_decode_tests(tests); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_decoding_array() { | ||||
| 	let v = vec![5u16, 2u16]; | ||||
| 	let res = super::encode_list(&v); | ||||
| 	let arr: [u16; 2] = super::decode(&res); | ||||
| 	assert_eq!(arr[0], 5); | ||||
| 	assert_eq!(arr[1], 2); | ||||
| 	run_decode_tests_list(tests); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| @ -290,7 +290,7 @@ impl EarlyMergeDB { | ||||
| 					&r.drain() | ||||
| 				}).expect("Low-level database error.") { | ||||
| 					let rlp = Rlp::new(&rlp_data); | ||||
| 					let inserts: Vec<H256> = rlp.val_at(1); | ||||
| 					let inserts: Vec<H256> = rlp.list_at(1); | ||||
| 					Self::replay_keys(&inserts, db, col, &mut refs); | ||||
| 					index += 1; | ||||
| 				}; | ||||
| @ -466,11 +466,11 @@ impl JournalDB for EarlyMergeDB { | ||||
| 			&last | ||||
| 		})? { | ||||
| 			let rlp = Rlp::new(&rlp_data); | ||||
| 			let inserts: Vec<H256> = rlp.val_at(1); | ||||
| 			let inserts: Vec<H256> = rlp.list_at(1); | ||||
| 
 | ||||
| 			if canon_id == &rlp.val_at::<H256>(0) { | ||||
| 				// Collect keys to be removed. Canon block - remove the (enacted) deletes.
 | ||||
| 				let deletes: Vec<H256> = rlp.val_at(2); | ||||
| 				let deletes: Vec<H256> = rlp.list_at(2); | ||||
| 				trace!(target: "jdb.ops", "  Expunging: {:?}", deletes); | ||||
| 				Self::remove_keys(&deletes, &mut refs, batch, self.column, RemoveFrom::Archive, trace); | ||||
| 
 | ||||
|  | ||||
| @ -155,7 +155,7 @@ impl OverlayRecentDB { | ||||
| 					let rlp = Rlp::new(&rlp_data); | ||||
| 					let id: H256 = rlp.val_at(0); | ||||
| 					let insertions = rlp.at(1); | ||||
| 					let deletions: Vec<H256> = rlp.val_at(2); | ||||
| 					let deletions: Vec<H256> = rlp.list_at(2); | ||||
| 					let mut inserted_keys = Vec::new(); | ||||
| 					for r in insertions.iter() { | ||||
| 						let k: H256 = r.val_at(0); | ||||
|  | ||||
| @ -171,7 +171,7 @@ impl JournalDB for RefCountedDB { | ||||
| 		} { | ||||
| 			let rlp = Rlp::new(&rlp_data); | ||||
| 			let our_id: H256 = rlp.val_at(0); | ||||
| 			let to_remove: Vec<H256> = rlp.val_at(if *canon_id == our_id {2} else {1}); | ||||
| 			let to_remove: Vec<H256> = rlp.list_at(if *canon_id == our_id {2} else {1}); | ||||
| 			trace!(target: "rcdb", "delete journal for time #{}.{}=>{}, (canon was {}): deleting {:?}", end_era, index, our_id, canon_id, to_remove); | ||||
| 			for i in &to_remove { | ||||
| 				self.forward.remove(i); | ||||
|  | ||||
| @ -23,7 +23,7 @@ use std::path::PathBuf; | ||||
| use common::*; | ||||
| use elastic_array::*; | ||||
| use hashdb::DBValue; | ||||
| use rlp::{UntrustedRlp, RlpType, View, Compressible}; | ||||
| use rlp::{UntrustedRlp, RlpType, Compressible}; | ||||
| use rocksdb::{DB, Writable, WriteBatch, WriteOptions, IteratorMode, DBIterator, | ||||
| 	Options, DBCompactionStyle, BlockBasedOptions, Direction, Cache, Column, ReadOptions}; | ||||
| #[cfg(target_os = "linux")] | ||||
|  | ||||
| @ -18,7 +18,7 @@ | ||||
| 
 | ||||
| use hashdb::HashDB; | ||||
| use nibbleslice::NibbleSlice; | ||||
| use rlp::{Rlp, View}; | ||||
| use rlp::Rlp; | ||||
| use ::{H256}; | ||||
| 
 | ||||
| use super::{TrieError, Query}; | ||||
|  | ||||
| @ -24,7 +24,7 @@ use super::node::NodeKey; | ||||
| use ::{HashDB, H256}; | ||||
| use ::bytes::ToPretty; | ||||
| use ::nibbleslice::NibbleSlice; | ||||
| use ::rlp::{Rlp, RlpStream, View}; | ||||
| use ::rlp::{Rlp, RlpStream}; | ||||
| use ::sha3::SHA3_NULL_RLP; | ||||
| use hashdb::DBValue; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user