Client app
This commit is contained in:
		
							parent
							
								
									aff4e24775
								
							
						
					
					
						commit
						2a4d470039
					
				| @ -1,15 +1,28 @@ | |||||||
| extern crate ethcore_util as util; | extern crate ethcore_util as util; | ||||||
|  | extern crate ethcore; | ||||||
|  | extern crate rustc_serialize; | ||||||
| 
 | 
 | ||||||
| use std::io::*; | use std::io::*; | ||||||
|  | use std::env; | ||||||
|  | use std::sync::Arc; | ||||||
|  | use rustc_serialize::hex::FromHex; | ||||||
|  | use util::hash::*; | ||||||
| use util::network::{NetworkService}; | use util::network::{NetworkService}; | ||||||
| 
 | use ethcore::client::Client; | ||||||
|  | use ethcore::sync::EthSync; | ||||||
| 
 | 
 | ||||||
| fn main() { | fn main() { | ||||||
| 	let _service = NetworkService::start().unwrap(); | 	let mut service = NetworkService::start().unwrap(); | ||||||
|  | 	let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a059262c330941f3fe2a34d16d6e3c7b30d2ceb37c6a0e9a994c494ee1a61d2410885aa4c8bf8e56e264c0c0".from_hex().unwrap(); | ||||||
|  | 	let mut dir = env::temp_dir(); | ||||||
|  | 	dir.push(H32::random().hex()); | ||||||
|  | 	let client = Arc::new(Client::new(&genesis, &dir)); | ||||||
|  | 	let sync = Box::new(EthSync::new(client)); | ||||||
|  | 	service.register_protocol(sync, "eth", &[62u8, 63u8]).expect("Error registering eth protocol handler"); | ||||||
| 	loop { | 	loop { | ||||||
| 		let mut cmd = String::new(); | 		let mut cmd = String::new(); | ||||||
| 		stdin().read_line(&mut cmd).unwrap(); | 		stdin().read_line(&mut cmd).unwrap(); | ||||||
| 		if cmd == "quit" || cmd == "exit" || cmd == "q" { | 		if cmd == "quit\n" || cmd == "exit\n" || cmd == "q\n" { | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -1,9 +1,9 @@ | |||||||
| //! Fast access to blockchain data.
 | //! Fast access to blockchain data.
 | ||||||
| 
 | 
 | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| use std::cell::RefCell; |  | ||||||
| use std::path::Path; | use std::path::Path; | ||||||
| use std::hash::Hash; | use std::hash::Hash; | ||||||
|  | use std::sync::RwLock; | ||||||
| use rocksdb::{DB, WriteBatch, Writable}; | use rocksdb::{DB, WriteBatch, Writable}; | ||||||
| use heapsize::HeapSizeOf; | use heapsize::HeapSizeOf; | ||||||
| use util::hash::*; | use util::hash::*; | ||||||
| @ -62,17 +62,17 @@ impl BestBlock { | |||||||
| ///
 | ///
 | ||||||
| /// **Does not do input data verification.**
 | /// **Does not do input data verification.**
 | ||||||
| pub struct BlockChain { | pub struct BlockChain { | ||||||
| 	best_block: RefCell<BestBlock>, | 	best_block: RwLock<BestBlock>, | ||||||
| 
 | 
 | ||||||
| 	// block cache
 | 	// block cache
 | ||||||
| 	blocks: RefCell<HashMap<H256, Bytes>>, | 	blocks: RwLock<HashMap<H256, Bytes>>, | ||||||
| 
 | 
 | ||||||
| 	// extra caches
 | 	// extra caches
 | ||||||
| 	block_details: RefCell<HashMap<H256, BlockDetails>>, | 	block_details: RwLock<HashMap<H256, BlockDetails>>, | ||||||
| 	block_hashes: RefCell<HashMap<U256, H256>>, | 	block_hashes: RwLock<HashMap<U256, H256>>, | ||||||
| 	transaction_addresses: RefCell<HashMap<H256, TransactionAddress>>, | 	transaction_addresses: RwLock<HashMap<H256, TransactionAddress>>, | ||||||
| 	block_logs: RefCell<HashMap<H256, BlockLogBlooms>>, | 	block_logs: RwLock<HashMap<H256, BlockLogBlooms>>, | ||||||
| 	blocks_blooms: RefCell<HashMap<H256, BlocksBlooms>>, | 	blocks_blooms: RwLock<HashMap<H256, BlocksBlooms>>, | ||||||
| 
 | 
 | ||||||
| 	extras_db: DB, | 	extras_db: DB, | ||||||
| 	blocks_db: DB | 	blocks_db: DB | ||||||
| @ -117,13 +117,13 @@ impl BlockChain { | |||||||
| 		let blocks_db = DB::open_default(blocks_path.to_str().unwrap()).unwrap(); | 		let blocks_db = DB::open_default(blocks_path.to_str().unwrap()).unwrap(); | ||||||
| 
 | 
 | ||||||
| 		let bc = BlockChain { | 		let bc = BlockChain { | ||||||
| 			best_block: RefCell::new(BestBlock::new()), | 			best_block: RwLock::new(BestBlock::new()), | ||||||
| 			blocks: RefCell::new(HashMap::new()), | 			blocks: RwLock::new(HashMap::new()), | ||||||
| 			block_details: RefCell::new(HashMap::new()), | 			block_details: RwLock::new(HashMap::new()), | ||||||
| 			block_hashes: RefCell::new(HashMap::new()), | 			block_hashes: RwLock::new(HashMap::new()), | ||||||
| 			transaction_addresses: RefCell::new(HashMap::new()), | 			transaction_addresses: RwLock::new(HashMap::new()), | ||||||
| 			block_logs: RefCell::new(HashMap::new()), | 			block_logs: RwLock::new(HashMap::new()), | ||||||
| 			blocks_blooms: RefCell::new(HashMap::new()), | 			blocks_blooms: RwLock::new(HashMap::new()), | ||||||
| 			extras_db: extras_db, | 			extras_db: extras_db, | ||||||
| 			blocks_db: blocks_db | 			blocks_db: blocks_db | ||||||
| 		}; | 		}; | ||||||
| @ -158,7 +158,7 @@ impl BlockChain { | |||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		{ | 		{ | ||||||
| 			let mut best_block = bc.best_block.borrow_mut(); | 			let mut best_block = bc.best_block.write().unwrap(); | ||||||
| 			best_block.number = bc.block_number(&best_block_hash).unwrap(); | 			best_block.number = bc.block_number(&best_block_hash).unwrap(); | ||||||
| 			best_block.total_difficulty = bc.block_details(&best_block_hash).unwrap().total_difficulty; | 			best_block.total_difficulty = bc.block_details(&best_block_hash).unwrap().total_difficulty; | ||||||
| 			best_block.hash = best_block_hash; | 			best_block.hash = best_block_hash; | ||||||
| @ -272,7 +272,7 @@ impl BlockChain { | |||||||
| 		// create views onto rlp
 | 		// create views onto rlp
 | ||||||
| 		let block = BlockView::new(bytes); | 		let block = BlockView::new(bytes); | ||||||
| 		let header = block.header_view(); | 		let header = block.header_view(); | ||||||
| 		let hash = block.sha3(); | 		let hash = header.sha3(); | ||||||
| 
 | 
 | ||||||
| 		if self.is_known(&hash) { | 		if self.is_known(&hash) { | ||||||
| 			return; | 			return; | ||||||
| @ -283,13 +283,13 @@ impl BlockChain { | |||||||
| 		let (batch, new_best) = self.block_to_extras_insert_batch(bytes); | 		let (batch, new_best) = self.block_to_extras_insert_batch(bytes); | ||||||
| 
 | 
 | ||||||
| 		// update best block
 | 		// update best block
 | ||||||
| 		let mut best_block = self.best_block.borrow_mut(); | 		let mut best_block = self.best_block.write().unwrap(); | ||||||
| 		if let Some(b) = new_best { | 		if let Some(b) = new_best { | ||||||
| 			*best_block = b; | 			*best_block = b; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// update caches
 | 		// update caches
 | ||||||
| 		let mut write = self.block_details.borrow_mut(); | 		let mut write = self.block_details.write().unwrap(); | ||||||
| 		write.remove(&header.parent_hash()); | 		write.remove(&header.parent_hash()); | ||||||
| 
 | 
 | ||||||
| 		// update extras database
 | 		// update extras database
 | ||||||
| @ -425,17 +425,17 @@ impl BlockChain { | |||||||
| 
 | 
 | ||||||
| 	/// Get best block hash.
 | 	/// Get best block hash.
 | ||||||
| 	pub fn best_block_hash(&self) -> H256 { | 	pub fn best_block_hash(&self) -> H256 { | ||||||
| 		self.best_block.borrow().hash.clone() | 		self.best_block.read().unwrap().hash.clone() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/// Get best block number.
 | 	/// Get best block number.
 | ||||||
| 	pub fn best_block_number(&self) -> U256 { | 	pub fn best_block_number(&self) -> U256 { | ||||||
| 		self.best_block.borrow().number | 		self.best_block.read().unwrap().number | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/// Get best block total difficulty.
 | 	/// Get best block total difficulty.
 | ||||||
| 	pub fn best_block_total_difficulty(&self) -> U256 { | 	pub fn best_block_total_difficulty(&self) -> U256 { | ||||||
| 		self.best_block.borrow().total_difficulty | 		self.best_block.read().unwrap().total_difficulty | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/// Get the number of given block's hash.
 | 	/// Get the number of given block's hash.
 | ||||||
| @ -448,9 +448,10 @@ impl BlockChain { | |||||||
| 		self.query_extras(hash, &self.block_logs) | 		self.query_extras(hash, &self.block_logs) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn block(&self, hash: &H256) -> Option<Bytes> { | 	/// Get raw block data
 | ||||||
|  | 	pub fn block(&self, hash: &H256) -> Option<Bytes> { | ||||||
| 		{ | 		{ | ||||||
| 			let read = self.blocks.borrow(); | 			let read = self.blocks.read().unwrap(); | ||||||
| 			match read.get(hash) { | 			match read.get(hash) { | ||||||
| 				Some(v) => return Some(v.clone()), | 				Some(v) => return Some(v.clone()), | ||||||
| 				None => () | 				None => () | ||||||
| @ -463,7 +464,7 @@ impl BlockChain { | |||||||
| 		match opt { | 		match opt { | ||||||
| 			Some(b) => { | 			Some(b) => { | ||||||
| 				let bytes: Bytes = b.to_vec(); | 				let bytes: Bytes = b.to_vec(); | ||||||
| 				let mut write = self.blocks.borrow_mut(); | 				let mut write = self.blocks.write().unwrap(); | ||||||
| 				write.insert(hash.clone(), bytes.clone()); | 				write.insert(hash.clone(), bytes.clone()); | ||||||
| 				Some(bytes) | 				Some(bytes) | ||||||
| 			}, | 			}, | ||||||
| @ -471,11 +472,11 @@ impl BlockChain { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn query_extras<K, T>(&self, hash: &K, cache: &RefCell<HashMap<K, T>>) -> Option<T> where | 	fn query_extras<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> Option<T> where | ||||||
| 		T: Clone + Decodable + ExtrasIndexable, | 		T: Clone + Decodable + ExtrasIndexable, | ||||||
| 		K: ExtrasSliceConvertable + Eq + Hash + Clone { | 		K: ExtrasSliceConvertable + Eq + Hash + Clone { | ||||||
| 		{ | 		{ | ||||||
| 			let read = cache.borrow(); | 			let read = cache.read().unwrap(); | ||||||
| 			match read.get(hash) { | 			match read.get(hash) { | ||||||
| 				Some(v) => return Some(v.clone()), | 				Some(v) => return Some(v.clone()), | ||||||
| 				None => () | 				None => () | ||||||
| @ -483,17 +484,17 @@ impl BlockChain { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		self.extras_db.get_extras(hash).map(| t: T | { | 		self.extras_db.get_extras(hash).map(| t: T | { | ||||||
| 			let mut write = cache.borrow_mut(); | 			let mut write = cache.write().unwrap(); | ||||||
| 			write.insert(hash.clone(), t.clone()); | 			write.insert(hash.clone(), t.clone()); | ||||||
| 			t | 			t | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn query_extras_exist<K, T>(&self, hash: &K, cache: &RefCell<HashMap<K, T>>) -> bool where | 	fn query_extras_exist<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> bool where | ||||||
| 		K: ExtrasSliceConvertable + Eq + Hash + Clone, | 		K: ExtrasSliceConvertable + Eq + Hash + Clone, | ||||||
| 		T: ExtrasIndexable { | 		T: ExtrasIndexable { | ||||||
| 		{ | 		{ | ||||||
| 			let read = cache.borrow(); | 			let read = cache.read().unwrap(); | ||||||
| 			match read.get(hash) { | 			match read.get(hash) { | ||||||
| 				Some(_) => return true, | 				Some(_) => return true, | ||||||
| 				None => () | 				None => () | ||||||
| @ -506,21 +507,21 @@ impl BlockChain { | |||||||
| 	/// Get current cache size.
 | 	/// Get current cache size.
 | ||||||
| 	pub fn cache_size(&self) -> CacheSize { | 	pub fn cache_size(&self) -> CacheSize { | ||||||
| 		CacheSize { | 		CacheSize { | ||||||
| 			blocks: self.blocks.heap_size_of_children(), | 			blocks: self.blocks.read().unwrap().heap_size_of_children(), | ||||||
| 			block_details: self.block_details.heap_size_of_children(), | 			block_details: self.block_details.read().unwrap().heap_size_of_children(), | ||||||
| 			transaction_addresses: self.transaction_addresses.heap_size_of_children(), | 			transaction_addresses: self.transaction_addresses.read().unwrap().heap_size_of_children(), | ||||||
| 			block_logs: self.block_logs.heap_size_of_children(), | 			block_logs: self.block_logs.read().unwrap().heap_size_of_children(), | ||||||
| 			blocks_blooms: self.blocks_blooms.heap_size_of_children() | 			blocks_blooms: self.blocks_blooms.read().unwrap().heap_size_of_children() | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/// Tries to squeeze the cache if its too big.
 | 	/// Tries to squeeze the cache if its too big.
 | ||||||
| 	pub fn squeeze_to_fit(&self, size: CacheSize) { | 	pub fn squeeze_to_fit(&self, size: CacheSize) { | ||||||
| 		self.blocks.borrow_mut().squeeze(size.blocks); | 		self.blocks.write().unwrap().squeeze(size.blocks); | ||||||
| 		self.block_details.borrow_mut().squeeze(size.block_details); | 		self.block_details.write().unwrap().squeeze(size.block_details); | ||||||
| 		self.transaction_addresses.borrow_mut().squeeze(size.transaction_addresses); | 		self.transaction_addresses.write().unwrap().squeeze(size.transaction_addresses); | ||||||
| 		self.block_logs.borrow_mut().squeeze(size.block_logs); | 		self.block_logs.write().unwrap().squeeze(size.block_logs); | ||||||
| 		self.blocks_blooms.borrow_mut().squeeze(size.blocks_blooms); | 		self.blocks_blooms.write().unwrap().squeeze(size.blocks_blooms); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								src/eth.rs
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/eth.rs
									
									
									
									
									
								
							| @ -27,8 +27,8 @@ pub struct BlockChainInfo { | |||||||
| 	pub total_difficulty: U256, | 	pub total_difficulty: U256, | ||||||
| 	pub pending_total_difficulty: U256, | 	pub pending_total_difficulty: U256, | ||||||
| 	pub genesis_hash: H256, | 	pub genesis_hash: H256, | ||||||
| 	pub last_block_hash: H256, | 	pub best_block_hash: H256, | ||||||
| 	pub last_block_number: BlockNumber | 	pub best_block_number: BlockNumber | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct BlockQueueStatus { | pub struct BlockQueueStatus { | ||||||
| @ -37,21 +37,21 @@ pub struct BlockQueueStatus { | |||||||
| 
 | 
 | ||||||
| pub type TreeRoute = ::blockchain::TreeRoute; | pub type TreeRoute = ::blockchain::TreeRoute; | ||||||
| 
 | 
 | ||||||
| pub type BlockNumber = u32; | pub type BlockNumber = u64; | ||||||
| 
 | 
 | ||||||
| pub trait BlockChainClient : Sync { | pub trait BlockChainClient : Sync { | ||||||
| 	fn block_header(&self, h: &H256) -> Option<Bytes>; | 	fn block_header(&self, hash: &H256) -> Option<Bytes>; | ||||||
| 	fn block_body(&self, h: &H256) -> Option<Bytes>; | 	fn block_body(&self, hash: &H256) -> Option<Bytes>; | ||||||
| 	fn block(&self, h: &H256) -> Option<Bytes>; | 	fn block(&self, hash: &H256) -> Option<Bytes>; | ||||||
| 	fn block_status(&self, h: &H256) -> BlockStatus; | 	fn block_status(&self, hash: &H256) -> BlockStatus; | ||||||
| 	fn block_header_at(&self, n: BlockNumber) -> Option<Bytes>; | 	fn block_header_at(&self, n: BlockNumber) -> Option<Bytes>; | ||||||
| 	fn block_body_at(&self, n: BlockNumber) -> Option<Bytes>; | 	fn block_body_at(&self, n: BlockNumber) -> Option<Bytes>; | ||||||
| 	fn block_at(&self, n: BlockNumber) -> Option<Bytes>; | 	fn block_at(&self, n: BlockNumber) -> Option<Bytes>; | ||||||
| 	fn block_status_at(&self, n: BlockNumber) -> BlockStatus; | 	fn block_status_at(&self, n: BlockNumber) -> BlockStatus; | ||||||
| 	fn tree_route(&self, from: &H256, to: &H256) -> TreeRoute; | 	fn tree_route(&self, from: &H256, to: &H256) -> TreeRoute; | ||||||
| 	fn state_data(&self, h: &H256) -> Option<Bytes>; | 	fn state_data(&self, hash: &H256) -> Option<Bytes>; | ||||||
| 	fn block_receipts(&self, h: &H256) -> Option<Bytes>; | 	fn block_receipts(&self, hash: &H256) -> Option<Bytes>; | ||||||
| 	fn import_block(&mut self, b: &[u8]) -> ImportResult; | 	fn import_block(&mut self, byte: &[u8]) -> ImportResult; | ||||||
| 	fn queue_status(&self) -> BlockQueueStatus; | 	fn queue_status(&self) -> BlockQueueStatus; | ||||||
| 	fn clear_queue(&mut self); | 	fn clear_queue(&mut self); | ||||||
| 	fn info(&self) -> BlockChainInfo; | 	fn info(&self) -> BlockChainInfo; | ||||||
|  | |||||||
| @ -104,6 +104,8 @@ pub mod genesis; | |||||||
| pub mod views; | pub mod views; | ||||||
| pub mod blockchain; | pub mod blockchain; | ||||||
| pub mod extras; | pub mod extras; | ||||||
|  | pub mod client; | ||||||
| 
 | 
 | ||||||
| pub mod eth; | pub mod eth; | ||||||
| pub mod sync; | pub mod sync; | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -202,7 +202,7 @@ impl ChainSync { | |||||||
| 		self.highest_block = 0; | 		self.highest_block = 0; | ||||||
| 		self.have_common_block = false; | 		self.have_common_block = false; | ||||||
| 		io.chain().clear_queue(); | 		io.chain().clear_queue(); | ||||||
| 		self.starting_block = io.chain().info().last_block_number; | 		self.starting_block = io.chain().info().best_block_number; | ||||||
| 		self.state = SyncState::NotSynced; | 		self.state = SyncState::NotSynced; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -516,7 +516,7 @@ impl ChainSync { | |||||||
| 			if !self.have_common_block { | 			if !self.have_common_block { | ||||||
| 				// download backwards until common block is found 1 header at a time
 | 				// download backwards until common block is found 1 header at a time
 | ||||||
| 				let chain_info = io.chain().info(); | 				let chain_info = io.chain().info(); | ||||||
| 				start = chain_info.last_block_number as usize; | 				start = chain_info.best_block_number as usize; | ||||||
| 				if !self.headers.is_empty() { | 				if !self.headers.is_empty() { | ||||||
| 					start = min(start, self.headers.range_iter().next().unwrap().0 as usize - 1); | 					start = min(start, self.headers.range_iter().next().unwrap().0 as usize - 1); | ||||||
| 				} | 				} | ||||||
| @ -724,7 +724,7 @@ impl ChainSync { | |||||||
| 		packet.append(&(PROTOCOL_VERSION as u32)); | 		packet.append(&(PROTOCOL_VERSION as u32)); | ||||||
| 		packet.append(&0u32); //TODO: network id
 | 		packet.append(&0u32); //TODO: network id
 | ||||||
| 		packet.append(&chain.total_difficulty); | 		packet.append(&chain.total_difficulty); | ||||||
| 		packet.append(&chain.last_block_hash); | 		packet.append(&chain.best_block_hash); | ||||||
| 		packet.append(&chain.genesis_hash); | 		packet.append(&chain.genesis_hash); | ||||||
| 		//TODO: handle timeout for status request
 | 		//TODO: handle timeout for status request
 | ||||||
| 		match io.send(*peer_id, STATUS_PACKET, packet.out()) { | 		match io.send(*peer_id, STATUS_PACKET, packet.out()) { | ||||||
| @ -742,7 +742,7 @@ impl ChainSync { | |||||||
| 		let max_headers: usize = r.val_at(1); | 		let max_headers: usize = r.val_at(1); | ||||||
| 		let skip: usize = r.val_at(2); | 		let skip: usize = r.val_at(2); | ||||||
| 		let reverse: bool = r.val_at(3); | 		let reverse: bool = r.val_at(3); | ||||||
| 		let last = io.chain().info().last_block_number; | 		let last = io.chain().info().best_block_number; | ||||||
| 		let mut number = if r.at(0).size() == 32 { | 		let mut number = if r.at(0).size() == 32 { | ||||||
| 			// id is a hash
 | 			// id is a hash
 | ||||||
| 			let hash: H256 = r.val_at(0); | 			let hash: H256 = r.val_at(0); | ||||||
|  | |||||||
| @ -63,6 +63,13 @@ pub struct EthSync { | |||||||
| pub use self::chain::SyncStatus; | pub use self::chain::SyncStatus; | ||||||
| 
 | 
 | ||||||
| impl EthSync { | impl EthSync { | ||||||
|  | 	pub fn new(chain: Arc<BlockChainClient+Send+Sized>) -> EthSync { | ||||||
|  | 		EthSync { | ||||||
|  | 			chain: chain, | ||||||
|  | 			sync: ChainSync::new(), | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	pub fn is_syncing(&self) -> bool { | 	pub fn is_syncing(&self) -> bool { | ||||||
| 		self.sync.is_syncing() | 		self.sync.is_syncing() | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -180,7 +180,7 @@ impl<K, V> RangeCollection<K, V> for Vec<(K, Vec<V>)> where K: Ord + PartialEq + | |||||||
| fn test_range() { | fn test_range() { | ||||||
| 	use std::cmp::{Ordering}; | 	use std::cmp::{Ordering}; | ||||||
| 
 | 
 | ||||||
| 	let mut ranges: Vec<(u32, Vec<char>)> = Vec::new(); | 	let mut ranges: Vec<(u64, Vec<char>)> = Vec::new(); | ||||||
| 	assert_eq!(ranges.range_iter().next(), None); | 	assert_eq!(ranges.range_iter().next(), None); | ||||||
| 	assert_eq!(ranges.find_item(&1), None); | 	assert_eq!(ranges.find_item(&1), None); | ||||||
| 	assert!(!ranges.have_item(&1)); | 	assert!(!ranges.have_item(&1)); | ||||||
|  | |||||||
| @ -169,8 +169,8 @@ impl BlockChainClient for TestBlockChainClient { | |||||||
| 			total_difficulty: self.difficulty, | 			total_difficulty: self.difficulty, | ||||||
| 			pending_total_difficulty: self.difficulty, | 			pending_total_difficulty: self.difficulty, | ||||||
| 			genesis_hash: self.genesis_hash.clone(), | 			genesis_hash: self.genesis_hash.clone(), | ||||||
| 			last_block_hash: self.last_hash.clone(), | 			best_block_hash: self.last_hash.clone(), | ||||||
| 			last_block_number: self.blocks.len() as BlockNumber - 1, | 			best_block_number: self.blocks.len() as BlockNumber - 1, | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user