diff --git a/README.md b/README.md index 50715eaf1c6..e4aec89927a 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,12 @@ 3.2 [Building from Source Code](#chapter-0032)
3.3 [Simple One-Line Installer for Mac and Linux](#chapter-0033)
3.4 [Starting Parity Ethereum](#chapter-0034) -4. [Documentation](#chapter-004) -5. [Toolchain](#chapter-005) -6. [Community](#chapter-006) -7. [Contributing](#chapter-007) -8. [License](#chapter-008) +4. [Testing](#chapter-004) +5. [Documentation](#chapter-005) +6. [Toolchain](#chapter-006) +7. [Community](#chapter-007) +8. [Contributing](#chapter-008) +9. [License](#chapter-009) ## 1. Description @@ -148,7 +149,25 @@ To start Parity Ethereum as a regular user using `systemd` init: 2. Copy release to bin folder, write `sudo install ./target/release/parity /usr/bin/parity` 3. To configure Parity Ethereum, write a `/etc/parity/config.toml` config file, see [Configuring Parity Ethereum](https://paritytech.github.io/wiki/Configuring-Parity) for details. -## 4. Documentation +## 4. Testing + +You can run tests with the following commands: + +* **All** packages + ``` + cargo test --all + ``` + +* Specific package + ``` + cargo test --package + ``` + +Replace `` with one of the packages from the [package list](#package-list) (e.g. `cargo test --package evmbin`). + +You can show your logs in the test output by passing `--nocapture` (i.e. `cargo test --package evmbin -- --nocapture`) + +## 5. Documentation Official website: https://parity.io @@ -160,16 +179,20 @@ You can generate documentation for Parity Ethereum Rust packages that automatica * **All** packages ``` - cargo doc --open + cargo doc --document-private-items --open ``` * Specific package ``` - cargo doc --package --open + cargo doc --package -- --document-private-items --open ``` +Use`--document-private-items` to also view private documentation and `--no-deps` to exclude building documentation for dependencies. + Replacing `` with one of the following from the details section below (i.e. `cargo doc --package parity-ethereum --open`): + +**Package List**

* Parity Ethereum (EthCore) Client Application @@ -330,7 +353,7 @@ Example (generic documentation comment): /// ``` -## 5. Toolchain +## 6. Toolchain In addition to the Parity Ethereum client, there are additional tools in this repository available: @@ -342,7 +365,7 @@ In addition to the Parity Ethereum client, there are additional tools in this re The following tool is available in a separate repository: - [ethabi](https://github.com/paritytech/ethabi) - Parity Ethereum Encoding of Function Calls. [Docs here](https://crates.io/crates/ethabi) -## 6. Community +## 7. Community ### Join the chat! @@ -355,7 +378,7 @@ Questions? Get in touch with us on Gitter: Alternatively, join our community on Matrix: [![Riot: +Parity](https://img.shields.io/badge/riot-%2Bparity%3Amatrix.parity.io-orange.svg)](https://riot.im/app/#/group/+parity:matrix.parity.io) -## 7. Contributing +## 8. Contributing An introduction has been provided in the ["So You Want to be a Core Developer" presentation slides by Hernando Castano](http://tiny.cc/contrib-to-parity-eth). Additional guidelines are provided in [CONTRIBUTING](./.github/CONTRIBUTING.md). @@ -363,6 +386,6 @@ An introduction has been provided in the ["So You Want to be a Core Developer" p [CODE_OF_CONDUCT](./.github/CODE_OF_CONDUCT.md) -## 8. License +## 9. License [LICENSE](./LICENSE) diff --git a/accounts/ethstore/src/json/crypto.rs b/accounts/ethstore/src/json/crypto.rs index 34664f98b0e..a7315d7e5c9 100644 --- a/accounts/ethstore/src/json/crypto.rs +++ b/accounts/ethstore/src/json/crypto.rs @@ -41,7 +41,7 @@ impl str::FromStr for Crypto { impl From for String { fn from(c: Crypto) -> Self { - serde_json::to_string(&c).expect("serialization cannot fail, cause all crypto keys are strings") + serde_json::to_string(&c).expect("Serialization cannot fail, because all crypto keys are strings") } } diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index d2cb128c48c..7eb81f4238d 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -22,13 +22,13 @@ //! and can be appended to with transactions and uncles. //! //! When ready, `OpenBlock` can be closed and turned into a `ClosedBlock`. A `ClosedBlock` can -//! be reopend again by a miner under certain circumstances. On block close, state commit is +//! be re-opend again by a miner under certain circumstances. On block close, state commit is //! performed. //! //! `LockedBlock` is a version of a `ClosedBlock` that cannot be reopened. It can be sealed //! using an engine. //! -//! `ExecutedBlock` is an underlaying data structure used by all structs above to store block +//! `ExecutedBlock` is an underlying data structure used by all structs above to store block //! related info. use std::{cmp, ops}; @@ -52,7 +52,7 @@ use vm::{EnvInfo, LastHashes}; use hash::keccak; use rlp::{RlpStream, Encodable, encode_list}; use types::transaction::{SignedTransaction, Error as TransactionError}; -use types::header::{Header, ExtendedHeader}; +use types::header::Header; use types::receipt::{Receipt, TransactionOutcome}; /// Block that is ready for transactions to be added. @@ -62,6 +62,7 @@ use types::receipt::{Receipt, TransactionOutcome}; pub struct OpenBlock<'x> { block: ExecutedBlock, engine: &'x dyn Engine, + parent: Header, } /// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields, @@ -72,6 +73,7 @@ pub struct OpenBlock<'x> { pub struct ClosedBlock { block: ExecutedBlock, unclosed_state: State, + parent: Header, } /// Just like `ClosedBlock` except that we can't reopen it and it's faster. @@ -102,7 +104,7 @@ pub struct ExecutedBlock { pub receipts: Vec, /// Hashes of already executed transactions. pub transactions_set: HashSet, - /// Underlaying state. + /// Underlying state. pub state: State, /// Transaction traces. pub traces: Tracing, @@ -119,13 +121,13 @@ impl ExecutedBlock { uncles: Default::default(), receipts: Default::default(), transactions_set: Default::default(), - state: state, + state, traces: if tracing { Tracing::enabled() } else { Tracing::Disabled }, - last_hashes: last_hashes, + last_hashes, } } @@ -162,7 +164,7 @@ pub trait Drain { impl<'x> OpenBlock<'x> { /// Create a new `OpenBlock` ready for transaction pushing. - pub fn new<'a, I: IntoIterator>( + pub fn new<'a>( engine: &'x dyn Engine, factories: Factories, tracing: bool, @@ -173,14 +175,11 @@ impl<'x> OpenBlock<'x> { gas_range_target: (U256, U256), extra_data: Bytes, is_epoch_begin: bool, - ancestry: I, ) -> Result { let number = parent.number() + 1; let state = State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce(number), factories)?; - let mut r = OpenBlock { - block: ExecutedBlock::new(state, last_hashes, tracing), - engine: engine, - }; + + let mut r = OpenBlock { block: ExecutedBlock::new(state, last_hashes, tracing), engine, parent: parent.clone() }; r.block.header.set_parent_hash(parent.hash()); r.block.header.set_number(number); @@ -195,7 +194,7 @@ impl<'x> OpenBlock<'x> { engine.populate_from_parent(&mut r.block.header, parent); engine.machine().on_new_block(&mut r.block)?; - engine.on_new_block(&mut r.block, is_epoch_begin, &mut ancestry.into_iter())?; + engine.on_new_block(&mut r.block, is_epoch_begin)?; Ok(r) } @@ -297,19 +296,20 @@ impl<'x> OpenBlock<'x> { /// Turn this into a `ClosedBlock`. pub fn close(self) -> Result { let unclosed_state = self.block.state.clone(); + let parent = self.parent.clone(); let locked = self.close_and_lock()?; Ok(ClosedBlock { block: locked.block, unclosed_state, + parent, }) } /// Turn this into a `LockedBlock`. pub fn close_and_lock(self) -> Result { let mut s = self; - - s.engine.on_close_block(&mut s.block)?; + s.engine.on_close_block(&mut s.block, &s.parent)?; s.block.state.commit()?; s.block.header.set_transactions_root(ordered_trie_root(s.block.transactions.iter().map(|e| e.rlp_bytes()))); @@ -378,10 +378,8 @@ impl ClosedBlock { // revert rewards (i.e. set state back at last transaction's state). let mut block = self.block; block.state = self.unclosed_state; - OpenBlock { - block: block, - engine: engine, - } + let parent = self.parent; + OpenBlock { block, engine, parent } } } @@ -479,7 +477,6 @@ pub(crate) fn enact( last_hashes: Arc, factories: Factories, is_epoch_begin: bool, - ancestry: &mut dyn Iterator, ) -> Result { // For trace log let trace_state = if log_enabled!(target: "enact", ::log::Level::Trace) { @@ -501,7 +498,6 @@ pub(crate) fn enact( (3141562.into(), 31415620.into()), vec![], is_epoch_begin, - ancestry, )?; if let Some(ref s) = trace_state { @@ -522,7 +518,7 @@ pub(crate) fn enact( b.close_and_lock() } -/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header +/// Enact the block given by `block_bytes` using `engine` on the database `db` with the given `parent` block header pub fn enact_verified( block: PreverifiedBlock, engine: &dyn Engine, @@ -532,7 +528,6 @@ pub fn enact_verified( last_hashes: Arc, factories: Factories, is_epoch_begin: bool, - ancestry: &mut dyn Iterator, ) -> Result { enact( @@ -546,7 +541,6 @@ pub fn enact_verified( last_hashes, factories, is_epoch_begin, - ancestry, ) } @@ -608,7 +602,6 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, - None, )?; b.populate_from(&header); @@ -643,7 +636,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b = b.close_and_lock().unwrap(); let _ = b.seal(&*spec.engine, vec![]); } @@ -657,7 +650,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap() + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap() .close_and_lock().unwrap().seal(engine, vec![]).unwrap(); let orig_bytes = b.rlp_bytes(); let orig_db = b.drain().state.drop().1; @@ -682,7 +675,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); let mut uncle1_header = Header::new(); uncle1_header.set_extra_data(b"uncle1".to_vec()); let mut uncle2_header = Header::new(); diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 7678314f0ee..e9847437c9d 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -407,7 +407,6 @@ impl Importer { last_hashes, client.factories.clone(), is_epoch_begin, - &mut chain.ancestry_with_metadata_iter(*header.parent_hash()), ); let mut locked_block = match enact_result { @@ -2361,7 +2360,6 @@ impl PrepareOpenBlock for Client { gas_range_target, extra_data, is_epoch_begin, - chain.ancestry_with_metadata_iter(best_header.hash()), )?; // Add uncles diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 9eb1b14eb8f..7894a665de3 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -417,7 +417,6 @@ impl PrepareOpenBlock for TestBlockChainClient { gas_range_target, extra_data, false, - None, )?; // TODO [todr] Override timestamp for predictability open_block.set_timestamp(*self.latest_block_timestamp.read()); diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 97305efad84..cb9b8a49954 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1211,7 +1211,6 @@ impl Engine for AuthorityRound { &self, block: &mut ExecutedBlock, epoch_begin: bool, - _ancestry: &mut dyn Iterator, ) -> Result<(), Error> { // with immediate transitions, we don't use the epoch mechanism anyway. // the genesis is always considered an epoch, but we ignore it intentionally. @@ -1236,26 +1235,18 @@ impl Engine for AuthorityRound { } /// Apply the block reward on finalisation of the block. - fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { + fn on_close_block( + &self, + block: &mut ExecutedBlock, + parent: &Header, + ) -> Result<(), Error> { let mut beneficiaries = Vec::new(); if block.header.number() >= self.empty_steps_transition { let empty_steps = if block.header.seal().is_empty() { // this is a new block, calculate rewards based on the empty steps messages we have accumulated - let client = match self.client.read().as_ref().and_then(|weak| weak.upgrade()) { - Some(client) => client, - None => { - debug!(target: "engine", "Unable to close block: missing client ref."); - return Err(EngineError::RequiresClient.into()) - }, - }; - - let parent = client.block_header(::client::BlockId::Hash(*block.header.parent_hash())) - .expect("hash is from parent; parent header must exist; qed") - .decode()?; - - let parent_step = header_step(&parent, self.empty_steps_transition)?; + let parent_step = header_step(parent, self.empty_steps_transition)?; let current_step = self.step.inner.load(); - self.empty_steps(parent_step.into(), current_step.into(), parent.hash()) + self.empty_steps(parent_step, current_step, parent.hash()) } else { // we're verifying a block, extract empty steps from the seal header_empty_steps(&block.header)? @@ -1707,9 +1698,9 @@ mod tests { let db1 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b1 = b1.close_and_lock().unwrap(); - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); @@ -1741,9 +1732,9 @@ mod tests { let db2 = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b1 = b1.close_and_lock().unwrap(); - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); @@ -1991,7 +1982,7 @@ mod tests { engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b1 = b1.close_and_lock().unwrap(); // the block is empty so we don't seal and instead broadcast an empty step message @@ -2029,7 +2020,7 @@ mod tests { engine.register_client(Arc::downgrade(&client) as _); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps @@ -2038,7 +2029,7 @@ mod tests { engine.step(); // step 3 - let mut b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let mut b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap(); b2.push_transaction(Transaction { action: Action::Create, nonce: U256::from(0), @@ -2082,7 +2073,7 @@ mod tests { engine.register_client(Arc::downgrade(&client) as _); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps @@ -2091,7 +2082,7 @@ mod tests { engine.step(); // step 3 - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr2, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b2 = b2.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr2, "0".into()))); assert_eq!(engine.generate_seal(&b2, &genesis_header), Seal::None); @@ -2099,7 +2090,7 @@ mod tests { // step 4 // the spec sets the maximum_empty_steps to 2 so we will now seal an empty block and include the empty step messages - let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b3 = OpenBlock::new(engine, Default::default(), false, db3, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b3 = b3.close_and_lock().unwrap(); engine.set_signer(Box::new((tap.clone(), addr1, "1".into()))); @@ -2132,7 +2123,7 @@ mod tests { engine.register_client(Arc::downgrade(&client) as _); // step 2 - let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b1 = b1.close_and_lock().unwrap(); // since the block is empty it isn't sealed and we generate empty steps @@ -2142,7 +2133,7 @@ mod tests { // step 3 // the signer of the accumulated empty step message should be rewarded - let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let addr1_balance = b2.state.balance(&addr1).unwrap(); // after closing the block `addr1` should be reward twice, one for the included empty step message and another for block creation @@ -2242,7 +2233,6 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, - None, ).unwrap(); let b1 = b1.close_and_lock().unwrap(); @@ -2264,7 +2254,6 @@ mod tests { (3141562.into(), 31415620.into()), vec![], false, - None, ).unwrap(); let addr1_balance = b2.state.balance(&addr1).unwrap(); diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 18afc51ce68..b08512b79b5 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -268,7 +268,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b = b.close_and_lock().unwrap(); if let Seal::Regular(seal) = engine.generate_seal(&b, &genesis_header) { assert!(b.try_seal(engine, seal).is_ok()); diff --git a/ethcore/src/engines/clique/mod.rs b/ethcore/src/engines/clique/mod.rs index 9c8e1823feb..89bcef94c2b 100644 --- a/ethcore/src/engines/clique/mod.rs +++ b/ethcore/src/engines/clique/mod.rs @@ -368,13 +368,16 @@ impl Engine for Clique { &self, _block: &mut ExecutedBlock, _epoch_begin: bool, - _ancestry: &mut dyn Iterator, ) -> Result<(), Error> { Ok(()) } // Clique has no block reward. - fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { + fn on_close_block( + &self, + _block: &mut ExecutedBlock, + _parent_header: &Header + ) -> Result<(), Error> { Ok(()) } diff --git a/ethcore/src/engines/clique/tests.rs b/ethcore/src/engines/clique/tests.rs index 76140284f6d..97e218a05ce 100644 --- a/ethcore/src/engines/clique/tests.rs +++ b/ethcore/src/engines/clique/tests.rs @@ -111,7 +111,7 @@ impl CliqueTester { /// Get signers after a certain state // This is generally used to fetch the state after a test has been executed and checked against - // the intial list of signers provided in the test + // the initial list of signers provided in the test pub fn clique_signers(&self, hash: &H256) -> impl Iterator { self.get_state_at_block(hash).signers().clone().into_iter() } @@ -171,7 +171,6 @@ impl CliqueTester { (3141562.into(), 31415620.into()), extra_data, false, - None, ).unwrap(); { diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 27f133424d5..58fbfeed1d4 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -110,7 +110,7 @@ mod tests { let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let genesis_header = spec.genesis_header(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b = b.close_and_lock().unwrap(); if let Seal::Regular(seal) = engine.generate_seal(&b, &genesis_header) { assert!(b.try_seal(engine, seal).is_ok()); diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index c550f74c2b0..b0207b075eb 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -304,13 +304,16 @@ pub trait Engine: Sync + Send { &self, _block: &mut ExecutedBlock, _epoch_begin: bool, - _ancestry: &mut dyn Iterator, ) -> Result<(), Error> { Ok(()) } /// Block transformation functions, after the transactions. - fn on_close_block(&self, _block: &mut ExecutedBlock) -> Result<(), Error> { + fn on_close_block( + &self, + _block: &mut ExecutedBlock, + _parent_header: &Header, + ) -> Result<(), Error> { Ok(()) } diff --git a/ethcore/src/engines/null_engine.rs b/ethcore/src/engines/null_engine.rs index a291969772c..71cb9d459b5 100644 --- a/ethcore/src/engines/null_engine.rs +++ b/ethcore/src/engines/null_engine.rs @@ -61,7 +61,11 @@ impl Engine for NullEngine { fn machine(&self) -> &Machine { &self.machine } - fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { + fn on_close_block( + &self, + block: &mut ExecutedBlock, + _parent_header: &Header + ) -> Result<(), Error> { use std::ops::Shr; let author = *block.header.author(); diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index c29f960e573..a6540ab7908 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -239,7 +239,7 @@ impl Engine for Arc { /// Apply the block reward on finalisation of the block. /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). - fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> { + fn on_close_block(&self, block: &mut ExecutedBlock, _parent_header: &Header) -> Result<(), Error> { use std::ops::Shr; let author = *block.header.author(); @@ -540,7 +540,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b = b.close().unwrap(); assert_eq!(b.state.balance(&Address::zero()).unwrap(), U256::from_str("4563918244f40000").unwrap()); } @@ -589,7 +589,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); let mut uncle = Header::new(); let uncle_author = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(); uncle.set_author(uncle_author); @@ -607,7 +607,7 @@ mod tests { let genesis_header = spec.genesis_header(); let db = spec.ensure_db_good(get_temp_state_db(), &Default::default()).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false, None).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![], false).unwrap(); let b = b.close().unwrap(); let ubi_contract = Address::from_str("00efdd5883ec628983e9063c7d969fe268bbf310").unwrap(); diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index d6835c34874..a6dec0c1c2d 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -170,6 +170,7 @@ pub mod state_db; pub mod trace; pub mod transaction_ext; pub mod verification; +pub mod account_db; mod externalities; mod factory; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index c35423d7403..e933d7d58b6 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -548,7 +548,7 @@ impl Miner { } }, // Invalid nonce error can happen only if previous transaction is skipped because of gas limit. - // If there is errornous state of transaction queue it will be fixed when next block is imported. + // If there is erroneous state of transaction queue it will be fixed when next block is imported. Err(Error::Execution(ExecutionError::InvalidNonce { expected, got })) => { debug!(target: "miner", "Skipping adding transaction to block because of invalid nonce: {:?} (expected: {:?}, got: {:?})", hash, expected, got); }, diff --git a/ethcore/src/test_helpers.rs b/ethcore/src/test_helpers.rs index 6bdaeadf9bd..5137aade025 100644 --- a/ethcore/src/test_helpers.rs +++ b/ethcore/src/test_helpers.rs @@ -155,7 +155,6 @@ pub fn generate_dummy_client_with_spec_and_data(test_spec: F, block_number: u (3141562.into(), 31415620.into()), vec![], false, - None, ).unwrap(); rolling_timestamp += 10; b.set_timestamp(rolling_timestamp); diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 093c55a9137..343751b0481 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -117,7 +117,7 @@ fn query_none_block() { Arc::new(Miner::new_for_tests(&spec, None)), IoChannel::disconnected(), ).unwrap(); - let non_existant = client.block_header(BlockId::Number(188)); + let non_existant = client.block_header(BlockId::Number(188)); assert!(non_existant.is_none()); } diff --git a/ethcore/src/tests/trace.rs b/ethcore/src/tests/trace.rs index 882fed4436a..b80c7485128 100644 --- a/ethcore/src/tests/trace.rs +++ b/ethcore/src/tests/trace.rs @@ -87,7 +87,6 @@ fn can_trace_block_and_uncle_reward() { (3141562.into(), 31415620.into()), vec![], false, - None, ).unwrap(); rolling_timestamp += 10; root_block.set_timestamp(rolling_timestamp); @@ -116,7 +115,6 @@ fn can_trace_block_and_uncle_reward() { (3141562.into(), 31415620.into()), vec![], false, - None, ).unwrap(); rolling_timestamp += 10; parent_block.set_timestamp(rolling_timestamp); @@ -144,7 +142,6 @@ fn can_trace_block_and_uncle_reward() { (3141562.into(), 31415620.into()), vec![], false, - None, ).unwrap(); rolling_timestamp += 10; block.set_timestamp(rolling_timestamp); diff --git a/ethcore/state-account/src/lib.rs b/ethcore/state-account/src/lib.rs index d2f773c3cd8..24e136d1e7b 100644 --- a/ethcore/state-account/src/lib.rs +++ b/ethcore/state-account/src/lib.rs @@ -632,7 +632,7 @@ mod tests { use journaldb::new_memory_db; use parity_bytes::Bytes; use super::*; - use account_db::*; + use ethcore::account_db::*; use std::str::FromStr; #[test] diff --git a/evmbin/src/display/json.rs b/evmbin/src/display/json.rs index 449938eab56..195e00c7379 100644 --- a/evmbin/src/display/json.rs +++ b/evmbin/src/display/json.rs @@ -47,6 +47,42 @@ pub struct Informant { unmatched: bool, } +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TraceData<'a> { + pc: usize, + op: u8, + op_name: &'a str, + gas: &'a str, + gas_cost: &'a str, + memory: &'a str, + stack: &'a [U256], + storage: &'a HashMap, + depth: usize, +} + +#[derive(Serialize, Debug)] +pub struct MessageInitial<'a> { + action: &'a str, + test: &'a str, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct MessageSuccess<'a> { + output: &'a str, + gas_used: &'a str, + time: &'a u64, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct MessageFailure<'a> { + error: &'a str, + gas_used: &'a str, + time: &'a u64, +} + impl Informant { fn with_informant_in_depth(informant: &mut Informant, depth: usize, f: F) { if depth == 0 { @@ -59,17 +95,21 @@ impl Informant { fn informant_trace(informant: &Informant, gas_used: U256) -> String { let info = ::evm::Instruction::from_u8(informant.instruction).map(|i| i.info()); - json!({ - "pc": informant.pc, - "op": informant.instruction, - "opName": info.map(|i| i.name).unwrap_or(""), - "gas": format!("{:#x}", gas_used.saturating_add(informant.gas_cost)), - "gasCost": format!("{:#x}", informant.gas_cost), - "memory": format!("0x{}", informant.memory.to_hex()), - "stack": informant.stack, - "storage": informant.storage, - "depth": informant.depth, - }).to_string() + let trace_data = + TraceData { + pc: informant.pc, + op: informant.instruction, + op_name: info.map(|i| i.name).unwrap_or(""), + gas: &format!("{:#x}", gas_used.saturating_add(informant.gas_cost)), + gas_cost: &format!("{:#x}", informant.gas_cost), + memory: &format!("0x{}", informant.memory.to_hex()), + stack: &informant.stack, + storage: &informant.storage, + depth: informant.depth, + } + ; + + serde_json::to_string(&trace_data).expect("Serialization cannot fail; qed") } } @@ -77,7 +117,15 @@ impl vm::Informant for Informant { type Sink = (); fn before_test(&mut self, name: &str, action: &str) { - println!("{}", json!({"action": action, "test": name})); + let message_init = + MessageInitial { + action, + test: &name, + } + ; + + let s = serde_json::to_string(&message_init).expect("Serialization cannot fail; qed"); + println!("{}", s); } fn set_gas(&mut self, gas: U256) { @@ -93,26 +141,32 @@ impl vm::Informant for Informant { println!("{}", trace); } - let success_msg = json!({ - "output": format!("0x{}", success.output.to_hex()), - "gasUsed": format!("{:#x}", success.gas_used), - "time": display::as_micros(&success.time), - }); + let message_success = + MessageSuccess { + output: &format!("0x{}", success.output.to_hex()), + gas_used: &format!("{:#x}", success.gas_used), + time: &display::as_micros(&success.time), + } + ; - println!("{}", success_msg) + let s = serde_json::to_string(&message_success).expect("Serialization cannot fail; qed"); + println!("{}", s); }, Err(failure) => { for trace in failure.traces.unwrap_or_else(Vec::new) { println!("{}", trace); } - let failure_msg = json!({ - "error": &failure.error.to_string(), - "gasUsed": format!("{:#x}", failure.gas_used), - "time": display::as_micros(&failure.time), - }); + let message_failure = + MessageFailure { + error: &failure.error.to_string(), + gas_used: &format!("{:#x}", failure.gas_used), + time: &display::as_micros(&failure.time), + } + ; - println!("{}", failure_msg) + let s = serde_json::to_string(&message_failure).expect("Serialization cannot fail; qed"); + println!("{}", s); }, } } diff --git a/evmbin/src/display/std_json.rs b/evmbin/src/display/std_json.rs index 74d9e0040a2..1734c305e24 100644 --- a/evmbin/src/display/std_json.rs +++ b/evmbin/src/display/std_json.rs @@ -64,6 +64,52 @@ pub struct Informant { out_sink: Out, } +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TraceData<'a> { + pc: usize, + op: u8, + op_name: &'a str, + gas: &'a str, + stack: &'a [U256], + storage: &'a HashMap, + depth: usize, +} + +#[derive(Serialize, Debug)] +pub struct MessageInitial<'a> { + action: &'a str, + test: &'a str, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct MessageSuccess<'a> { + output: &'a str, + gas_used: &'a str, + time: &'a u64, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct MessageFailure<'a> { + error: &'a str, + gas_used: &'a str, + time: &'a u64, +} + +#[derive(Serialize, Debug)] +pub struct DumpData<'a> { + root: &'a H256, + accounts: &'a pod_state::PodState, +} + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TraceDataStateRoot<'a> { + state_root: &'a H256, +} + impl Default for Informant { fn default() -> Self { Self::new(io::stderr(), io::stdout()) @@ -95,7 +141,8 @@ impl Informant { storage: Default::default(), subinfos: Default::default(), subdepth: 0, - trace_sink, out_sink + trace_sink, + out_sink, } } @@ -108,12 +155,16 @@ impl Informant { } fn dump_state_into(trace_sink: &mut Trace, root: H256, end_state: &Option) { - if let Some(ref end_state) = end_state { - let dump_data = json!({ - "root": root, - "accounts": end_state, - }); - writeln!(trace_sink, "{}", dump_data).expect("The sink must be writeable."); + if let Some(ref end_state) = end_state { + let dump_data = + DumpData { + root: &root, + accounts: end_state, + } + ; + + let s = serde_json::to_string(&dump_data).expect("Serialization cannot fail; qed"); + writeln!(trace_sink, "{}", s).expect("The sink must be writeable."); } } @@ -124,12 +175,15 @@ impl vm::Informant for Informant { type Sink = (Trace, Out); fn before_test(&mut self, name: &str, action: &str) { - let out_data = json!({ - "action": action, - "test": name, - }); + let message_init = + MessageInitial { + action, + test: &name, + } + ; - writeln!(&mut self.out_sink, "{}", out_data).expect("The sink must be writeable."); + let s = serde_json::to_string(&message_init).expect("Serialization cannot fail; qed"); + writeln!(&mut self.out_sink, "{}", s).expect("The sink must be writeable."); } fn set_gas(&mut self, _gas: U256) {} @@ -137,34 +191,46 @@ impl vm::Informant for Informant { fn clone_sink(&self) -> Self::Sink { (self.trace_sink.clone(), self.out_sink.clone()) } + fn finish(result: vm::RunResult<::Output>, (ref mut trace_sink, ref mut out_sink): &mut Self::Sink) { match result { Ok(success) => { - let trace_data = json!({"stateRoot": success.state_root}); - writeln!(trace_sink, "{}", trace_data) - .expect("The sink must be writeable."); + let state_root_data = + TraceDataStateRoot { + state_root: &success.state_root, + } + ; + + let s = serde_json::to_string(&state_root_data).expect("Serialization cannot fail; qed"); + writeln!(trace_sink, "{}", s).expect("The sink must be writeable."); Self::dump_state_into(trace_sink, success.state_root, &success.end_state); - let out_data = json!({ - "output": format!("0x{}", success.output.to_hex()), - "gasUsed": format!("{:#x}", success.gas_used), - "time": display::as_micros(&success.time), - }); + let message_success = + MessageSuccess { + output: &format!("0x{}", success.output.to_hex()), + gas_used: &format!("{:#x}", success.gas_used), + time: &display::as_micros(&success.time), + } + ; - writeln!(out_sink, "{}", out_data).expect("The sink must be writeable."); + let s = serde_json::to_string(&message_success).expect("Serialization cannot fail; qed"); + writeln!(out_sink, "{}", s).expect("The sink must be writeable."); }, Err(failure) => { - let out_data = json!({ - "error": &failure.error.to_string(), - "gasUsed": format!("{:#x}", failure.gas_used), - "time": display::as_micros(&failure.time), - }); + let message_failure = + MessageFailure { + error: &failure.error.to_string(), + gas_used: &format!("{:#x}", failure.gas_used), + time: &display::as_micros(&failure.time), + } + ; Self::dump_state_into(trace_sink, failure.state_root, &failure.end_state); - writeln!(out_sink, "{}", out_data).expect("The sink must be writeable."); + let s = serde_json::to_string(&message_failure).expect("Serialization cannot fail; qed"); + writeln!(out_sink, "{}", s).expect("The sink must be writeable."); }, } } @@ -178,17 +244,22 @@ impl trace::VMTracer for Informant { Self::with_informant_in_depth(self, subdepth, |informant: &mut Informant| { let info = ::evm::Instruction::from_u8(instruction).map(|i| i.info()); informant.instruction = instruction; - let trace_data = json!({ - "pc": pc, - "op": instruction, - "opName": info.map(|i| i.name).unwrap_or(""), - "gas": format!("{:#x}", current_gas), - "stack": informant.stack, - "storage": informant.storage, - "depth": informant.depth, - }); - - writeln!(&mut informant.trace_sink, "{}", trace_data).expect("The sink must be writeable."); + + let trace_data = + TraceData { + pc: pc, + op: instruction, + op_name: info.map(|i| i.name).unwrap_or(""), + gas: &format!("{:#x}", current_gas), + stack: &informant.stack, + storage: &informant.storage, + depth: informant.depth, + } + ; + + let s = serde_json::to_string(&trace_data).expect("Serialization cannot fail; qed"); + + writeln!(&mut informant.trace_sink, "{}", s).expect("The sink must be writeable."); }); true } @@ -279,8 +350,8 @@ pub mod tests { }, "60F8d6", 0xffff, - r#"{"depth":1,"gas":"0xffff","op":96,"opName":"PUSH1","pc":0,"stack":[],"storage":{}} -{"depth":1,"gas":"0xfffc","op":214,"opName":"","pc":2,"stack":["0xf8"],"storage":{}} + r#"{"pc":0,"op":96,"opName":"PUSH1","gas":"0xffff","stack":[],"storage":{},"depth":1} +{"pc":2,"op":214,"opName":"","gas":"0xfffc","stack":["0xf8"],"storage":{},"depth":1} "#, ); @@ -293,7 +364,7 @@ pub mod tests { }, "F8d6", 0xffff, - r#"{"depth":1,"gas":"0xffff","op":248,"opName":"","pc":0,"stack":[],"storage":{}} + r#"{"pc":0,"op":248,"opName":"","gas":"0xffff","stack":[],"storage":{},"depth":1} "#, ); } @@ -309,30 +380,30 @@ pub mod tests { }, "32343434345830f138343438323439f0", 0xffff, - r#"{"depth":1,"gas":"0xffff","op":50,"opName":"ORIGIN","pc":0,"stack":[],"storage":{}} -{"depth":1,"gas":"0xfffd","op":52,"opName":"CALLVALUE","pc":1,"stack":["0x0"],"storage":{}} -{"depth":1,"gas":"0xfffb","op":52,"opName":"CALLVALUE","pc":2,"stack":["0x0","0x0"],"storage":{}} -{"depth":1,"gas":"0xfff9","op":52,"opName":"CALLVALUE","pc":3,"stack":["0x0","0x0","0x0"],"storage":{}} -{"depth":1,"gas":"0xfff7","op":52,"opName":"CALLVALUE","pc":4,"stack":["0x0","0x0","0x0","0x0"],"storage":{}} -{"depth":1,"gas":"0xfff5","op":88,"opName":"PC","pc":5,"stack":["0x0","0x0","0x0","0x0","0x0"],"storage":{}} -{"depth":1,"gas":"0xfff3","op":48,"opName":"ADDRESS","pc":6,"stack":["0x0","0x0","0x0","0x0","0x0","0x5"],"storage":{}} -{"depth":1,"gas":"0xfff1","op":241,"opName":"CALL","pc":7,"stack":["0x0","0x0","0x0","0x0","0x0","0x5","0x0"],"storage":{}} -{"depth":1,"gas":"0x9e21","op":56,"opName":"CODESIZE","pc":8,"stack":["0x1"],"storage":{}} -{"depth":1,"gas":"0x9e1f","op":52,"opName":"CALLVALUE","pc":9,"stack":["0x1","0x10"],"storage":{}} -{"depth":1,"gas":"0x9e1d","op":52,"opName":"CALLVALUE","pc":10,"stack":["0x1","0x10","0x0"],"storage":{}} -{"depth":1,"gas":"0x9e1b","op":56,"opName":"CODESIZE","pc":11,"stack":["0x1","0x10","0x0","0x0"],"storage":{}} -{"depth":1,"gas":"0x9e19","op":50,"opName":"ORIGIN","pc":12,"stack":["0x1","0x10","0x0","0x0","0x10"],"storage":{}} -{"depth":1,"gas":"0x9e17","op":52,"opName":"CALLVALUE","pc":13,"stack":["0x1","0x10","0x0","0x0","0x10","0x0"],"storage":{}} -{"depth":1,"gas":"0x9e15","op":57,"opName":"CODECOPY","pc":14,"stack":["0x1","0x10","0x0","0x0","0x10","0x0","0x0"],"storage":{}} -{"depth":1,"gas":"0x9e0c","op":240,"opName":"CREATE","pc":15,"stack":["0x1","0x10","0x0","0x0"],"storage":{}} -{"depth":2,"gas":"0x210c","op":50,"opName":"ORIGIN","pc":0,"stack":[],"storage":{}} -{"depth":2,"gas":"0x210a","op":52,"opName":"CALLVALUE","pc":1,"stack":["0x0"],"storage":{}} -{"depth":2,"gas":"0x2108","op":52,"opName":"CALLVALUE","pc":2,"stack":["0x0","0x0"],"storage":{}} -{"depth":2,"gas":"0x2106","op":52,"opName":"CALLVALUE","pc":3,"stack":["0x0","0x0","0x0"],"storage":{}} -{"depth":2,"gas":"0x2104","op":52,"opName":"CALLVALUE","pc":4,"stack":["0x0","0x0","0x0","0x0"],"storage":{}} -{"depth":2,"gas":"0x2102","op":88,"opName":"PC","pc":5,"stack":["0x0","0x0","0x0","0x0","0x0"],"storage":{}} -{"depth":2,"gas":"0x2100","op":48,"opName":"ADDRESS","pc":6,"stack":["0x0","0x0","0x0","0x0","0x0","0x5"],"storage":{}} -{"depth":2,"gas":"0x20fe","op":241,"opName":"CALL","pc":7,"stack":["0x0","0x0","0x0","0x0","0x0","0x5","0xbd770416a3345f91e4b34576cb804a576fa48eb1"],"storage":{}} + r#"{"pc":0,"op":50,"opName":"ORIGIN","gas":"0xffff","stack":[],"storage":{},"depth":1} +{"pc":1,"op":52,"opName":"CALLVALUE","gas":"0xfffd","stack":["0x0"],"storage":{},"depth":1} +{"pc":2,"op":52,"opName":"CALLVALUE","gas":"0xfffb","stack":["0x0","0x0"],"storage":{},"depth":1} +{"pc":3,"op":52,"opName":"CALLVALUE","gas":"0xfff9","stack":["0x0","0x0","0x0"],"storage":{},"depth":1} +{"pc":4,"op":52,"opName":"CALLVALUE","gas":"0xfff7","stack":["0x0","0x0","0x0","0x0"],"storage":{},"depth":1} +{"pc":5,"op":88,"opName":"PC","gas":"0xfff5","stack":["0x0","0x0","0x0","0x0","0x0"],"storage":{},"depth":1} +{"pc":6,"op":48,"opName":"ADDRESS","gas":"0xfff3","stack":["0x0","0x0","0x0","0x0","0x0","0x5"],"storage":{},"depth":1} +{"pc":7,"op":241,"opName":"CALL","gas":"0xfff1","stack":["0x0","0x0","0x0","0x0","0x0","0x5","0x0"],"storage":{},"depth":1} +{"pc":8,"op":56,"opName":"CODESIZE","gas":"0x9e21","stack":["0x1"],"storage":{},"depth":1} +{"pc":9,"op":52,"opName":"CALLVALUE","gas":"0x9e1f","stack":["0x1","0x10"],"storage":{},"depth":1} +{"pc":10,"op":52,"opName":"CALLVALUE","gas":"0x9e1d","stack":["0x1","0x10","0x0"],"storage":{},"depth":1} +{"pc":11,"op":56,"opName":"CODESIZE","gas":"0x9e1b","stack":["0x1","0x10","0x0","0x0"],"storage":{},"depth":1} +{"pc":12,"op":50,"opName":"ORIGIN","gas":"0x9e19","stack":["0x1","0x10","0x0","0x0","0x10"],"storage":{},"depth":1} +{"pc":13,"op":52,"opName":"CALLVALUE","gas":"0x9e17","stack":["0x1","0x10","0x0","0x0","0x10","0x0"],"storage":{},"depth":1} +{"pc":14,"op":57,"opName":"CODECOPY","gas":"0x9e15","stack":["0x1","0x10","0x0","0x0","0x10","0x0","0x0"],"storage":{},"depth":1} +{"pc":15,"op":240,"opName":"CREATE","gas":"0x9e0c","stack":["0x1","0x10","0x0","0x0"],"storage":{},"depth":1} +{"pc":0,"op":50,"opName":"ORIGIN","gas":"0x210c","stack":[],"storage":{},"depth":2} +{"pc":1,"op":52,"opName":"CALLVALUE","gas":"0x210a","stack":["0x0"],"storage":{},"depth":2} +{"pc":2,"op":52,"opName":"CALLVALUE","gas":"0x2108","stack":["0x0","0x0"],"storage":{},"depth":2} +{"pc":3,"op":52,"opName":"CALLVALUE","gas":"0x2106","stack":["0x0","0x0","0x0"],"storage":{},"depth":2} +{"pc":4,"op":52,"opName":"CALLVALUE","gas":"0x2104","stack":["0x0","0x0","0x0","0x0"],"storage":{},"depth":2} +{"pc":5,"op":88,"opName":"PC","gas":"0x2102","stack":["0x0","0x0","0x0","0x0","0x0"],"storage":{},"depth":2} +{"pc":6,"op":48,"opName":"ADDRESS","gas":"0x2100","stack":["0x0","0x0","0x0","0x0","0x0","0x5"],"storage":{},"depth":2} +{"pc":7,"op":241,"opName":"CALL","gas":"0x20fe","stack":["0x0","0x0","0x0","0x0","0x0","0x5","0xbd770416a3345f91e4b34576cb804a576fa48eb1"],"storage":{},"depth":2} "#, ) } diff --git a/evmbin/src/info.rs b/evmbin/src/info.rs index 9090c5377e6..ca068c36b0d 100644 --- a/evmbin/src/info.rs +++ b/evmbin/src/info.rs @@ -256,16 +256,16 @@ pub mod tests { assert_eq!( &String::from_utf8_lossy(&**res.lock().unwrap()), -r#"{"depth":1,"gas":"0xffff","op":98,"opName":"PUSH3","pc":0,"stack":[],"storage":{}} -{"depth":1,"gas":"0xfffc","op":96,"opName":"PUSH1","pc":4,"stack":["0xaaaaaa"],"storage":{}} -{"depth":1,"gas":"0xfff9","op":96,"opName":"PUSH1","pc":6,"stack":["0xaaaaaa","0xaa"],"storage":{}} -{"depth":1,"gas":"0xfff6","op":80,"opName":"POP","pc":8,"stack":["0xaaaaaa","0xaa","0xaa"],"storage":{}} -{"depth":1,"gas":"0xfff4","op":96,"opName":"PUSH1","pc":9,"stack":["0xaaaaaa","0xaa"],"storage":{}} -{"depth":1,"gas":"0xfff1","op":96,"opName":"PUSH1","pc":11,"stack":["0xaaaaaa","0xaa","0xaa"],"storage":{}} -{"depth":1,"gas":"0xffee","op":96,"opName":"PUSH1","pc":13,"stack":["0xaaaaaa","0xaa","0xaa","0xaa"],"storage":{}} -{"depth":1,"gas":"0xffeb","op":96,"opName":"PUSH1","pc":15,"stack":["0xaaaaaa","0xaa","0xaa","0xaa","0xaa"],"storage":{}} -{"depth":1,"gas":"0xffe8","op":96,"opName":"PUSH1","pc":17,"stack":["0xaaaaaa","0xaa","0xaa","0xaa","0xaa","0xaa"],"storage":{}} -{"depth":1,"gas":"0xffe5","op":96,"opName":"PUSH1","pc":19,"stack":["0xaaaaaa","0xaa","0xaa","0xaa","0xaa","0xaa","0xaa"],"storage":{}} +r#"{"pc":0,"op":98,"opName":"PUSH3","gas":"0xffff","stack":[],"storage":{},"depth":1} +{"pc":4,"op":96,"opName":"PUSH1","gas":"0xfffc","stack":["0xaaaaaa"],"storage":{},"depth":1} +{"pc":6,"op":96,"opName":"PUSH1","gas":"0xfff9","stack":["0xaaaaaa","0xaa"],"storage":{},"depth":1} +{"pc":8,"op":80,"opName":"POP","gas":"0xfff6","stack":["0xaaaaaa","0xaa","0xaa"],"storage":{},"depth":1} +{"pc":9,"op":96,"opName":"PUSH1","gas":"0xfff4","stack":["0xaaaaaa","0xaa"],"storage":{},"depth":1} +{"pc":11,"op":96,"opName":"PUSH1","gas":"0xfff1","stack":["0xaaaaaa","0xaa","0xaa"],"storage":{},"depth":1} +{"pc":13,"op":96,"opName":"PUSH1","gas":"0xffee","stack":["0xaaaaaa","0xaa","0xaa","0xaa"],"storage":{},"depth":1} +{"pc":15,"op":96,"opName":"PUSH1","gas":"0xffeb","stack":["0xaaaaaa","0xaa","0xaa","0xaa","0xaa"],"storage":{},"depth":1} +{"pc":17,"op":96,"opName":"PUSH1","gas":"0xffe8","stack":["0xaaaaaa","0xaa","0xaa","0xaa","0xaa","0xaa"],"storage":{},"depth":1} +{"pc":19,"op":96,"opName":"PUSH1","gas":"0xffe5","stack":["0xaaaaaa","0xaa","0xaa","0xaa","0xaa","0xaa","0xaa"],"storage":{},"depth":1} "#); } } diff --git a/util/network-devp2p/src/connection.rs b/util/network-devp2p/src/connection.rs index a0a6da17156..4892d0be6e3 100644 --- a/util/network-devp2p/src/connection.rs +++ b/util/network-devp2p/src/connection.rs @@ -194,7 +194,10 @@ impl Connection { /// Get remote peer address string pub fn remote_addr_str(&self) -> String { - self.socket.peer_addr().map(|a| a.to_string()).unwrap_or_else(|_| "Unknown".to_owned()) + self.socket.peer_addr().map(|a| a.to_string()).unwrap_or_else(|err| { + debug!("error occurred getting peer_addr: {}, connection token: {}", err, self.token); + "Unknown peer address".to_owned() + }) } /// Get local peer address string diff --git a/whisper/src/message.rs b/whisper/src/message.rs index ad50e3d9bf0..cf12d65b3a8 100644 --- a/whisper/src/message.rs +++ b/whisper/src/message.rs @@ -27,11 +27,38 @@ use tiny_keccak::{keccak256, Keccak}; #[cfg(not(time_checked_add))] use time_utils::CheckedSystemTime; +/// Bloom of topics. +type Bloom = H512; +/// Topic data index within a bloom. +type BloomTopicIndex = usize; +/// List of envelope topics. +type EnvelopeTopics = SmallVec<[EnvelopeTopic; 4]>; +/// Envelope topic data. +type EnvelopeTopicData = u8; +/// List of envelope topics data. +type EnvelopeTopicsData = [EnvelopeTopicData; 4]; +/// Expiry timestamp of an envelope. +type EnvelopeExpiryTimestamp = u64; +/// Message contained within an envelope +type EnvelopeMessage = Vec; +/// Arbitrary value used to target lower PoW hash. +type EnvelopeNonce = u64; +/// Envelope nonce in bytes. +type EnvelopeNonceBytes = [u8; 8]; +/// Envelope proving work duration in milliseconds. +type EnvelopeProvingWorkDuration = u64; +/// Envelope message uniquely identifying proving hash. +type EnvelopeProvingHash = H256; +/// Envelope work that has been proved by the proving hash. +type EnvelopeProvenWork = f64; +/// Time-to-live of an envelope in seconds. +type EnvelopeTTLDuration = u64; + /// Work-factor proved. Takes 3 parameters: size of message, time to live, /// and hash. /// /// Panics if size or TTL is zero. -pub fn work_factor_proved(size: u64, ttl: u64, hash: H256) -> f64 { +pub fn work_factor_proved(size: u64, ttl: EnvelopeTTLDuration, hash: EnvelopeProvingHash) -> EnvelopeProvenWork { assert!(size != 0 && ttl != 0); let leading_zeros = { @@ -44,51 +71,51 @@ pub fn work_factor_proved(size: u64, ttl: u64, hash: H256) -> f64 { 2.0_f64.powi(leading_zeros as i32) / spacetime } -/// A topic of a message. +/// A topic of a message. The topic is an abridged version of the first four bytes of the original topic's hash. #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct Topic(pub [u8; 4]); +pub struct EnvelopeTopic(pub EnvelopeTopicsData); -impl From<[u8; 4]> for Topic { - fn from(x: [u8; 4]) -> Self { - Topic(x) +impl From for EnvelopeTopic { + fn from(x: EnvelopeTopicsData) -> Self { + EnvelopeTopic(x) } } -impl Topic { - /// set up to three bits in the 64-byte bloom passed. +impl EnvelopeTopic { + /// Set up to three bits in the 64-byte bloom passed. /// - /// this takes 3 sets of 9 bits, treating each as an index in the range + /// This takes 3 sets of 9 bits, treating each as an index in the range /// 0..512 into the bloom and setting the corresponding bit in the bloom to 1. - pub fn bloom_into(&self, bloom: &mut H512) { + pub fn bloom_into(&self, bloom: &mut Bloom) { - let data = &self.0; + let topics_data = &self.0; for i in 0..3 { - let mut idx = data[i] as usize; + let mut topic_idx = topics_data[i] as BloomTopicIndex; - if data[3] & (1 << i) != 0 { - idx += 256; + if topics_data[3] & (1 << i) != 0 { + topic_idx += 256; } - debug_assert!(idx <= 511); - bloom.as_bytes_mut()[idx / 8] |= 1 << (7 - idx % 8); + debug_assert!(topic_idx <= 511); + bloom.as_bytes_mut()[topic_idx / 8] |= 1 << (7 - topic_idx % 8); } } /// Get bloom for single topic. - pub fn bloom(&self) -> H512 { + pub fn bloom(&self) -> Bloom { let mut bloom = Default::default(); self.bloom_into(&mut bloom); bloom } } -impl rlp::Encodable for Topic { +impl rlp::Encodable for EnvelopeTopic { fn rlp_append(&self, s: &mut RlpStream) { s.encoder().encode_value(&self.0); } } -impl rlp::Decodable for Topic { +impl rlp::Decodable for EnvelopeTopic { fn decode(rlp: &Rlp) -> Result { use std::cmp; @@ -96,16 +123,16 @@ impl rlp::Decodable for Topic { cmp::Ordering::Less => Err(DecoderError::RlpIsTooShort), cmp::Ordering::Greater => Err(DecoderError::RlpIsTooBig), cmp::Ordering::Equal => { - let mut t = [0u8; 4]; + let mut t: EnvelopeTopicsData = [0u8; 4]; t.copy_from_slice(bytes); - Ok(Topic(t)) + Ok(EnvelopeTopic(t)) } }) } } /// Calculate union of blooms for given topics. -pub fn bloom_topics(topics: &[Topic]) -> H512 { +pub fn bloom_topics(topics: &[EnvelopeTopic]) -> Bloom { let mut bloom = H512::default(); for topic in topics { topic.bloom_into(&mut bloom); @@ -143,7 +170,8 @@ impl fmt::Display for Error { } } -fn append_topics<'a>(s: &'a mut RlpStream, topics: &[Topic]) -> &'a mut RlpStream { +/// Append given topic(s) to RLP stream. +fn append_topics<'a>(s: &'a mut RlpStream, topics: &[EnvelopeTopic]) -> &'a mut RlpStream { if topics.len() == 1 { s.append(&topics[0]) } else { @@ -151,27 +179,27 @@ fn append_topics<'a>(s: &'a mut RlpStream, topics: &[Topic]) -> &'a mut RlpStrea } } -fn decode_topics(rlp: Rlp) -> Result, DecoderError> { +fn decode_topics(rlp: Rlp) -> Result { if rlp.is_list() { - rlp.iter().map(|r| r.as_val::()).collect() + rlp.iter().map(|r| r.as_val::()).collect() } else { rlp.as_val().map(|t| SmallVec::from_slice(&[t])) } } -// Raw envelope struct. +/// An `Envelope` instance is contained in each `Message`. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Envelope { - /// Expiry timestamp - pub expiry: u64, - /// Time-to-live in seconds - pub ttl: u64, - /// series of 4-byte topics. - pub topics: SmallVec<[Topic; 4]>, - /// The message contained within. - pub data: Vec, + /// Expiry timestamp. + pub expiry: EnvelopeExpiryTimestamp, + /// Time-to-live in seconds. + pub ttl: EnvelopeTTLDuration, + /// Series of 4-byte topics. + pub topics: EnvelopeTopics, + /// The message contained within an envelope. + pub message_data: EnvelopeMessage, /// Arbitrary value used to target lower PoW hash. - pub nonce: u64, + pub nonce: EnvelopeNonce, } impl Envelope { @@ -180,7 +208,8 @@ impl Envelope { self.topics.len() != 1 } - fn proving_hash(&self) -> H256 { + // Generate the uniquely identifying proving hash for the message. + fn proving_hash(&self) -> EnvelopeProvingHash { use byteorder::{BigEndian, ByteOrder}; let mut buf = [0; 32]; @@ -189,7 +218,7 @@ impl Envelope { stream.append(&self.expiry).append(&self.ttl); append_topics(&mut stream, &self.topics) - .append(&self.data); + .append(&self.message_data); let mut digest = Keccak::new_keccak256(); digest.update(&*stream.drain()); @@ -212,7 +241,7 @@ impl rlp::Encodable for Envelope { .append(&self.ttl); append_topics(s, &self.topics) - .append(&self.data) + .append(&self.message_data) .append(&self.nonce); } } @@ -225,7 +254,7 @@ impl rlp::Decodable for Envelope { expiry: rlp.val_at(0)?, ttl: rlp.val_at(1)?, topics: decode_topics(rlp.at(2)?)?, - data: rlp.val_at(3)?, + message_data: rlp.val_at(3)?, nonce: rlp.val_at(4)?, }) } @@ -234,22 +263,22 @@ impl rlp::Decodable for Envelope { /// Message creation parameters. /// Pass this to `Message::create` to make a message. pub struct CreateParams { - /// time-to-live in seconds. - pub ttl: u64, - /// payload data. - pub payload: Vec, - /// Topics. May not be empty. - pub topics: Vec, + /// Envelope time-to-live in seconds. + pub ttl: EnvelopeTTLDuration, + /// Envelope payload of message data. + pub payload: EnvelopeMessage, + /// Envelope topics. Must not be empty. + pub topics: Vec, /// How many milliseconds to spend proving work. - pub work: u64, + pub work: EnvelopeProvingWorkDuration, } /// A whisper message. This is a checked message carrying around metadata. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Message { envelope: Envelope, - bloom: H512, - hash: H256, + bloom: Bloom, + hash: EnvelopeProvingHash, encoded_size: usize, } @@ -270,6 +299,7 @@ impl Message { assert!(params.ttl > 0); + // Expiry period since the last epoch rounded up to the nearest second. let expiry = { let since_epoch = SystemTime::now() .checked_add(Duration::from_secs(params.ttl)) @@ -277,10 +307,13 @@ impl Message { .ok_or(Error::TimestampOverflow)? .duration_since(time::UNIX_EPOCH).expect("time after now is after unix epoch; qed"); - // round up the sub-second to next whole second. + // Round up the sub-second to next whole second. since_epoch.as_secs() + if since_epoch.subsec_nanos() == 0 { 0 } else { 1 } }; + // Encrypt an RLP stream into a digest. Create the RLP stream by appending + // to it the envelope topics, envelope payload of message data, + // envelope ttl, and the expiry period since the last epoch. let start_digest = { let mut stream = RlpStream::new_list(4); stream.append(&expiry).append(¶ms.ttl); @@ -291,8 +324,10 @@ impl Message { digest }; + // Find the best nonce based on using updating the digest with + // randomly generated envelope nonce bytes let mut buf = [0; 32]; - let mut try_nonce = move |nonce: &[u8; 8]| { + let mut try_nonce = move |nonce: &EnvelopeNonceBytes| { let mut digest = start_digest.clone(); digest.update(&nonce[..]); digest.finalize(&mut buf[..]); @@ -300,9 +335,12 @@ impl Message { buf.clone() }; - let mut nonce: [u8; 8] = rng.gen(); + let mut nonce: EnvelopeNonceBytes = rng.gen(); let mut best_found = try_nonce(&nonce); + // Start proving work, which involves repeatedly trying to create another + // nonce hash that is better (lower PoW hash) than the latest best nonce, + // to replace it. let start = Instant::now(); while start.elapsed() <= Duration::from_millis(params.work) { @@ -316,10 +354,10 @@ impl Message { } let envelope = Envelope { - expiry: expiry, + expiry, ttl: params.ttl, topics: params.topics.into_iter().collect(), - data: params.payload, + message_data: params.payload, nonce: BigEndian::read_u64(&nonce[..]), }; @@ -344,9 +382,9 @@ impl Message { Message::from_components(envelope, encoded_size, hash, now) } - // create message from envelope, hash, and encoded size. - // does checks for validity. - fn from_components(envelope: Envelope, size: usize, hash: H256, now: SystemTime) + // Create message from envelope, hash, and encoded size. + // Does checks for validity. + fn from_components(envelope: Envelope, size: usize, hash: EnvelopeProvingHash, now: SystemTime) -> Result { const LEEWAY_SECONDS: u64 = 2; @@ -371,9 +409,9 @@ impl Message { let bloom = bloom_topics(&envelope.topics); Ok(Message { - envelope: envelope, - bloom: bloom, - hash: hash, + envelope, + bloom, + hash, encoded_size: size, }) } @@ -388,18 +426,18 @@ impl Message { self.encoded_size } - /// Get a uniquely identifying hash for the message. - pub fn hash(&self) -> &H256 { + /// Get a uniquely identifying proving hash for the message. + pub fn hash(&self) -> &EnvelopeProvingHash { &self.hash } - /// Get the bloom filter of the topics + /// Get the bloom filter of the topics. pub fn bloom(&self) -> &H512 { &self.bloom } /// Get the work proved by the hash. - pub fn work_proved(&self) -> f64 { + pub fn work_proved(&self) -> EnvelopeProvenWork { let proving_hash = self.envelope.proving_hash(); work_factor_proved(self.encoded_size as _, self.envelope.ttl, proving_hash) @@ -411,13 +449,13 @@ impl Message { } /// Get the topics. - pub fn topics(&self) -> &[Topic] { + pub fn topics(&self) -> &[EnvelopeTopic] { &self.envelope.topics } /// Get the message data. - pub fn data(&self) -> &[u8] { - &self.envelope.data + pub fn message_data(&self) -> &EnvelopeMessage { + &self.envelope.message_data } } @@ -438,7 +476,7 @@ mod tests { assert!(Message::create(CreateParams { ttl: 100, payload: vec![1, 2, 3, 4], - topics: vec![Topic([1, 2, 1, 2])], + topics: vec![EnvelopeTopic([1, 2, 1, 2])], work: 50, }).is_ok()); } @@ -448,7 +486,7 @@ mod tests { let envelope = Envelope { expiry: 100_000, ttl: 30, - data: vec![9; 256], + message_data: vec![9; 256], topics: SmallVec::from_slice(&[Default::default()]), nonce: 1010101, }; @@ -464,8 +502,8 @@ mod tests { let envelope = Envelope { expiry: 100_000, ttl: 30, - data: vec![9; 256], - topics: SmallVec::from_slice(&[Default::default(), Topic([1, 2, 3, 4])]), + message_data: vec![9; 256], + topics: SmallVec::from_slice(&[Default::default(), EnvelopeTopic([1, 2, 3, 4])]), nonce: 1010101, }; @@ -480,7 +518,7 @@ mod tests { let envelope = Envelope { expiry: 100_000, ttl: 30, - data: vec![9; 256], + message_data: vec![9; 256], topics: SmallVec::from_slice(&[Default::default()]), nonce: 1010101, }; @@ -499,7 +537,7 @@ mod tests { let envelope = Envelope { expiry: 100_000, ttl: 30, - data: vec![9; 256], + message_data: vec![9; 256], topics: SmallVec::from_slice(&[Default::default()]), nonce: 1010101, }; @@ -516,7 +554,7 @@ mod tests { let envelope = Envelope { expiry: 100_000, ttl: 200_000, - data: vec![9; 256], + message_data: vec![9; 256], topics: SmallVec::from_slice(&[Default::default()]), nonce: 1010101, }; @@ -530,10 +568,10 @@ mod tests { #[test] fn work_factor() { // 256 leading zeros -> 2^256 / 1 - assert_eq!(work_factor_proved(1, 1, H256::zero()), 115792089237316200000000000000000000000000000000000000000000000000000000000000.0); + assert_eq!(work_factor_proved(1, 1, EnvelopeProvingHash::zero()), 115792089237316200000000000000000000000000000000000000000000000000000000000000.0); // 255 leading zeros -> 2^255 / 1 - assert_eq!(work_factor_proved(1, 1, H256::from_low_u64_be(1)), 57896044618658100000000000000000000000000000000000000000000000000000000000000.0); + assert_eq!(work_factor_proved(1, 1, EnvelopeProvingHash::from_low_u64_be(1)), 57896044618658100000000000000000000000000000000000000000000000000000000000000.0); // 0 leading zeros -> 2^0 / 1 - assert_eq!(work_factor_proved(1, 1, serde_json::from_str::("\"0xff00000000000000000000000000000000000000000000000000000000000000\"").unwrap()), 1.0); + assert_eq!(work_factor_proved(1, 1, serde_json::from_str::("\"0xff00000000000000000000000000000000000000000000000000000000000000\"").unwrap()), 1.0); } } diff --git a/whisper/src/rpc/filter.rs b/whisper/src/rpc/filter.rs index a58f16f9c85..84a6445ca51 100644 --- a/whisper/src/rpc/filter.rs +++ b/whisper/src/rpc/filter.rs @@ -24,7 +24,7 @@ use ethkey::Public; use jsonrpc_pubsub::typed::{Subscriber, Sink}; use parking_lot::{Mutex, RwLock}; -use message::{Message, Topic}; +use message::{Message, EnvelopeTopic}; use super::{key_store::KeyStore, types::{self, FilterItem, HexEncode}}; /// Kinds of filters, @@ -198,7 +198,7 @@ impl Drop for Manager { /// Filter incoming messages by critera. pub struct Filter { - topics: Vec<(Vec, H512, Topic)>, + topics: Vec<(Vec, H512, EnvelopeTopic)>, from: Option, decrypt_with: Option, } @@ -278,7 +278,7 @@ impl Filter { } }; - let decrypted = match decrypt.decrypt(message.data()) { + let decrypted = match decrypt.decrypt(message.message_data()) { Some(d) => d, None => { trace!(target: "whisper", "Failed to decrypt message with {} matching topics", @@ -317,7 +317,7 @@ impl Filter { #[cfg(test)] mod tests { - use message::{CreateParams, Message, Topic}; + use message::{CreateParams, Message, EnvelopeTopic}; use rpc::types::{FilterRequest, HexEncode}; use rpc::abridge_topic; use super::*; @@ -366,7 +366,7 @@ mod tests { let message = Message::create(CreateParams { ttl: 100, payload: vec![1, 3, 5, 7, 9], - topics: vec![Topic([1, 8, 3, 99])], + topics: vec![EnvelopeTopic([1, 8, 3, 99])], work: 0, }).unwrap(); diff --git a/whisper/src/rpc/mod.rs b/whisper/src/rpc/mod.rs index 57ec4c6c4f7..0612fb5ac33 100644 --- a/whisper/src/rpc/mod.rs +++ b/whisper/src/rpc/mod.rs @@ -19,7 +19,7 @@ //! Manages standard message format decoding, ephemeral identities, signing, //! encryption, and decryption. //! -//! Provides an interface for using whisper to transmit data securely. +//! Provides an interface for using Whisper to transmit data securely. use std::sync::Arc; @@ -35,7 +35,7 @@ use self::filter::Filter; use self::key_store::{Key, KeyStore}; use self::types::HexEncode; -use message::{CreateParams, Message, Topic}; +use message::{CreateParams, Message, EnvelopeTopic}; mod crypto; mod filter; @@ -61,7 +61,7 @@ fn topic_hash(topic: &[u8]) -> H256 { } // abridge topic using first four bytes of hash. -fn abridge_topic(topic: &[u8]) -> Topic { +fn abridge_topic(topic: &[u8]) -> EnvelopeTopic { let mut abridged = [0; 4]; let hash = topic_hash(topic).0; abridged.copy_from_slice(&hash[..4]); @@ -99,6 +99,7 @@ pub trait Whisper { #[rpc(name = "shh_getPrivateKey")] fn get_private(&self, types::Identity) -> Result; + /// Get symmetric key. Succeeds if identity has been stored. #[rpc(name = "shh_getSymKey")] fn get_symmetric(&self, types::Identity) -> Result;