Initial structure for auto-updater.
- Add auto-gen'ed Operations and Registry ABIs. - Add Updater for managing updates. - Add fields in Client to enable update checking and registry.
This commit is contained in:
		
							parent
							
								
									28aabcdb6c
								
							
						
					
					
						commit
						401a4a37c1
					
				| @ -13,7 +13,9 @@ | ||||
| 
 | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| use std::collections::{HashSet, HashMap, BTreeMap, VecDeque}; | ||||
| use std::str::FromStr; | ||||
| use std::sync::{Arc, Weak}; | ||||
| use std::path::{Path}; | ||||
| use std::fmt; | ||||
| @ -22,12 +24,11 @@ use std::time::{Instant}; | ||||
| use time::precise_time_ns; | ||||
| 
 | ||||
| // util
 | ||||
| use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, ToPretty}; | ||||
| use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, MutexGuard, Hashable}; | ||||
| use util::{journaldb, TrieFactory, Trie}; | ||||
| use util::trie::TrieSpec; | ||||
| use util::{U256, H256, Address, H2048, Uint, FixedHash}; | ||||
| use util::kvdb::*; | ||||
| use util::misc::code_hash; | ||||
| 
 | ||||
| // other
 | ||||
| use io::*; | ||||
| @ -69,7 +70,8 @@ use factory::Factories; | ||||
| use rlp::{decode, View, UntrustedRlp}; | ||||
| use state_db::StateDB; | ||||
| use rand::OsRng; | ||||
| use ethabi::{Interface, Contract, Token}; | ||||
| use client::updater::Updater; | ||||
| use client::registry::Registry; | ||||
| 
 | ||||
| // re-export
 | ||||
| pub use types::blockchain_info::BlockChainInfo; | ||||
| @ -140,6 +142,7 @@ pub struct Client { | ||||
| 	panic_handler: Arc<PanicHandler>, | ||||
| 	verifier: Box<Verifier>, | ||||
| 	miner: Arc<Miner>, | ||||
| 	updater: Mutex<Option<Updater>>, | ||||
| 	sleep_state: Mutex<SleepState>, | ||||
| 	liveness: AtomicBool, | ||||
| 	io_channel: Mutex<IoChannel<ClientIoMessage>>, | ||||
| @ -150,6 +153,7 @@ pub struct Client { | ||||
| 	history: u64, | ||||
| 	rng: Mutex<OsRng>, | ||||
| 	on_mode_change: Mutex<Option<Box<FnMut(&Mode) + 'static + Send>>>, | ||||
| 	registrar: Mutex<Option<Registry>>, | ||||
| } | ||||
| 
 | ||||
| impl Client { | ||||
| @ -222,7 +226,7 @@ impl Client { | ||||
| 			accountdb: Default::default(), | ||||
| 		}; | ||||
| 
 | ||||
| 		let client = Client { | ||||
| 		let client = Arc::new(Client { | ||||
| 			sleep_state: Mutex::new(SleepState::new(awake)), | ||||
| 			liveness: AtomicBool::new(awake), | ||||
| 			mode: Mutex::new(config.mode.clone()), | ||||
| @ -239,6 +243,7 @@ impl Client { | ||||
| 			import_lock: Mutex::new(()), | ||||
| 			panic_handler: panic_handler, | ||||
| 			miner: miner, | ||||
| 			updater: Mutex::new(None), | ||||
| 			io_channel: Mutex::new(message_channel), | ||||
| 			notify: RwLock::new(Vec::new()), | ||||
| 			queue_transactions: AtomicUsize::new(0), | ||||
| @ -247,8 +252,19 @@ impl Client { | ||||
| 			history: history, | ||||
| 			rng: Mutex::new(try!(OsRng::new().map_err(::util::UtilError::StdIo))), | ||||
| 			on_mode_change: Mutex::new(None), | ||||
| 		}; | ||||
| 		Ok(Arc::new(client)) | ||||
| 			registrar: Mutex::new(None), | ||||
| 		}); | ||||
| 		if let Some(reg_addr) = client.additional_params().get("registrar").and_then(|s| Address::from_str(s).ok()) { | ||||
| 			let weak = Arc::downgrade(&client); | ||||
| 			let registrar = Registry::new(reg_addr, move |a, d| weak.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(a, d))); | ||||
| 			if let Ok(operations) = registrar.get_address(&(&b"operations"[..]).sha3(), "A") { | ||||
| 				if !operations.is_zero() { 
 | ||||
| 					*client.updater.lock() = Some(Updater::new(Arc::downgrade(&client), operations)); | ||||
| 				} | ||||
| 			} | ||||
| 			*client.registrar.lock() = Some(registrar); | ||||
| 		} | ||||
| 		Ok(client) | ||||
| 	} | ||||
| 
 | ||||
| 	/// Adds an actor to be notified on certain events
 | ||||
| @ -264,6 +280,11 @@ impl Client { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/// Get the Registry object - useful for looking up names.
 | ||||
| 	pub fn registrar(&self) -> MutexGuard<Option<Registry>> { | ||||
| 		self.registrar.lock() | ||||
| 	} | ||||
| 
 | ||||
| 	/// Register an action to be done if a mode change happens. 
 | ||||
| 	pub fn on_mode_change<F>(&self, f: F) where F: 'static + FnMut(&Mode) + Send { | ||||
| 		*self.on_mode_change.lock() = Some(Box::new(f)); | ||||
| @ -644,7 +665,9 @@ impl Client { | ||||
| 	pub fn tick(&self) { | ||||
| 		self.check_garbage(); | ||||
| 		self.check_snooze(); | ||||
| 		self.check_updates(); | ||||
| 		if let Some(ref mut updater) = *self.updater.lock() { | ||||
| 			updater.tick(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn check_garbage(&self) { | ||||
| @ -687,7 +710,8 @@ impl Client { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fn call_contract(&self, address: Address, data: Bytes) -> Result<Bytes, String> { | ||||
| 	/// Like `call`, but with various defaults. Designed to be used for calling contracts.
 | ||||
| 	pub fn call_contract(&self, address: Address, data: Bytes) -> Result<Bytes, String> { | ||||
| 		let from = Address::default(); | ||||
| 		let transaction = Transaction { | ||||
| 			nonce: self.latest_nonce(&from), | ||||
| @ -705,39 +729,6 @@ impl Client { | ||||
| 			}) | ||||
| 	} | ||||
| 
 | ||||
| 	fn check_updates(&self) { | ||||
| 		let operations_json = Interface::load(include_bytes!("../../res/Operations.json")).expect("Operations.json is valid ABI"); | ||||
| 		let operations = Contract::new(operations_json); | ||||
| 
 | ||||
| 		fn as_string<T: fmt::Debug>(e: T) -> String { | ||||
| 			format!("{:?}", e) | ||||
| 		} | ||||
| 
 | ||||
| 		let res = || { | ||||
| 			let is_latest = try!(operations.function("isLatest".into()).map_err(as_string)); | ||||
| 			let params = try!(is_latest.encode_call( | ||||
| 				vec![Token::FixedBytes(b"par"[..].to_owned()), Token::Address(code_hash().0)] | ||||
| 			).map_err(as_string)); | ||||
| 			println!("params: {}", params.pretty()); | ||||
| 			let output = try!(self.call_contract("0x4c1783B4FfB1A99eFC4cda632aA990F5138b26f1".into(), params)); | ||||
| 			let result = try!(is_latest.decode_output(output).map_err(as_string)); | ||||
| 
 | ||||
| 			match result.get(0) { | ||||
| 				Some(&Token::Bool(answer)) => Ok(answer), | ||||
| 				e => Err(format!("Invalid result: {:?}", e)), | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		match res() { | ||||
| 			Ok(res) => { | ||||
| 				info!("isLatest returned {}", res); | ||||
| 			}, | ||||
| 			Err(e) => { | ||||
| 				warn!(target: "dapps", "Error while calling Operations.isLatest: {:?}", e); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/// Look up the block number for the given block ID.
 | ||||
| 	pub fn block_number(&self, id: BlockID) -> Option<BlockNumber> { | ||||
| 		match id { | ||||
|  | ||||
| @ -1,3 +1,19 @@ | ||||
| // 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/>.
 | ||||
| 
 | ||||
| use trace::Error as TraceError; | ||||
| use util::UtilError; | ||||
| use std::fmt::{Display, Formatter, Error as FmtError}; | ||||
|  | ||||
| @ -16,11 +16,14 @@ | ||||
| 
 | ||||
| //! Blockchain database client.
 | ||||
| 
 | ||||
| mod operations; | ||||
| mod registry; | ||||
| mod config; | ||||
| mod error; | ||||
| mod test_client; | ||||
| mod trace; | ||||
| mod client; | ||||
| mod updater; | ||||
| 
 | ||||
| pub use self::client::*; | ||||
| pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; | ||||
|  | ||||
							
								
								
									
										336
									
								
								ethcore/src/client/operations.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										336
									
								
								ethcore/src/client/operations.rs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										264
									
								
								ethcore/src/client/registry.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								ethcore/src/client/registry.rs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										45
									
								
								ethcore/src/client/updater.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								ethcore/src/client/updater.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| // 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/>.
 | ||||
| 
 | ||||
| //use util::{U256, H256, Address, H2048, Uint, FixedHash};
 | ||||
| use std::sync::Weak; | ||||
| use util::misc::code_hash; | ||||
| use util::Address; | ||||
| use client::operations::Operations; | ||||
| use client::client::Client; | ||||
| 
 | ||||
| pub struct Updater { | ||||
| 	operations: Operations, | ||||
| } | ||||
| 
 | ||||
| impl Updater { | ||||
| 	pub fn new(client: Weak<Client>, operations: Address) -> Self { | ||||
| 		Updater { | ||||
| 			operations: Operations::new(operations, move |a, d| client.upgrade().ok_or("No client!".into()).and_then(|c| c.call_contract(a, d))), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	pub fn tick(&mut self) { | ||||
| 		match self.operations.is_latest("par", &code_hash().into()) { | ||||
| 			Ok(res) => { | ||||
| 				info!("isLatest returned {}", res); | ||||
| 			}, | ||||
| 			Err(e) => { | ||||
| 				warn!(target: "dapps", "Error while calling Operations.isLatest: {:?}", e); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user