From 1b4f67151f91d871850420ecf2c149cf7db3460a Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 27 Jun 2016 09:16:34 +0200 Subject: [PATCH 01/52] fatdb and fatdb iterator module --- util/src/hashdb.rs | 10 +++ util/src/journaldb/archivedb.rs | 26 +++++++ util/src/memorydb.rs | 17 +++++ util/src/trie/fatdb.rs | 122 ++++++++++++++++++++++++++++++++ util/src/trie/mod.rs | 7 +- util/src/trie/sectriedb.rs | 6 +- util/src/trie/sectriedbmut.rs | 10 +-- util/src/trie/triedb.rs | 2 +- util/src/trie/triedbmut.rs | 4 +- 9 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 util/src/trie/fatdb.rs diff --git a/util/src/hashdb.rs b/util/src/hashdb.rs index 1ec3069d8..35606e1ba 100644 --- a/util/src/hashdb.rs +++ b/util/src/hashdb.rs @@ -104,6 +104,16 @@ pub trait HashDB: AsHashDB { /// } /// ``` fn remove(&mut self, key: &H256); + + /// Insert auxiliary data into hashdb. + fn insert_aux(&mut self, _hash: Vec, _value: Vec) { + unimplemented!(); + } + + /// Get auxiliary data from hashdb. + fn get_aux(&self, _hash: &[u8]) -> Option> { + unimplemented!(); + } } /// Upcast trait. diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index c7f6b92fa..40b322802 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -26,6 +26,8 @@ use kvdb::{Database, DBTransaction, DatabaseConfig}; #[cfg(test)] use std::env; +const AUX_FLAG: u8 = 255; + /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay /// and latent-removal semantics. /// @@ -126,6 +128,23 @@ impl HashDB for ArchiveDB { fn remove(&mut self, key: &H256) { self.overlay.remove(key); } + + fn insert_aux(&mut self, hash: Vec, value: Vec) { + self.overlay.insert_aux(hash, value); + } + + fn get_aux(&self, hash: &[u8]) -> Option> { + if let Some(res) = self.overlay.get_aux(hash) { + return Some(res) + } + + let mut db_hash = hash.to_vec(); + db_hash.push(AUX_FLAG); + + self.backing.get(&db_hash) + .expect("Low-level database error. Some issue with your hard disk?") + .map(|v| v.to_vec()) + } } impl JournalDB for ArchiveDB { @@ -149,6 +168,7 @@ impl JournalDB for ArchiveDB { let batch = DBTransaction::new(); let mut inserts = 0usize; let mut deletes = 0usize; + for i in self.overlay.drain().into_iter() { let (key, (value, rc)) = i; if rc > 0 { @@ -161,6 +181,12 @@ impl JournalDB for ArchiveDB { deletes += 1; } } + + for (mut key, value) in self.overlay.drain_aux().into_iter() { + key.push(AUX_FLAG); + batch.put(&key, &value).expect("Low-level database error. Some issue with your hard disk?"); + } + if self.latest_era.map_or(true, |e| now > e) { try!(batch.put(&LATEST_ERA_KEY, &encode(&now))); self.latest_era = Some(now); diff --git a/util/src/memorydb.rs b/util/src/memorydb.rs index ea77f4aa2..f62c6b9b2 100644 --- a/util/src/memorydb.rs +++ b/util/src/memorydb.rs @@ -74,6 +74,7 @@ use std::default::Default; pub struct MemoryDB { data: HashMap, static_null_rlp: (Bytes, i32), + aux: HashMap, } impl Default for MemoryDB { @@ -88,6 +89,7 @@ impl MemoryDB { MemoryDB { data: HashMap::new(), static_null_rlp: (vec![0x80u8; 1], 1), + aux: HashMap::new(), } } @@ -139,6 +141,13 @@ impl MemoryDB { data } + /// Return the internal map of auxiliary data, clearing the current state. + pub fn drain_aux(&mut self) -> HashMap { + let mut aux = HashMap::new(); + mem::swap(&mut self.aux, &mut aux); + aux + } + /// Denote than an existing value has the given key. Used when a key gets removed without /// a prior insert and thus has a negative reference with no value. /// @@ -233,6 +242,14 @@ impl HashDB for MemoryDB { self.data.insert(key.clone(), (Bytes::new(), -1)); } } + + fn insert_aux(&mut self, hash: Vec, value: Vec) { + self.aux.insert(hash, value); + } + + fn get_aux(&self, hash: &[u8]) -> Option> { + self.aux.get(hash).cloned() + } } #[test] diff --git a/util/src/trie/fatdb.rs b/util/src/trie/fatdb.rs new file mode 100644 index 000000000..e9308d0fe --- /dev/null +++ b/util/src/trie/fatdb.rs @@ -0,0 +1,122 @@ +// 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 . + +use hash::H256; +use sha3::Hashable; +use hashdb::HashDB; +use super::{TrieDBMut, Trie, TrieDB, TrieMut, TrieDBIterator, TrieError}; + +/// A mutable `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. +/// +/// Use it as a `Trie` or `TrieMut` trait object. You can use `raw()` to get the backing `TrieDBMut` object. +pub struct FatDB<'db> { + raw: TrieDBMut<'db>, +} + +impl<'db> FatDB<'db> { + /// Create a new trie with the backing database `db` and empty `root` + /// Initialise to the state entailed by the genesis block. + /// This guarantees the trie is built correctly. + pub fn new(db: &'db mut HashDB, root: &'db mut H256) -> Self { + FatDB { raw: TrieDBMut::new(db, root) } + } + + /// Create a new trie with the backing database `db` and `root`. + /// + /// Returns an error if root does not exist. + pub fn from_existing(db: &'db mut HashDB, root: &'db mut H256) -> Result { + Ok(FatDB { raw: try!(TrieDBMut::from_existing(db, root)) }) + } + + /// Get the backing database. + pub fn db(&self) -> &HashDB { + self.raw.db() + } + + /// Get the backing database. + pub fn db_mut(&mut self) -> &mut HashDB { + self.raw.db_mut() + } +} + +impl<'db> Trie for FatDB<'db> { + fn root(&self) -> &H256 { + self.raw.root() + } + + fn contains(&self, key: &[u8]) -> bool { + self.raw.contains(&key.sha3()) + } + + fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Option<&'a [u8]> where 'a: 'key { + self.raw.get(&key.sha3()) + } +} + +impl<'db> TrieMut for FatDB<'db> { + fn insert(&mut self, key: &[u8], value: &[u8]) { + let hash = key.sha3(); + self.raw.insert(&hash, value); + let db = self.raw.db_mut(); + db.insert_aux(hash.to_vec(), key.to_vec()); + } + + fn remove(&mut self, key: &[u8]) { + self.raw.remove(&key.sha3()); + } +} + +/// Itarator over inserted pairs of key values. +pub struct FatDBIterator<'db> { + trie_iterator: TrieDBIterator<'db>, + trie: &'db TrieDB<'db>, +} + +impl<'db> FatDBIterator<'db> { + pub fn new(trie: &'db TrieDB) -> Self { + FatDBIterator { + trie_iterator: TrieDBIterator::new(trie), + trie: trie, + } + } +} + +impl<'db> Iterator for FatDBIterator<'db> { + type Item = (Vec, &'db [u8]); + + fn next(&mut self) -> Option { + self.trie_iterator.next() + .map(|(hash, value)| { + (self.trie.db().get_aux(&hash).expect("Missing fatdb hash"), value) + }) + } +} + +#[test] +fn fatdb_to_trie() { + use memorydb::MemoryDB; + use super::TrieDB; + + let mut memdb = MemoryDB::new(); + let mut root = H256::default(); + { + let mut t = FatDB::new(&mut memdb, &mut root); + t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); + } + let t = TrieDB::new(&memdb, &root).unwrap(); + assert_eq!(t.get(&(&[0x01u8, 0x23]).sha3()).unwrap(), &[0x01u8, 0x23]); + assert_eq!(FatDBIterator::new(&t).collect::>(), vec![(vec![0x01u8, 0x23], &[0x01u8, 0x23] as &[u8])]); +} diff --git a/util/src/trie/mod.rs b/util/src/trie/mod.rs index 79135162c..78b91b04a 100644 --- a/util/src/trie/mod.rs +++ b/util/src/trie/mod.rs @@ -35,12 +35,15 @@ pub mod sectriedb; /// Export the sectriedbmut module. pub mod sectriedbmut; +mod fatdb; + pub use self::trietraits::{Trie, TrieMut}; pub use self::standardmap::{Alphabet, StandardMap, ValueMode}; pub use self::triedbmut::TrieDBMut; -pub use self::triedb::TrieDB; +pub use self::triedb::{TrieDB, TrieDBIterator}; pub use self::sectriedbmut::SecTrieDBMut; pub use self::sectriedb::SecTrieDB; +pub use self::fatdb::{FatDB, FatDBIterator}; /// Trie Errors #[derive(Debug)] @@ -53,4 +56,4 @@ impl fmt::Display for TrieError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Trie Error: Invalid state root.") } -} \ No newline at end of file +} diff --git a/util/src/trie/sectriedb.rs b/util/src/trie/sectriedb.rs index eda4ac58b..f7f0b62cb 100644 --- a/util/src/trie/sectriedb.rs +++ b/util/src/trie/sectriedb.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use hash::*; -use sha3::*; +use hash::H256; +use sha3::Hashable; use hashdb::HashDB; use super::triedb::TrieDB; use super::trietraits::Trie; @@ -68,7 +68,7 @@ fn trie_to_sectrie() { use super::trietraits::TrieMut; let mut memdb = MemoryDB::new(); - let mut root = H256::new(); + let mut root = H256::default(); { let mut t = TrieDBMut::new(&mut memdb, &mut root); t.insert(&(&[0x01u8, 0x23]).sha3(), &[0x01u8, 0x23]); diff --git a/util/src/trie/sectriedbmut.rs b/util/src/trie/sectriedbmut.rs index 9c8231af4..43e17a1b0 100644 --- a/util/src/trie/sectriedbmut.rs +++ b/util/src/trie/sectriedbmut.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use hash::*; -use sha3::*; +use hash::H256; +use sha3::Hashable; use hashdb::HashDB; use super::triedbmut::TrieDBMut; use super::trietraits::{Trie, TrieMut}; @@ -44,10 +44,10 @@ impl<'db> SecTrieDBMut<'db> { } /// Get the backing database. - pub fn db(&'db self) -> &'db HashDB { self.raw.db() } + pub fn db(&self) -> &HashDB { self.raw.db() } /// Get the backing database. - pub fn db_mut(&'db mut self) -> &'db mut HashDB { self.raw.db_mut() } + pub fn db_mut(&mut self) -> &mut HashDB { self.raw.db_mut() } } impl<'db> Trie for SecTrieDBMut<'db> { @@ -78,7 +78,7 @@ fn sectrie_to_trie() { use super::triedb::*; let mut memdb = MemoryDB::new(); - let mut root = H256::new(); + let mut root = H256::default(); { let mut t = SecTrieDBMut::new(&mut memdb, &mut root); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index 9cd3a8c41..b3d20d56f 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -257,7 +257,7 @@ pub struct TrieDBIterator<'a> { impl<'a> TrieDBIterator<'a> { /// Create a new iterator. - fn new(db: &'a TrieDB) -> TrieDBIterator<'a> { + pub fn new(db: &'a TrieDB) -> TrieDBIterator<'a> { let mut r = TrieDBIterator { db: db, trail: vec![], diff --git a/util/src/trie/triedbmut.rs b/util/src/trie/triedbmut.rs index 65d5bbd2b..ed6ba7634 100644 --- a/util/src/trie/triedbmut.rs +++ b/util/src/trie/triedbmut.rs @@ -99,12 +99,12 @@ impl<'db> TrieDBMut<'db> { } /// Get the backing database. - pub fn db(&'db self) -> &'db HashDB { + pub fn db(&self) -> &HashDB { self.db } /// Get the backing database. - pub fn db_mut(&'db mut self) -> &'db mut HashDB { + pub fn db_mut(&mut self) -> &mut HashDB { self.db } From 5ecbeaa82f31e51994fdb870e19ff7c7595dff03 Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 27 Jun 2016 10:59:59 +0200 Subject: [PATCH 02/52] trie factory in progress --- util/src/trie/fatdb.rs | 53 ++++++++------------- util/src/trie/fatdbmut.rs | 95 +++++++++++++++++++++++++++++++++++++ util/src/trie/mod.rs | 59 +++++++++++++++++++++++ util/src/trie/sectriedb.rs | 4 ++ util/src/trie/triedb.rs | 10 +++- util/src/trie/trietraits.rs | 3 ++ 6 files changed, 190 insertions(+), 34 deletions(-) create mode 100644 util/src/trie/fatdbmut.rs diff --git a/util/src/trie/fatdb.rs b/util/src/trie/fatdb.rs index e9308d0fe..1b520d8ad 100644 --- a/util/src/trie/fatdb.rs +++ b/util/src/trie/fatdb.rs @@ -17,28 +17,25 @@ use hash::H256; use sha3::Hashable; use hashdb::HashDB; -use super::{TrieDBMut, Trie, TrieDB, TrieMut, TrieDBIterator, TrieError}; +use super::{TrieDB, Trie, TrieDBIterator, TrieError}; /// A mutable `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. /// -/// Use it as a `Trie` or `TrieMut` trait object. You can use `raw()` to get the backing `TrieDBMut` object. +/// Use it as a `Trie` or `TrieMut` trait object. You can use `raw()` to get the backing `TrieDB` object. pub struct FatDB<'db> { - raw: TrieDBMut<'db>, + raw: TrieDB<'db>, } impl<'db> FatDB<'db> { /// Create a new trie with the backing database `db` and empty `root` /// Initialise to the state entailed by the genesis block. /// This guarantees the trie is built correctly. - pub fn new(db: &'db mut HashDB, root: &'db mut H256) -> Self { - FatDB { raw: TrieDBMut::new(db, root) } - } + pub fn new(db: &'db HashDB, root: &'db H256) -> Result { + let fatdb = FatDB { + raw: try!(TrieDB::new(db, root)) + }; - /// Create a new trie with the backing database `db` and `root`. - /// - /// Returns an error if root does not exist. - pub fn from_existing(db: &'db mut HashDB, root: &'db mut H256) -> Result { - Ok(FatDB { raw: try!(TrieDBMut::from_existing(db, root)) }) + Ok(fatdb) } /// Get the backing database. @@ -46,13 +43,17 @@ impl<'db> FatDB<'db> { self.raw.db() } - /// Get the backing database. - pub fn db_mut(&mut self) -> &mut HashDB { - self.raw.db_mut() + /// Iterator over all key / vlaues in the trie. + pub fn iter(&self) -> FatDBIterator { + FatDBIterator::new(&self.raw) } } impl<'db> Trie for FatDB<'db> { + fn iter<'a>(&'a self) -> Box, &[u8])> + 'a> { + Box::new(FatDB::iter(self)) + } + fn root(&self) -> &H256 { self.raw.root() } @@ -66,19 +67,6 @@ impl<'db> Trie for FatDB<'db> { } } -impl<'db> TrieMut for FatDB<'db> { - fn insert(&mut self, key: &[u8], value: &[u8]) { - let hash = key.sha3(); - self.raw.insert(&hash, value); - let db = self.raw.db_mut(); - db.insert_aux(hash.to_vec(), key.to_vec()); - } - - fn remove(&mut self, key: &[u8]) { - self.raw.remove(&key.sha3()); - } -} - /// Itarator over inserted pairs of key values. pub struct FatDBIterator<'db> { trie_iterator: TrieDBIterator<'db>, @@ -86,6 +74,7 @@ pub struct FatDBIterator<'db> { } impl<'db> FatDBIterator<'db> { + /// Creates new iterator. pub fn new(trie: &'db TrieDB) -> Self { FatDBIterator { trie_iterator: TrieDBIterator::new(trie), @@ -108,15 +97,15 @@ impl<'db> Iterator for FatDBIterator<'db> { #[test] fn fatdb_to_trie() { use memorydb::MemoryDB; - use super::TrieDB; + use trie::{FatDBMut, TrieMut}; let mut memdb = MemoryDB::new(); let mut root = H256::default(); { - let mut t = FatDB::new(&mut memdb, &mut root); + let mut t = FatDBMut::new(&mut memdb, &mut root); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); } - let t = TrieDB::new(&memdb, &root).unwrap(); - assert_eq!(t.get(&(&[0x01u8, 0x23]).sha3()).unwrap(), &[0x01u8, 0x23]); - assert_eq!(FatDBIterator::new(&t).collect::>(), vec![(vec![0x01u8, 0x23], &[0x01u8, 0x23] as &[u8])]); + let t = FatDB::new(&memdb, &root).unwrap(); + assert_eq!(t.get(&[0x01u8, 0x23]).unwrap(), &[0x01u8, 0x23]); + assert_eq!(t.iter().collect::>(), vec![(vec![0x01u8, 0x23], &[0x01u8, 0x23] as &[u8])]); } diff --git a/util/src/trie/fatdbmut.rs b/util/src/trie/fatdbmut.rs new file mode 100644 index 000000000..b04b3dcaa --- /dev/null +++ b/util/src/trie/fatdbmut.rs @@ -0,0 +1,95 @@ +// 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 . + +use hash::H256; +use sha3::Hashable; +use hashdb::HashDB; +use super::{TrieDBMut, Trie, TrieMut, TrieError}; + +/// A mutable `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. +/// +/// Use it as a `Trie` or `TrieMut` trait object. You can use `raw()` to get the backing `TrieDBMut` object. +pub struct FatDBMut<'db> { + raw: TrieDBMut<'db>, +} + +impl<'db> FatDBMut<'db> { + /// Create a new trie with the backing database `db` and empty `root` + /// Initialise to the state entailed by the genesis block. + /// This guarantees the trie is built correctly. + pub fn new(db: &'db mut HashDB, root: &'db mut H256) -> Self { + FatDBMut { raw: TrieDBMut::new(db, root) } + } + + /// Create a new trie with the backing database `db` and `root`. + /// + /// Returns an error if root does not exist. + pub fn from_existing(db: &'db mut HashDB, root: &'db mut H256) -> Result { + Ok(FatDBMut { raw: try!(TrieDBMut::from_existing(db, root)) }) + } + + /// Get the backing database. + pub fn db(&self) -> &HashDB { + self.raw.db() + } + + /// Get the backing database. + pub fn db_mut(&mut self) -> &mut HashDB { + self.raw.db_mut() + } +} + +impl<'db> Trie for FatDBMut<'db> { + fn root(&self) -> &H256 { + self.raw.root() + } + + fn contains(&self, key: &[u8]) -> bool { + self.raw.contains(&key.sha3()) + } + + fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Option<&'a [u8]> where 'a: 'key { + self.raw.get(&key.sha3()) + } +} + +impl<'db> TrieMut for FatDBMut<'db> { + fn insert(&mut self, key: &[u8], value: &[u8]) { + let hash = key.sha3(); + self.raw.insert(&hash, value); + let db = self.raw.db_mut(); + db.insert_aux(hash.to_vec(), key.to_vec()); + } + + fn remove(&mut self, key: &[u8]) { + self.raw.remove(&key.sha3()); + } +} + +#[test] +fn fatdb_to_trie() { + use memorydb::MemoryDB; + use super::TrieDB; + + let mut memdb = MemoryDB::new(); + let mut root = H256::default(); + { + let mut t = FatDBMut::new(&mut memdb, &mut root); + t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); + } + let t = TrieDB::new(&memdb, &root).unwrap(); + assert_eq!(t.get(&(&[0x01u8, 0x23]).sha3()).unwrap(), &[0x01u8, 0x23]); +} diff --git a/util/src/trie/mod.rs b/util/src/trie/mod.rs index 78b91b04a..81d7fd774 100644 --- a/util/src/trie/mod.rs +++ b/util/src/trie/mod.rs @@ -17,6 +17,8 @@ //! Trie interface and implementation. use std::fmt; +use hash::H256; +use hashdb::HashDB; /// Export the trietraits module. pub mod trietraits; @@ -37,6 +39,8 @@ pub mod sectriedbmut; mod fatdb; +mod fatdbmut; + pub use self::trietraits::{Trie, TrieMut}; pub use self::standardmap::{Alphabet, StandardMap, ValueMode}; pub use self::triedbmut::TrieDBMut; @@ -44,6 +48,7 @@ pub use self::triedb::{TrieDB, TrieDBIterator}; pub use self::sectriedbmut::SecTrieDBMut; pub use self::sectriedb::SecTrieDB; pub use self::fatdb::{FatDB, FatDBIterator}; +pub use self::fatdbmut::FatDBMut; /// Trie Errors #[derive(Debug)] @@ -57,3 +62,57 @@ impl fmt::Display for TrieError { write!(f, "Trie Error: Invalid state root.") } } + +/// Trie types +#[derive(Debug, Clone)] +pub enum TrieSpec { + /// Secure trie. + Secure, + /// Secure trie with fat database. + Fat, +} + +impl Default for TrieSpec { + fn default() -> TrieSpec { + TrieSpec::Secure + } +} + +/// Trie factory. +#[derive(Default, Clone)] +pub struct TrieFactory { + spec: TrieSpec, +} + +impl TrieFactory { + /// Creates new factory. + pub fn new(spec: TrieSpec) -> Self { + TrieFactory { + spec: spec, + } + } + + /// Create new immutable instance of Trie. + pub fn create<'db>(&self, db: &'db HashDB, root: &'db H256) -> Result, TrieError> { + match self.spec { + TrieSpec::Secure => Ok(Box::new(try!(SecTrieDB::new(db, root)))), + TrieSpec::Fat => Ok(Box::new(try!(FatDB::new(db, root)))), + } + } + + /// Create new mutable instance of Trie. + pub fn create_mut<'db>(&self, db: &'db mut HashDB, root: &'db mut H256) -> Result, TrieError> { + match self.spec { + TrieSpec::Secure => Ok(Box::new(SecTrieDBMut::new(db, root))), + TrieSpec::Fat => Ok(Box::new(FatDBMut::new(db, root))), + } + } + + /// Create new mutable instance of trie and check for errors. + pub fn from_existing<'db>(&self, db: &'db mut HashDB, root: &'db mut H256) -> Result, TrieError> { + match self.spec { + TrieSpec::Secure => Ok(Box::new(try!(SecTrieDBMut::from_existing(db, root)))), + TrieSpec::Fat => Ok(Box::new(try!(FatDBMut::from_existing(db, root)))), + } + } +} diff --git a/util/src/trie/sectriedb.rs b/util/src/trie/sectriedb.rs index f7f0b62cb..99770e382 100644 --- a/util/src/trie/sectriedb.rs +++ b/util/src/trie/sectriedb.rs @@ -50,6 +50,10 @@ impl<'db> SecTrieDB<'db> { } impl<'db> Trie for SecTrieDB<'db> { + fn iter<'a>(&'a self) -> Box, &[u8])> + 'a> { + Box::new(TrieDB::iter(&self.raw)) + } + fn root(&self) -> &H256 { self.raw.root() } fn contains(&self, key: &[u8]) -> bool { diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index b3d20d56f..c88ec422e 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -18,7 +18,7 @@ use common::*; use hashdb::*; use nibbleslice::*; use rlp::*; -use super::trietraits::Trie; +use super::trietraits::{Trie}; use super::node::Node; use super::TrieError; @@ -331,10 +331,16 @@ impl<'a> Iterator for TrieDBIterator<'a> { impl<'db> TrieDB<'db> { /// Get all keys/values stored in the trie. - pub fn iter(&self) -> TrieDBIterator { TrieDBIterator::new(self) } + pub fn iter(&self) -> TrieDBIterator { + TrieDBIterator::new(self) + } } impl<'db> Trie for TrieDB<'db> { + fn iter<'a>(&'a self) -> Box, &[u8])> + 'a> { + Box::new(TrieDB::iter(self)) + } + fn root(&self) -> &H256 { &self.root } fn contains(&self, key: &[u8]) -> bool { diff --git a/util/src/trie/trietraits.rs b/util/src/trie/trietraits.rs index 160f9466f..03f5e6788 100644 --- a/util/src/trie/trietraits.rs +++ b/util/src/trie/trietraits.rs @@ -19,6 +19,9 @@ use rlp::SHA3_NULL_RLP; /// A key-value datastore implemented as a database-backed modified Merkle tree. pub trait Trie { + /// Returns an iterator over elements of trie. + fn iter<'a>(&'a self) -> Box, &[u8])> + 'a> { unimplemented!() } + /// Return the root of the trie. fn root(&self) -> &H256; From 36626f96a81ebd43c815a4e865096265fd812b14 Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 27 Jun 2016 11:19:27 +0200 Subject: [PATCH 03/52] separated TrieMut from Trie, added Generic Trie type to TrieFactory --- util/src/trie/fatdbmut.rs | 4 +--- util/src/trie/mod.rs | 13 +++++++++---- util/src/trie/sectriedbmut.rs | 4 +--- util/src/trie/triedbmut.rs | 4 +--- util/src/trie/trietraits.rs | 21 ++++++++++++++++----- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/util/src/trie/fatdbmut.rs b/util/src/trie/fatdbmut.rs index b04b3dcaa..b699bf208 100644 --- a/util/src/trie/fatdbmut.rs +++ b/util/src/trie/fatdbmut.rs @@ -52,7 +52,7 @@ impl<'db> FatDBMut<'db> { } } -impl<'db> Trie for FatDBMut<'db> { +impl<'db> TrieMut for FatDBMut<'db> { fn root(&self) -> &H256 { self.raw.root() } @@ -64,9 +64,7 @@ impl<'db> Trie for FatDBMut<'db> { fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Option<&'a [u8]> where 'a: 'key { self.raw.get(&key.sha3()) } -} -impl<'db> TrieMut for FatDBMut<'db> { fn insert(&mut self, key: &[u8], value: &[u8]) { let hash = key.sha3(); self.raw.insert(&hash, value); diff --git a/util/src/trie/mod.rs b/util/src/trie/mod.rs index 81d7fd774..130406948 100644 --- a/util/src/trie/mod.rs +++ b/util/src/trie/mod.rs @@ -66,6 +66,8 @@ impl fmt::Display for TrieError { /// Trie types #[derive(Debug, Clone)] pub enum TrieSpec { + /// Generic trie. + Generic, /// Secure trie. Secure, /// Secure trie with fat database. @@ -95,22 +97,25 @@ impl TrieFactory { /// Create new immutable instance of Trie. pub fn create<'db>(&self, db: &'db HashDB, root: &'db H256) -> Result, TrieError> { match self.spec { + TrieSpec::Generic => Ok(Box::new(try!(TrieDB::new(db, root)))), TrieSpec::Secure => Ok(Box::new(try!(SecTrieDB::new(db, root)))), TrieSpec::Fat => Ok(Box::new(try!(FatDB::new(db, root)))), } } /// Create new mutable instance of Trie. - pub fn create_mut<'db>(&self, db: &'db mut HashDB, root: &'db mut H256) -> Result, TrieError> { + pub fn create_mut<'db>(&self, db: &'db mut HashDB, root: &'db mut H256) -> Box { match self.spec { - TrieSpec::Secure => Ok(Box::new(SecTrieDBMut::new(db, root))), - TrieSpec::Fat => Ok(Box::new(FatDBMut::new(db, root))), + TrieSpec::Generic => Box::new(TrieDBMut::new(db, root)), + TrieSpec::Secure => Box::new(SecTrieDBMut::new(db, root)), + TrieSpec::Fat => Box::new(FatDBMut::new(db, root)), } } /// Create new mutable instance of trie and check for errors. - pub fn from_existing<'db>(&self, db: &'db mut HashDB, root: &'db mut H256) -> Result, TrieError> { + pub fn from_existing<'db>(&self, db: &'db mut HashDB, root: &'db mut H256) -> Result, TrieError> { match self.spec { + TrieSpec::Generic => Ok(Box::new(try!(TrieDBMut::from_existing(db, root)))), TrieSpec::Secure => Ok(Box::new(try!(SecTrieDBMut::from_existing(db, root)))), TrieSpec::Fat => Ok(Box::new(try!(FatDBMut::from_existing(db, root)))), } diff --git a/util/src/trie/sectriedbmut.rs b/util/src/trie/sectriedbmut.rs index 43e17a1b0..09ff48f7a 100644 --- a/util/src/trie/sectriedbmut.rs +++ b/util/src/trie/sectriedbmut.rs @@ -50,7 +50,7 @@ impl<'db> SecTrieDBMut<'db> { pub fn db_mut(&mut self) -> &mut HashDB { self.raw.db_mut() } } -impl<'db> Trie for SecTrieDBMut<'db> { +impl<'db> TrieMut for SecTrieDBMut<'db> { fn root(&self) -> &H256 { self.raw.root() } fn contains(&self, key: &[u8]) -> bool { @@ -60,9 +60,7 @@ impl<'db> Trie for SecTrieDBMut<'db> { fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Option<&'a [u8]> where 'a: 'key { self.raw.get(&key.sha3()) } -} -impl<'db> TrieMut for SecTrieDBMut<'db> { fn insert(&mut self, key: &[u8], value: &[u8]) { self.raw.insert(&key.sha3(), value); } diff --git a/util/src/trie/triedbmut.rs b/util/src/trie/triedbmut.rs index ed6ba7634..6d34096fc 100644 --- a/util/src/trie/triedbmut.rs +++ b/util/src/trie/triedbmut.rs @@ -642,7 +642,7 @@ impl<'db> TrieDBMut<'db> { } } -impl<'db> Trie for TrieDBMut<'db> { +impl<'db> TrieMut for TrieDBMut<'db> { fn root(&self) -> &H256 { &self.root } fn contains(&self, key: &[u8]) -> bool { @@ -652,9 +652,7 @@ impl<'db> Trie for TrieDBMut<'db> { fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Option<&'a [u8]> where 'a: 'key { self.do_lookup(&NibbleSlice::new(key)) } -} -impl<'db> TrieMut for TrieDBMut<'db> { fn insert(&mut self, key: &[u8], value: &[u8]) { match value.is_empty() { false => self.insert_ns(&NibbleSlice::new(key), value), diff --git a/util/src/trie/trietraits.rs b/util/src/trie/trietraits.rs index 03f5e6788..fb53350c9 100644 --- a/util/src/trie/trietraits.rs +++ b/util/src/trie/trietraits.rs @@ -19,9 +19,6 @@ use rlp::SHA3_NULL_RLP; /// A key-value datastore implemented as a database-backed modified Merkle tree. pub trait Trie { - /// Returns an iterator over elements of trie. - fn iter<'a>(&'a self) -> Box, &[u8])> + 'a> { unimplemented!() } - /// Return the root of the trie. fn root(&self) -> &H256; @@ -33,10 +30,25 @@ pub trait Trie { /// What is the value of the given key in this trie? fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Option<&'a [u8]> where 'a: 'key; + + /// Returns an iterator over elements of trie. + fn iter<'a>(&'a self) -> Box, &[u8])> + 'a>; } /// A key-value datastore implemented as a database-backed modified Merkle tree. -pub trait TrieMut: Trie { +pub trait TrieMut { + /// Return the root of the trie. + fn root(&self) -> &H256; + + /// Is the trie empty? + fn is_empty(&self) -> bool { *self.root() == SHA3_NULL_RLP } + + /// Does the trie contain a given key? + fn contains(&self, key: &[u8]) -> bool; + + /// What is the value of the given key in this trie? + fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Option<&'a [u8]> where 'a: 'key; + /// Insert a `key`/`value` pair into the trie. An `empty` value is equivalent to removing /// `key` from the trie. fn insert(&mut self, key: &[u8], value: &[u8]); @@ -45,4 +57,3 @@ pub trait TrieMut: Trie { /// value. fn remove(&mut self, key: &[u8]); } - From 7904464d248b205193735f74feb394d927eb15de Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 27 Jun 2016 13:37:22 +0200 Subject: [PATCH 04/52] use mem::replace instead of mem::swap in ArchiveDB, add aux_remove() --- util/src/hashdb.rs | 5 +++++ util/src/journaldb/archivedb.rs | 13 +++++++++++-- util/src/memorydb.rs | 12 ++++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/util/src/hashdb.rs b/util/src/hashdb.rs index 35606e1ba..51b9d445e 100644 --- a/util/src/hashdb.rs +++ b/util/src/hashdb.rs @@ -114,6 +114,11 @@ pub trait HashDB: AsHashDB { fn get_aux(&self, _hash: &[u8]) -> Option> { unimplemented!(); } + + /// Removes auxiliary data from hashdb. + fn remove_aux(&mut self, _hash: &[u8]) { + unimplemented!(); + } } /// Upcast trait. diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index 40b322802..3713fc79e 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -26,8 +26,13 @@ use kvdb::{Database, DBTransaction, DatabaseConfig}; #[cfg(test)] use std::env; +/// Suffix appended to auxiliary keys to distinguish them from normal keys. +/// Would be nich to use rocksdb columns for this eventually. const AUX_FLAG: u8 = 255; +/// Database version. +const DB_VERSION : u32 = 0x103; + /// Implementation of the `HashDB` trait for a disk-backed database with a memory overlay /// and latent-removal semantics. /// @@ -41,8 +46,6 @@ pub struct ArchiveDB { latest_era: Option, } -const DB_VERSION : u32 = 0x103; - impl ArchiveDB { /// Create a new instance from file pub fn new(path: &str, cache_size: Option) -> ArchiveDB { @@ -122,9 +125,11 @@ impl HashDB for ArchiveDB { fn insert(&mut self, value: &[u8]) -> H256 { self.overlay.insert(value) } + fn emplace(&mut self, key: H256, value: Bytes) { self.overlay.emplace(key, value); } + fn remove(&mut self, key: &H256) { self.overlay.remove(key); } @@ -145,6 +150,10 @@ impl HashDB for ArchiveDB { .expect("Low-level database error. Some issue with your hard disk?") .map(|v| v.to_vec()) } + + fn remove_aux(&mut self, hash: &[u8]) { + self.overlay.remove_aux(hash); + } } impl JournalDB for ArchiveDB { diff --git a/util/src/memorydb.rs b/util/src/memorydb.rs index f62c6b9b2..f63dfd992 100644 --- a/util/src/memorydb.rs +++ b/util/src/memorydb.rs @@ -136,16 +136,12 @@ impl MemoryDB { /// Return the internal map of hashes to data, clearing the current state. pub fn drain(&mut self) -> HashMap { - let mut data = HashMap::new(); - mem::swap(&mut self.data, &mut data); - data + mem::replace(&mut self.data, HashMap::new()) } /// Return the internal map of auxiliary data, clearing the current state. pub fn drain_aux(&mut self) -> HashMap { - let mut aux = HashMap::new(); - mem::swap(&mut self.aux, &mut aux); - aux + mem::replace(&mut self.aux, HashMap::new()) } /// Denote than an existing value has the given key. Used when a key gets removed without @@ -250,6 +246,10 @@ impl HashDB for MemoryDB { fn get_aux(&self, hash: &[u8]) -> Option> { self.aux.get(hash).cloned() } + + fn remove_aux(&mut self, hash: &[u8]) { + self.aux.remove(hash); + } } #[test] From 06cf2a3f418c4c3cdc36d2b661df7666083524ff Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 27 Jun 2016 13:50:08 +0200 Subject: [PATCH 05/52] updated FatDB description --- util/src/trie/fatdb.rs | 5 +++-- util/src/trie/fatdbmut.rs | 3 ++- util/src/trie/mod.rs | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/util/src/trie/fatdb.rs b/util/src/trie/fatdb.rs index 1b520d8ad..555e4644f 100644 --- a/util/src/trie/fatdb.rs +++ b/util/src/trie/fatdb.rs @@ -19,9 +19,10 @@ use sha3::Hashable; use hashdb::HashDB; use super::{TrieDB, Trie, TrieDBIterator, TrieError}; -/// A mutable `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. +/// A `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. +/// Additionaly it stores inserted hash-key mappings for later retrieval. /// -/// Use it as a `Trie` or `TrieMut` trait object. You can use `raw()` to get the backing `TrieDB` object. +/// Use it as a `Trie` or `TrieMut` trait object. pub struct FatDB<'db> { raw: TrieDB<'db>, } diff --git a/util/src/trie/fatdbmut.rs b/util/src/trie/fatdbmut.rs index b699bf208..3e72c0653 100644 --- a/util/src/trie/fatdbmut.rs +++ b/util/src/trie/fatdbmut.rs @@ -20,8 +20,9 @@ use hashdb::HashDB; use super::{TrieDBMut, Trie, TrieMut, TrieError}; /// A mutable `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. +/// Additionaly it stores inserted hash-key mappings for later retrieval. /// -/// Use it as a `Trie` or `TrieMut` trait object. You can use `raw()` to get the backing `TrieDBMut` object. +/// Use it as a `Trie` or `TrieMut` trait object. pub struct FatDBMut<'db> { raw: TrieDBMut<'db>, } diff --git a/util/src/trie/mod.rs b/util/src/trie/mod.rs index 130406948..f6e731370 100644 --- a/util/src/trie/mod.rs +++ b/util/src/trie/mod.rs @@ -95,7 +95,7 @@ impl TrieFactory { } /// Create new immutable instance of Trie. - pub fn create<'db>(&self, db: &'db HashDB, root: &'db H256) -> Result, TrieError> { + pub fn readonly<'db>(&self, db: &'db HashDB, root: &'db H256) -> Result, TrieError> { match self.spec { TrieSpec::Generic => Ok(Box::new(try!(TrieDB::new(db, root)))), TrieSpec::Secure => Ok(Box::new(try!(SecTrieDB::new(db, root)))), @@ -104,7 +104,7 @@ impl TrieFactory { } /// Create new mutable instance of Trie. - pub fn create_mut<'db>(&self, db: &'db mut HashDB, root: &'db mut H256) -> Box { + pub fn create<'db>(&self, db: &'db mut HashDB, root: &'db mut H256) -> Box { match self.spec { TrieSpec::Generic => Box::new(TrieDBMut::new(db, root)), TrieSpec::Secure => Box::new(SecTrieDBMut::new(db, root)), From 86c85bdd9ed22ef05a1868a2eb78677fa155aaec Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 30 Jun 2016 14:34:49 +0300 Subject: [PATCH 06/52] post expansion pass --- ipc/codegen/src/lib.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ipc/codegen/src/lib.rs b/ipc/codegen/src/lib.rs index 126aa3a85..fc737b060 100644 --- a/ipc/codegen/src/lib.rs +++ b/ipc/codegen/src/lib.rs @@ -50,11 +50,37 @@ include!("lib.rs.in"); #[cfg(feature = "with-syntex")] pub fn register(reg: &mut syntex::Registry) { + /// Strip the serde attributes from the crate. + #[cfg(feature = "with-syntex")] + fn strip_attributes(krate: ast::Crate) -> ast::Crate { + /// Helper folder that strips the serde attributes after the extensions have been expanded. + struct StripAttributeFolder; + + impl fold::Folder for StripAttributeFolder { + fn fold_attribute(&mut self, attr: ast::Attribute) -> Option { + match attr.node.value.node { + ast::MetaItemKind::List(ref n, _) if n == &"ipc" => { return None; } + _ => {} + } + + Some(attr) + } + + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } + } + + fold::Folder::fold_crate(&mut StripAttributeFolder, krate) + } + reg.add_attr("feature(custom_derive)"); reg.add_attr("feature(custom_attribute)"); reg.add_decorator("derive_Ipc", codegen::expand_ipc_implementation); reg.add_decorator("derive_Binary", serialization::expand_serialization_implementation); + + reg.add_post_expansion_pass(strip_attributes); } #[cfg(not(feature = "with-syntex"))] @@ -67,4 +93,6 @@ pub fn register(reg: &mut rustc_plugin::Registry) { syntax::parse::token::intern("derive_Binary"), syntax::ext::base::MultiDecorator( Box::new(serialization::expand_serialization_implementation))); + + reg.register_attribute("ipc".to_owned(), AttributeType::Normal); } From 427d54f3415a302c1b55d7954443ceb85f1c8285 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 30 Jun 2016 14:41:56 +0300 Subject: [PATCH 07/52] versions sorting --- ipc/tests/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/tests/Cargo.toml b/ipc/tests/Cargo.toml index f7a5ee9bd..d9c80145d 100644 --- a/ipc/tests/Cargo.toml +++ b/ipc/tests/Cargo.toml @@ -16,5 +16,5 @@ ethcore-ipc-nano = { path = "../nano" } ethcore-util = { path = "../../util" } [build-dependencies] -syntex = "*" +syntex = "0.33" ethcore-ipc-codegen = { path = "../codegen" } From 6259a5a7373292cebf4cbbbc04d6ecf59ccb8283 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 30 Jun 2016 14:42:11 +0300 Subject: [PATCH 08/52] versions sorting --- ipc/codegen/Cargo.toml | 4 ++-- ipc/codegen/src/lib.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/ipc/codegen/Cargo.toml b/ipc/codegen/Cargo.toml index 4d83b65e1..649882c51 100644 --- a/ipc/codegen/Cargo.toml +++ b/ipc/codegen/Cargo.toml @@ -22,5 +22,5 @@ aster = { version = "0.17", default-features = false } clippy = { version = "^0.*", optional = true } quasi = { version = "0.11", default-features = false } quasi_macros = { version = "0.11", optional = true } -syntex = { version = "*", optional = true } -syntex_syntax = { version = "*", optional = true } +syntex = { version = "0.33", optional = true } +syntex_syntax = { version = "0.33", optional = true } diff --git a/ipc/codegen/src/lib.rs b/ipc/codegen/src/lib.rs index fc737b060..afa7979d0 100644 --- a/ipc/codegen/src/lib.rs +++ b/ipc/codegen/src/lib.rs @@ -50,12 +50,11 @@ include!("lib.rs.in"); #[cfg(feature = "with-syntex")] pub fn register(reg: &mut syntex::Registry) { - /// Strip the serde attributes from the crate. + use syntax::{ast, fold}; + #[cfg(feature = "with-syntex")] fn strip_attributes(krate: ast::Crate) -> ast::Crate { - /// Helper folder that strips the serde attributes after the extensions have been expanded. struct StripAttributeFolder; - impl fold::Folder for StripAttributeFolder { fn fold_attribute(&mut self, attr: ast::Attribute) -> Option { match attr.node.value.node { From 6e8df6a6cec64dbbeb85b63f3b84bfc51c8c0bd8 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 30 Jun 2016 15:33:34 +0300 Subject: [PATCH 09/52] attribute parsing --- ipc/codegen/src/codegen.rs | 67 +++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs index 9dd6a7b32..672132c9f 100644 --- a/ipc/codegen/src/codegen.rs +++ b/ipc/codegen/src/codegen.rs @@ -497,9 +497,9 @@ fn client_generics(builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> .build() } -fn client_qualified_ident(builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P { +fn client_qualified_ident(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap) -> P { let generics = client_generics(builder, interface_map); - aster::ty::TyBuilder::new().path().segment(interface_map.ident_map.client_ident(builder)) + aster::ty::TyBuilder::new().path().segment(interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item)) .with_generics(generics).build() .build() } @@ -515,7 +515,7 @@ fn client_phantom_ident(builder: &aster::AstBuilder, interface_map: &InterfaceMa /// for say `Service` it generates `ServiceClient` fn push_client_struct(cx: &ExtCtxt, builder: &aster::AstBuilder, interface_map: &InterfaceMap, push: &mut FnMut(Annotatable)) { let generics = client_generics(builder, interface_map); - let client_short_ident = interface_map.ident_map.client_ident(builder); + let client_short_ident = interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item); let phantom = client_phantom_ident(builder, interface_map); let client_struct_item = quote_item!(cx, @@ -547,9 +547,9 @@ fn push_with_socket_client_implementation( push: &mut FnMut(Annotatable)) { let generics = client_generics(builder, interface_map); - let client_ident = client_qualified_ident(builder, interface_map); + let client_ident = client_qualified_ident(cx, builder, interface_map); let where_clause = &generics.where_clause; - let client_short_ident = interface_map.ident_map.client_ident(builder); + let client_short_ident = interface_map.ident_map.client_ident(cx, builder, &interface_map.original_item); let implement = quote_item!(cx, impl $generics ::ipc::WithSocket for $client_ident $where_clause { @@ -578,7 +578,7 @@ fn push_client_implementation( .collect::>>(); let generics = client_generics(builder, interface_map); - let client_ident = client_qualified_ident(builder, interface_map); + let client_ident = client_qualified_ident(cx, builder, interface_map); let where_clause = &generics.where_clause; let handshake_item = quote_impl_item!(cx, @@ -682,6 +682,52 @@ fn implement_handshake_arm( } +fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Result { + match lit.node { + ast::LitKind::Str(ref s, _) => Ok(format!("{}", s)), + _ => { + cx.span_err( + lit.span, + &format!("ipc client_ident annotation `{}` must be a string, not `{}`", + name, + ::syntax::print::pprust::lit_to_string(lit))); + + return Err(()); + } + } +} + +pub fn get_ipc_meta_items(attr: &ast::Attribute) -> Option<&[P]> { + match attr.node.value.node { + ast::MetaItemKind::List(ref name, ref items) if name == &"ipc" => { + Some(items) + } + _ => None + } +} + +fn client_ident_renamed(cx: &ExtCtxt, item: &ast::Item) -> Option { + for meta_items in item.attrs().iter().filter_map(get_ipc_meta_items) { + for meta_item in meta_items { + let span = meta_item.span; + match meta_item.node { + ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"client_ident" => { + if let Ok(s) = get_str_from_lit(cx, name, lit) { + return Some(s); + } + } + _ => { + cx.span_err( + meta_item.span, + &format!("unknown client_ident container attribute `{}`", + ::syntax::print::pprust::meta_item_to_string(meta_item))); + } + } + } + } + None +} + struct InterfaceMap { pub original_item: Item, pub item: P, @@ -700,8 +746,13 @@ impl IdentMap { builder.id(format!("{}", ::syntax::print::pprust::path_to_string(&self.original_path))) } - fn client_ident(&self, builder: &aster::AstBuilder) -> Ident { - builder.id(format!("{}Client", self.original_path.segments[0].identifier)) + fn client_ident(&self, cx: &ExtCtxt, builder: &aster::AstBuilder, item: &ast::Item) -> Ident { + if let Some(new_name) = client_ident_renamed(cx, item) { + builder.id(new_name) + } + else { + builder.id(format!("{}Client", self.original_path.segments[0].identifier)) + } } fn qualified_ident(&self, builder: &aster::AstBuilder) -> Ident { From 5c5f52c01792b6b7ae31750c4dae83aaadee143e Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 30 Jun 2016 16:23:10 +0300 Subject: [PATCH 10/52] tests for client_ident --- ipc/tests/build.rs | 17 +++++++++++++++++ ipc/tests/examples.rs | 6 +++--- ipc/tests/over_nano.rs | 7 +++++++ ipc/tests/run.rs | 1 + ipc/tests/with_attrs.rs | 18 ++++++++++++++++++ ipc/tests/with_attrs.rs.in | 39 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 ipc/tests/with_attrs.rs create mode 100644 ipc/tests/with_attrs.rs.in diff --git a/ipc/tests/build.rs b/ipc/tests/build.rs index e498e3405..6538f56e1 100644 --- a/ipc/tests/build.rs +++ b/ipc/tests/build.rs @@ -58,6 +58,23 @@ pub fn main() { registry.expand("", &src, &dst).unwrap(); } + // rpc pass + if { + let src = Path::new("with_attrs.rs.in"); + let dst = Path::new(&out_dir).join("with_attrs_ipc.rs"); + let mut registry = syntex::Registry::new(); + codegen::register(&mut registry); + registry.expand("", &src, &dst).is_ok() + } + // serialization pass + { + let src = Path::new(&out_dir).join("with_attrs_ipc.rs"); + let dst = Path::new(&out_dir).join("with_attrs_cg.rs"); + let mut registry = syntex::Registry::new(); + codegen::register(&mut registry); + registry.expand("", &src, &dst).unwrap(); + } + // rpc pass { let src = Path::new("binary.rs.in"); diff --git a/ipc/tests/examples.rs b/ipc/tests/examples.rs index 99cf385fa..b4159f196 100644 --- a/ipc/tests/examples.rs +++ b/ipc/tests/examples.rs @@ -86,7 +86,7 @@ mod tests { 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0], - service_client.socket().borrow().write_buffer.clone()); + service_client.socket().write().unwrap().write_buffer.clone()); assert_eq!(10, result); } @@ -103,7 +103,7 @@ mod tests { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 10, 0, 0, 0], service_client.socket().borrow().write_buffer.clone()); + 5, 0, 0, 0, 10, 0, 0, 0], service_client.socket().write().unwrap().write_buffer.clone()); assert_eq!(10, result); } @@ -145,7 +145,7 @@ mod tests { // items 3, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0], - service_client.socket().borrow().write_buffer.clone()); + service_client.socket().write().unwrap().write_buffer.clone()); assert_eq!(true, result); } diff --git a/ipc/tests/over_nano.rs b/ipc/tests/over_nano.rs index 36ad17f2a..bdeaec3d5 100644 --- a/ipc/tests/over_nano.rs +++ b/ipc/tests/over_nano.rs @@ -18,6 +18,7 @@ mod tests { use super::super::service::*; + use super::super::with_attrs::PrettyNamedClient; use nanoipc; use std::sync::Arc; use std::io::Write; @@ -43,6 +44,12 @@ mod tests { assert!(client.is_ok()); } + #[test] + fn can_create_renamed_client() { + let client = nanoipc::init_duplex_client::>("ipc:///tmp/parity-nano-test10.ipc"); + assert!(client.is_ok()); + } + #[test] fn can_call_handshake() { let url = "ipc:///tmp/parity-test-nano-20.ipc"; diff --git a/ipc/tests/run.rs b/ipc/tests/run.rs index cdda5275b..ab0041899 100644 --- a/ipc/tests/run.rs +++ b/ipc/tests/run.rs @@ -28,3 +28,4 @@ mod examples; mod over_nano; mod nested; mod binary; +mod with_attrs; diff --git a/ipc/tests/with_attrs.rs b/ipc/tests/with_attrs.rs new file mode 100644 index 000000000..e9b3e0d76 --- /dev/null +++ b/ipc/tests/with_attrs.rs @@ -0,0 +1,18 @@ +// 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 . + +#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues +include!(concat!(env!("OUT_DIR"), "/with_attrs_cg.rs")); diff --git a/ipc/tests/with_attrs.rs.in b/ipc/tests/with_attrs.rs.in new file mode 100644 index 000000000..bca1b0bfe --- /dev/null +++ b/ipc/tests/with_attrs.rs.in @@ -0,0 +1,39 @@ +// 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 . + +use std::sync::RwLock; +use std::ops::*; +use ipc::IpcConfig; +use std::mem; +use ipc::binary::BinaryConvertError; +use std::collections::VecDeque; + +pub struct BadlyNamedService; + +#[derive(Ipc)] +#[ipc(client_ident="PrettyNamedClient")] +impl BadlyNamedService { + fn is_zero(&self, x: u64) -> bool { + x == 0 + } +} + +impl ::ipc::IpcConfig for BadlyNamedService {} + +#[test] +fn invoke() { + +} From eb56e743409ffe22b079207b531e1708f76a7aaa Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 30 Jun 2016 16:24:46 +0300 Subject: [PATCH 11/52] unused test --- ipc/tests/with_attrs.rs.in | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ipc/tests/with_attrs.rs.in b/ipc/tests/with_attrs.rs.in index bca1b0bfe..c49ce9c72 100644 --- a/ipc/tests/with_attrs.rs.in +++ b/ipc/tests/with_attrs.rs.in @@ -32,8 +32,3 @@ impl BadlyNamedService { } impl ::ipc::IpcConfig for BadlyNamedService {} - -#[test] -fn invoke() { - -} From 08048a7377123cf79fe37ed21046892f15961fa9 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Thu, 30 Jun 2016 16:26:37 +0300 Subject: [PATCH 12/52] redundant space --- ipc/tests/with_attrs.rs.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/tests/with_attrs.rs.in b/ipc/tests/with_attrs.rs.in index c49ce9c72..0168f3a72 100644 --- a/ipc/tests/with_attrs.rs.in +++ b/ipc/tests/with_attrs.rs.in @@ -25,7 +25,7 @@ pub struct BadlyNamedService; #[derive(Ipc)] #[ipc(client_ident="PrettyNamedClient")] -impl BadlyNamedService { +impl BadlyNamedService { fn is_zero(&self, x: u64) -> bool { x == 0 } From 6616b5e17d2810e9dffa3f021106dbf1e409e1ad Mon Sep 17 00:00:00 2001 From: goldylucks Date: Thu, 30 Jun 2016 18:14:20 +0200 Subject: [PATCH 13/52] bump status page v0.5.1 --- Cargo.lock | 6 +++--- dapps/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18168f795..6faa0cf32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,7 +286,7 @@ dependencies = [ "mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", "parity-dapps-builtins 0.5.2 (git+https://github.com/ethcore/parity-dapps-builtins-rs.git)", - "parity-dapps-status 0.5.0 (git+https://github.com/ethcore/parity-dapps-status-rs.git)", + "parity-dapps-status 0.5.1 (git+https://github.com/ethcore/parity-dapps-status-rs.git)", "parity-dapps-wallet 0.6.1 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -919,8 +919,8 @@ dependencies = [ [[package]] name = "parity-dapps-status" -version = "0.5.0" -source = "git+https://github.com/ethcore/parity-dapps-status-rs.git#0cdd3512004e403aff7da3b8c16ba0bf5d6c911c" +version = "0.5.1" +source = "git+https://github.com/ethcore/parity-dapps-status-rs.git#110ef2e66142ec8dc15fc40b8ddda5ed3bcfc1fb" dependencies = [ "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", ] diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index 6aaceb50a..d33bd6702 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -22,7 +22,7 @@ ethcore-rpc = { path = "../rpc" } ethcore-util = { path = "../util" } parity-dapps = { git = "https://github.com/ethcore/parity-dapps-rs.git", version = "0.3" } # List of apps -parity-dapps-status = { git = "https://github.com/ethcore/parity-dapps-status-rs.git", version = "0.5.0" } +parity-dapps-status = { git = "https://github.com/ethcore/parity-dapps-status-rs.git", version = "0.5.1" } parity-dapps-builtins = { git = "https://github.com/ethcore/parity-dapps-builtins-rs.git", version = "0.5.2" } parity-dapps-wallet = { git = "https://github.com/ethcore/parity-dapps-wallet-rs.git", version = "0.6.0", optional = true } parity-dapps-dao = { git = "https://github.com/ethcore/parity-dapps-dao-rs.git", version = "0.4.0", optional = true } From d3cb79833b4a087f7f258a478cc6501521103a00 Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:07:22 +0700 Subject: [PATCH 14/52] Update Ubuntu Dockerfile [ci skip] --- docker/ubuntu/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/ubuntu/Dockerfile b/docker/ubuntu/Dockerfile index 9999909c3..6c80238a1 100644 --- a/docker/ubuntu/Dockerfile +++ b/docker/ubuntu/Dockerfile @@ -27,7 +27,9 @@ g++ -v # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity && \ + git checkout master && \ + git pull && \ cargo build --release --verbose && \ - ls /build/parity/target/release/parity && \ + ls /build/parity/target/release/parity && \ strip /build/parity/target/release/parity RUN file /build/parity/target/release/parity From 8134a89b87f398e27094eae6c810c38da4e2f1da Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:08:07 +0700 Subject: [PATCH 15/52] Update Ubuntu-jit Dockerfile [ci skip] --- docker/ubuntu-jit/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/ubuntu-jit/Dockerfile b/docker/ubuntu-jit/Dockerfile index 89c38cee7..07f351460 100644 --- a/docker/ubuntu-jit/Dockerfile +++ b/docker/ubuntu-jit/Dockerfile @@ -47,6 +47,8 @@ g++ -v # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity && \ + git checkout master && \ + git pull && \ cargo build --release --features ethcore/jit --verbose && \ ls /build/parity/target/release/parity && \ strip /build/parity/target/release/parity From bb70cd889eccef2070264b09969e339ced34dcfa Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:08:58 +0700 Subject: [PATCH 16/52] Update Ubuntu-arm Dockerfile [ci skip] --- docker/ubuntu-arm/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/ubuntu-arm/Dockerfile b/docker/ubuntu-arm/Dockerfile index fab325e5e..075f7324e 100644 --- a/docker/ubuntu-arm/Dockerfile +++ b/docker/ubuntu-arm/Dockerfile @@ -36,6 +36,8 @@ ENV CC arm-linux-gnueabihf-gcc # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity && \ + git checkout master && \ + git pull && \ mkdir -p .cargo && \ echo '[target.armv7-unknown-linux-gnueabihf]\n\ linker = "arm-linux-gnueabihf-gcc"\n'\ From bee2102424a52c690f41aea0da071c3e4d9e31a7 Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:09:48 +0700 Subject: [PATCH 17/52] Update Dockerfile ubuntu-aarch64 [ci skip] --- docker/ubuntu-aarch64/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/ubuntu-aarch64/Dockerfile b/docker/ubuntu-aarch64/Dockerfile index 3212f84d0..c9939074c 100644 --- a/docker/ubuntu-aarch64/Dockerfile +++ b/docker/ubuntu-aarch64/Dockerfile @@ -36,6 +36,8 @@ ENV CC aarch64-linux-gnu-gcc # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity && \ + git checkout master && \ + git pull && \ mkdir -p .cargo && \ echo '[target.aarch64-unknown-linux-gnu]\n\ linker = "aarch64-linux-gnu-gcc"\n'\ From 90a4475f526537ddecc085e9ee1155047ce4abeb Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:10:58 +0700 Subject: [PATCH 18/52] Update CentOS Dockerfile [ci skip] --- docker/centos/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/centos/Dockerfile b/docker/centos/Dockerfile index 56015422c..ea0571cca 100644 --- a/docker/centos/Dockerfile +++ b/docker/centos/Dockerfile @@ -20,6 +20,8 @@ g++ -v # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity&&\ + git checkout master && \ + git pull && \ ls -a&&\ cargo build --release --verbose && \ ls /build/parity/target/release/parity && \ From f370e17a544c9fd7af117611036cb9b0b7a25d1d Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:26:56 +0700 Subject: [PATCH 19/52] Update CentOS Dockerfile [ci skip] --- docker/centos/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/centos/Dockerfile b/docker/centos/Dockerfile index ea0571cca..9fd33f4ff 100644 --- a/docker/centos/Dockerfile +++ b/docker/centos/Dockerfile @@ -20,7 +20,7 @@ g++ -v # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity&&\ - git checkout master && \ + git checkout beta && \ git pull && \ ls -a&&\ cargo build --release --verbose && \ From 6bdbc2cb9344614dedacbaf821ca451b259ae3c1 Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:27:36 +0700 Subject: [PATCH 20/52] Update Dockerfile ubuntu-aarch64 [ci skip] --- docker/ubuntu-aarch64/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/ubuntu-aarch64/Dockerfile b/docker/ubuntu-aarch64/Dockerfile index c9939074c..38ed4c9b1 100644 --- a/docker/ubuntu-aarch64/Dockerfile +++ b/docker/ubuntu-aarch64/Dockerfile @@ -36,7 +36,7 @@ ENV CC aarch64-linux-gnu-gcc # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity && \ - git checkout master && \ + git checkout beta && \ git pull && \ mkdir -p .cargo && \ echo '[target.aarch64-unknown-linux-gnu]\n\ From 6bbd237711f8fa4d1214de68ba1bfd4d133ec55d Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:28:18 +0700 Subject: [PATCH 21/52] Update Ubuntu-arm Dockerfile [ci skip] --- docker/ubuntu-arm/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/ubuntu-arm/Dockerfile b/docker/ubuntu-arm/Dockerfile index 075f7324e..b59573a0f 100644 --- a/docker/ubuntu-arm/Dockerfile +++ b/docker/ubuntu-arm/Dockerfile @@ -36,7 +36,7 @@ ENV CC arm-linux-gnueabihf-gcc # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity && \ - git checkout master && \ + git checkout beta && \ git pull && \ mkdir -p .cargo && \ echo '[target.armv7-unknown-linux-gnueabihf]\n\ From c8c7fbbf277555d9bfe35dede9305449f115bebe Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:29:00 +0700 Subject: [PATCH 22/52] Update Ubuntu-jit Dockerfile [ci skip] --- docker/ubuntu-jit/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/ubuntu-jit/Dockerfile b/docker/ubuntu-jit/Dockerfile index 07f351460..666b16904 100644 --- a/docker/ubuntu-jit/Dockerfile +++ b/docker/ubuntu-jit/Dockerfile @@ -47,7 +47,7 @@ g++ -v # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity && \ - git checkout master && \ + git checkout beta && \ git pull && \ cargo build --release --features ethcore/jit --verbose && \ ls /build/parity/target/release/parity && \ From 038ef2b3c30c2d7f8cb57ea78fbddbb223562510 Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 1 Jul 2016 03:29:45 +0700 Subject: [PATCH 23/52] Update Ubuntu Dockerfile [ci skip] --- docker/ubuntu/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/ubuntu/Dockerfile b/docker/ubuntu/Dockerfile index 6c80238a1..4c82e1ecc 100644 --- a/docker/ubuntu/Dockerfile +++ b/docker/ubuntu/Dockerfile @@ -27,7 +27,7 @@ g++ -v # build parity RUN git clone https://github.com/ethcore/parity && \ cd parity && \ - git checkout master && \ + git checkout beta && \ git pull && \ cargo build --release --verbose && \ ls /build/parity/target/release/parity && \ From 29b6ba4a87579423019cdcaa76e842a9a2097170 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 30 Jun 2016 22:35:59 +0200 Subject: [PATCH 24/52] Fix the reseal mechanism. --- ethcore/src/miner/miner.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 7b101afc7..35c9998c7 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -158,7 +158,7 @@ impl Miner { fn prepare_sealing(&self, chain: &MiningBlockChainClient) { trace!(target: "miner", "prepare_sealing: entering"); - let (transactions, mut open_block, last_work_hash) = { + let (transactions, mut open_block, original_work_hash) = { let transactions = {self.transaction_queue.lock().unwrap().top_transactions()}; let mut sealing_work = self.sealing_work.lock().unwrap(); let last_work_hash = sealing_work.peek_last_ref().map(|pb| pb.block().fields().header.hash()); @@ -254,23 +254,27 @@ impl Miner { } } - let work = { + let (work, is_new) = { let mut sealing_work = self.sealing_work.lock().unwrap(); - trace!(target: "miner", "Checking whether we need to reseal: last={:?}, this={:?}", last_work_hash, block.block().fields().header.hash()); - let work = if last_work_hash.map_or(true, |h| h != block.block().fields().header.hash()) { + let last_work_hash = sealing_work.peek_last_ref().map(|pb| pb.block().fields().header.hash()); + trace!(target: "miner", "Checking whether we need to reseal: orig={:?} last={:?}, this={:?}", original_work_hash, last_work_hash, block.block().fields().header.hash()); + let (work, is_new) = if last_work_hash.map_or(true, |h| h != block.block().fields().header.hash()) { trace!(target: "miner", "Pushing a new, refreshed or borrowed pending {}...", block.block().fields().header.hash()); let pow_hash = block.block().fields().header.hash(); let number = block.block().fields().header.number(); let difficulty = *block.block().fields().header.difficulty(); + let is_new = original_work_hash.map_or(false, |h| block.block().fields().header.hash() == h); sealing_work.push(block); - Some((pow_hash, difficulty, number)) + (Some((pow_hash, difficulty, number)), is_new) } else { - None + (None, false) }; trace!(target: "miner", "prepare_sealing: leaving (last={:?})", sealing_work.peek_last_ref().map(|b| b.block().fields().header.hash())); - work + (work, is_new) }; - work.map(|(pow_hash, difficulty, number)| self.work_poster.as_ref().map(|ref p| p.notify(pow_hash, difficulty, number))); + if is_new { + work.map(|(pow_hash, difficulty, number)| self.work_poster.as_ref().map(|ref p| p.notify(pow_hash, difficulty, number))); + } } fn update_gas_limit(&self, chain: &MiningBlockChainClient) { From 1d780f456ac7d7bf09af7df366478289788d4d72 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 30 Jun 2016 23:14:54 +0200 Subject: [PATCH 25/52] Fix is_new. --- ethcore/src/miner/miner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 35c9998c7..d3e32c797 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -263,7 +263,7 @@ impl Miner { let pow_hash = block.block().fields().header.hash(); let number = block.block().fields().header.number(); let difficulty = *block.block().fields().header.difficulty(); - let is_new = original_work_hash.map_or(false, |h| block.block().fields().header.hash() == h); + let is_new = original_work_hash.map_or(true, |h| block.block().fields().header.hash() != h); sealing_work.push(block); (Some((pow_hash, difficulty, number)), is_new) } else { From 5c2ca9a0cb3076ffeab59d5e44af250a1ef931e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 1 Jul 2016 02:08:14 +0200 Subject: [PATCH 26/52] Fixing warnings --- ethcore/src/client/client.rs | 2 +- ethcore/src/miner/work_notify.rs | 6 +++--- util/bigint/src/uint.rs | 2 +- util/src/network/host.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index d5e509e62..99617023a 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -348,7 +348,7 @@ impl Client { imported } - fn commit_block(&self, block: B, hash: &H256, block_data: &Bytes) -> ImportRoute where B: IsBlock + Drain { + fn commit_block(&self, block: B, hash: &H256, block_data: &[u8]) -> ImportRoute where B: IsBlock + Drain { let number = block.header().number(); // Are we committing an era? let ancient = if number >= HISTORY { diff --git a/ethcore/src/miner/work_notify.rs b/ethcore/src/miner/work_notify.rs index a153be79f..ba45e5b70 100644 --- a/ethcore/src/miner/work_notify.rs +++ b/ethcore/src/miner/work_notify.rs @@ -52,10 +52,10 @@ impl WorkPoster { } fn create_client() -> Client { - let client = Client::::configure() + Client::::configure() .keep_alive(true) - .build().expect("Error creating HTTP client") as Client; - client + .build() + .expect("Error creating HTTP client") } pub fn notify(&self, pow_hash: H256, difficulty: U256, number: u64) { diff --git a/util/bigint/src/uint.rs b/util/bigint/src/uint.rs index 2b9863135..1ea03679a 100644 --- a/util/bigint/src/uint.rs +++ b/util/bigint/src/uint.rs @@ -43,7 +43,7 @@ use std::cmp; use std::str::{FromStr}; use std::convert::From; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; use std::ops::*; use std::cmp::*; diff --git a/util/src/network/host.rs b/util/src/network/host.rs index a48d1544c..a8bbc17e5 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -539,7 +539,7 @@ impl Host where Message: Send + Sync + Clone { self.info.write().unwrap().public_endpoint = Some(public_endpoint.clone()); if self.first_time.load(AtomicOrdering::Relaxed) { - info!("Public node URL: {}", paint(White.bold(), format!("{}", self.external_url().unwrap()))); + info!("Public node URL: {}", paint(White.bold(), self.external_url().unwrap())); self.first_time.store(false, AtomicOrdering::Relaxed); } From 52f4034bdda1deab91e8e7bbae21934e7edf98fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 1 Jul 2016 02:21:22 +0200 Subject: [PATCH 27/52] Formatting --- ethcore/src/miner/work_notify.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ethcore/src/miner/work_notify.rs b/ethcore/src/miner/work_notify.rs index ba45e5b70..ea2f6140e 100644 --- a/ethcore/src/miner/work_notify.rs +++ b/ethcore/src/miner/work_notify.rs @@ -63,8 +63,10 @@ impl WorkPoster { let target = Ethash::difficulty_to_boundary(&difficulty); let seed_hash = &self.seed_compute.lock().unwrap().get_seedhash(number); let seed_hash = H256::from_slice(&seed_hash[..]); - let body = format!(r#"{{ "result": ["0x{}","0x{}","0x{}","0x{:x}"] }}"#, - pow_hash.hex(), seed_hash.hex(), target.hex(), number); + let body = format!( + r#"{{ "result": ["0x{}","0x{}","0x{}","0x{:x}"] }}"#, + pow_hash.hex(), seed_hash.hex(), target.hex(), number + ); let mut client = self.client.lock().unwrap(); for u in &self.urls { if let Err(e) = client.request(u.clone(), PostHandler { body: body.clone() }) { @@ -104,12 +106,12 @@ impl hyper::client::Handler for PostHandler { } fn on_response_readable(&mut self, _decoder: &mut hyper::Decoder) -> Next { - Next::end() + Next::end() } - fn on_error(&mut self, err: hyper::Error) -> Next { + fn on_error(&mut self, err: hyper::Error) -> Next { trace!("Error posting work data: {}", err); Next::end() - } + } } From 7ad8599324ac0dc3ba76cbea65c45a39066b0494 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 1 Jul 2016 13:26:44 +0300 Subject: [PATCH 28/52] uncle as rlp in the api --- ethcore/src/client/client.rs | 9 +++-- ethcore/src/client/mod.rs | 4 +- ethcore/src/client/test_client.rs | 4 +- ethcore/src/types/ids.rs | 10 ++--- rpc/src/v1/impls/eth.rs | 64 +++++++++++++++++-------------- 5 files changed, 49 insertions(+), 42 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index d5e509e62..e265fe4c0 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -22,7 +22,7 @@ use util::*; use util::panics::*; use views::BlockView; use error::{Error, ImportError, ExecutionError, BlockError, ImportResult}; -use header::{BlockNumber, Header}; +use header::{BlockNumber}; use state::State; use spec::Spec; use engine::Engine; @@ -50,6 +50,7 @@ pub use types::blockchain_info::BlockChainInfo; pub use types::block_status::BlockStatus; use evm::Factory as EvmFactory; use miner::{Miner, MinerService, TransactionImportResult, AccountDetails}; +use basic_types::*; const MAX_TX_QUEUE_SIZE: usize = 4096; @@ -579,9 +580,9 @@ impl BlockChainClient for Client { self.transaction_address(id).and_then(|address| self.chain.transaction(&address)) } - fn uncle(&self, id: UncleID) -> Option
{ - let index = id.1; - self.block(id.0).and_then(|block| BlockView::new(&block).uncle_at(index)) + fn uncle(&self, id: UncleID) -> Option { + let index = id.position; + self.block(id.block).and_then(|block| BlockView::new(&block).uncle_at(index).and_then(|u| Some(u.rlp(Seal::With)))) } fn transaction_receipt(&self, id: TransactionID) -> Option { diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 7f3c3bb3a..27a1d3265 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -38,7 +38,7 @@ use util::Itertools; use blockchain::TreeRoute; use block_queue::BlockQueueInfo; use block::{OpenBlock, SealedBlock}; -use header::{BlockNumber, Header}; +use header::{BlockNumber}; use transaction::{LocalizedTransaction, SignedTransaction}; use log_entry::LocalizedLogEntry; use filter::Filter; @@ -126,7 +126,7 @@ pub trait BlockChainClient : Sync + Send { fn transaction(&self, id: TransactionID) -> Option; /// Get uncle with given id. - fn uncle(&self, id: UncleID) -> Option
; + fn uncle(&self, id: UncleID) -> Option; /// Get transaction receipt with given hash. fn transaction_receipt(&self, id: TransactionID) -> Option; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index f51f978de..be90d9b67 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -244,7 +244,7 @@ impl MiningBlockChainClient for TestBlockChainClient { fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock { unimplemented!(); } - + fn vm_factory(&self) -> &EvmFactory { unimplemented!(); } @@ -298,7 +298,7 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn uncle(&self, _id: UncleID) -> Option { + fn uncle(&self, _id: UncleID) -> Option { unimplemented!(); } diff --git a/ethcore/src/types/ids.rs b/ethcore/src/types/ids.rs index 0a492735c..99dadc4ea 100644 --- a/ethcore/src/types/ids.rs +++ b/ethcore/src/types/ids.rs @@ -55,10 +55,10 @@ pub struct TraceId { } /// Uniquely identifies Uncle. -#[derive(Debug)] -pub struct UncleID ( +#[derive(Debug, Binary)] +pub struct UncleID { /// Block id. - pub BlockID, + pub block: BlockID, /// Position in block. - pub usize -); + pub position: usize +} diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 8bfc661e3..f2325de93 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -41,6 +41,7 @@ use v1::traits::Eth; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; use v1::impls::{default_gas_price, dispatch_transaction, error_codes}; use serde; +use ethcore::header::Header as BlockHeader; /// Eth rpc implementation. pub struct EthClient where @@ -126,33 +127,38 @@ impl EthClient where fn uncle(&self, id: UncleID) -> Result { let client = take_weak!(self.client); - match client.uncle(id).and_then(|u| client.block_total_difficulty(BlockID::Hash(u.parent_hash().clone())).map(|diff| (diff, u))) { - Some((parent_difficulty, uncle)) => { - let block = Block { - hash: OptionalValue::Value(uncle.hash()), - parent_hash: uncle.parent_hash, - uncles_hash: uncle.uncles_hash, - author: uncle.author, - miner: uncle.author, - state_root: uncle.state_root, - transactions_root: uncle.transactions_root, - number: OptionalValue::Value(U256::from(uncle.number)), - gas_used: uncle.gas_used, - gas_limit: uncle.gas_limit, - logs_bloom: uncle.log_bloom, - timestamp: U256::from(uncle.timestamp), - difficulty: uncle.difficulty, - total_difficulty: uncle.difficulty + parent_difficulty, - receipts_root: uncle.receipts_root, - extra_data: Bytes::new(uncle.extra_data), - seal_fields: uncle.seal.into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), - uncles: vec![], - transactions: BlockTransactions::Hashes(vec![]), - }; - to_value(&block) - }, - None => Ok(Value::Null) - } + + let uncle: BlockHeader = match client.uncle(id) { + Some(rlp) => decode(&rlp), + None => { return Ok(Value::Null); } + }; + let parent_difficulty = match client.block_total_difficulty(BlockID::Hash(uncle.parent_hash().clone())) { + Some(difficulty) => difficulty, + None => { return Ok(Value::Null); } + }; + + let block = Block { + hash: OptionalValue::Value(uncle.hash()), + parent_hash: uncle.parent_hash, + uncles_hash: uncle.uncles_hash, + author: uncle.author, + miner: uncle.author, + state_root: uncle.state_root, + transactions_root: uncle.transactions_root, + number: OptionalValue::Value(U256::from(uncle.number)), + gas_used: uncle.gas_used, + gas_limit: uncle.gas_limit, + logs_bloom: uncle.log_bloom, + timestamp: U256::from(uncle.timestamp), + difficulty: uncle.difficulty, + total_difficulty: uncle.difficulty + parent_difficulty, + receipts_root: uncle.receipts_root, + extra_data: Bytes::new(uncle.extra_data), + seal_fields: uncle.seal.into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), + uncles: vec![], + transactions: BlockTransactions::Hashes(vec![]), + }; + to_value(&block) } fn sign_call(&self, request: CallRequest) -> Result { @@ -435,12 +441,12 @@ impl Eth for EthClient where fn uncle_by_block_hash_and_index(&self, params: Params) -> Result { from_params::<(H256, Index)>(params) - .and_then(|(hash, index)| self.uncle(UncleID(BlockID::Hash(hash), index.value()))) + .and_then(|(hash, index)| self.uncle(UncleID { block: BlockID::Hash(hash), position: index.value() })) } fn uncle_by_block_number_and_index(&self, params: Params) -> Result { from_params::<(BlockNumber, Index)>(params) - .and_then(|(number, index)| self.uncle(UncleID(number.into(), index.value()))) + .and_then(|(number, index)| self.uncle(UncleID { block: number.into(), position: index.value() })) } fn compilers(&self, params: Params) -> Result { From 654cd570b4348f788ce83c50fce9986afdcbea30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 1 Jul 2016 12:35:14 +0200 Subject: [PATCH 29/52] Optimizing shr --- util/bigint/src/uint.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/util/bigint/src/uint.rs b/util/bigint/src/uint.rs index 2b9863135..2bc8e9810 100644 --- a/util/bigint/src/uint.rs +++ b/util/bigint/src/uint.rs @@ -1031,7 +1031,7 @@ macro_rules! construct_uint { // shift for i in word_shift..$n_words { - ret[i] += original[i - word_shift] << bit_shift; + ret[i] = original[i - word_shift] << bit_shift; } // carry if bit_shift > 0 { @@ -1052,14 +1052,18 @@ macro_rules! construct_uint { let word_shift = shift / 64; let bit_shift = shift % 64; + // shift for i in word_shift..$n_words { - // Shift - ret[i - word_shift] += original[i] >> bit_shift; - // Carry - if bit_shift > 0 && i < $n_words - 1 { - ret[i - word_shift] += original[i + 1] << (64 - bit_shift); + ret[i - word_shift] = original[i] >> bit_shift; + } + + // Carry + if bit_shift > 0 { + for i in word_shift+1..$n_words { + ret[i - word_shift - 1] += original[i] << (64 - bit_shift); } } + $name(ret) } } From d4ff3e51e9302d742189c4d81e6984d8b1aff72a Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 1 Jul 2016 16:33:37 +0300 Subject: [PATCH 30/52] uncle rlp in block view --- ethcore/src/client/client.rs | 2 +- ethcore/src/views/block.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index e265fe4c0..87ad26647 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -582,7 +582,7 @@ impl BlockChainClient for Client { fn uncle(&self, id: UncleID) -> Option { let index = id.position; - self.block(id.block).and_then(|block| BlockView::new(&block).uncle_at(index).and_then(|u| Some(u.rlp(Seal::With)))) + self.block(id.block).and_then(|block| BlockView::new(&block).uncle_rlp_at(index)) } fn transaction_receipt(&self, id: TransactionID) -> Option { diff --git a/ethcore/src/views/block.rs b/ethcore/src/views/block.rs index 82b8fb805..42fd52a20 100644 --- a/ethcore/src/views/block.rs +++ b/ethcore/src/views/block.rs @@ -139,6 +139,11 @@ impl<'a> BlockView<'a> { pub fn uncle_at(&self, index: usize) -> Option
{ self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_val()) } + + /// Return nth uncle rlp. + pub fn uncle_rlp_at(&self, index: usize) -> Option { + self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_raw().to_vec()) + } } impl<'a> Hashable for BlockView<'a> { From 0907722fc87dc857226474bb9744a5d7280fc4df Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 1 Jul 2016 16:34:15 +0300 Subject: [PATCH 31/52] fix warning --- ethcore/src/client/client.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 87ad26647..9bfe1758d 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -50,7 +50,6 @@ pub use types::blockchain_info::BlockChainInfo; pub use types::block_status::BlockStatus; use evm::Factory as EvmFactory; use miner::{Miner, MinerService, TransactionImportResult, AccountDetails}; -use basic_types::*; const MAX_TX_QUEUE_SIZE: usize = 4096; From d8a4cca817ae2684ddbeffe33989a31f99ea9b88 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 1 Jul 2016 20:29:56 +0200 Subject: [PATCH 32/52] Fatdb integration with CLI (#1464) * fatdb integration * --fat-db * rerun with --pruning=archive comment --- ethcore/src/account.rs | 14 ++++---- ethcore/src/basic_authority.rs | 2 +- ethcore/src/block.rs | 35 +++++++++++--------- ethcore/src/client/client.rs | 13 ++++++-- ethcore/src/client/config.rs | 3 ++ ethcore/src/ethereum/ethash.rs | 4 +-- ethcore/src/ethereum/mod.rs | 2 +- ethcore/src/state.rs | 59 ++++++++++++++++++++-------------- ethcore/src/tests/helpers.rs | 5 +-- parity/cli.rs | 2 ++ parity/configuration.rs | 8 +++++ 11 files changed, 91 insertions(+), 56 deletions(-) diff --git a/ethcore/src/account.rs b/ethcore/src/account.rs index 2edbf87ae..2db4ffcc0 100644 --- a/ethcore/src/account.rs +++ b/ethcore/src/account.rs @@ -214,8 +214,8 @@ impl Account { } /// Commit the `storage_overlay` to the backing DB and update `storage_root`. - pub fn commit_storage(&mut self, db: &mut AccountDBMut) { - let mut t = SecTrieDBMut::from_existing(db, &mut self.storage_root) + pub fn commit_storage(&mut self, trie_factory: &TrieFactory, db: &mut AccountDBMut) { + let mut t = trie_factory.from_existing(db, &mut self.storage_root) .expect("Account storage_root initially set to zero (valid) and only altered by SecTrieDBMut. \ SecTrieDBMut would not set it to an invalid state root. Therefore the root is valid and DB creation \ using it will not fail."); @@ -275,7 +275,7 @@ mod tests { let rlp = { let mut a = Account::new_contract(69.into(), 0.into()); a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64))); - a.commit_storage(&mut db); + a.commit_storage(&Default::default(), &mut db); a.init_code(vec![]); a.commit_code(&mut db); a.rlp() @@ -313,7 +313,7 @@ mod tests { let mut db = AccountDBMut::new(&mut db, &Address::new()); a.set_storage(0.into(), 0x1234.into()); assert_eq!(a.storage_root(), None); - a.commit_storage(&mut db); + a.commit_storage(&Default::default(), &mut db); assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2"); } @@ -323,11 +323,11 @@ mod tests { let mut db = MemoryDB::new(); let mut db = AccountDBMut::new(&mut db, &Address::new()); a.set_storage(0.into(), 0x1234.into()); - a.commit_storage(&mut db); + a.commit_storage(&Default::default(), &mut db); a.set_storage(1.into(), 0x1234.into()); - a.commit_storage(&mut db); + a.commit_storage(&Default::default(), &mut db); a.set_storage(1.into(), 0.into()); - a.commit_storage(&mut db); + a.commit_storage(&Default::default(), &mut db); assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2"); } diff --git a/ethcore/src/basic_authority.rs b/ethcore/src/basic_authority.rs index 4426d3059..e487548a3 100644 --- a/ethcore/src/basic_authority.rs +++ b/ethcore/src/basic_authority.rs @@ -254,7 +254,7 @@ mod tests { spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; let vm_factory = Default::default(); - let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); + let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, None, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); assert!(b.try_seal(engine.deref(), seal).is_ok()); diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 13a2024d9..9453e1350 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -222,6 +222,7 @@ impl<'x> OpenBlock<'x> { pub fn new( engine: &'x Engine, vm_factory: &'x EvmFactory, + trie_factory: TrieFactory, tracing: bool, db: Box, parent: &Header, @@ -231,7 +232,7 @@ impl<'x> OpenBlock<'x> { gas_range_target: (U256, U256), extra_data: Bytes, ) -> Result { - let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce())); + let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce(), trie_factory)); let mut r = OpenBlock { block: ExecutedBlock::new(state, tracing), engine: engine, @@ -481,16 +482,17 @@ pub fn enact( parent: &Header, last_hashes: LastHashes, dao_rescue_block_gas_limit: Option, - vm_factory: &EvmFactory + vm_factory: &EvmFactory, + trie_factory: TrieFactory, ) -> Result { { if ::log::max_log_level() >= ::log::LogLevel::Trace { - let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce())); + let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce(), trie_factory.clone())); trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author())); } } - let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), (3141562.into(), 31415620.into()), header.extra_data().clone())); + let mut b = try!(OpenBlock::new(engine, vm_factory, trie_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), (3141562.into(), 31415620.into()), header.extra_data().clone())); b.set_difficulty(*header.difficulty()); b.set_gas_limit(*header.gas_limit()); b.set_timestamp(header.timestamp()); @@ -509,11 +511,12 @@ pub fn enact_bytes( parent: &Header, last_hashes: LastHashes, dao_rescue_block_gas_limit: Option, - vm_factory: &EvmFactory + vm_factory: &EvmFactory, + trie_factory: TrieFactory, ) -> Result { let block = BlockView::new(block_bytes); let header = block.header(); - enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory) + enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory, trie_factory) } /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header @@ -526,10 +529,11 @@ pub fn enact_verified( parent: &Header, last_hashes: LastHashes, dao_rescue_block_gas_limit: Option, - vm_factory: &EvmFactory + vm_factory: &EvmFactory, + trie_factory: TrieFactory, ) -> Result { let view = BlockView::new(&block.bytes); - enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory) + enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory, trie_factory) } /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards @@ -542,10 +546,11 @@ pub fn enact_and_seal( parent: &Header, last_hashes: LastHashes, dao_rescue_block_gas_limit: Option, - vm_factory: &EvmFactory + vm_factory: &EvmFactory, + trie_factory: TrieFactory, ) -> Result { let header = BlockView::new(block_bytes).header_view(); - Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)).seal(engine, header.seal()))) + Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory, trie_factory)).seal(engine, header.seal()))) } #[cfg(test)] @@ -565,7 +570,7 @@ mod tests { spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; let vm_factory = Default::default(); - let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); + let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); let _ = b.seal(engine.deref(), vec![]); } @@ -581,7 +586,7 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); let vm_factory = Default::default(); - let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap() + let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap() .close_and_lock().seal(engine.deref(), vec![]).unwrap(); let orig_bytes = b.rlp_bytes(); let orig_db = b.drain(); @@ -589,7 +594,7 @@ mod tests { let mut db_result = get_temp_journal_db(); let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); - let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap(); + let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default(), Default::default()).unwrap(); assert_eq!(e.rlp_bytes(), orig_bytes); @@ -609,7 +614,7 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); let vm_factory = Default::default(); - let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); + let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut uncle1_header = Header::new(); uncle1_header.extra_data = b"uncle1".to_vec(); let mut uncle2_header = Header::new(); @@ -624,7 +629,7 @@ mod tests { let mut db_result = get_temp_journal_db(); let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); - let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap(); + let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default(), Default::default()).unwrap(); let bytes = e.rlp_bytes(); assert_eq!(bytes, orig_bytes); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 99617023a..bf1ae7f05 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -94,6 +94,7 @@ pub struct Client { panic_handler: Arc, verifier: Box, vm_factory: Arc, + trie_factory: TrieFactory, miner: Arc, io_channel: IoChannel, queue_transactions: AtomicUsize, @@ -175,6 +176,7 @@ impl Client { panic_handler: panic_handler, verifier: verification::new(config.verifier_type), vm_factory: Arc::new(EvmFactory::new(config.vm_type)), + trie_factory: TrieFactory::new(config.trie_spec), miner: miner, io_channel: message_channel, queue_transactions: AtomicUsize::new(0), @@ -233,7 +235,7 @@ impl Client { let last_hashes = self.build_last_hashes(header.parent_hash.clone()); let db = self.state_db.lock().unwrap().boxed_clone(); - let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, self.dao_rescue_block_gas_limit(header.parent_hash.clone()), &self.vm_factory); + let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, self.dao_rescue_block_gas_limit(header.parent_hash.clone()), &self.vm_factory, self.trie_factory.clone()); if let Err(e) = enact_result { warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); return Err(()); @@ -418,13 +420,17 @@ impl Client { let root = HeaderView::new(&header).state_root(); - State::from_existing(db, root, self.engine.account_start_nonce()).ok() + State::from_existing(db, root, self.engine.account_start_nonce(), self.trie_factory.clone()).ok() }) } /// Get a copy of the best block's state. pub fn state(&self) -> State { - State::from_existing(self.state_db.lock().unwrap().boxed_clone(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce()) + State::from_existing( + self.state_db.lock().unwrap().boxed_clone(), + HeaderView::new(&self.best_block_header()).state_root(), + self.engine.account_start_nonce(), + self.trie_factory.clone()) .expect("State root of best block header always valid.") } @@ -809,6 +815,7 @@ impl MiningBlockChainClient for Client { let mut open_block = OpenBlock::new( engine, &self.vm_factory, + self.trie_factory.clone(), false, // TODO: this will need to be parameterised once we want to do immediate mining insertion. self.state_db.lock().unwrap().boxed_clone(), &self.chain.block_header(&h).expect("h is best block hash: so it's header must exist: qed"), diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index 52a875a2f..6cb34c151 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -20,6 +20,7 @@ pub use trace::{Config as TraceConfig, Switch}; pub use evm::VMType; pub use verification::VerifierType; use util::journaldb; +use util::trie::TrieSpec; /// Client state db compaction profile #[derive(Debug, PartialEq)] @@ -45,6 +46,8 @@ pub struct ClientConfig { pub tracing: TraceConfig, /// VM type. pub vm_type: VMType, + /// Trie type. + pub trie_spec: TrieSpec, /// The JournalDB ("pruning") algorithm to use. pub pruning: journaldb::Algorithm, /// The name of the client instance. diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 84c2a9608..c438c33ca 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -325,7 +325,7 @@ mod tests { spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; let vm_factory = Default::default(); - let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); + let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close(); assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap()); } @@ -340,7 +340,7 @@ mod tests { spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; let vm_factory = Default::default(); - let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); + let mut b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut uncle = Header::new(); let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106"); uncle.author = uncle_author.clone(); diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index ed75576c6..d40ee8983 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -67,7 +67,7 @@ mod tests { let mut db_result = get_temp_journal_db(); let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); - let s = State::from_existing(db, genesis_header.state_root.clone(), engine.account_start_nonce()).unwrap(); + let s = State::from_existing(db, genesis_header.state_root.clone(), engine.account_start_nonce(), Default::default()).unwrap(); assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000001")), U256::from(1u64)); assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64)); assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000003")), U256::from(1u64)); diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index 0c086ffc3..92a501e80 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -42,6 +42,7 @@ pub struct State { cache: RefCell>>, snapshots: RefCell>>>>, account_start_nonce: U256, + trie_factory: TrieFactory, } const SEC_TRIE_DB_UNWRAP_STR: &'static str = "A state can only be created with valid root. Creating a SecTrieDB with a valid root will not fail. \ @@ -50,11 +51,11 @@ const SEC_TRIE_DB_UNWRAP_STR: &'static str = "A state can only be created with v impl State { /// Creates new state with empty state root #[cfg(test)] - pub fn new(mut db: Box, account_start_nonce: U256) -> State { + pub fn new(mut db: Box, account_start_nonce: U256, trie_factory: TrieFactory) -> State { let mut root = H256::new(); { // init trie and reset root too null - let _ = SecTrieDBMut::new(db.as_hashdb_mut(), &mut root); + let _ = trie_factory.create(db.as_hashdb_mut(), &mut root); } State { @@ -63,22 +64,26 @@ impl State { cache: RefCell::new(HashMap::new()), snapshots: RefCell::new(Vec::new()), account_start_nonce: account_start_nonce, + trie_factory: trie_factory, } } /// Creates new state with existing state root - pub fn from_existing(db: Box, root: H256, account_start_nonce: U256) -> Result { + pub fn from_existing(db: Box, root: H256, account_start_nonce: U256, trie_factory: TrieFactory) -> Result { if !db.as_hashdb().contains(&root) { - Err(TrieError::InvalidStateRoot) - } else { - Ok(State { - db: db, - root: root, - cache: RefCell::new(HashMap::new()), - snapshots: RefCell::new(Vec::new()), - account_start_nonce: account_start_nonce, - }) + return Err(TrieError::InvalidStateRoot); } + + let state = State { + db: db, + root: root, + cache: RefCell::new(HashMap::new()), + snapshots: RefCell::new(Vec::new()), + account_start_nonce: account_start_nonce, + trie_factory: trie_factory, + }; + + Ok(state) } /// Create a recoverable snaphot of this state @@ -156,7 +161,7 @@ impl State { /// Determine whether an account exists. pub fn exists(&self, a: &Address) -> bool { - let db = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); + let db = self.trie_factory.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); self.cache.borrow().get(&a).unwrap_or(&None).is_some() || db.contains(&a) } @@ -242,7 +247,10 @@ impl State { for a in &addresses { if self.code(a).map_or(false, |c| c.sha3() == broken_dao) { // Figure out if the balance has been reduced. - let maybe_original = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR).get(&a).map(Account::from_rlp); + let maybe_original = self.trie_factory + .readonly(self.db.as_hashdb(), &self.root) + .expect(SEC_TRIE_DB_UNWRAP_STR) + .get(&a).map(Account::from_rlp); if maybe_original.map_or(false, |original| *original.balance() > self.balance(a)) { return Err(Error::Transaction(TransactionError::DAORescue)); } @@ -262,14 +270,14 @@ impl State { /// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit. /// `accounts` is mutable because we may need to commit the code or storage and record that. #[cfg_attr(feature="dev", allow(match_ref_pats))] - pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap>) { + pub fn commit_into(trie_factory: &TrieFactory, db: &mut HashDB, root: &mut H256, accounts: &mut HashMap>) { // first, commit the sub trees. // TODO: is this necessary or can we dispense with the `ref mut a` for just `a`? for (address, ref mut a) in accounts.iter_mut() { match a { &mut&mut Some(ref mut account) => { let mut account_db = AccountDBMut::new(db, address); - account.commit_storage(&mut account_db); + account.commit_storage(trie_factory, &mut account_db); account.commit_code(&mut account_db); } &mut&mut None => {} @@ -277,7 +285,7 @@ impl State { } { - let mut trie = SecTrieDBMut::from_existing(db, root).unwrap(); + let mut trie = trie_factory.from_existing(db, root).unwrap(); for (address, ref a) in accounts.iter() { match **a { Some(ref account) => trie.insert(address, &account.rlp()), @@ -290,7 +298,7 @@ impl State { /// Commits our cached account changes into the trie. pub fn commit(&mut self) { assert!(self.snapshots.borrow().is_empty()); - Self::commit_into(self.db.as_hashdb_mut(), &mut self.root, self.cache.borrow_mut().deref_mut()); + Self::commit_into(&self.trie_factory, self.db.as_hashdb_mut(), &mut self.root, self.cache.borrow_mut().deref_mut()); } #[cfg(test)] @@ -340,7 +348,7 @@ impl State { fn get<'a>(&'a self, a: &Address, require_code: bool) -> &'a Option { let have_key = self.cache.borrow().contains_key(a); if !have_key { - let db = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); + let db = self.trie_factory.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); self.insert_cache(a, db.get(&a).map(Account::from_rlp)) } if require_code { @@ -361,7 +369,7 @@ impl State { fn require_or_from<'a, F: FnOnce() -> Account, G: FnOnce(&mut Account)>(&self, a: &Address, require_code: bool, default: F, not_default: G) -> &'a mut Account { let have_key = self.cache.borrow().contains_key(a); if !have_key { - let db = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); + let db = self.trie_factory.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR); self.insert_cache(a, db.get(&a).map(Account::from_rlp)) } else { self.note_cache(a); @@ -396,6 +404,7 @@ impl Clone for State { cache: RefCell::new(self.cache.borrow().clone()), snapshots: RefCell::new(self.snapshots.borrow().clone()), account_start_nonce: self.account_start_nonce.clone(), + trie_factory: self.trie_factory.clone(), } } } @@ -1179,7 +1188,7 @@ fn code_from_database() { state.drop() }; - let state = State::from_existing(db, root, U256::from(0u8)).unwrap(); + let state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap(); assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec())); } @@ -1194,7 +1203,7 @@ fn storage_at_from_database() { state.drop() }; - let s = State::from_existing(db, root, U256::from(0u8)).unwrap(); + let s = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap(); assert_eq!(s.storage_at(&a, &H256::from(&U256::from(01u64))), H256::from(&U256::from(69u64))); } @@ -1211,7 +1220,7 @@ fn get_from_database() { state.drop() }; - let state = State::from_existing(db, root, U256::from(0u8)).unwrap(); + let state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap(); assert_eq!(state.balance(&a), U256::from(69u64)); assert_eq!(state.nonce(&a), U256::from(1u64)); } @@ -1244,7 +1253,7 @@ fn remove_from_database() { }; let (root, db) = { - let mut state = State::from_existing(db, root, U256::from(0u8)).unwrap(); + let mut state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap(); assert_eq!(state.exists(&a), true); assert_eq!(state.nonce(&a), U256::from(1u64)); state.kill_account(&a); @@ -1254,7 +1263,7 @@ fn remove_from_database() { state.drop() }; - let state = State::from_existing(db, root, U256::from(0u8)).unwrap(); + let state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap(); assert_eq!(state.exists(&a), false); assert_eq!(state.nonce(&a), U256::from(0u64)); } diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 70a644896..ad8058ac6 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -175,6 +175,7 @@ pub fn generate_dummy_client_with_spec_and_data(get_test_spec: F, block_numbe let mut b = OpenBlock::new( test_engine.deref(), &vm_factory, + Default::default(), false, db, &last_header, @@ -315,7 +316,7 @@ pub fn get_temp_state() -> GuardedTempResult { let journal_db = get_temp_journal_db_in(temp.as_path()); GuardedTempResult { _temp: temp, - result: Some(State::new(journal_db, U256::from(0u8))) + result: Some(State::new(journal_db, U256::from(0), Default::default())), } } @@ -325,7 +326,7 @@ pub fn get_temp_journal_db_in(path: &Path) -> Box { pub fn get_temp_state_in(path: &Path) -> State { let journal_db = get_temp_journal_db_in(path); - State::new(journal_db, U256::from(0u8)) + State::new(journal_db, U256::from(0), Default::default()) } pub fn get_good_dummy_block_seq(count: usize) -> Vec { diff --git a/parity/cli.rs b/parity/cli.rs index 7ebbcb0aa..ef9ce8ce3 100644 --- a/parity/cli.rs +++ b/parity/cli.rs @@ -203,6 +203,7 @@ Database Options: --db-compaction TYPE Database compaction type. TYPE may be one of: ssd - suitable for SSDs and fast HDDs; hdd - suitable for slow HDDs [default: ssd]. + --fat-db Fat database. Import/Export Options: --from BLOCK Export from block BLOCK, which may be an index or @@ -362,6 +363,7 @@ pub struct Args { pub flag_ipcapi: Option, pub flag_db_cache_size: Option, pub flag_db_compaction: String, + pub flag_fat_db: bool, } pub fn print_version() { diff --git a/parity/configuration.rs b/parity/configuration.rs index fb31bf7ad..96524f5ea 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -333,6 +333,14 @@ impl Configuration { _ => { die!("Invalid pruning method given."); } }; + if self.args.flag_fat_db { + if let journaldb::Algorithm::Archive = client_config.pruning { + client_config.trie_spec = TrieSpec::Fat; + } else { + die!("Fatdb is not supported. Please rerun with --pruning=archive") + } + } + // forced state db cache size if provided client_config.db_cache_size = self.args.flag_db_cache_size.and_then(|cs| Some(cs / 4)); From 07521c17b4e9b876db9d3a110ce6cf5c5625240e Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 1 Jul 2016 21:33:59 +0300 Subject: [PATCH 33/52] dedicated types --- ethcore/src/client/mod.rs | 4 ++- ethcore/src/error.rs | 17 ++++++++- ethcore/src/types/block_import_error.rs | 44 +++++++++++++++++++++++ ethcore/src/types/mod.rs.in | 2 ++ ethcore/src/types/transaction_import.rs | 46 +++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 ethcore/src/types/block_import_error.rs create mode 100644 ethcore/src/types/transaction_import.rs diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 27a1d3265..e54e8e382 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -49,6 +49,8 @@ use trace::LocalizedTrace; use evm::Factory as EvmFactory; use miner::{TransactionImportResult}; use error::Error as EthError; +pub use block_import_error::BlockImportError; +pub use transaction_import::{TransactionImportResult, TransactionImportError}; /// Options concerning what analytics we run on the call. #[derive(Eq, PartialEq, Default, Clone, Copy, Debug)] @@ -188,7 +190,7 @@ pub trait BlockChainClient : Sync + Send { fn last_hashes(&self) -> LastHashes; /// import transactions from network/other 3rd party - fn import_transactions(&self, transactions: Vec) -> Vec>; + fn import_transactions(&self, transactions: Vec) -> Vec>; /// Queue transactions for importing. fn queue_transactions(&self, transactions: Vec); diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 92d3cbe6b..7460762c2 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -250,7 +250,7 @@ impl fmt::Display for Error { } /// Result of import block operation. -pub type ImportResult = Result; +pub type ImportResult = Result; impl From for Error { fn from(err: ClientError) -> Error { @@ -312,6 +312,21 @@ impl From for Error { } } +impl From for Error { + fn from(err: BlockImportError) -> Error { + match err { + BlockImportError::Block(e) => Error::Block(e), + BlockImportError::Import(e) => Error::Import(e), + BlockImportError::Other(s) => Error::Util(UtilError::SimpleString(s)), + } + } +} + +binary_fixed_size!(BlockError); +binary_fixed_size!(ImportError); +binary_fixed_size!(TransactionError); + + // TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted. /*#![feature(concat_idents)] macro_rules! assimilate { diff --git a/ethcore/src/types/block_import_error.rs b/ethcore/src/types/block_import_error.rs new file mode 100644 index 000000000..8b400613f --- /dev/null +++ b/ethcore/src/types/block_import_error.rs @@ -0,0 +1,44 @@ +// 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 . + +//! Block import error related types + +use std::mem; +use ipc::binary::BinaryConvertError; +use std::collections::VecDeque; +use error::{ImportError, BlockError, Error}; +use std::convert::From; + +/// Error dedicated to import block function +#[derive(Binary, Debug)] +pub enum BlockImportError { + /// Import error + Import(ImportError), + /// Block error + Block(BlockError), + /// Other error + Other(String), +} + +impl From for BlockImportError { + fn from(e: Error) -> Self { + match e { + Error::Block(block_error) => BlockImportError::Block(block_error), + Error::Import(import_error) => BlockImportError::Import(import_error), + _ => BlockImportError::Other(format!("other block import error: {:?}", e)), + } + } +} diff --git a/ethcore/src/types/mod.rs.in b/ethcore/src/types/mod.rs.in index b51e9e57b..97579da8a 100644 --- a/ethcore/src/types/mod.rs.in +++ b/ethcore/src/types/mod.rs.in @@ -25,3 +25,5 @@ pub mod executed; pub mod block_status; pub mod account_diff; pub mod state_diff; +pub mod transaction_import; +pub mod block_import_error; diff --git a/ethcore/src/types/transaction_import.rs b/ethcore/src/types/transaction_import.rs new file mode 100644 index 000000000..78078cfea --- /dev/null +++ b/ethcore/src/types/transaction_import.rs @@ -0,0 +1,46 @@ +// 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 . + +//! Transaction import result related types + +use ipc::binary::BinaryConvertError; +use std::collections::VecDeque; + +#[derive(Debug, Clone, PartialEq)] +/// Represents the result of importing transaction. +pub enum TransactionImportResult { + /// Transaction was imported to current queue. + Current, + /// Transaction was imported to future queue. + Future +} + +binary_fixed_size!(TransactionImportResult); + +#[derive(Debug, Clone, Binary)] +pub enum TransactionImportError { + Transaction(TransactionError), + Other(String), +} + +impl From for BlockImportError { + fn from(e: Error) -> Self { + match e { + Error::Transaction(transaction_error) => TransactionImportError::Transaction(block_error), + _ => TransactionImportError::Other(format!("other block import error: {:?}", e)), + } + } +} From 8102fb9306c927170012fddaa8f568b4c5bd1f04 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 1 Jul 2016 22:37:17 +0400 Subject: [PATCH 34/52] Client api cleaning - uncles are returned as rlp (#1516) * uncle as rlp in the api * uncle rlp in block view * fix warning --- ethcore/src/client/client.rs | 8 ++-- ethcore/src/client/mod.rs | 4 +- ethcore/src/client/test_client.rs | 4 +- ethcore/src/types/ids.rs | 10 ++--- ethcore/src/views/block.rs | 5 +++ rpc/src/v1/impls/eth.rs | 64 +++++++++++++++++-------------- 6 files changed, 53 insertions(+), 42 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index bf1ae7f05..4f17901b7 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -22,7 +22,7 @@ use util::*; use util::panics::*; use views::BlockView; use error::{Error, ImportError, ExecutionError, BlockError, ImportResult}; -use header::{BlockNumber, Header}; +use header::{BlockNumber}; use state::State; use spec::Spec; use engine::Engine; @@ -585,9 +585,9 @@ impl BlockChainClient for Client { self.transaction_address(id).and_then(|address| self.chain.transaction(&address)) } - fn uncle(&self, id: UncleID) -> Option
{ - let index = id.1; - self.block(id.0).and_then(|block| BlockView::new(&block).uncle_at(index)) + fn uncle(&self, id: UncleID) -> Option { + let index = id.position; + self.block(id.block).and_then(|block| BlockView::new(&block).uncle_rlp_at(index)) } fn transaction_receipt(&self, id: TransactionID) -> Option { diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 7f3c3bb3a..27a1d3265 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -38,7 +38,7 @@ use util::Itertools; use blockchain::TreeRoute; use block_queue::BlockQueueInfo; use block::{OpenBlock, SealedBlock}; -use header::{BlockNumber, Header}; +use header::{BlockNumber}; use transaction::{LocalizedTransaction, SignedTransaction}; use log_entry::LocalizedLogEntry; use filter::Filter; @@ -126,7 +126,7 @@ pub trait BlockChainClient : Sync + Send { fn transaction(&self, id: TransactionID) -> Option; /// Get uncle with given id. - fn uncle(&self, id: UncleID) -> Option
; + fn uncle(&self, id: UncleID) -> Option; /// Get transaction receipt with given hash. fn transaction_receipt(&self, id: TransactionID) -> Option; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index f51f978de..be90d9b67 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -244,7 +244,7 @@ impl MiningBlockChainClient for TestBlockChainClient { fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock { unimplemented!(); } - + fn vm_factory(&self) -> &EvmFactory { unimplemented!(); } @@ -298,7 +298,7 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn uncle(&self, _id: UncleID) -> Option { + fn uncle(&self, _id: UncleID) -> Option { unimplemented!(); } diff --git a/ethcore/src/types/ids.rs b/ethcore/src/types/ids.rs index 0a492735c..99dadc4ea 100644 --- a/ethcore/src/types/ids.rs +++ b/ethcore/src/types/ids.rs @@ -55,10 +55,10 @@ pub struct TraceId { } /// Uniquely identifies Uncle. -#[derive(Debug)] -pub struct UncleID ( +#[derive(Debug, Binary)] +pub struct UncleID { /// Block id. - pub BlockID, + pub block: BlockID, /// Position in block. - pub usize -); + pub position: usize +} diff --git a/ethcore/src/views/block.rs b/ethcore/src/views/block.rs index 82b8fb805..42fd52a20 100644 --- a/ethcore/src/views/block.rs +++ b/ethcore/src/views/block.rs @@ -139,6 +139,11 @@ impl<'a> BlockView<'a> { pub fn uncle_at(&self, index: usize) -> Option
{ self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_val()) } + + /// Return nth uncle rlp. + pub fn uncle_rlp_at(&self, index: usize) -> Option { + self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_raw().to_vec()) + } } impl<'a> Hashable for BlockView<'a> { diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 8bfc661e3..f2325de93 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -41,6 +41,7 @@ use v1::traits::Eth; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; use v1::impls::{default_gas_price, dispatch_transaction, error_codes}; use serde; +use ethcore::header::Header as BlockHeader; /// Eth rpc implementation. pub struct EthClient where @@ -126,33 +127,38 @@ impl EthClient where fn uncle(&self, id: UncleID) -> Result { let client = take_weak!(self.client); - match client.uncle(id).and_then(|u| client.block_total_difficulty(BlockID::Hash(u.parent_hash().clone())).map(|diff| (diff, u))) { - Some((parent_difficulty, uncle)) => { - let block = Block { - hash: OptionalValue::Value(uncle.hash()), - parent_hash: uncle.parent_hash, - uncles_hash: uncle.uncles_hash, - author: uncle.author, - miner: uncle.author, - state_root: uncle.state_root, - transactions_root: uncle.transactions_root, - number: OptionalValue::Value(U256::from(uncle.number)), - gas_used: uncle.gas_used, - gas_limit: uncle.gas_limit, - logs_bloom: uncle.log_bloom, - timestamp: U256::from(uncle.timestamp), - difficulty: uncle.difficulty, - total_difficulty: uncle.difficulty + parent_difficulty, - receipts_root: uncle.receipts_root, - extra_data: Bytes::new(uncle.extra_data), - seal_fields: uncle.seal.into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), - uncles: vec![], - transactions: BlockTransactions::Hashes(vec![]), - }; - to_value(&block) - }, - None => Ok(Value::Null) - } + + let uncle: BlockHeader = match client.uncle(id) { + Some(rlp) => decode(&rlp), + None => { return Ok(Value::Null); } + }; + let parent_difficulty = match client.block_total_difficulty(BlockID::Hash(uncle.parent_hash().clone())) { + Some(difficulty) => difficulty, + None => { return Ok(Value::Null); } + }; + + let block = Block { + hash: OptionalValue::Value(uncle.hash()), + parent_hash: uncle.parent_hash, + uncles_hash: uncle.uncles_hash, + author: uncle.author, + miner: uncle.author, + state_root: uncle.state_root, + transactions_root: uncle.transactions_root, + number: OptionalValue::Value(U256::from(uncle.number)), + gas_used: uncle.gas_used, + gas_limit: uncle.gas_limit, + logs_bloom: uncle.log_bloom, + timestamp: U256::from(uncle.timestamp), + difficulty: uncle.difficulty, + total_difficulty: uncle.difficulty + parent_difficulty, + receipts_root: uncle.receipts_root, + extra_data: Bytes::new(uncle.extra_data), + seal_fields: uncle.seal.into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), + uncles: vec![], + transactions: BlockTransactions::Hashes(vec![]), + }; + to_value(&block) } fn sign_call(&self, request: CallRequest) -> Result { @@ -435,12 +441,12 @@ impl Eth for EthClient where fn uncle_by_block_hash_and_index(&self, params: Params) -> Result { from_params::<(H256, Index)>(params) - .and_then(|(hash, index)| self.uncle(UncleID(BlockID::Hash(hash), index.value()))) + .and_then(|(hash, index)| self.uncle(UncleID { block: BlockID::Hash(hash), position: index.value() })) } fn uncle_by_block_number_and_index(&self, params: Params) -> Result { from_params::<(BlockNumber, Index)>(params) - .and_then(|(number, index)| self.uncle(UncleID(number.into(), index.value()))) + .and_then(|(number, index)| self.uncle(UncleID { block: number.into(), position: index.value() })) } fn compilers(&self, params: Params) -> Result { From 789b903de65415baec4a021595f7f9f5573cf9b8 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 1 Jul 2016 22:37:42 +0400 Subject: [PATCH 35/52] bigint tests in targets (#1522) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b7124b2df..d051971bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ env: global: # GH_TOKEN - secure: bumJASbZSU8bxJ0EyPUJmu16AiV9EXOpyOj86Jlq/Ty9CfwGqsSXt96uDyE+OUJf34RUFQMsw0nk37/zC4lcn6kqk2wpuH3N/o85Zo/cVZY/NusBWLQqtT5VbYWsV+u2Ua4Tmmsw8yVYQhYwU2ZOejNpflL+Cs9XGgORp1L+/gMRMC2y5Se6ZhwnKPQlRJ8LGsG1dzjQULxzADIt3/zuspNBS8a2urJwlHfGMkvHDoUWCviP/GXoSqw3TZR7FmKyxE19I8n9+iSvm9+oZZquvcgfUxMHn8Gq/b44UbPvjtFOg2yam4xdWXF/RyWCHdc/R9EHorSABeCbefIsm+zcUF3/YQxwpSxM4IZEeH2rTiC7dcrsKw3XsO16xFQz5YI5Bay+CT/wTdMmJd7DdYz7Dyf+pOvcM9WOf/zorxYWSBOMYy0uzbusU2iyIghQ82s7E/Ahg+WARtPgkuTLSB5aL1oCTBKHqQscMr7lo5Ti6RpWLxEdTQMBznc+bMr+6dEtkEcG9zqc6cE9XX+ox3wTU6+HVMfQ1ltCntJ4UKcw3A6INEbw9wgocQa812CIASQ2fE+SCAbz6JxBjIAlFUnD1lUB7S8PdMPwn9plfQgKQ2A5YZqg6FnBdf0rQXIJYxQWKHXj/rBHSUCT0tHACDlzTA+EwWggvkP5AGIxRxm8jhw= - - TARGETS="-p ethkey -p ethstore -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethjson -p ethcore-dapps -p ethcore-signer" + - TARGETS="-p ethkey -p ethstore -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethjson -p ethcore-dapps -p ethcore-signer -p bigint" - ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}" - KCOV_FEATURES="" - KCOV_CMD="./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /usr/,/.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests,ethstore/tests target/kcov" From d91e8ccd34b2b6938e569ef1c9c25b16f922bc5c Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Fri, 1 Jul 2016 20:38:37 +0200 Subject: [PATCH 36/52] Save the block reference in the queue on notification (#1501) --- ethcore/src/miner/miner.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index d3e32c797..40254b8c2 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -265,6 +265,10 @@ impl Miner { let difficulty = *block.block().fields().header.difficulty(); let is_new = original_work_hash.map_or(true, |h| block.block().fields().header.hash() != h); sealing_work.push(block); + // If push notifications are enabled we assume all work items are used. + if self.work_poster.is_some() && is_new { + sealing_work.use_last_ref(); + } (Some((pow_hash, difficulty, number)), is_new) } else { (None, false) From 46b0af6121f017cef079811f3e168cc078f5c543 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 1 Jul 2016 22:13:56 +0300 Subject: [PATCH 37/52] flush work --- ethcore/src/client/client.rs | 16 +++++++++------- ethcore/src/client/mod.rs | 3 +-- ethcore/src/client/test_client.rs | 8 +++++--- ethcore/src/error.rs | 6 ++++-- ethcore/src/miner/miner.rs | 4 +++- ethcore/src/miner/mod.rs | 3 ++- ethcore/src/miner/transaction_queue.rs | 10 +--------- ethcore/src/types/transaction_import.rs | 8 +++++--- 8 files changed, 30 insertions(+), 28 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 9bfe1758d..655c66fde 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -38,7 +38,9 @@ use filter::Filter; use log_entry::LocalizedLogEntry; use block_queue::{BlockQueue, BlockQueueInfo}; use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute}; -use client::{BlockID, TransactionID, UncleID, TraceId, ClientConfig, DatabaseCompactionProfile, BlockChainClient, MiningBlockChainClient, TraceFilter, CallAnalytics}; +use client::{BlockID, TransactionID, UncleID, TraceId, ClientConfig, DatabaseCompactionProfile, + BlockChainClient, MiningBlockChainClient, TraceFilter, CallAnalytics, TransactionImportError, + BlockImportError, TransactionImportResult}; use client::Error as ClientError; use env_info::EnvInfo; use executive::{Executive, Executed, TransactOptions, contract_address}; @@ -49,7 +51,7 @@ use trace; pub use types::blockchain_info::BlockChainInfo; pub use types::block_status::BlockStatus; use evm::Factory as EvmFactory; -use miner::{Miner, MinerService, TransactionImportResult, AccountDetails}; +use miner::{Miner, MinerService, AccountDetails}; const MAX_TX_QUEUE_SIZE: usize = 4096; @@ -648,17 +650,17 @@ impl BlockChainClient for Client { self.chain.block_receipts(hash).map(|receipts| rlp::encode(&receipts).to_vec()) } - fn import_block(&self, bytes: Bytes) -> ImportResult { + fn import_block(&self, bytes: Bytes) -> Result { { let header = BlockView::new(&bytes).header_view(); if self.chain.is_known(&header.sha3()) { - return Err(ImportError::AlreadyInChain.into()); + return Err(BlockImportError::Import(ImportError::AlreadyInChain)); } if self.block_status(BlockID::Hash(header.parent_hash())) == BlockStatus::Unknown { - return Err(BlockError::UnknownParent(header.parent_hash()).into()); + return Err(BlockImportError::Block(BlockError::UnknownParent(header.parent_hash()))); } } - self.block_queue.import_block(bytes) + Ok(try!(self.block_queue.import_block(bytes))) } fn queue_info(&self) -> BlockQueueInfo { @@ -772,7 +774,7 @@ impl BlockChainClient for Client { self.build_last_hashes(self.chain.best_block_hash()) } - fn import_transactions(&self, transactions: Vec) -> Vec> { + fn import_transactions(&self, transactions: Vec) -> Vec> { let fetch_account = |a: &Address| AccountDetails { nonce: self.latest_nonce(a), balance: self.latest_balance(a), diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index e54e8e382..54d38b034 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -47,7 +47,6 @@ use error::{ImportResult, ExecutionError}; use receipt::LocalizedReceipt; use trace::LocalizedTrace; use evm::Factory as EvmFactory; -use miner::{TransactionImportResult}; use error::Error as EthError; pub use block_import_error::BlockImportError; pub use transaction_import::{TransactionImportResult, TransactionImportError}; @@ -147,7 +146,7 @@ pub trait BlockChainClient : Sync + Send { fn block_receipts(&self, hash: &H256) -> Option; /// Import a block into the blockchain. - fn import_block(&self, bytes: Bytes) -> ImportResult; + fn import_block(&self, bytes: Bytes) -> Result; /// Get block queue information. fn queue_info(&self) -> BlockQueueInfo; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index be90d9b67..0ce308a30 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -20,7 +20,9 @@ use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder}; use util::*; use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action}; use blockchain::TreeRoute; -use client::{BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockID, TransactionID, UncleID, TraceId, TraceFilter, LastHashes, CallAnalytics}; +use client::{BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockID, + TransactionID, UncleID, TraceId, TraceFilter, LastHashes, CallAnalytics, + TransactionImportError, BlockImportError}; use header::{Header as BlockHeader, BlockNumber}; use filter::Filter; use log_entry::LocalizedLogEntry; @@ -402,7 +404,7 @@ impl BlockChainClient for TestBlockChainClient { None } - fn import_block(&self, b: Bytes) -> ImportResult { + fn import_block(&self, b: Bytes) -> Result { let header = Rlp::new(&b).val_at::(0); let h = header.hash(); let number: usize = header.number as usize; @@ -487,7 +489,7 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn import_transactions(&self, transactions: Vec) -> Vec> { + fn import_transactions(&self, transactions: Vec) -> Vec> { let nonces = self.nonces.read().unwrap(); let balances = self.balances.read().unwrap(); let fetch_account = |a: &Address| AccountDetails { diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 7460762c2..cfe6b3679 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -20,8 +20,10 @@ use util::*; use header::BlockNumber; use basic_types::LogBloom; use client::Error as ClientError; - pub use types::executed::ExecutionError; +use ipc::binary::{BinaryConvertError, BinaryConvertable}; +use types::transaction_import::TransactionImportError; +use types::block_import_error::BlockImportError; #[derive(Debug, PartialEq)] /// Errors concerning transaction processing. @@ -250,7 +252,7 @@ impl fmt::Display for Error { } /// Result of import block operation. -pub type ImportResult = Result; +pub type ImportResult = Result; impl From for Error { fn from(err: ClientError) -> Error { diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index d3e32c797..fe1877116 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -29,8 +29,10 @@ use transaction::SignedTransaction; use receipt::{Receipt}; use spec::Spec; use engine::Engine; -use miner::{MinerService, MinerStatus, TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin}; +use miner::{MinerService, MinerStatus, TransactionQueue, AccountDetails, TransactionOrigin}; use miner::work_notify::WorkPoster; +use client::TransactionImportResult; + /// Different possible definitions for pending transaction set. #[derive(Debug)] diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 152bd1a61..3d0185753 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -47,9 +47,10 @@ mod external; mod transaction_queue; mod work_notify; -pub use self::transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin}; +pub use self::transaction_queue::{TransactionQueue, AccountDetails, TransactionOrigin}; pub use self::miner::{Miner, MinerOptions, PendingSet}; pub use self::external::{ExternalMiner, ExternalMinerService}; +pub use client::TransactionImportResult; use std::collections::BTreeMap; use util::{H256, U256, Address, Bytes}; diff --git a/ethcore/src/miner/transaction_queue.rs b/ethcore/src/miner/transaction_queue.rs index 7f5b59c38..fde8b67d8 100644 --- a/ethcore/src/miner/transaction_queue.rs +++ b/ethcore/src/miner/transaction_queue.rs @@ -90,6 +90,7 @@ use util::hash::{Address, H256}; use util::table::*; use transaction::*; use error::{Error, TransactionError}; +use client::TransactionImportResult; /// Transaction origin #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -309,15 +310,6 @@ pub struct TransactionQueueStatus { pub future: usize, } -#[derive(Debug, PartialEq)] -/// Represents the result of importing transaction. -pub enum TransactionImportResult { - /// Transaction was imported to current queue. - Current, - /// Transaction was imported to future queue. - Future -} - /// Details of account pub struct AccountDetails { /// Most recent account nonce diff --git a/ethcore/src/types/transaction_import.rs b/ethcore/src/types/transaction_import.rs index 78078cfea..fa7455cfd 100644 --- a/ethcore/src/types/transaction_import.rs +++ b/ethcore/src/types/transaction_import.rs @@ -16,8 +16,10 @@ //! Transaction import result related types -use ipc::binary::BinaryConvertError; +use ipc::binary::{BinaryConvertError, BinaryConvertable}; use std::collections::VecDeque; +use error::{TransactionError, Error}; +use std::mem; #[derive(Debug, Clone, PartialEq)] /// Represents the result of importing transaction. @@ -36,10 +38,10 @@ pub enum TransactionImportError { Other(String), } -impl From for BlockImportError { +impl From for TransactionImportError { fn from(e: Error) -> Self { match e { - Error::Transaction(transaction_error) => TransactionImportError::Transaction(block_error), + Error::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error), _ => TransactionImportError::Other(format!("other block import error: {:?}", e)), } } From fa73ae17d960dec6f72afa63f6fc0c94d27452b8 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 1 Jul 2016 23:27:50 +0400 Subject: [PATCH 38/52] BTreeMap binary serialization (#1489) * btree map serializer * serde tests * fix styling --- ipc/rpc/src/binary.rs | 103 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/ipc/rpc/src/binary.rs b/ipc/rpc/src/binary.rs index 62a3c43b0..f33d640f4 100644 --- a/ipc/rpc/src/binary.rs +++ b/ipc/rpc/src/binary.rs @@ -19,7 +19,7 @@ use util::bytes::Populatable; use util::numbers::{U256, U512, H256, H2048, Address}; use std::mem; -use std::collections::VecDeque; +use std::collections::{VecDeque, BTreeMap}; use std::ops::Range; #[derive(Debug)] @@ -139,6 +139,92 @@ impl BinaryConvertable for Result BinaryConvertable for BTreeMap where K : BinaryConvertable + Ord, V: BinaryConvertable { + fn size(&self) -> usize { + 0usize + match K::len_params() { + 0 => mem::size_of::() * self.len(), + _ => self.iter().fold(0usize, |acc, (k, _)| acc + k.size()) + } + match V::len_params() { + 0 => mem::size_of::() * self.len(), + _ => self.iter().fold(0usize, |acc, (_, v)| acc + v.size()) + } + } + + fn to_bytes(&self, buffer: &mut [u8], length_stack: &mut VecDeque) -> Result<(), BinaryConvertError> { + let mut offset = 0usize; + for (key, val) in self.iter() { + let key_size = match K::len_params() { + 0 => mem::size_of::(), + _ => { let size = key.size(); length_stack.push_back(size); size } + }; + let val_size = match K::len_params() { + 0 => mem::size_of::(), + _ => { let size = val.size(); length_stack.push_back(size); size } + }; + + if key_size > 0 { + let item_end = offset + key_size; + try!(key.to_bytes(&mut buffer[offset..item_end], length_stack)); + offset = item_end; + } + + if val_size > 0 { + let item_end = offset + key_size; + try!(val.to_bytes(&mut buffer[offset..item_end], length_stack)); + offset = item_end; + } + } + Ok(()) + } + + fn from_bytes(buffer: &[u8], length_stack: &mut VecDeque) -> Result { + let mut index = 0; + let mut result = Self::new(); + + if buffer.len() == 0 { return Ok(result); } + + loop { + let key_size = match K::len_params() { + 0 => mem::size_of::(), + _ => try!(length_stack.pop_front().ok_or(BinaryConvertError)), + }; + let key = if key_size == 0 { + try!(K::from_empty_bytes()) + } else { + try!(K::from_bytes(&buffer[index..index+key_size], length_stack)) + }; + index = index + key_size; + + let val_size = match V::len_params() { + 0 => mem::size_of::(), + _ => try!(length_stack.pop_front().ok_or(BinaryConvertError)), + }; + let val = if val_size == 0 { + try!(V::from_empty_bytes()) + } else { + try!(V::from_bytes(&buffer[index..index+val_size], length_stack)) + }; + result.insert(key, val); + index = index + val_size; + + if index == buffer.len() { break; } + if index > buffer.len() { + return Err(BinaryConvertError) + } + } + + Ok(result) + } + + fn from_empty_bytes() -> Result { + Ok(Self::new()) + } + + fn len_params() -> usize { + 1 + } +} + impl BinaryConvertable for Vec where T: BinaryConvertable { fn size(&self) -> usize { match T::len_params() { @@ -652,3 +738,18 @@ fn serialize_err_opt_vec_in_out() { assert!(vec.is_ok()); } + +#[test] +fn serialize_btree() { + use std::io::{Cursor, SeekFrom, Seek}; + + let mut buff = Cursor::new(Vec::new()); + let mut btree = BTreeMap::new(); + btree.insert(1u64, 5u64); + serialize_into(&btree, &mut buff).unwrap(); + + buff.seek(SeekFrom::Start(0)).unwrap(); + let res = deserialize_from::, _>(&mut buff).unwrap(); + + assert_eq!(res[&1u64], 5u64); +} From edb86631954a18a810ca4ddeee5ee415cb9aab72 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 1 Jul 2016 22:34:50 +0300 Subject: [PATCH 39/52] ethcore finished --- ethcore/src/client/client.rs | 8 ++++++-- ethcore/src/client/mod.rs | 1 - ethcore/src/client/test_client.rs | 4 +++- ethcore/src/error.rs | 3 +-- ethcore/src/types/transaction_import.rs | 4 ++++ util/src/error.rs | 2 +- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 655c66fde..522f1c457 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -21,7 +21,7 @@ use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use util::*; use util::panics::*; use views::BlockView; -use error::{Error, ImportError, ExecutionError, BlockError, ImportResult}; +use error::{ImportError, ExecutionError, BlockError, ImportResult}; use header::{BlockNumber}; use state::State; use spec::Spec; @@ -779,7 +779,11 @@ impl BlockChainClient for Client { nonce: self.latest_nonce(a), balance: self.latest_balance(a), }; - self.miner.import_transactions(self, transactions, fetch_account) + + self.miner.import_transactions(self, transactions, &fetch_account) + .into_iter() + .map(|res| res.map_err(|e| e.into())) + .collect() } fn queue_transactions(&self, transactions: Vec) { diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 54d38b034..c09da450d 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -47,7 +47,6 @@ use error::{ImportResult, ExecutionError}; use receipt::LocalizedReceipt; use trace::LocalizedTrace; use evm::Factory as EvmFactory; -use error::Error as EthError; pub use block_import_error::BlockImportError; pub use transaction_import::{TransactionImportResult, TransactionImportError}; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 0ce308a30..1e51719c0 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -40,7 +40,6 @@ use error::{ExecutionError}; use trace::LocalizedTrace; use miner::{TransactionImportResult, AccountDetails}; -use error::Error as EthError; /// Test client. pub struct TestBlockChainClient { @@ -498,6 +497,9 @@ impl BlockChainClient for TestBlockChainClient { }; self.miner.import_transactions(self, transactions, &fetch_account) + .into_iter() + .map(|res| res.map_err(|e| e.into())) + .collect() } fn queue_transactions(&self, transactions: Vec) { diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index cfe6b3679..8c37e98ef 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -22,10 +22,9 @@ use basic_types::LogBloom; use client::Error as ClientError; pub use types::executed::ExecutionError; use ipc::binary::{BinaryConvertError, BinaryConvertable}; -use types::transaction_import::TransactionImportError; use types::block_import_error::BlockImportError; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] /// Errors concerning transaction processing. pub enum TransactionError { /// Transaction is already imported to the queue diff --git a/ethcore/src/types/transaction_import.rs b/ethcore/src/types/transaction_import.rs index fa7455cfd..c52a9fb80 100644 --- a/ethcore/src/types/transaction_import.rs +++ b/ethcore/src/types/transaction_import.rs @@ -20,6 +20,7 @@ use ipc::binary::{BinaryConvertError, BinaryConvertable}; use std::collections::VecDeque; use error::{TransactionError, Error}; use std::mem; +use util::Populatable; #[derive(Debug, Clone, PartialEq)] /// Represents the result of importing transaction. @@ -32,9 +33,12 @@ pub enum TransactionImportResult { binary_fixed_size!(TransactionImportResult); +/// Api-level error for transaction import #[derive(Debug, Clone, Binary)] pub enum TransactionImportError { + /// Transaction error Transaction(TransactionError), + /// Other error Other(String), } diff --git a/util/src/error.rs b/util/src/error.rs index 5e9f8e7a8..c5f40d717 100644 --- a/util/src/error.rs +++ b/util/src/error.rs @@ -101,7 +101,7 @@ impl fmt::Display for Mismatch { } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Clone)] /// Error indicating value found is outside of a valid range. pub struct OutOfBounds { /// Minimum allowed value. From 0f7b66f5573a2fbd99fb1ad33470a687ca5f0326 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Fri, 1 Jul 2016 22:40:54 +0300 Subject: [PATCH 40/52] fixed compilation & warnings --- parity/main.rs | 6 +++--- sync/src/chain.rs | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index d466987ef..8d46d28e5 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -82,8 +82,8 @@ use rustc_serialize::hex::FromHex; use ctrlc::CtrlC; use util::{H256, ToPretty, NetworkConfiguration, PayloadInfo, Bytes, UtilError, paint, Colour, version}; use util::panics::{MayPanic, ForwardPanic, PanicHandler}; -use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path}; -use ethcore::error::{Error, ImportError}; +use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path, BlockImportError}; +use ethcore::error::{ImportError}; use ethcore::service::ClientService; use ethcore::spec::Spec; use ethsync::EthSync; @@ -465,7 +465,7 @@ fn execute_import(conf: Configuration) { while client.queue_info().is_full() { sleep(Duration::from_secs(1)); } match client.import_block(bytes) { Ok(_) => {} - Err(Error::Import(ImportError::AlreadyInChain)) => { trace!("Skipping block already in chain."); } + Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { trace!("Skipping block already in chain."); } Err(e) => die!("Cannot import block: {:?}", e) } informant.tick(client.deref(), None); diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 1897b02f4..6845c32e3 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -93,7 +93,7 @@ use util::*; use std::mem::{replace}; use ethcore::views::{HeaderView, BlockView}; use ethcore::header::{BlockNumber, Header as BlockHeader}; -use ethcore::client::{BlockChainClient, BlockStatus, BlockID, BlockChainInfo}; +use ethcore::client::{BlockChainClient, BlockStatus, BlockID, BlockChainInfo, BlockImportError}; use ethcore::error::*; use ethcore::block::Block; use io::SyncIo; @@ -544,10 +544,10 @@ impl ChainSync { peer.latest_number = Some(header.number()); } match io.chain().import_block(block_rlp.as_raw().to_vec()) { - Err(Error::Import(ImportError::AlreadyInChain)) => { + Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { trace!(target: "sync", "New block already in chain {:?}", h); }, - Err(Error::Import(ImportError::AlreadyQueued)) => { + Err(BlockImportError::Import(ImportError::AlreadyQueued)) => { trace!(target: "sync", "New block already queued {:?}", h); }, Ok(_) => { @@ -557,7 +557,7 @@ impl ChainSync { } trace!(target: "sync", "New block queued {:?} ({})", h, header.number); }, - Err(Error::Block(BlockError::UnknownParent(p))) => { + Err(BlockImportError::Block(BlockError::UnknownParent(p))) => { unknown = true; trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h); }, @@ -841,11 +841,11 @@ impl ChainSync { } match io.chain().import_block(block) { - Err(Error::Import(ImportError::AlreadyInChain)) => { + Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { trace!(target: "sync", "Block already in chain {:?}", h); self.block_imported(&h, number, &parent); }, - Err(Error::Import(ImportError::AlreadyQueued)) => { + Err(BlockImportError::Import(ImportError::AlreadyQueued)) => { trace!(target: "sync", "Block already queued {:?}", h); self.block_imported(&h, number, &parent); }, @@ -854,7 +854,7 @@ impl ChainSync { imported.insert(h.clone()); self.block_imported(&h, number, &parent); }, - Err(Error::Block(BlockError::UnknownParent(_))) if self.state == SyncState::NewBlocks => { + Err(BlockImportError::Block(BlockError::UnknownParent(_))) if self.state == SyncState::NewBlocks => { trace!(target: "sync", "Unknown new block parent, restarting sync"); break; }, From 316fae2cc4b9e6e373a7e97cd35f58f417422cd7 Mon Sep 17 00:00:00 2001 From: petevine Date: Sat, 2 Jul 2016 07:58:32 +0200 Subject: [PATCH 41/52] Fix error message. (#1527) --- parity/configuration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/configuration.rs b/parity/configuration.rs index 96524f5ea..dfa135dd6 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -348,7 +348,7 @@ impl Configuration { client_config.db_compaction = match self.args.flag_db_compaction.as_str() { "ssd" => DatabaseCompactionProfile::Default, "hdd" => DatabaseCompactionProfile::HDD, - _ => { die!("Invalid compaction profile given (--db-compaction argument), expected hdd/default."); } + _ => { die!("Invalid compaction profile given (--db-compaction argument), expected hdd/ssd (default)."); } }; if self.args.flag_jitvm { From 8e98f06ce5ee38f2b816ab3d3d215a04a3f51903 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Sat, 2 Jul 2016 02:15:44 -0700 Subject: [PATCH 42/52] Fix gitter-url link in README.md (#1528) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53212b229..d605fa87c 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ This includes a few useful Dapps, including Ethereum Wallet, Maker OTC, and a no In a near-future release, it will be easy to install Dapps and use them through this web interface. If you run into an issue while using parity, feel free to file one in this repository -or hop on our [gitter chat room]([gitter-url]) to ask a question. We are glad to help! +or hop on our [gitter chat room][gitter-url] to ask a question. We are glad to help! Parity's current release is 1.2. You can download it at https://ethcore.io/parity.html or follow the instructions below to build from source. From ff7fcd09923a933818f50d6f985a34040337f7bf Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sat, 2 Jul 2016 13:16:31 +0400 Subject: [PATCH 43/52] add client timeout (#1526) --- parity/price_info.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/parity/price_info.rs b/parity/price_info.rs index ad25f31da..0c04b3a77 100644 --- a/parity/price_info.rs +++ b/parity/price_info.rs @@ -28,10 +28,12 @@ impl PriceInfo { pub fn get() -> Option { let mut body = String::new(); // TODO: Handle each error type properly - Client::new() - .get("http://api.etherscan.io/api?module=stats&action=ethprice") + let mut client = Client::new(); + client.set_read_timeout(Some(::std::time::Duration::from_secs(3))); + client.get("http://api.etherscan.io/api?module=stats&action=ethprice") .header(Connection::close()) - .send().ok() + .send() + .ok() .and_then(|mut s| s.read_to_string(&mut body).ok()) .and_then(|_| Json::from_str(&body).ok()) .and_then(|json| json.find_path(&["result", "ethusd"]) From 8f6e48e4c3f1cf3e077dcebcab7eff06e1a90341 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Sat, 2 Jul 2016 20:08:52 +0300 Subject: [PATCH 44/52] fix tests --- ethcore/src/miner/transaction_queue.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ethcore/src/miner/transaction_queue.rs b/ethcore/src/miner/transaction_queue.rs index fde8b67d8..0e71b1d83 100644 --- a/ethcore/src/miner/transaction_queue.rs +++ b/ethcore/src/miner/transaction_queue.rs @@ -804,6 +804,7 @@ mod test { use error::{Error, TransactionError}; use super::*; use super::{TransactionSet, TransactionOrder, VerifiedTransaction}; + use client::TransactionImportResult; fn unwrap_tx_err(err: Result) -> TransactionError { match err.unwrap_err() { From 1aee197d79cbd6df840efcc4162dcf637f963df1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 3 Jul 2016 17:11:31 +0100 Subject: [PATCH 45/52] Make signer default as long as --unlock isn't used. (#1524) --- parity/cli.rs | 23 ++++++++++------------- parity/configuration.rs | 4 ++-- parity/main.rs | 7 ------- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/parity/cli.rs b/parity/cli.rs index ef9ce8ce3..17954eb2a 100644 --- a/parity/cli.rs +++ b/parity/cli.rs @@ -52,12 +52,21 @@ Protocol Options: Account Options: --unlock ACCOUNTS Unlock ACCOUNTS for the duration of the execution. ACCOUNTS is a comma-delimited list of addresses. + Implies --no-signer. --password FILE Provide a file containing a password for unlocking an account. --keys-iterations NUM Specify the number of iterations to use when deriving key from the password (bigger is more secure) [default: 10240]. --no-import-keys Do not import keys from legacy clients. + --force-signer Enable Trusted Signer WebSocket endpoint used by + Signer UIs, even when --unlock is in use. + --no-signer Disable Trusted Signer WebSocket endpoint used by + Signer UIs. + --signer-port PORT Specify the port of Trusted Signer server + [default: 8180]. + --signer-path PATH Specify directory where Signer UIs tokens should + be stored. [default: $HOME/.parity/signer] Networking Options: --no-network Disable p2p networking. @@ -114,17 +123,6 @@ API and Console Options: --dapps-path PATH Specify directory where dapps should be installed. [default: $HOME/.parity/dapps] - --signer Enable Trusted Signer WebSocket endpoint used by - Signer UIs. Default if run with ui command. - --no-signer Disable Trusted Signer WebSocket endpoint used by - Signer UIs. Default if no command is specified. - --signer-port PORT Specify the port of Trusted Signer server - [default: 8180]. - --signer-path PATH Specify directory where Signer UIs tokens should - be stored. [default: $HOME/.parity/signer] - --no-token By default a new system UI security token will be - output on start up. This will prevent it. - Sealing/Mining Options: --author ADDRESS Specify the block author (aka "coinbase") address for sending block rewards from sealed blocks. @@ -309,11 +307,10 @@ pub struct Args { pub flag_dapps_user: Option, pub flag_dapps_pass: Option, pub flag_dapps_path: String, - pub flag_signer: bool, + pub flag_force_signer: bool, pub flag_no_signer: bool, pub flag_signer_port: u16, pub flag_signer_path: String, - pub flag_no_token: bool, pub flag_force_sealing: bool, pub flag_reseal_on_txs: String, pub flag_reseal_min_period: u64, diff --git a/parity/configuration.rs b/parity/configuration.rs index dfa135dd6..195f1e0c3 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -539,8 +539,8 @@ impl Configuration { } pub fn signer_enabled(&self) -> bool { - (self.args.cmd_ui && !self.args.flag_no_signer) || - (!self.args.cmd_ui && self.args.flag_signer) + (self.args.flag_unlock.is_none() && !self.args.flag_no_signer) || + self.args.flag_force_signer } } diff --git a/parity/main.rs b/parity/main.rs index d466987ef..841261dd0 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -193,13 +193,6 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) let net_settings = conf.net_settings(&spec); let sync_config = conf.sync_config(&spec); - // Create and display a new token for UIs. - if conf.signer_enabled() && !conf.args.flag_no_token { - new_token(conf.directories().signer).unwrap_or_else(|e| { - die!("Error generating token: {:?}", e) - }); - } - // Display warning about using unlock with signer if conf.signer_enabled() && conf.args.flag_unlock.is_some() { warn!("Using Trusted Signer and --unlock is not recommended!"); From 5c438cc58a06ef447431023ade424dbec96280d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 4 Jul 2016 05:52:59 -0400 Subject: [PATCH 46/52] Bumping clippy (#1532) --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 2 +- dapps/Cargo.toml | 2 +- db/Cargo.toml | 2 +- ethcore/Cargo.toml | 2 +- json/Cargo.toml | 2 +- rpc/Cargo.toml | 2 +- signer/Cargo.toml | 2 +- sync/Cargo.toml | 2 +- util/Cargo.toml | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6faa0cf32..8fdbfa351 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "parity" version = "1.3.0" dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)", "daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -129,15 +129,15 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.77" +version = "0.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clippy_lints 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy_lints" -version = "0.0.77" +version = "0.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -250,7 +250,7 @@ name = "ethcore" version = "1.3.0" dependencies = [ "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.78 (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)", "ethash 1.3.0", @@ -276,7 +276,7 @@ dependencies = [ name = "ethcore-dapps" version = "1.3.0" dependencies = [ - "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.3.0", "ethcore-util 1.3.0", "hyper 0.9.4 (git+https://github.com/ethcore/hyper)", @@ -338,7 +338,7 @@ dependencies = [ name = "ethcore-rpc" version = "1.3.0" dependencies = [ - "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "ethash 1.3.0", "ethcore 1.3.0", "ethcore-devtools 1.3.0", @@ -361,7 +361,7 @@ dependencies = [ name = "ethcore-signer" version = "1.3.0" dependencies = [ - "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-rpc 1.3.0", "ethcore-util 1.3.0", @@ -381,7 +381,7 @@ dependencies = [ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "bigint 0.1.0", "chrono 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -453,7 +453,7 @@ dependencies = [ name = "ethsync" version = "1.3.0" dependencies = [ - "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.3.0", "ethcore-util 1.3.0", diff --git a/Cargo.toml b/Cargo.toml index 9493af006..e49c3efc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ fdlimit = { path = "util/fdlimit" } num_cpus = "0.2" number_prefix = "0.2" rpassword = "0.2.1" -clippy = { version = "0.0.77", optional = true} +clippy = { version = "0.0.78", optional = true} ethcore = { path = "ethcore" } ethcore-util = { path = "util" } ethsync = { path = "sync" } diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index d33bd6702..94af56ca3 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -28,7 +28,7 @@ parity-dapps-wallet = { git = "https://github.com/ethcore/parity-dapps-wallet-rs parity-dapps-dao = { git = "https://github.com/ethcore/parity-dapps-dao-rs.git", version = "0.4.0", optional = true } parity-dapps-makerotc = { git = "https://github.com/ethcore/parity-dapps-makerotc-rs.git", version = "0.3.0", optional = true } mime_guess = { version = "1.6.1" } -clippy = { version = "0.0.77", optional = true} +clippy = { version = "0.0.78", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } diff --git a/db/Cargo.toml b/db/Cargo.toml index 2f5f0254e..92bc8282c 100644 --- a/db/Cargo.toml +++ b/db/Cargo.toml @@ -12,7 +12,7 @@ syntex = "*" ethcore-ipc-codegen = { path = "../ipc/codegen" } [dependencies] -clippy = { version = "0.0.77", optional = true} +clippy = { version = "0.0.78", optional = true} ethcore-devtools = { path = "../devtools" } ethcore-ipc = { path = "../ipc/rpc" } rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" } diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 2d94aebab..0ea0023d6 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -22,7 +22,7 @@ ethcore-util = { path = "../util" } evmjit = { path = "../evmjit", optional = true } ethash = { path = "../ethash" } num_cpus = "0.2" -clippy = { version = "0.0.77", optional = true} +clippy = { version = "0.0.78", optional = true} crossbeam = "0.2.9" lazy_static = "0.2" ethcore-devtools = { path = "../devtools" } diff --git a/json/Cargo.toml b/json/Cargo.toml index e93f493e1..591d3969f 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -10,7 +10,7 @@ rustc-serialize = "0.3" serde = "0.7.0" serde_json = "0.7.0" serde_macros = { version = "0.7.0", optional = true } -clippy = { version = "0.0.77", optional = true} +clippy = { version = "0.0.78", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 21a59ad50..7550adb84 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -23,7 +23,7 @@ ethcore-devtools = { path = "../devtools" } rustc-serialize = "0.3" transient-hashmap = "0.1" serde_macros = { version = "0.7.0", optional = true } -clippy = { version = "0.0.77", optional = true} +clippy = { version = "0.0.78", optional = true} json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" } [build-dependencies] diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 4ef8bb03e..5e59d04a7 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -20,7 +20,7 @@ ethcore-util = { path = "../util" } ethcore-rpc = { path = "../rpc" } parity-minimal-sysui = { git = "https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git", version = "0.2.0" } -clippy = { version = "0.0.77", optional = true} +clippy = { version = "0.0.78", optional = true} [features] dev = ["clippy"] diff --git a/sync/Cargo.toml b/sync/Cargo.toml index 10edcd0ed..1cf9d21a4 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -10,7 +10,7 @@ authors = ["Ethcore Date: Mon, 4 Jul 2016 13:53:21 +0400 Subject: [PATCH 47/52] creating ethereum dir while in geth mode (#1530) * creating ethereum dir while in geth mode * fix warning * more descriptive error --- parity/configuration.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/parity/configuration.rs b/parity/configuration.rs index 195f1e0c3..78c4b286a 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -475,6 +475,11 @@ impl Configuration { let signer_path = Configuration::replace_home(&self.args.flag_signer_path); ::std::fs::create_dir_all(&signer_path).unwrap_or_else(|e| die_with_io_error("main", e)); + if self.args.flag_geth { + let geth_path = path::ethereum::default(); + ::std::fs::create_dir_all(geth_path.as_path()).unwrap_or_else( + |e| die!("Error while attempting to create '{}' for geth mode: {}", &geth_path.to_str().unwrap(), e)); + } Directories { keys: keys_path, From bb2a6318851339a391ae12079fee3185b73c558d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 4 Jul 2016 07:53:55 -0400 Subject: [PATCH 48/52] Fixing compilation&clippy warnings (#1531) * Fixing compilation&clippy warnings * Adding spaces --- util/src/trie/fatdb.rs | 3 ++- util/src/trie/fatdbmut.rs | 3 ++- util/src/trie/mod.rs | 1 + util/src/trie/sectriedb.rs | 4 ++-- util/src/trie/sectriedbmut.rs | 3 ++- util/src/trie/triedb.rs | 4 ++-- util/src/trie/triedbmut.rs | 2 +- util/src/trie/trietraits.rs | 5 ++++- 8 files changed, 16 insertions(+), 9 deletions(-) diff --git a/util/src/trie/fatdb.rs b/util/src/trie/fatdb.rs index 555e4644f..cc5786f43 100644 --- a/util/src/trie/fatdb.rs +++ b/util/src/trie/fatdb.rs @@ -18,6 +18,7 @@ use hash::H256; use sha3::Hashable; use hashdb::HashDB; use super::{TrieDB, Trie, TrieDBIterator, TrieError}; +use trie::trietraits::TrieItem; /// A `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. /// Additionaly it stores inserted hash-key mappings for later retrieval. @@ -51,7 +52,7 @@ impl<'db> FatDB<'db> { } impl<'db> Trie for FatDB<'db> { - fn iter<'a>(&'a self) -> Box, &[u8])> + 'a> { + fn iter<'a>(&'a self) -> Box + 'a> { Box::new(FatDB::iter(self)) } diff --git a/util/src/trie/fatdbmut.rs b/util/src/trie/fatdbmut.rs index 3e72c0653..e07ee0ed1 100644 --- a/util/src/trie/fatdbmut.rs +++ b/util/src/trie/fatdbmut.rs @@ -17,7 +17,7 @@ use hash::H256; use sha3::Hashable; use hashdb::HashDB; -use super::{TrieDBMut, Trie, TrieMut, TrieError}; +use super::{TrieDBMut, TrieMut, TrieError}; /// A mutable `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. /// Additionaly it stores inserted hash-key mappings for later retrieval. @@ -82,6 +82,7 @@ impl<'db> TrieMut for FatDBMut<'db> { fn fatdb_to_trie() { use memorydb::MemoryDB; use super::TrieDB; + use super::Trie; let mut memdb = MemoryDB::new(); let mut root = H256::default(); diff --git a/util/src/trie/mod.rs b/util/src/trie/mod.rs index f6e731370..2843932a7 100644 --- a/util/src/trie/mod.rs +++ b/util/src/trie/mod.rs @@ -86,6 +86,7 @@ pub struct TrieFactory { spec: TrieSpec, } +#[cfg_attr(feature="dev", allow(wrong_self_convention))] impl TrieFactory { /// Creates new factory. pub fn new(spec: TrieSpec) -> Self { diff --git a/util/src/trie/sectriedb.rs b/util/src/trie/sectriedb.rs index 99770e382..9217fb4fc 100644 --- a/util/src/trie/sectriedb.rs +++ b/util/src/trie/sectriedb.rs @@ -18,7 +18,7 @@ use hash::H256; use sha3::Hashable; use hashdb::HashDB; use super::triedb::TrieDB; -use super::trietraits::Trie; +use super::trietraits::{Trie, TrieItem}; use super::TrieError; /// A `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. @@ -50,7 +50,7 @@ impl<'db> SecTrieDB<'db> { } impl<'db> Trie for SecTrieDB<'db> { - fn iter<'a>(&'a self) -> Box, &[u8])> + 'a> { + fn iter<'a>(&'a self) -> Box + 'a> { Box::new(TrieDB::iter(&self.raw)) } diff --git a/util/src/trie/sectriedbmut.rs b/util/src/trie/sectriedbmut.rs index 09ff48f7a..243e5dec8 100644 --- a/util/src/trie/sectriedbmut.rs +++ b/util/src/trie/sectriedbmut.rs @@ -18,7 +18,7 @@ use hash::H256; use sha3::Hashable; use hashdb::HashDB; use super::triedbmut::TrieDBMut; -use super::trietraits::{Trie, TrieMut}; +use super::trietraits::TrieMut; use super::TrieError; /// A mutable `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. @@ -74,6 +74,7 @@ impl<'db> TrieMut for SecTrieDBMut<'db> { fn sectrie_to_trie() { use memorydb::*; use super::triedb::*; + use super::Trie; let mut memdb = MemoryDB::new(); let mut root = H256::default(); diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index c88ec422e..e938fcc64 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -18,7 +18,7 @@ use common::*; use hashdb::*; use nibbleslice::*; use rlp::*; -use super::trietraits::{Trie}; +use super::trietraits::{Trie, TrieItem}; use super::node::Node; use super::TrieError; @@ -337,7 +337,7 @@ impl<'db> TrieDB<'db> { } impl<'db> Trie for TrieDB<'db> { - fn iter<'a>(&'a self) -> Box, &[u8])> + 'a> { + fn iter<'a>(&'a self) -> Box + 'a> { Box::new(TrieDB::iter(self)) } diff --git a/util/src/trie/triedbmut.rs b/util/src/trie/triedbmut.rs index 6d34096fc..4d46814c0 100644 --- a/util/src/trie/triedbmut.rs +++ b/util/src/trie/triedbmut.rs @@ -20,7 +20,7 @@ use nibbleslice::*; use rlp::*; use super::node::Node; use super::journal::Journal; -use super::trietraits::{Trie, TrieMut}; +use super::trietraits::TrieMut; use super::TrieError; /// A `Trie` implementation using a generic `HashDB` backing database. diff --git a/util/src/trie/trietraits.rs b/util/src/trie/trietraits.rs index fb53350c9..f4d53d158 100644 --- a/util/src/trie/trietraits.rs +++ b/util/src/trie/trietraits.rs @@ -17,6 +17,9 @@ use hash::H256; use rlp::SHA3_NULL_RLP; +/// Trie-Item type. +pub type TrieItem<'a> = (Vec, &'a[u8]); + /// A key-value datastore implemented as a database-backed modified Merkle tree. pub trait Trie { /// Return the root of the trie. @@ -32,7 +35,7 @@ pub trait Trie { fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Option<&'a [u8]> where 'a: 'key; /// Returns an iterator over elements of trie. - fn iter<'a>(&'a self) -> Box, &[u8])> + 'a>; + fn iter<'a>(&'a self) -> Box + 'a>; } /// A key-value datastore implemented as a database-backed modified Merkle tree. From 24f09de60e910927f743584d5e08dfa1eff9fa96 Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 4 Jul 2016 18:21:22 +0200 Subject: [PATCH 49/52] Fixed public address config --- parity/configuration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parity/configuration.rs b/parity/configuration.rs index 78c4b286a..14932423c 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -254,7 +254,7 @@ impl Configuration { let host = IpAddr::from_str(host).unwrap_or_else(|_| die!("Invalid host given with `--nat extip:{}`", host)); Some(SocketAddr::new(host, port)) } else { - listen_address + None }; (listen_address, public_address) } From 548b4e164eea2b1a71a23ba8f18691cd73cbf03c Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 4 Jul 2016 18:24:14 +0200 Subject: [PATCH 50/52] Attempt to fix blochchain DB sync --- ethcore/src/blockchain/blockchain.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 4b2246b21..252c17b34 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -30,7 +30,7 @@ use blockchain::best_block::BestBlock; use types::tree_route::TreeRoute; use blockchain::update::ExtrasUpdate; use blockchain::{CacheSize, ImportRoute, Config}; -use db::{Writable, Readable, CacheUpdatePolicy}; +use db::{Writable, Readable, CacheUpdatePolicy, Key}; const LOG_BLOOMS_LEVELS: usize = 3; const LOG_BLOOMS_ELEMENTS_PER_INDEX: usize = 16; @@ -295,7 +295,22 @@ impl BlockChain { // load best block let best_block_hash = match bc.extras_db.get(b"best").unwrap() { - Some(best) => H256::from_slice(&best), + Some(best) => { + let best = H256::from_slice(&best); + let mut b = best.clone(); + while !bc.blocks_db.get(&b).unwrap().is_some() { + // track back to the best block we have in the blocks database + let extras: BlockDetails = bc.extras_db.read(&b).unwrap(); + type DetailsKey = Key; + bc.extras_db.delete(&(DetailsKey::key(&b))).unwrap(); + b = extras.parent; + } + if b != best { + info!("Restored mismatched best block. Was: {}, new: {}", best.hex(), b.hex()); + bc.extras_db.put(b"best", &b).unwrap(); + } + b + } None => { // best block does not exist // we need to insert genesis into the cache From 0242c66a1b53b269bd52cb5083b2d7e262c75076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 4 Jul 2016 19:21:40 +0200 Subject: [PATCH 51/52] Bump parity-dapps --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8fdbfa351..5071da96b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -898,7 +898,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "parity-dapps" version = "0.3.0" -source = "git+https://github.com/ethcore/parity-dapps-rs.git#8cc812c26c903cf5764ce0f4cc3f2a7c3ddb0dc2" +source = "git+https://github.com/ethcore/parity-dapps-rs.git#8ce18c014d8b69fa31fb203b68ff240091d77a23" dependencies = [ "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", From 1ab2060afac3ed8a3ff00502a5a7ca5fe057a406 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 5 Jul 2016 12:11:09 +0400 Subject: [PATCH 52/52] add void method support (#1540) --- ipc/codegen/src/codegen.rs | 44 +++++++++++++++++++++++++++----------- ipc/tests/examples.rs | 16 ++++++++++++++ ipc/tests/service.rs.in | 5 +++++ 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs index 672132c9f..c07f0b37a 100644 --- a/ipc/codegen/src/codegen.rs +++ b/ipc/codegen/src/codegen.rs @@ -201,15 +201,20 @@ fn implement_dispatch_arm_invoke_stmt( { let _sp = ext_cx.call_site(); let mut tt = ::std::vec::Vec::new(); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Brace))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep)); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("ipc")))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep)); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("binary")))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep)); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("serialize")))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And))); + + if dispatch.return_type_ty.is_some() { + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep)); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("ipc")))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep)); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("binary")))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep)); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("serialize")))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::BinOp(::syntax::parse::token::And))); + } + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("self")))); tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Dot)); tt.extend(::quasi::ToTokens::to_tokens(&function_name, ext_cx).into_iter()); @@ -221,12 +226,25 @@ fn implement_dispatch_arm_invoke_stmt( } tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Dot)); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("unwrap")))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); - tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); + + if dispatch.return_type_ty.is_some() { + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Dot)); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("unwrap")))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); + } + else { + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Semi)); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("Vec")))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::ModSep)); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::Ident(ext_cx.ident_of("new")))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::OpenDelim(::syntax::parse::token::Paren))); + tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Paren))); + + } tt.push(::syntax::ast::TokenTree::Token(_sp, ::syntax::parse::token::CloseDelim(::syntax::parse::token::Brace))); + tt })).unwrap() } diff --git a/ipc/tests/examples.rs b/ipc/tests/examples.rs index b4159f196..8b52be11c 100644 --- a/ipc/tests/examples.rs +++ b/ipc/tests/examples.rs @@ -190,4 +190,20 @@ mod tests { assert_eq!(struct_, new_struct); } + + #[test] + fn can_call_void_method() { + let mut socket = TestSocket::new(); + socket.read_buffer = vec![1]; + let service_client = ServiceClient::init(socket); + + service_client.void(99); + + assert_eq!(vec![ + 0, 19, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 0, 0, 0, 0, 0, 0, + 99, 0, 0, 0, 0, 0, 0, 0], + service_client.socket().write().unwrap().write_buffer.clone()); + } } diff --git a/ipc/tests/service.rs.in b/ipc/tests/service.rs.in index 2c58122bf..6bee63133 100644 --- a/ipc/tests/service.rs.in +++ b/ipc/tests/service.rs.in @@ -39,12 +39,14 @@ impl Service { *lock = *lock + f as usize; f } + pub fn rollback(&self, a: Option, b: u32) -> i32 { let a_0 = a.unwrap_or_else(|| 0); let mut lock = self.rollbacks.write().unwrap(); *lock = *lock + a_0 as usize - b as usize; (a_0 - b) as i32 } + pub fn push_custom(&self, data: CustomData) -> bool { let mut clock = self.commits.write().unwrap(); let mut rlock = self.commits.write().unwrap(); @@ -54,6 +56,9 @@ impl Service { true } + + pub fn void(&self, a: u64) { + } } impl Service {