move light to its own crate again
This commit is contained in:
		
							parent
							
								
									6e1a1f9dec
								
							
						
					
					
						commit
						61c3358447
					
				| @ -35,5 +35,17 @@ pub mod client; | |||||||
| pub mod net; | pub mod net; | ||||||
| pub mod provider; | pub mod provider; | ||||||
| 
 | 
 | ||||||
|  | mod types; | ||||||
|  | 
 | ||||||
| pub use self::provider::Provider; | pub use self::provider::Provider; | ||||||
| pub use types::les_request as request; | pub use types::les_request as request; | ||||||
|  | 
 | ||||||
|  | #[macro_use] | ||||||
|  | extern crate log; | ||||||
|  | 
 | ||||||
|  | extern crate ethcore; | ||||||
|  | extern crate ethcore_util as util; | ||||||
|  | extern crate ethcore_network as network; | ||||||
|  | extern crate ethcore_io as io; | ||||||
|  | extern crate rlp; | ||||||
|  | extern crate time; | ||||||
							
								
								
									
										194
									
								
								ethcore/light/src/provider.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								ethcore/light/src/provider.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,194 @@ | |||||||
|  | // Copyright 2015, 2016 Ethcore (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/>.
 | ||||||
|  | 
 | ||||||
|  | //! A provider for the LES protocol. This is typically a full node, who can
 | ||||||
|  | //! give as much data as necessary to its peers.
 | ||||||
|  | 
 | ||||||
|  | use ethcore::blockchain_info::BlockChainInfo; | ||||||
|  | use ethcore::client::{BlockChainClient, ProvingBlockChainClient}; | ||||||
|  | use ethcore::transaction::SignedTransaction; | ||||||
|  | 
 | ||||||
|  | use util::{Bytes, H256}; | ||||||
|  | 
 | ||||||
|  | use light::request; | ||||||
|  | 
 | ||||||
|  | /// Defines the operations that a provider for `LES` must fulfill.
 | ||||||
|  | ///
 | ||||||
|  | /// These are defined at [1], but may be subject to change.
 | ||||||
|  | /// Requests which can't be fulfilled should return either an empty RLP list
 | ||||||
|  | /// or empty vector where appropriate.
 | ||||||
|  | ///
 | ||||||
|  | /// [1]: https://github.com/ethcore/parity/wiki/Light-Ethereum-Subprotocol-(LES)
 | ||||||
|  | pub trait Provider: Send + Sync { | ||||||
|  | 	/// Provide current blockchain info.
 | ||||||
|  | 	fn chain_info(&self) -> BlockChainInfo; | ||||||
|  | 
 | ||||||
|  | 	/// Find the depth of a common ancestor between two blocks.
 | ||||||
|  | 	/// If either block is unknown or an ancestor can't be found
 | ||||||
|  | 	/// then return `None`.
 | ||||||
|  | 	fn reorg_depth(&self, a: &H256, b: &H256) -> Option<u64>; | ||||||
|  | 
 | ||||||
|  | 	/// Earliest block where state queries are available.
 | ||||||
|  | 	/// If `None`, no state queries are servable.
 | ||||||
|  | 	fn earliest_state(&self) -> Option<u64>; | ||||||
|  | 
 | ||||||
|  | 	/// Provide a list of headers starting at the requested block,
 | ||||||
|  | 	/// possibly in reverse and skipping `skip` at a time.
 | ||||||
|  | 	///
 | ||||||
|  | 	/// The returned vector may have any length in the range [0, `max`], but the
 | ||||||
|  | 	/// results within must adhere to the `skip` and `reverse` parameters.
 | ||||||
|  | 	fn block_headers(&self, req: request::Headers) -> Vec<Bytes>; | ||||||
|  | 
 | ||||||
|  | 	/// Provide as many as possible of the requested blocks (minus the headers) encoded
 | ||||||
|  | 	/// in RLP format.
 | ||||||
|  | 	fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes>; | ||||||
|  | 
 | ||||||
|  | 	/// Provide the receipts as many as possible of the requested blocks.
 | ||||||
|  | 	/// Returns a vector of RLP-encoded lists of receipts.
 | ||||||
|  | 	fn receipts(&self, req: request::Receipts) -> Vec<Bytes>; | ||||||
|  | 
 | ||||||
|  | 	/// Provide a set of merkle proofs, as requested. Each request is a
 | ||||||
|  | 	/// block hash and request parameters.
 | ||||||
|  | 	///
 | ||||||
|  | 	/// Returns a vector of RLP-encoded lists satisfying the requests.
 | ||||||
|  | 	fn proofs(&self, req: request::StateProofs) -> Vec<Bytes>; | ||||||
|  | 
 | ||||||
|  | 	/// Provide contract code for the specified (block_hash, account_hash) pairs.
 | ||||||
|  | 	/// Each item in the resulting vector is either the raw bytecode or empty.
 | ||||||
|  | 	fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes>; | ||||||
|  | 
 | ||||||
|  | 	/// Provide header proofs from the Canonical Hash Tries.
 | ||||||
|  | 	fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes>; | ||||||
|  | 
 | ||||||
|  | 	/// Provide pending transactions.
 | ||||||
|  | 	fn pending_transactions(&self) -> Vec<SignedTransaction>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Implementation of a light client data provider for a client.
 | ||||||
|  | impl<T: ProvingBlockChainClient + ?Sized> light::Provider for T { | ||||||
|  | 	fn chain_info(&self) -> BlockChainInfo { | ||||||
|  | 		BlockChainClient::chain_info(self) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn reorg_depth(&self, a: &H256, b: &H256) -> Option<u64> { | ||||||
|  | 		self.tree_route(a, b).map(|route| route.index as u64) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn earliest_state(&self) -> Option<u64> { | ||||||
|  | 		Some(self.pruning_info().earliest_state) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn block_headers(&self, req: request::Headers) -> Vec<Bytes> { | ||||||
|  | 		let best_num = self.chain.read().best_block_number(); | ||||||
|  | 		let start_num = req.block_num; | ||||||
|  | 
 | ||||||
|  | 		match self.block_hash(BlockID::Number(req.block_num)) { | ||||||
|  | 			Some(hash) if hash == req.block_hash => {} | ||||||
|  | 			_=> { | ||||||
|  | 				trace!(target: "les_provider", "unknown/non-canonical start block in header request: {:?}", (req.block_num, req.block_hash)); | ||||||
|  | 				return vec![] | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		(0u64..req.max as u64) | ||||||
|  | 			.map(|x: u64| x.saturating_mul(req.skip)) | ||||||
|  | 			.take_while(|x| if req.reverse { x < &start_num } else { best_num - start_num < *x }) | ||||||
|  | 			.map(|x| if req.reverse { start_num - x } else { start_num + x }) | ||||||
|  | 			.map(|x| self.block_header(BlockID::Number(x))) | ||||||
|  | 			.take_while(|x| x.is_some()) | ||||||
|  | 			.flat_map(|x| x) | ||||||
|  | 			.collect() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> { | ||||||
|  | 		use ids::BlockID; | ||||||
|  | 
 | ||||||
|  | 		req.block_hashes.into_iter() | ||||||
|  | 			.map(|hash| self.block_body(BlockID::Hash(hash))) | ||||||
|  | 			.map(|body| body.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec())) | ||||||
|  | 			.collect() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn receipts(&self, req: request::Receipts) -> Vec<Bytes> { | ||||||
|  | 		req.block_hashes.into_iter() | ||||||
|  | 			.map(|hash| self.block_receipts(&hash)) | ||||||
|  | 			.map(|receipts| receipts.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec())) | ||||||
|  | 			.collect() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn proofs(&self, req: request::StateProofs) -> Vec<Bytes> { | ||||||
|  | 		use rlp::{EMPTY_LIST_RLP, RlpStream, Stream}; | ||||||
|  | 
 | ||||||
|  | 		let mut results = Vec::with_capacity(req.requests.len()); | ||||||
|  | 
 | ||||||
|  | 		for request in req.requests { | ||||||
|  | 			let state = match self.state_at(BlockID::Hash(request.block)) { | ||||||
|  | 				Some(state) => state, | ||||||
|  | 				None => { | ||||||
|  | 					trace!(target: "light_provider", "state for {} not available", request.block); | ||||||
|  | 					results.push(EMPTY_LIST_RLP.to_vec()); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 			}; | ||||||
|  | 
 | ||||||
|  | 			let res = match request.key2 { | ||||||
|  | 				Some(storage_key) => state.prove_storage(request.key1, storage_key, request.from_level), | ||||||
|  | 				None => state.prove_account(request.key1, request.from_level), | ||||||
|  | 			}; | ||||||
|  | 
 | ||||||
|  | 			match res { | ||||||
|  | 				Ok(records) => { | ||||||
|  | 					let mut stream = RlpStream::new_list(records.len()); | ||||||
|  | 					for record in records { | ||||||
|  | 						stream.append_raw(&record, 1); | ||||||
|  | 					} | ||||||
|  | 					results.push(stream.out()) | ||||||
|  | 				} | ||||||
|  | 				Err(e) => { | ||||||
|  | 					debug!(target: "light_provider", "encountered error {} while forming proof of state at {}", e, request.block); | ||||||
|  | 					results.push(EMPTY_LIST_RLP.to_vec()); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		results | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes> { | ||||||
|  | 		req.code_requests.into_iter() | ||||||
|  | 			.map(|req| { | ||||||
|  | 				self.state_at(BlockID::Hash(req.block_hash)) | ||||||
|  | 					.map(|state| { | ||||||
|  | 						match state.code_by_address_hash(req.account_key) { | ||||||
|  | 							Ok(code) => code.unwrap_or_else(Vec::new), | ||||||
|  | 							Err(e) => { | ||||||
|  | 								debug!(target: "light_provider", "encountered error {} while fetching code.", e); | ||||||
|  | 								Vec::new() | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					}).unwrap_or_else(Vec::new) | ||||||
|  | 			}) | ||||||
|  | 			.collect() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes> { | ||||||
|  | 		req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fn pending_transactions(&self) -> Vec<SignedTransaction> { | ||||||
|  | 		BlockChainClient::pending_transactions(self) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -52,7 +52,7 @@ use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute}; | |||||||
| use client::{ | use client::{ | ||||||
| 	BlockID, TransactionID, UncleID, TraceId, ClientConfig, BlockChainClient, | 	BlockID, TransactionID, UncleID, TraceId, ClientConfig, BlockChainClient, | ||||||
| 	MiningBlockChainClient, TraceFilter, CallAnalytics, BlockImportError, Mode, | 	MiningBlockChainClient, TraceFilter, CallAnalytics, BlockImportError, Mode, | ||||||
| 	ChainNotify, PruningInfo, | 	ChainNotify, PruningInfo, ProvingBlockChainClient, | ||||||
| }; | }; | ||||||
| use client::Error as ClientError; | use client::Error as ClientError; | ||||||
| use env_info::EnvInfo; | use env_info::EnvInfo; | ||||||
| @ -68,7 +68,6 @@ use factory::Factories; | |||||||
| use rlp::{decode, View, UntrustedRlp}; | use rlp::{decode, View, UntrustedRlp}; | ||||||
| use state_db::StateDB; | use state_db::StateDB; | ||||||
| use rand::OsRng; | use rand::OsRng; | ||||||
| use light::{self, request}; |  | ||||||
| 
 | 
 | ||||||
| // re-export
 | // re-export
 | ||||||
| pub use types::blockchain_info::BlockChainInfo; | pub use types::blockchain_info::BlockChainInfo; | ||||||
| @ -1378,119 +1377,24 @@ impl MayPanic for Client { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Implementation of a light client data provider for a client.
 | impl ProvingBlockChainClient for Client { | ||||||
| impl light::Provider for Client { | 	fn prove_storage(&self, key1: H256, key2: H256, from_level: u32, id: BlockID) -> Vec<Bytes> { | ||||||
| 	fn chain_info(&self) -> BlockChainInfo { | 		self.state_at(id) | ||||||
| 		BlockChainClient::chain_info(self) | 			.and_then(move |state| state.prove_storage(key1, key2, from_level).ok()) | ||||||
|  | 			.unwrap_or_else(Vec::new) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn reorg_depth(&self, a: &H256, b: &H256) -> Option<u64> { | 	fn prove_account(&self, key1: H256, from_level: u32, id: BlockID) -> Vec<Bytes> { | ||||||
| 		self.tree_route(a, b).map(|route| route.index as u64) | 		self.state_at(id) | ||||||
|  | 			.and_then(move |state| state.prove_account(key1, from_level).ok()) | ||||||
|  | 			.unwrap_or_else(Vec::new) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn earliest_state(&self) -> Option<u64> { | 	fn code_by_hash(&self, account_key: H256, id: BlockID) -> Bytes { | ||||||
| 		Some(self.pruning_info().earliest_state) | 		self.state_at(id) | ||||||
| 	} | 			.and_then(move |state| state.code_by_address_hash(account_key).ok()) | ||||||
| 
 | 			.and_then(|x| x) | ||||||
| 	fn block_headers(&self, req: request::Headers) -> Vec<Bytes> { | 			.unwrap_or_else(Vec::new) | ||||||
| 		let best_num = self.chain.read().best_block_number(); |  | ||||||
| 		let start_num = req.block_num; |  | ||||||
| 
 |  | ||||||
| 		match self.block_hash(BlockID::Number(req.block_num)) { |  | ||||||
| 			Some(hash) if hash == req.block_hash => {} |  | ||||||
| 			_=> { |  | ||||||
| 				trace!(target: "les_provider", "unknown/non-canonical start block in header request: {:?}", (req.block_num, req.block_hash)); |  | ||||||
| 				return vec![] |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		(0u64..req.max as u64) |  | ||||||
| 			.map(|x: u64| x.saturating_mul(req.skip)) |  | ||||||
| 			.take_while(|x| if req.reverse { x < &start_num } else { best_num - start_num < *x }) |  | ||||||
| 			.map(|x| if req.reverse { start_num - x } else { start_num + x }) |  | ||||||
| 			.map(|x| self.block_header(BlockID::Number(x))) |  | ||||||
| 			.take_while(|x| x.is_some()) |  | ||||||
| 			.flat_map(|x| x) |  | ||||||
| 			.collect() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes> { |  | ||||||
| 		use ids::BlockID; |  | ||||||
| 
 |  | ||||||
| 		req.block_hashes.into_iter() |  | ||||||
| 			.map(|hash| self.block_body(BlockID::Hash(hash))) |  | ||||||
| 			.map(|body| body.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec())) |  | ||||||
| 			.collect() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fn receipts(&self, req: request::Receipts) -> Vec<Bytes> { |  | ||||||
| 		req.block_hashes.into_iter() |  | ||||||
| 			.map(|hash| self.block_receipts(&hash)) |  | ||||||
| 			.map(|receipts| receipts.unwrap_or_else(|| ::rlp::EMPTY_LIST_RLP.to_vec())) |  | ||||||
| 			.collect() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fn proofs(&self, req: request::StateProofs) -> Vec<Bytes> { |  | ||||||
| 		use rlp::{EMPTY_LIST_RLP, RlpStream, Stream}; |  | ||||||
| 
 |  | ||||||
| 		let mut results = Vec::with_capacity(req.requests.len()); |  | ||||||
| 
 |  | ||||||
| 		for request in req.requests { |  | ||||||
| 			let state = match self.state_at(BlockID::Hash(request.block)) { |  | ||||||
| 				Some(state) => state, |  | ||||||
| 				None => { |  | ||||||
| 					trace!(target: "light_provider", "state for {} not available", request.block); |  | ||||||
| 					results.push(EMPTY_LIST_RLP.to_vec()); |  | ||||||
| 					continue; |  | ||||||
| 				} |  | ||||||
| 			}; |  | ||||||
| 
 |  | ||||||
| 			let res = match request.key2 { |  | ||||||
| 				Some(storage_key) => state.prove_storage(request.key1, storage_key, request.from_level), |  | ||||||
| 				None => state.prove_account(request.key1, request.from_level), |  | ||||||
| 			}; |  | ||||||
| 
 |  | ||||||
| 			match res { |  | ||||||
| 				Ok(records) => { |  | ||||||
| 					let mut stream = RlpStream::new_list(records.len()); |  | ||||||
| 					for record in records { |  | ||||||
| 						stream.append_raw(&record, 1); |  | ||||||
| 					} |  | ||||||
| 					results.push(stream.out()) |  | ||||||
| 				} |  | ||||||
| 				Err(e) => { |  | ||||||
| 					debug!(target: "light_provider", "encountered error {} while forming proof of state at {}", e, request.block); |  | ||||||
| 					results.push(EMPTY_LIST_RLP.to_vec()); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		results |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes> { |  | ||||||
| 		req.code_requests.into_iter() |  | ||||||
| 			.map(|req| { |  | ||||||
| 				self.state_at(BlockID::Hash(req.block_hash)) |  | ||||||
| 					.map(|state| { |  | ||||||
| 						match state.code_by_address_hash(req.account_key) { |  | ||||||
| 							Ok(code) => code.unwrap_or_else(Vec::new), |  | ||||||
| 							Err(e) => { |  | ||||||
| 								debug!(target: "light_provider", "encountered error {} while fetching code.", e); |  | ||||||
| 								Vec::new() |  | ||||||
| 							} |  | ||||||
| 						} |  | ||||||
| 					}).unwrap_or_else(Vec::new) |  | ||||||
| 			}) |  | ||||||
| 			.collect() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes> { |  | ||||||
| 		req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fn pending_transactions(&self) -> Vec<SignedTransaction> { |  | ||||||
| 		BlockChainClient::pending_transactions(self) |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChain | |||||||
| pub use self::error::Error; | pub use self::error::Error; | ||||||
| pub use self::test_client::{TestBlockChainClient, EachBlockWith}; | pub use self::test_client::{TestBlockChainClient, EachBlockWith}; | ||||||
| pub use self::chain_notify::ChainNotify; | pub use self::chain_notify::ChainNotify; | ||||||
| pub use self::traits::{BlockChainClient, MiningBlockChainClient}; | pub use self::traits::{BlockChainClient, MiningBlockChainClient, ProvingBlockChainClient}; | ||||||
| 
 | 
 | ||||||
| pub use types::ids::*; | pub use types::ids::*; | ||||||
| pub use types::trace_filter::Filter as TraceFilter; | pub use types::trace_filter::Filter as TraceFilter; | ||||||
|  | |||||||
| @ -256,8 +256,10 @@ pub trait BlockChainClient : Sync + Send { | |||||||
| 	fn pruning_info(&self) -> PruningInfo; | 	fn pruning_info(&self) -> PruningInfo; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl IpcConfig for BlockChainClient { } | ||||||
|  | 
 | ||||||
| /// Extended client interface used for mining
 | /// Extended client interface used for mining
 | ||||||
| pub trait MiningBlockChainClient : BlockChainClient { | pub trait MiningBlockChainClient: BlockChainClient { | ||||||
| 	/// Returns OpenBlock prepared for closing.
 | 	/// Returns OpenBlock prepared for closing.
 | ||||||
| 	fn prepare_open_block(&self, | 	fn prepare_open_block(&self, | ||||||
| 		author: Address, | 		author: Address, | ||||||
| @ -275,4 +277,23 @@ pub trait MiningBlockChainClient : BlockChainClient { | |||||||
| 	fn latest_schedule(&self) -> Schedule; | 	fn latest_schedule(&self) -> Schedule; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl IpcConfig for BlockChainClient { } | /// Extended client interface for providing proofs of the state.
 | ||||||
|  | pub trait ProvingBlockChainClient: BlockChainClient { | ||||||
|  | 	/// Prove account storage at a specific block id.
 | ||||||
|  | 	///
 | ||||||
|  | 	/// Both provided keys assume a secure trie.
 | ||||||
|  | 	/// Returns a vector of raw trie nodes (in order from the root) proving the storage query.
 | ||||||
|  | 	/// Nodes after `from_level` may be omitted.
 | ||||||
|  | 	/// An empty vector indicates unservable query.
 | ||||||
|  | 	fn prove_storage(&self, key1: H256, key2: H256, from_level: u32, id: BlockID) -> Vec<Bytes>; | ||||||
|  | 
 | ||||||
|  | 	/// Prove account existence at a specific block id.
 | ||||||
|  | 	/// The key is the keccak hash of the account's address.
 | ||||||
|  | 	/// Returns a vector of raw trie nodes (in order from the root) proving the query.
 | ||||||
|  | 	/// Nodes after `from_level` may be omitted.
 | ||||||
|  | 	/// An empty vector indicates unservable query.	
 | ||||||
|  | 	fn prove_account(&self, key1: H256, from_level: u32, id: BlockID) -> Vec<Bytes>; | ||||||
|  | 
 | ||||||
|  | 	/// Get code by address hash.
 | ||||||
|  | 	fn code_by_hash(&self, account_key: H256, id: BlockID) -> Bytes; | ||||||
|  | } | ||||||
| @ -140,7 +140,6 @@ pub mod snapshot; | |||||||
| pub mod action_params; | pub mod action_params; | ||||||
| pub mod db; | pub mod db; | ||||||
| pub mod verification; | pub mod verification; | ||||||
| pub mod light; |  | ||||||
| #[macro_use] pub mod evm; | #[macro_use] pub mod evm; | ||||||
| 
 | 
 | ||||||
| mod cache_manager; | mod cache_manager; | ||||||
|  | |||||||
| @ -1,77 +0,0 @@ | |||||||
| // Copyright 2015, 2016 Ethcore (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/>.
 |  | ||||||
| 
 |  | ||||||
| //! A provider for the LES protocol. This is typically a full node, who can
 |  | ||||||
| //! give as much data as necessary to its peers.
 |  | ||||||
| 
 |  | ||||||
| use transaction::SignedTransaction; |  | ||||||
| use blockchain_info::BlockChainInfo; |  | ||||||
| 
 |  | ||||||
| use util::{Bytes, H256}; |  | ||||||
| 
 |  | ||||||
| use light::request; |  | ||||||
| 
 |  | ||||||
| /// Defines the operations that a provider for `LES` must fulfill.
 |  | ||||||
| ///
 |  | ||||||
| /// These are defined at [1], but may be subject to change.
 |  | ||||||
| /// Requests which can't be fulfilled should return either an empty RLP list
 |  | ||||||
| /// or empty vector where appropriate.
 |  | ||||||
| ///
 |  | ||||||
| /// [1]: https://github.com/ethcore/parity/wiki/Light-Ethereum-Subprotocol-(LES)
 |  | ||||||
| pub trait Provider: Send + Sync { |  | ||||||
| 	/// Provide current blockchain info.
 |  | ||||||
| 	fn chain_info(&self) -> BlockChainInfo; |  | ||||||
| 
 |  | ||||||
| 	/// Find the depth of a common ancestor between two blocks.
 |  | ||||||
| 	/// If either block is unknown or an ancestor can't be found
 |  | ||||||
| 	/// then return `None`.
 |  | ||||||
| 	fn reorg_depth(&self, a: &H256, b: &H256) -> Option<u64>; |  | ||||||
| 
 |  | ||||||
| 	/// Earliest block where state queries are available.
 |  | ||||||
| 	/// If `None`, no state queries are servable.
 |  | ||||||
| 	fn earliest_state(&self) -> Option<u64>; |  | ||||||
| 
 |  | ||||||
| 	/// Provide a list of headers starting at the requested block,
 |  | ||||||
| 	/// possibly in reverse and skipping `skip` at a time.
 |  | ||||||
| 	///
 |  | ||||||
| 	/// The returned vector may have any length in the range [0, `max`], but the
 |  | ||||||
| 	/// results within must adhere to the `skip` and `reverse` parameters.
 |  | ||||||
| 	fn block_headers(&self, req: request::Headers) -> Vec<Bytes>; |  | ||||||
| 
 |  | ||||||
| 	/// Provide as many as possible of the requested blocks (minus the headers) encoded
 |  | ||||||
| 	/// in RLP format.
 |  | ||||||
| 	fn block_bodies(&self, req: request::Bodies) -> Vec<Bytes>; |  | ||||||
| 
 |  | ||||||
| 	/// Provide the receipts as many as possible of the requested blocks.
 |  | ||||||
| 	/// Returns a vector of RLP-encoded lists of receipts.
 |  | ||||||
| 	fn receipts(&self, req: request::Receipts) -> Vec<Bytes>; |  | ||||||
| 
 |  | ||||||
| 	/// Provide a set of merkle proofs, as requested. Each request is a
 |  | ||||||
| 	/// block hash and request parameters.
 |  | ||||||
| 	///
 |  | ||||||
| 	/// Returns a vector of RLP-encoded lists satisfying the requests.
 |  | ||||||
| 	fn proofs(&self, req: request::StateProofs) -> Vec<Bytes>; |  | ||||||
| 
 |  | ||||||
| 	/// Provide contract code for the specified (block_hash, account_hash) pairs.
 |  | ||||||
| 	/// Each item in the resulting vector is either the raw bytecode or empty.
 |  | ||||||
| 	fn contract_code(&self, req: request::ContractCodes) -> Vec<Bytes>; |  | ||||||
| 
 |  | ||||||
| 	/// Provide header proofs from the Canonical Hash Tries.
 |  | ||||||
| 	fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes>; |  | ||||||
| 
 |  | ||||||
| 	/// Provide pending transactions.
 |  | ||||||
| 	fn pending_transactions(&self) -> Vec<SignedTransaction>; |  | ||||||
| } |  | ||||||
| @ -1,167 +0,0 @@ | |||||||
| // Copyright 2015, 2016 Ethcore (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 util::H256; |  | ||||||
| 
 |  | ||||||
| /// A request for block headers.
 |  | ||||||
| #[derive(Debug, Clone, PartialEq, Eq, Binary)] |  | ||||||
| pub struct Headers { |  | ||||||
| 	/// Starting block number
 |  | ||||||
| 	pub block_num: u64, |  | ||||||
| 	/// Starting block hash. This and number could be combined but IPC codegen is
 |  | ||||||
| 	/// not robust enough to support it.
 |  | ||||||
| 	pub block_hash: H256, |  | ||||||
| 	/// 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, 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, 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, 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, Binary)] |  | ||||||
| pub struct StateProofs { |  | ||||||
| 	/// All the proof requests.
 |  | ||||||
| 	pub requests: Vec<StateProof>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// A request for contract code.
 |  | ||||||
| #[derive(Debug, Clone, PartialEq, Eq, 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, 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, Binary)] |  | ||||||
| pub struct HeaderProof { |  | ||||||
| 	/// Number of the CHT.
 |  | ||||||
| 	pub cht_number: u64, |  | ||||||
| 	/// Block number requested.
 |  | ||||||
| 	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, Binary)] |  | ||||||
| pub struct HeaderProofs { |  | ||||||
| 	/// All the proof requests.
 |  | ||||||
| 	pub requests: Vec<HeaderProof>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Kinds of requests.
 |  | ||||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq, 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, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Encompasses all possible types of requests in a single structure.
 |  | ||||||
| #[derive(Debug, Clone, PartialEq, Eq, 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), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/// Get the amount of requests being made.
 |  | ||||||
| 	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(), |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @ -34,5 +34,4 @@ pub mod block_import_error; | |||||||
| pub mod restoration_status; | pub mod restoration_status; | ||||||
| pub mod snapshot_manifest; | pub mod snapshot_manifest; | ||||||
| pub mod mode; | pub mod mode; | ||||||
| pub mod pruning_info; | pub mod pruning_info; | ||||||
| pub mod les_request; |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user