From 4bb4ed95516e8f8e31af774120fb434a6bf07855 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 13 Nov 2016 15:52:33 +0100 Subject: [PATCH] Initial checking. --- Cargo.lock | 1 + ethcore/Cargo.toml | 1 + ethcore/src/client/client.rs | 62 +++++++++++++++++++++++++++++++++++- ethcore/src/lib.rs | 1 + util/src/misc.rs | 5 +++ 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c3fa096b3..b53b28426 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -282,6 +282,7 @@ dependencies = [ "clippy 0.0.96 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ethabi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.4.0", "ethcore-bloom-journal 0.1.0", "ethcore-devtools 1.4.0", diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 667b40ace..439263794 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -41,6 +41,7 @@ ethcore-ipc-nano = { path = "../ipc/nano" } rlp = { path = "../util/rlp" } lru-cache = "0.1.0" ethcore-bloom-journal = { path = "../util/bloom" } +ethabi = "0.2.2" [dependencies.hyper] git = "https://github.com/ethcore/hyper" diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index ec59e01cf..400d53ed1 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -27,6 +27,7 @@ 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::*; @@ -42,7 +43,7 @@ use env_info::LastHashes; use verification; use verification::{PreverifiedBlock, Verifier}; use block::*; -use transaction::{LocalizedTransaction, SignedTransaction, Action}; +use transaction::{LocalizedTransaction, SignedTransaction, Transaction, Action}; use blockchain::extras::TransactionAddress; use types::filter::Filter; use types::mode::Mode as IpcMode; @@ -68,6 +69,7 @@ use factory::Factories; use rlp::{decode, View, UntrustedRlp}; use state_db::StateDB; use rand::OsRng; +use ethabi::{Interface, Contract, Token}; // re-export pub use types::blockchain_info::BlockChainInfo; @@ -634,10 +636,18 @@ impl Client { /// Tick the client. // TODO: manage by real events. pub fn tick(&self) { + self.check_garbage(); + self.check_snooze(); + self.check_updates(); + } + + fn check_garbage(&self) { self.chain.read().collect_garbage(); self.block_queue.collect_garbage(); self.tracedb.read().collect_garbage(); + } + fn check_snooze(&self) { let mode = self.mode.lock().clone(); match mode { Mode::Dark(timeout) => { @@ -671,6 +681,56 @@ impl Client { } } + fn call_contract(&self, address: Address, data: Bytes) -> Result { + let from = Address::default(); + let transaction = Transaction { + nonce: self.latest_nonce(&from), + action: Action::Call(address), + gas: U256::from(50_000_000), + gas_price: U256::default(), + value: U256::default(), + data: data, + }.fake_sign(from); + + self.call(&transaction, BlockID::Latest, Default::default()) + .map_err(|e| format!("{:?}", e)) + .map(|executed| { + executed.output + }) + } + + 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(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::String("par".into()), Token::Address(code_hash().0)] + ).map_err(as_string)); + 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 { match id { diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index bf3e59171..59e45f381 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -117,6 +117,7 @@ extern crate lru_cache; #[cfg(feature = "jit" )] extern crate evmjit; +extern crate ethabi; pub extern crate ethstore; diff --git a/util/src/misc.rs b/util/src/misc.rs index b0452e85e..d9eab1af0 100644 --- a/util/src/misc.rs +++ b/util/src/misc.rs @@ -32,6 +32,11 @@ pub enum Filth { Dirty, } +/// Get the (SHA1?) 160-bit hash of this build's code base. +pub fn code_hash() -> H160 { + sha().into() +} + /// Get the standard version string for this software. pub fn version() -> String { let sha3 = short_sha();