initial request definitions
This commit is contained in:
		
							parent
							
								
									af235e564e
								
							
						
					
					
						commit
						bbb50caa89
					
				| @ -57,7 +57,7 @@ mod types; | ||||
| 
 | ||||
| pub use self::provider::Provider; | ||||
| pub use self::transaction_queue::TransactionQueue; | ||||
| pub use types::les_request as request; | ||||
| pub use types::request as request; | ||||
| 
 | ||||
| #[macro_use] | ||||
| extern crate log; | ||||
|  | ||||
| @ -1,228 +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/>.
 | ||||
| 
 | ||||
| //! LES request types.
 | ||||
| 
 | ||||
| use ethcore::transaction::Action; | ||||
| use util::{Address, H256, U256, Uint}; | ||||
| 
 | ||||
| /// Either a hash or a number.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub enum HashOrNumber { | ||||
| 	/// Block hash variant.
 | ||||
| 	Hash(H256), | ||||
| 	/// Block number variant.
 | ||||
| 	Number(u64), | ||||
| } | ||||
| 
 | ||||
| impl From<H256> for HashOrNumber { | ||||
| 	fn from(hash: H256) -> Self { | ||||
| 		HashOrNumber::Hash(hash) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl From<u64> for HashOrNumber { | ||||
| 	fn from(num: u64) -> Self { | ||||
| 		HashOrNumber::Number(num) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// A request for block headers.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct Headers { | ||||
| 	/// Starting block number or hash.
 | ||||
| 	pub start: HashOrNumber, | ||||
| 	/// The maximum amount of headers which can be returned.
 | ||||
| 	pub max: usize, | ||||
| 	/// The amount of headers to skip between each response entry.
 | ||||
| 	pub skip: u64, | ||||
| 	/// Whether the headers should proceed in falling number from the initial block.
 | ||||
| 	pub reverse: bool, | ||||
| } | ||||
| 
 | ||||
| /// A request for specific block bodies.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct Bodies { | ||||
| 	/// Hashes which bodies are being requested for.
 | ||||
| 	pub block_hashes: Vec<H256> | ||||
| } | ||||
| 
 | ||||
| /// A request for transaction receipts.
 | ||||
| ///
 | ||||
| /// This request is answered with a list of transaction receipts for each block
 | ||||
| /// requested.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct Receipts { | ||||
| 	/// Block hashes to return receipts for.
 | ||||
| 	pub block_hashes: Vec<H256>, | ||||
| } | ||||
| 
 | ||||
| /// A request for a state proof
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct StateProof { | ||||
| 	/// Block hash to query state from.
 | ||||
| 	pub block: H256, | ||||
| 	/// Key of the state trie -- corresponds to account hash.
 | ||||
| 	pub key1: H256, | ||||
| 	/// Key in that account's storage trie; if empty, then the account RLP should be
 | ||||
| 	/// returned.
 | ||||
| 	pub key2: Option<H256>, | ||||
| 	/// if greater than zero, trie nodes beyond this level may be omitted.
 | ||||
| 	pub from_level: u32, // could even safely be u8; trie w/ 32-byte key can be at most 64-levels deep.
 | ||||
| } | ||||
| 
 | ||||
| /// A request for state proofs.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct StateProofs { | ||||
| 	/// All the proof requests.
 | ||||
| 	pub requests: Vec<StateProof>, | ||||
| } | ||||
| 
 | ||||
| /// A request for contract code.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct ContractCode { | ||||
| 	/// Block hash
 | ||||
| 	pub block_hash: H256, | ||||
| 	/// Account key (== sha3(address))
 | ||||
| 	pub account_key: H256, | ||||
| } | ||||
| 
 | ||||
| /// A request for contract code.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct ContractCodes { | ||||
| 	/// Block hash and account key (== sha3(address)) pairs to fetch code for.
 | ||||
| 	pub code_requests: Vec<ContractCode>, | ||||
| } | ||||
| 
 | ||||
| /// A request for a header proof from the Canonical Hash Trie.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct HeaderProof { | ||||
| 	/// Number of the CHT.
 | ||||
| 	pub cht_number: u64, | ||||
| 	/// Block number requested. May not be 0: genesis isn't included in any CHT.
 | ||||
| 	pub block_number: u64, | ||||
| 	/// If greater than zero, trie nodes beyond this level may be omitted.
 | ||||
| 	pub from_level: u32, | ||||
| } | ||||
| 
 | ||||
| /// A request for header proofs from the CHT.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct HeaderProofs { | ||||
| 	/// All the proof requests.
 | ||||
| 	pub requests: Vec<HeaderProof>, | ||||
| } | ||||
| 
 | ||||
| /// A request for proof of (simulated) transaction execution.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub struct TransactionProof { | ||||
| 	/// Block hash to request for.
 | ||||
| 	pub at: H256, | ||||
| 	/// Address to treat as the caller.
 | ||||
| 	pub from: Address, | ||||
| 	/// Action to take: either a call or a create.
 | ||||
| 	pub action: Action, | ||||
| 	/// Amount of gas to request proof-of-execution for.
 | ||||
| 	pub gas: U256, | ||||
| 	/// Price for each gas.
 | ||||
| 	pub gas_price: U256, | ||||
| 	/// Value to simulate sending.
 | ||||
| 	pub value: U256, | ||||
| 	/// Transaction data.
 | ||||
| 	pub data: Vec<u8>, | ||||
| } | ||||
| 
 | ||||
| /// Kinds of requests.
 | ||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub enum Kind { | ||||
| 	/// Requesting headers.
 | ||||
| 	Headers, | ||||
| 	/// Requesting block bodies.
 | ||||
| 	Bodies, | ||||
| 	/// Requesting transaction receipts.
 | ||||
| 	Receipts, | ||||
| 	/// Requesting proofs of state trie nodes.
 | ||||
| 	StateProofs, | ||||
| 	/// Requesting contract code by hash.
 | ||||
| 	Codes, | ||||
| 	/// Requesting header proofs (from the CHT).
 | ||||
| 	HeaderProofs, | ||||
| 	/// Requesting proof of transaction execution.
 | ||||
| 	TransactionProof, | ||||
| } | ||||
| 
 | ||||
| /// Encompasses all possible types of requests in a single structure.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub enum Request { | ||||
| 	/// Requesting headers.
 | ||||
| 	Headers(Headers), | ||||
| 	/// Requesting block bodies.
 | ||||
| 	Bodies(Bodies), | ||||
| 	/// Requesting transaction receipts.
 | ||||
| 	Receipts(Receipts), | ||||
| 	/// Requesting state proofs.
 | ||||
| 	StateProofs(StateProofs), | ||||
| 	/// Requesting contract codes.
 | ||||
| 	Codes(ContractCodes), | ||||
| 	/// Requesting header proofs.
 | ||||
| 	HeaderProofs(HeaderProofs), | ||||
| 	/// Requesting proof of transaction execution.
 | ||||
| 	TransactionProof(TransactionProof), | ||||
| } | ||||
| 
 | ||||
| impl Request { | ||||
| 	/// Get the kind of request this is.
 | ||||
| 	pub fn kind(&self) -> Kind { | ||||
| 		match *self { | ||||
| 			Request::Headers(_) => Kind::Headers, | ||||
| 			Request::Bodies(_) => Kind::Bodies, | ||||
| 			Request::Receipts(_) => Kind::Receipts, | ||||
| 			Request::StateProofs(_) => Kind::StateProofs, | ||||
| 			Request::Codes(_) => Kind::Codes, | ||||
| 			Request::HeaderProofs(_) => Kind::HeaderProofs, | ||||
| 			Request::TransactionProof(_) => Kind::TransactionProof, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/// Get the amount of requests being made.
 | ||||
| 	/// In the case of `TransactionProof`, this is the amount of gas being requested.
 | ||||
| 	pub fn amount(&self) -> usize { | ||||
| 		match *self { | ||||
| 			Request::Headers(ref req) => req.max, | ||||
| 			Request::Bodies(ref req) => req.block_hashes.len(), | ||||
| 			Request::Receipts(ref req) => req.block_hashes.len(), | ||||
| 			Request::StateProofs(ref req) => req.requests.len(), | ||||
| 			Request::Codes(ref req) => req.code_requests.len(), | ||||
| 			Request::HeaderProofs(ref req) => req.requests.len(), | ||||
| 			Request::TransactionProof(ref req) => match req.gas > usize::max_value().into() { | ||||
| 				true => usize::max_value(), | ||||
| 				false => req.gas.low_u64() as usize, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @ -14,4 +14,4 @@ | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| pub mod les_request; | ||||
| pub mod request; | ||||
|  | ||||
							
								
								
									
										707
									
								
								ethcore/light/src/types/request.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										707
									
								
								ethcore/light/src/types/request.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,707 @@ | ||||
| // 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/>.
 | ||||
| 
 | ||||
| //! Light protocol request types.
 | ||||
| 
 | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use ethcore::transaction::Action; | ||||
| use util::{Address, H256, U256, Uint}; | ||||
| 
 | ||||
| // re-exports of request types.
 | ||||
| pub use self::header::{ | ||||
| 	Complete as CompleteHeadersRequest, | ||||
| 	Incomplete as IncompleteHeadersRequest, | ||||
| 	Response as HeadersResponse | ||||
| }; | ||||
| pub use self::header_proof::{ | ||||
| 	Complete as CompleteHeaderProofRequest, | ||||
| 	Incomplete as IncompleteHeaderProofRequest, | ||||
| 	Response as HeaderProofResponse | ||||
| }; | ||||
| pub use self::block_body::{ | ||||
| 	Complete as CompleteBodyRequest, | ||||
| 	Incomplete as IncompleteBodyRequest, | ||||
| 	Response as BodyResponse | ||||
| }; | ||||
| pub use self::receipts::{ | ||||
| 	Complete as CompleteReceiptsRequest, | ||||
| 	Incomplete as IncompleteReceiptsRequest | ||||
| 	Response as ReceiptsResponse | ||||
| }; | ||||
| pub use self::account::{ | ||||
| 	Complete as CompleteAccountRequest, | ||||
| 	Incomplete as IncompleteAccountRequest, | ||||
| 	Response as AccountResponse, | ||||
| }; | ||||
| pub use self::storage::{ | ||||
| 	Complete as CompleteStorageRequest, | ||||
| 	Incomplete as IncompleteStorageRequest, | ||||
| 	Response as StorageResponse | ||||
| }; | ||||
| pub use self::contract_code::{ | ||||
| 	Complete as CompleteCodeRequest, | ||||
| 	Incomplete as IncompleteCodeRequest, | ||||
| 	Response as CodeResponse, | ||||
| }; | ||||
| 
 | ||||
| /// Error indicating a reference to a non-existent or wrongly-typed output.
 | ||||
| pub struct NoSuchOutput; | ||||
| 
 | ||||
| /// An input to a request.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| pub enum Field<T> { | ||||
| 	/// A pre-specified input.
 | ||||
| 	Scalar(T), | ||||
| 	/// An input which can be resolved later on.
 | ||||
| 	/// (Request index, output index)
 | ||||
| 	BackReference(usize, usize), | ||||
| } | ||||
| 
 | ||||
| impl From<T> for Field<T> { | ||||
| 	fn from(val: T) -> Self { | ||||
| 		Field::Scalar(val) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// Request outputs which can be reused as inputs.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| pub enum Output { | ||||
| 	/// A 32-byte hash output.
 | ||||
| 	Hash(H256), | ||||
| 	/// An unsigned-integer output.
 | ||||
| 	Number(u64), | ||||
| } | ||||
| 
 | ||||
| /// Response output kinds which can be used as back-references.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| pub enum OutputKind { | ||||
| 	/// A 32-byte hash output.
 | ||||
| 	Hash, | ||||
| 	/// An unsigned-integer output.
 | ||||
| 	Number, | ||||
| } | ||||
| 
 | ||||
| /// Either a hash or a number.
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||||
| #[cfg_attr(feature = "ipc", binary)] | ||||
| pub enum HashOrNumber { | ||||
| 	/// Block hash variant.
 | ||||
| 	Hash(H256), | ||||
| 	/// Block number variant.
 | ||||
| 	Number(u64), | ||||
| } | ||||
| 
 | ||||
| impl From<H256> for HashOrNumber { | ||||
| 	fn from(hash: H256) -> Self { | ||||
| 		HashOrNumber::Hash(hash) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl From<u64> for HashOrNumber { | ||||
| 	fn from(num: u64) -> Self { | ||||
| 		HashOrNumber::Number(num) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// A potentially incomplete request.
 | ||||
| pub trait IncompleteRequest: Sized { | ||||
| 	type Complete; | ||||
| 
 | ||||
| 	/// Check prior outputs against the needed inputs.
 | ||||
| 	///
 | ||||
| 	/// This is called to ensure consistency of this request with
 | ||||
| 	/// others in the same packet.
 | ||||
| 	fn check_outputs<F>(&self, f: F) -> Result<(), NoSuchOutput> | ||||
| 		where F: FnMut(usize, usize, OutputKind) -> Result<(), NoSuchOutput>; | ||||
| 
 | ||||
| 	/// Note that this request will produce the following outputs.
 | ||||
| 	fn note_outputs<F>(&self, f: F) where F: FnMut(usize, OutputKind); | ||||
| 
 | ||||
| 	/// Fill the request.
 | ||||
| 	///
 | ||||
| 	/// This function is provided an "output oracle" which allows fetching of
 | ||||
| 	/// prior request outputs.
 | ||||
| 	/// Only outputs previously checked with `check_outputs` will be available.
 | ||||
| 	fn fill<F>(self, oracle: F) -> Result<Self::Complete, NoSuchOutput> | ||||
| 		where F: Fn(usize, usize) -> Result<Output, NoSuchOutput>; | ||||
| } | ||||
| 
 | ||||
| /// Header request.
 | ||||
| pub mod header { | ||||
| 	use super::{Field, HashOrNumber, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::encoded; | ||||
| 	use util::U256; | ||||
| 
 | ||||
| 	/// Potentially incomplete headers request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Incomplete { | ||||
| 		/// Start block.
 | ||||
| 		pub start: Field<HashOrNumber>, | ||||
| 		/// Skip between.
 | ||||
| 		pub skip: U256, | ||||
| 		/// Maximum to return.
 | ||||
| 		pub max: U256, | ||||
| 		/// Whether to reverse from start.
 | ||||
| 		pub reverse: bool, | ||||
| 	} | ||||
| 
 | ||||
| 	impl super::IncompleteRequest for Incomplete { | ||||
| 		type Complete = Complete; | ||||
| 
 | ||||
| 		fn check_outputs<F>(&self, mut f: F) -> Result<(), NoSuchOutput> | ||||
| 			where F: FnMut(usize, usize, OutputKind) -> Result<(), NoSuchOutput> | ||||
| 		{ | ||||
| 			match self.start { | ||||
| 				Field::Scalar(_) => Ok(()), | ||||
| 				Field::BackReference(req, idx) => | ||||
| 					f(req, idx, OutputKind::Hash).or_else(|| f(req, idx, OutputKind::Number)) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		fn note_outputs<F>(&self, _: F) where F: FnMut(usize, OutputKind) { } | ||||
| 
 | ||||
| 		fn fill<F>(self, oracle: F) -> Result<Self::Complete, NoSuchOutput> | ||||
| 			where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> | ||||
| 		{ | ||||
| 			let start = match self.start { | ||||
| 				Field::Scalar(start) => start, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash.into(), | ||||
| 					Output::Number(num) => num.into(), | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			Ok(Complete { | ||||
| 				start: start, | ||||
| 				skip: self.skip, | ||||
| 				max: self.max, | ||||
| 				reverse: self.reverse, | ||||
| 			}) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/// A complete header request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Complete { | ||||
| 		/// Start block.
 | ||||
| 		pub start: HashOrNumber, | ||||
| 		/// Skip between.
 | ||||
| 		pub skip: U256, | ||||
| 		/// Maximum to return.
 | ||||
| 		pub max: U256, | ||||
| 		/// Whether to reverse from start.
 | ||||
| 		pub reverse: bool, | ||||
| 	} | ||||
| 
 | ||||
| 	/// The output of a request for headers.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Response { | ||||
| 		header: Vec<encoded::Header>, | ||||
| 	} | ||||
| 
 | ||||
| 	impl Response { | ||||
| 		/// Fill reusable outputs by writing them into the function.
 | ||||
| 		pub fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) { } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// Request and response for header proofs.
 | ||||
| pub mod header_proof { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use util::{Bytes, U256, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete header proof request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Incomplete { | ||||
| 		/// Block number.
 | ||||
| 		pub num: Field<u64>, | ||||
| 	} | ||||
| 
 | ||||
| 	impl super::IncompleteRequest for Incomplete { | ||||
| 		type Complete = Complete; | ||||
| 
 | ||||
| 		fn check_outputs<F>(&self, mut f: F) -> Result<(), NoSuchOutput> | ||||
| 			where F: FnMut(usize, usize, OutputKind) -> Result<(), NoSuchOutput> | ||||
| 		{ | ||||
| 			match self.num { | ||||
| 				Field::Scalar(_) => Ok(()), | ||||
| 				Field::BackReference(req, idx) => f(req, idx, OutputKind::Number), | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		fn note_outputs<F>(&self, mut note: F) where F: FnMut(usize, OutputKind) { | ||||
| 			note(1, OutputKind::Hash); | ||||
| 		} | ||||
| 
 | ||||
| 		fn fill<F>(self, oracle: F) -> Result<Self::Complete, NoSuchOutput> | ||||
| 			where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> | ||||
| 		{ | ||||
| 			let num = match self.num { | ||||
| 				Field::Scalar(num) => num, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Number(num) => num, | ||||
| 					_ => return Err(NoSuchOutput), | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			Ok(Complete { | ||||
| 				num: num, | ||||
| 			}) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/// A complete header proof request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Complete { | ||||
| 		/// The number to get a header proof for.
 | ||||
| 		pub num: u64, | ||||
| 	} | ||||
| 
 | ||||
| 	/// The output of a request for a header proof.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Response { | ||||
| 		/// Inclusion proof of the header and total difficulty in the CHT.
 | ||||
| 		pub proof: Vec<Bytes>, | ||||
| 		/// The proved header's hash.
 | ||||
| 		pub hash: H256, | ||||
| 		/// The proved header's total difficulty.
 | ||||
| 		pub td: U256, | ||||
| 	} | ||||
| 
 | ||||
| 	impl Response { | ||||
| 		/// Fill reusable outputs by providing them to the function.
 | ||||
| 		pub fn fill_outputs<F>(&self, mut f: F) where F: FnMut(usize, Output) { | ||||
| 			f(1, Output::Hash(self.hash)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// Request and response for block receipts
 | ||||
| pub mod block_receipts { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use util::{Bytes, U256, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete block receipts request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Incomplete { | ||||
| 		/// Block hash to get receipts for.
 | ||||
| 		pub hash: Field<H256>, | ||||
| 	} | ||||
| 
 | ||||
| 	impl super::IncompleteRequest for Incomplete { | ||||
| 		type Complete = Complete; | ||||
| 
 | ||||
| 		fn check_outputs<F>(&self, mut f: F) -> Result<(), NoSuchOutput> | ||||
| 			where F: FnMut(usize, usize, OutputKind) -> Result<(), NoSuchOutput> | ||||
| 		{ | ||||
| 			match self.num { | ||||
| 				Field::Scalar(_) => Ok(()), | ||||
| 				Field::BackReference(req, idx) => f(req, idx, OutputKind::Hash), | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		fn note_outputs<F>(&self, _: F) where F: FnMut(usize, OutputKind) {} | ||||
| 
 | ||||
| 		fn fill<F>(self, oracle: F) -> Result<Self::Complete, NoSuchOutput> | ||||
| 			where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> | ||||
| 		{ | ||||
| 			let hash = match self.hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput), | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			Ok(Complete { | ||||
| 				hash: hash, | ||||
| 			}) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/// A complete block receipts request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Complete { | ||||
| 		/// The number to get block receipts for.
 | ||||
| 		pub hash: H256, | ||||
| 	} | ||||
| 
 | ||||
| 	/// The output of a request for block receipts.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Response { | ||||
| 		/// The block receipts.
 | ||||
| 		pub receipts: Vec<Receipt> | ||||
| 	} | ||||
| 
 | ||||
| 	impl Response { | ||||
| 		/// Fill reusable outputs by providing them to the function.
 | ||||
| 		pub fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// Request and response for a block body
 | ||||
| pub mod block_body { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::encoded; | ||||
| 	use util::{Bytes, U256, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete block body request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Incomplete { | ||||
| 		/// Block hash to get receipts for.
 | ||||
| 		pub hash: Field<H256>, | ||||
| 	} | ||||
| 
 | ||||
| 	impl super::IncompleteRequest for Incomplete { | ||||
| 		type Complete = Complete; | ||||
| 
 | ||||
| 		fn check_outputs<F>(&self, mut f: F) -> Result<(), NoSuchOutput> | ||||
| 			where F: FnMut(usize, usize, OutputKind) -> Result<(), NoSuchOutput> | ||||
| 		{ | ||||
| 			match self.num { | ||||
| 				Field::Scalar(_) => Ok(()), | ||||
| 				Field::BackReference(req, idx) => f(req, idx, OutputKind::Hash), | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		fn note_outputs<F>(&self, _: F) where F: FnMut(usize, OutputKind) {} | ||||
| 
 | ||||
| 		fn fill<F>(self, oracle: F) -> Result<Self::Complete, NoSuchOutput> | ||||
| 			where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> | ||||
| 		{ | ||||
| 			let hash = match self.hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput), | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			Ok(Complete { | ||||
| 				hash: hash, | ||||
| 			}) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/// A complete block body request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Complete { | ||||
| 		/// The hash to get a block body for.
 | ||||
| 		pub hash: H256, | ||||
| 	} | ||||
| 
 | ||||
| 	/// The output of a request for block body.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Response { | ||||
| 		/// The block body.
 | ||||
| 		pub body: encoded::Body, | ||||
| 	} | ||||
| 
 | ||||
| 	impl Response { | ||||
| 		/// Fill reusable outputs by providing them to the function.
 | ||||
| 		pub fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// A request for an account proof.
 | ||||
| pub mod account { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::encoded; | ||||
| 	use util::{Bytes, U256, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete request for an account proof.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Incomplete { | ||||
| 		/// Block hash to request state proof for.
 | ||||
| 		pub block_hash: Field<H256>, | ||||
| 		/// Hash of the account's address.
 | ||||
| 		pub address_hash: Field<H256>, | ||||
| 	} | ||||
| 
 | ||||
| 	impl super::IncompleteRequest for Incomplete { | ||||
| 		type Complete = Complete; | ||||
| 
 | ||||
| 		fn check_outputs<F>(&self, mut f: F) -> Result<(), NoSuchOutput> | ||||
| 			where F: FnMut(usize, usize, OutputKind) -> Result<(), NoSuchOutput> | ||||
| 		{ | ||||
| 			if let Field::BackReference(req, idx) = self.block_hash { | ||||
| 				f(req, idx, OutputKind::Hash)? | ||||
| 			} | ||||
| 
 | ||||
| 			if let Field::BackReference(req, idx) = self.address_hash { | ||||
| 				f(req, idx, OutputKind::Hash)? | ||||
| 			} | ||||
| 
 | ||||
| 			Ok(()) | ||||
| 		} | ||||
| 
 | ||||
| 		fn note_outputs<F>(&self, mut f: F) where F: FnMut(usize, OutputKind) { | ||||
| 			f(0, OutputKind::Hash); | ||||
| 			f(1, OutputKind::Hash); | ||||
| 		} | ||||
| 
 | ||||
| 		fn fill<F>(self, oracle: F) -> Result<Self::Complete, NoSuchOutput> | ||||
| 			where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> | ||||
| 		{ | ||||
| 			let block_hash = match self.block_hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput)?, | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			let address_hash = match self.address_hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput)?, | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			Ok(Complete { | ||||
| 				block_hash: block_hash, | ||||
| 				address_hash: address_hash, | ||||
| 			}) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/// A complete request for an account.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Complete { | ||||
| 		/// Block hash to request state proof for.
 | ||||
| 		pub block_hash: H256, | ||||
| 		/// Hash of the account's address.
 | ||||
| 		pub address_hash: H256, | ||||
| 	} | ||||
| 
 | ||||
| 	/// The output of a request for an account state proof.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Response { | ||||
| 		/// Inclusion/exclusion proof
 | ||||
| 		pub proof: Vec<Bytes>, | ||||
| 		/// Account nonce.
 | ||||
| 		pub nonce: U256, | ||||
| 		/// Account balance.
 | ||||
| 		pub balance: U256, | ||||
| 		/// Account's code hash.
 | ||||
| 		pub code_hash: H256, | ||||
| 		/// Account's storage trie root.
 | ||||
| 		pub storage_root: H256, | ||||
| 	} | ||||
| 
 | ||||
| 	impl Response { | ||||
| 		/// Fill reusable outputs by providing them to the function.
 | ||||
| 		pub fn fill_outputs<F>(&self, mut f: F) where F: FnMut(usize, Output) { | ||||
| 			f(0, Output::Hash(self.code_hash)); | ||||
| 			f(1, Output::Hash(self.storage_root)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// A request for a storage proof.
 | ||||
| pub mod storage { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::encoded; | ||||
| 	use util::{Bytes, U256, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete request for an storage proof.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Incomplete { | ||||
| 		/// Block hash to request state proof for.
 | ||||
| 		pub block_hash: Field<H256>, | ||||
| 		/// Hash of the account's address.
 | ||||
| 		pub address_hash: Field<H256>, | ||||
| 		/// Hash of the storage key.
 | ||||
| 		pub key_hash: Field<H256>, | ||||
| 	} | ||||
| 
 | ||||
| 	impl super::IncompleteRequest for Incomplete { | ||||
| 		type Complete = Complete; | ||||
| 
 | ||||
| 		fn check_outputs<F>(&self, mut f: F) -> Result<(), NoSuchOutput> | ||||
| 			where F: FnMut(usize, usize, OutputKind) -> Result<(), NoSuchOutput> | ||||
| 		{ | ||||
| 			if let Field::BackReference(req, idx) = self.block_hash { | ||||
| 				f(req, idx, OutputKind::Hash)? | ||||
| 			} | ||||
| 
 | ||||
| 			if let Field::BackReference(req, idx) = self.address_hash { | ||||
| 				f(req, idx, OutputKind::Hash)? | ||||
| 			} | ||||
| 
 | ||||
| 			if let Field::BackReference(req, idx) = self.key_hash { | ||||
| 				f(req, idx, OutputKind::Hash)? | ||||
| 			} | ||||
| 
 | ||||
| 			Ok(()) | ||||
| 		} | ||||
| 
 | ||||
| 		fn note_outputs<F>(&self, mut f: F) where F: FnMut(usize, OutputKind) { | ||||
| 			f(0, OutputKind::Hash); | ||||
| 		} | ||||
| 
 | ||||
| 		fn fill<F>(self, oracle: F) -> Result<Self::Complete, NoSuchOutput> | ||||
| 			where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> | ||||
| 		{ | ||||
| 			let block_hash = match self.block_hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput)?, | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			let address_hash = match self.address_hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput)?, | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			let key_hash = match self.key_hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput)?, | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			Ok(Complete { | ||||
| 				block_hash: block_hash, | ||||
| 				address_hash: address_hash, | ||||
| 				key_hash: key_hash | ||||
| 			}) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/// A complete request for a storage proof.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Complete { | ||||
| 		/// Block hash to request state proof for.
 | ||||
| 		pub block_hash: H256, | ||||
| 		/// Hash of the account's address.
 | ||||
| 		pub address_hash: H256, | ||||
| 		/// Storage key hash.
 | ||||
| 		pub key_hash: H256, | ||||
| 	} | ||||
| 
 | ||||
| 	/// The output of a request for an account state proof.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Response { | ||||
| 		/// Inclusion/exclusion proof
 | ||||
| 		pub proof: Vec<Bytes>, | ||||
| 		/// Storage value.
 | ||||
| 		pub value: H256, | ||||
| 	} | ||||
| 
 | ||||
| 	impl Response { | ||||
| 		/// Fill reusable outputs by providing them to the function.
 | ||||
| 		pub fn fill_outputs<F>(&self, mut f: F) where F: FnMut(usize, Output) { | ||||
| 			f(0, Output::Hash(self.value)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /// A request for contract code.
 | ||||
| pub mod contract_code { | ||||
| 	use super::{Field, NoSuchOutput, OutputKind, Output}; | ||||
| 	use ethcore::encoded; | ||||
| 	use util::{Bytes, U256, H256}; | ||||
| 
 | ||||
| 	/// Potentially incomplete _ request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Incomplete { | ||||
| 		/// The block hash to request the state for.
 | ||||
| 		pub block_hash: Field<H256>, | ||||
| 		/// The code hash.
 | ||||
| 		pub code_hash: Field<H256>, | ||||
| 	} | ||||
| 
 | ||||
| 	impl super::IncompleteRequest for Incomplete { | ||||
| 		type Complete = Complete; | ||||
| 
 | ||||
| 		fn check_outputs<F>(&self, mut f: F) -> Result<(), NoSuchOutput> | ||||
| 			where F: FnMut(usize, usize, OutputKind) -> Result<(), NoSuchOutput> | ||||
| 		{ | ||||
| 			if let Field::BackReference(req, idx) = self.block_hash { | ||||
| 				f(req, idx, OutputKind::Hash)?; | ||||
| 			} | ||||
| 			if let Field::BackReference(req, idx) = self.code_hash { | ||||
| 				f(req, idx, OutputKind::Hash)?; | ||||
| 			} | ||||
| 
 | ||||
| 			Ok(()) | ||||
| 		} | ||||
| 
 | ||||
| 		fn note_outputs<F>(&self, _: F) where F: FnMut(usize, OutputKind) {} | ||||
| 
 | ||||
| 		fn fill<F>(self, oracle: F) -> Result<Self::Complete, NoSuchOutput> | ||||
| 			where F: Fn(usize, usize) -> Result<Output, NoSuchOutput> | ||||
| 		{ | ||||
| 			let block_hash = match self.block_hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput)?, | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			let code_hash = match self.code_hash { | ||||
| 				Field::Scalar(hash) => hash, | ||||
| 				Field::BackReference(req, idx) => match oracle(req, idx)? { | ||||
| 					Output::Hash(hash) => hash, | ||||
| 					_ => return Err(NoSuchOutput)?, | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			Ok(Complete { | ||||
| 				block_hash: block_hash, | ||||
| 				code_hash: code_hash, | ||||
| 			}) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/// A complete request.
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Complete { | ||||
| 		/// The block hash to request the state for.
 | ||||
| 		pub block_hash: H256, | ||||
| 		/// The code hash.
 | ||||
| 		pub code_hash: H256, | ||||
| 	} | ||||
| 
 | ||||
| 	/// The output of a request for
 | ||||
| 	#[derive(Debug, Clone, PartialEq, Eq)] | ||||
| 	pub struct Response { | ||||
| 		/// The requested code.
 | ||||
| 		pub code: Bytes, | ||||
| 	} | ||||
| 
 | ||||
| 	impl Response { | ||||
| 		/// Fill reusable outputs by providing them to the function.
 | ||||
| 		pub fn fill_outputs<F>(&self, _: F) where F: FnMut(usize, Output) {} | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user