diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 000000000..1efef4f21
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,16 @@
+language: rust
+
+rust:
+ - nightly
+
+os:
+ - osx
+
+before_script:
+ - brew update
+ - brew install rocksdb
+
+cache:
+ directories:
+ - $TRAVIS_BUILD_DIR/target
+ - $HOME/.cargo
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 75f983253..82658c6ac 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,10 +21,13 @@ evmjit = { path = "rust-evmjit", optional = true }
ethash = { path = "ethash" }
num_cpus = "0.2"
docopt = "0.6"
+ctrlc = "1.0"
+clippy = "0.0.37"
[features]
jit = ["evmjit"]
-evm_debug = []
+test-heavy = []
+evm-debug = []
[[bin]]
name = "client"
diff --git a/README.md b/README.md
index 216ac8091..48172bb60 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,5 @@
# ethcore
+
+
+# Running clippy
+
diff --git a/ethash/src/lib.rs b/ethash/src/lib.rs
index f7b6d2308..e87ee1a03 100644
--- a/ethash/src/lib.rs
+++ b/ethash/src/lib.rs
@@ -30,11 +30,13 @@ impl EthashManager {
/// `nonce` - The nonce to pack into the mix
pub fn compute_light(&self, block_number: u64, header_hash: &H256, nonce: u64) -> ProofOfWork {
let epoch = block_number / ETHASH_EPOCH_LENGTH;
- if !self.lights.read().unwrap().contains_key(&epoch) {
- let mut lights = self.lights.write().unwrap(); // obtain write lock
- if !lights.contains_key(&epoch) {
- let light = Light::new(block_number);
- lights.insert(epoch, light);
+ while !self.lights.read().unwrap().contains_key(&epoch) {
+ if let Ok(mut lights) = self.lights.try_write()
+ {
+ if !lights.contains_key(&epoch) {
+ let light = Light::new(block_number);
+ lights.insert(epoch, light);
+ }
}
}
self.lights.read().unwrap().get(&epoch).unwrap().compute(header_hash, nonce)
diff --git a/hook.sh b/hook.sh
new file mode 100755
index 000000000..a82f926b9
--- /dev/null
+++ b/hook.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+echo "#!/bin/sh\ncargo test" >> ./.git/hooks/pre-push
+chmod +x ./.git/hooks/pre-push
diff --git a/src/account.rs b/src/account.rs
index c6c4136df..b0fbf3f85 100644
--- a/src/account.rs
+++ b/src/account.rs
@@ -103,7 +103,7 @@ impl Account {
/// Get (and cache) the contents of the trie's storage at `key`.
pub fn storage_at(&self, db: &HashDB, key: &H256) -> H256 {
self.storage_overlay.borrow_mut().entry(key.clone()).or_insert_with(||{
- (Filth::Clean, H256::from(SecTrieDB::new(db, &self.storage_root).get(key.bytes()).map(|v| -> U256 {decode(v)}).unwrap_or(U256::zero())))
+ (Filth::Clean, H256::from(SecTrieDB::new(db, &self.storage_root).get(key.bytes()).map_or(U256::zero(), |v| -> U256 {decode(v)})))
}).1.clone()
}
@@ -149,7 +149,7 @@ impl Account {
/// Provide a database to lookup `code_hash`. Should not be called if it is a contract without code.
pub fn cache_code(&mut self, db: &HashDB) -> bool {
// TODO: fill out self.code_cache;
- return self.is_cached() ||
+ self.is_cached() ||
match self.code_hash {
Some(ref h) => match db.lookup(h) {
Some(x) => { self.code_cache = x.to_vec(); true },
@@ -248,8 +248,8 @@ mod tests {
let a = Account::from_rlp(&rlp);
assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
- assert_eq!(a.storage_at(&mut db, &H256::from(&U256::from(0x00u64))), H256::from(&U256::from(0x1234u64)));
- assert_eq!(a.storage_at(&mut db, &H256::from(&U256::from(0x01u64))), H256::new());
+ assert_eq!(a.storage_at(&db, &H256::from(&U256::from(0x00u64))), H256::from(&U256::from(0x1234u64)));
+ assert_eq!(a.storage_at(&db, &H256::from(&U256::from(0x01u64))), H256::new());
}
#[test]
diff --git a/src/account_diff.rs b/src/account_diff.rs
index 06315db95..1843c4381 100644
--- a/src/account_diff.rs
+++ b/src/account_diff.rs
@@ -15,10 +15,10 @@ pub enum Existance {
impl fmt::Display for Existance {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- &Existance::Born => try!(write!(f, "+++")),
- &Existance::Alive => try!(write!(f, "***")),
- &Existance::Died => try!(write!(f, "XXX")),
+ match *self {
+ Existance::Born => try!(write!(f, "+++")),
+ Existance::Alive => try!(write!(f, "***")),
+ Existance::Died => try!(write!(f, "XXX")),
}
Ok(())
}
@@ -72,11 +72,11 @@ impl AccountDiff {
code: Diff::new(pre.code.clone(), post.code.clone()),
storage: storage.into_iter().map(|k|
(k.clone(), Diff::new(
- pre.storage.get(&k).cloned().unwrap_or(H256::new()),
- post.storage.get(&k).cloned().unwrap_or(H256::new())
+ pre.storage.get(&k).cloned().unwrap_or_else(H256::new),
+ post.storage.get(&k).cloned().unwrap_or_else(H256::new)
))).collect(),
};
- if r.balance.is_same() && r.nonce.is_same() && r.code.is_same() && r.storage.len() == 0 {
+ if r.balance.is_same() && r.nonce.is_same() && r.code.is_same() && r.storage.is_empty() {
None
} else {
Some(r)
@@ -112,16 +112,15 @@ impl fmt::Display for AccountDiff {
Diff::Changed(ref pre, ref post) => try!(write!(f, "${} ({} {} {})", post, pre, if pre > post {"-"} else {"+"}, *max(pre, post) - *min(pre, post))),
_ => {},
}
- match self.code {
- Diff::Born(ref x) => try!(write!(f, " code {}", x.pretty())),
- _ => {},
+ if let Diff::Born(ref x) = self.code {
+ try!(write!(f, " code {}", x.pretty()));
}
try!(write!(f, "\n"));
- for (k, dv) in self.storage.iter() {
- match dv {
- &Diff::Born(ref v) => try!(write!(f, " + {} => {}\n", interpreted_hash(k), interpreted_hash(v))),
- &Diff::Changed(ref pre, ref post) => try!(write!(f, " * {} => {} (was {})\n", interpreted_hash(k), interpreted_hash(post), interpreted_hash(pre))),
- &Diff::Died(_) => try!(write!(f, " X {}\n", interpreted_hash(k))),
+ for (k, dv) in &self.storage {
+ match *dv {
+ Diff::Born(ref v) => try!(write!(f, " + {} => {}\n", interpreted_hash(k), interpreted_hash(v))),
+ Diff::Changed(ref pre, ref post) => try!(write!(f, " * {} => {} (was {})\n", interpreted_hash(k), interpreted_hash(post), interpreted_hash(pre))),
+ Diff::Died(_) => try!(write!(f, " X {}\n", interpreted_hash(k))),
_ => {},
}
}
diff --git a/src/bin/client/main.rs b/src/bin/client/main.rs
index 0d0368480..30f320e9d 100644
--- a/src/bin/client/main.rs
+++ b/src/bin/client/main.rs
@@ -7,17 +7,18 @@ extern crate ethcore_util as util;
extern crate ethcore;
extern crate log;
extern crate env_logger;
+extern crate ctrlc;
-use std::io::stdin;
use std::env;
use log::{LogLevelFilter};
use env_logger::LogBuilder;
+use ctrlc::CtrlC;
use util::*;
use ethcore::client::*;
-use ethcore::service::ClientService;
+use ethcore::service::{ClientService, NetSyncMessage};
use ethcore::ethereum;
use ethcore::blockchain::CacheSize;
-use ethcore::sync::*;
+use ethcore::sync::EthSync;
use docopt::Docopt;
const USAGE: &'static str = "
@@ -66,42 +67,57 @@ fn main() {
};
let mut service = ClientService::start(spec, &init_nodes).unwrap();
- let io_handler = Box::new(ClientIoHandler { client: service.client(), timer: 0, info: Default::default() });
-
+ let io_handler = Arc::new(ClientIoHandler { client: service.client(), info: Default::default(), sync: service.sync() });
service.io().register_handler(io_handler).expect("Error registering IO handler");
- loop {
- let mut cmd = String::new();
- stdin().read_line(&mut cmd).unwrap();
- if cmd == "quit\n" || cmd == "exit\n" || cmd == "q\n" {
- break;
+
+ let exit = Arc::new(Condvar::new());
+ let e = exit.clone();
+ CtrlC::set_handler(move || { e.notify_all(); });
+ let mutex = Mutex::new(());
+ let _ = exit.wait(mutex.lock().unwrap()).unwrap();
+}
+
+struct Informant {
+ chain_info: RwLock