From a950b81ee81e39b349acab2283aacd98859cf222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 17 May 2016 10:32:05 +0200 Subject: [PATCH 1/3] Fixing clippy warnings --- ethcore/src/account.rs | 2 -- ethcore/src/basic_authority.rs | 1 - ethcore/src/ethereum/ethash.rs | 1 - ethcore/src/ethereum/mod.rs | 1 - ethcore/src/state.rs | 2 -- ethcore/src/trace/db.rs | 2 +- ethcore/src/types/ids.rs | 1 - ipc/codegen/src/codegen.rs | 1 - ipc/codegen/src/serialization.rs | 4 ++-- miner/src/transaction_queue.rs | 26 +++++++++++++------------- parity/configuration.rs | 8 ++++---- parity/hypervisor/service.rs.in | 1 - parity/main.rs | 2 +- parity/price_info.rs | 2 +- parity/setup_log.rs | 2 +- parity/upgrade.rs | 2 +- sync/src/chain.rs | 12 ++++++------ sync/src/range_collection.rs | 2 +- sync/src/tests/chain.rs | 1 - sync/src/tests/helpers.rs | 2 +- webapp/src/router/redirect.rs | 1 - 21 files changed, 32 insertions(+), 44 deletions(-) diff --git a/ethcore/src/account.rs b/ethcore/src/account.rs index f2942a7e1..66cceda42 100644 --- a/ethcore/src/account.rs +++ b/ethcore/src/account.rs @@ -342,7 +342,6 @@ mod tests { #[test] fn new_account() { - use rustc_serialize::hex::ToHex; let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new()); assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); @@ -354,7 +353,6 @@ mod tests { #[test] fn create_account() { - use rustc_serialize::hex::ToHex; let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new()); assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); diff --git a/ethcore/src/basic_authority.rs b/ethcore/src/basic_authority.rs index e1dab7c17..d56cbb638 100644 --- a/ethcore/src/basic_authority.rs +++ b/ethcore/src/basic_authority.rs @@ -200,7 +200,6 @@ mod tests { use super::*; use common::*; use block::*; - use engine::*; use tests::helpers::*; use util::keys::{TestAccountProvider, TestAccount}; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 11b13c0c1..e7a378483 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -299,7 +299,6 @@ mod tests { use common::*; use block::*; - use engine::*; use tests::helpers::*; use super::super::new_morden; diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 4cc98ee2b..1f5712c54 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -51,7 +51,6 @@ pub fn new_morden() -> Spec { Spec::load(include_bytes!("../../res/ethereum/mord mod tests { use common::*; use state::*; - use engine::*; use super::*; use tests::helpers::*; diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index c44614550..391730a94 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -358,8 +358,6 @@ mod tests { use super::*; use util::common::*; -use util::trie::*; -use util::rlp::*; use account::*; use tests::helpers::*; use devtools::*; diff --git a/ethcore/src/trace/db.rs b/ethcore/src/trace/db.rs index 5c88ee52b..a69a1ca27 100644 --- a/ethcore/src/trace/db.rs +++ b/ethcore/src/trace/db.rs @@ -22,7 +22,7 @@ use std::sync::{RwLock, Arc}; use std::path::Path; use bloomchain::{Number, Config as BloomConfig}; use bloomchain::group::{BloomGroupDatabase, BloomGroupChain, GroupPosition, BloomGroup}; -use util::{FixedHash, H256, H264, Database, DBTransaction}; +use util::{H256, H264, Database, DBTransaction}; use header::BlockNumber; use trace::{BlockTraces, LocalizedTrace, Config, Switch, Filter, Database as TraceDatabase, ImportRequest, DatabaseExtras}; diff --git a/ethcore/src/types/ids.rs b/ethcore/src/types/ids.rs index 8fffcb8f7..3390f020e 100644 --- a/ethcore/src/types/ids.rs +++ b/ethcore/src/types/ids.rs @@ -19,7 +19,6 @@ use util::hash::H256; use header::BlockNumber; use ipc::binary::BinaryConvertError; -use ipc::binary::BinaryConvertable; use std::mem; use std::collections::VecDeque; diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs index 6f16994b6..362257fcf 100644 --- a/ipc/codegen/src/codegen.rs +++ b/ipc/codegen/src/codegen.rs @@ -33,7 +33,6 @@ use syntax::ast::{ use syntax::ast; use syntax::codemap::Span; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; pub struct Error; diff --git a/ipc/codegen/src/serialization.rs b/ipc/codegen/src/serialization.rs index e8f3d2cd8..8cd9ffdca 100644 --- a/ipc/codegen/src/serialization.rs +++ b/ipc/codegen/src/serialization.rs @@ -252,14 +252,14 @@ fn binary_expr_struct( map_stmts.push(quote_stmt!(cx, map[$field_index] = total;).unwrap()); if ::syntax::print::pprust::ty_to_string(&codegen::strip_ptr(&field.ty)) == "u8" { - map_stmts.push(quote_stmt!(cx, total = total + 1;).unwrap()); + map_stmts.push(quote_stmt!(cx, total += 1;).unwrap()); } else { map_stmts.push(quote_stmt!(cx, let size = match $field_type_ident_qualified::len_params() { 0 => mem::size_of::<$field_type_ident>(), _ => length_stack.pop_front().unwrap(), }).unwrap()); - map_stmts.push(quote_stmt!(cx, total = total + size;).unwrap()); + map_stmts.push(quote_stmt!(cx, total += size;).unwrap()); } }; diff --git a/miner/src/transaction_queue.rs b/miner/src/transaction_queue.rs index 987dfde50..fc62c411e 100644 --- a/miner/src/transaction_queue.rs +++ b/miner/src/transaction_queue.rs @@ -535,12 +535,12 @@ impl TransactionQueue { /// Update height of all transactions in future transactions set. fn update_future(&mut self, sender: &Address, current_nonce: U256) { // We need to drain all transactions for current sender from future and reinsert them with updated height - let all_nonces_from_sender = match self.future.by_address.row(&sender) { + let all_nonces_from_sender = match self.future.by_address.row(sender) { Some(row_map) => row_map.keys().cloned().collect::>(), None => vec![], }; for k in all_nonces_from_sender { - let order = self.future.drop(&sender, &k).unwrap(); + let order = self.future.drop(sender, &k).unwrap(); if k >= current_nonce { self.future.insert(*sender, k, order.update_height(k, current_nonce)); } else { @@ -554,14 +554,14 @@ impl TransactionQueue { /// Drop all transactions from given sender from `current`. /// Either moves them to `future` or removes them from queue completely. fn move_all_to_future(&mut self, sender: &Address, current_nonce: U256) { - let all_nonces_from_sender = match self.current.by_address.row(&sender) { + let all_nonces_from_sender = match self.current.by_address.row(sender) { Some(row_map) => row_map.keys().cloned().collect::>(), None => vec![], }; for k in all_nonces_from_sender { // Goes to future or is removed - let order = self.current.drop(&sender, &k).unwrap(); + let order = self.current.drop(sender, &k).unwrap(); if k >= current_nonce { self.future.insert(*sender, k, order.update_height(k, current_nonce)); } else { @@ -803,7 +803,7 @@ mod test { fn new_tx() -> SignedTransaction { let keypair = KeyPair::create().unwrap(); - new_unsigned_tx(U256::from(123)).sign(&keypair.secret()) + new_unsigned_tx(U256::from(123)).sign(keypair.secret()) } @@ -1173,9 +1173,9 @@ mod test { let mut txq = TransactionQueue::new(); let kp = KeyPair::create().unwrap(); let secret = kp.secret(); - let tx = new_unsigned_tx(U256::from(123)).sign(&secret); - let tx1 = new_unsigned_tx(U256::from(124)).sign(&secret); - let tx2 = new_unsigned_tx(U256::from(125)).sign(&secret); + let tx = new_unsigned_tx(U256::from(123)).sign(secret); + let tx1 = new_unsigned_tx(U256::from(124)).sign(secret); + let tx2 = new_unsigned_tx(U256::from(125)).sign(secret); txq.add(tx, &default_nonce, TransactionOrigin::External).unwrap(); assert_eq!(txq.status().pending, 1); @@ -1403,11 +1403,11 @@ mod test { // given let mut txq = TransactionQueue::new(); let keypair = KeyPair::create().unwrap(); - let tx = new_unsigned_tx(U256::from(123)).sign(&keypair.secret()); + let tx = new_unsigned_tx(U256::from(123)).sign(keypair.secret()); let tx2 = { let mut tx2 = tx.deref().clone(); tx2.gas_price = U256::from(200); - tx2.sign(&keypair.secret()) + tx2.sign(keypair.secret()) }; // when @@ -1426,16 +1426,16 @@ mod test { // given let mut txq = TransactionQueue::new(); let keypair = KeyPair::create().unwrap(); - let tx0 = new_unsigned_tx(U256::from(123)).sign(&keypair.secret()); + let tx0 = new_unsigned_tx(U256::from(123)).sign(keypair.secret()); let tx1 = { let mut tx1 = tx0.deref().clone(); tx1.nonce = U256::from(124); - tx1.sign(&keypair.secret()) + tx1.sign(keypair.secret()) }; let tx2 = { let mut tx2 = tx1.deref().clone(); tx2.gas_price = U256::from(200); - tx2.sign(&keypair.secret()) + tx2.sign(keypair.secret()) }; // when diff --git a/parity/configuration.rs b/parity/configuration.rs index ba7789c08..92d69b068 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -171,7 +171,7 @@ impl Configuration { let (listen, public) = self.net_addresses(); ret.listen_address = listen; ret.public_address = public; - ret.use_secret = self.args.flag_node_key.as_ref().map(|s| Secret::from_str(&s).unwrap_or_else(|_| s.sha3())); + ret.use_secret = self.args.flag_node_key.as_ref().map(|s| Secret::from_str(s).unwrap_or_else(|_| s.sha3())); ret.discovery_enabled = !self.args.flag_no_discovery && !self.args.flag_nodiscover; ret.ideal_peers = self.max_peers(); let mut net_path = PathBuf::from(&self.path()); @@ -185,7 +185,7 @@ impl Configuration { let mut latest_era = None; let jdb_types = [journaldb::Algorithm::Archive, journaldb::Algorithm::EarlyMerge, journaldb::Algorithm::OverlayRecent, journaldb::Algorithm::RefCounted]; for i in jdb_types.into_iter() { - let db = journaldb::new(&append_path(&get_db_path(&Path::new(&self.path()), *i, spec.genesis_header().hash()), "state"), *i); + let db = journaldb::new(&append_path(&get_db_path(Path::new(&self.path()), *i, spec.genesis_header().hash()), "state"), *i); trace!(target: "parity", "Looking for best DB: {} at {:?}", i, db.latest_era()); match (latest_era, db.latest_era()) { (Some(best), Some(this)) if best >= this => {} @@ -251,7 +251,7 @@ impl Configuration { let account_service = AccountService::with_security(Path::new(&self.keys_path()), self.keys_iterations()); if let Some(ref unlocks) = self.args.flag_unlock { for d in unlocks.split(',') { - let a = Address::from_str(clean_0x(&d)).unwrap_or_else(|_| { + let a = Address::from_str(clean_0x(d)).unwrap_or_else(|_| { die!("{}: Invalid address for --unlock. Must be 40 hex characters, without the 0x at the beginning.", d) }); if passwords.iter().find(|p| account_service.unlock_account_no_expire(&a, p).is_ok()).is_none() { @@ -302,7 +302,7 @@ impl Configuration { pub fn directories(&self) -> Directories { let db_path = Configuration::replace_home( - &self.args.flag_datadir.as_ref().unwrap_or(&self.args.flag_db_path)); + self.args.flag_datadir.as_ref().unwrap_or(&self.args.flag_db_path)); ::std::fs::create_dir_all(&db_path).unwrap_or_else(|e| die_with_io_error("main", e)); let keys_path = Configuration::replace_home(&self.args.flag_keys_path); diff --git a/parity/hypervisor/service.rs.in b/parity/hypervisor/service.rs.in index a8ad90e12..12c39d90a 100644 --- a/parity/hypervisor/service.rs.in +++ b/parity/hypervisor/service.rs.in @@ -18,7 +18,6 @@ use std::sync::{RwLock,Arc}; use std::ops::*; use ipc::IpcConfig; use std::collections::HashMap; -use ipc::BinaryConvertable; use std::mem; use ipc::binary::BinaryConvertError; use std::collections::VecDeque; diff --git a/parity/main.rs b/parity/main.rs index dd70d39cc..862e3d336 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -138,7 +138,7 @@ fn execute_client(conf: Configuration) { // Build client let mut service = ClientService::start( - client_config, spec, net_settings, &Path::new(&conf.path()) + client_config, spec, net_settings, Path::new(&conf.path()) ).unwrap_or_else(|e| die_with_error("Client", e)); panic_handler.forward_from(&service); diff --git a/parity/price_info.rs b/parity/price_info.rs index 05b89d848..ad25f31da 100644 --- a/parity/price_info.rs +++ b/parity/price_info.rs @@ -37,7 +37,7 @@ impl PriceInfo { .and_then(|json| json.find_path(&["result", "ethusd"]) .and_then(|obj| match *obj { Json::String(ref s) => Some(PriceInfo { - ethusd: FromStr::from_str(&s).unwrap() + ethusd: FromStr::from_str(s).unwrap() }), _ => None })) diff --git a/parity/setup_log.rs b/parity/setup_log.rs index 75cd0f574..0fbc76fb3 100644 --- a/parity/setup_log.rs +++ b/parity/setup_log.rs @@ -31,7 +31,7 @@ pub fn setup_log(init: &Option) -> Arc { if env::var("RUST_LOG").is_ok() { let lvl = &env::var("RUST_LOG").unwrap(); - levels.push_str(&lvl); + levels.push_str(lvl); levels.push_str(","); builder.parse(lvl); } diff --git a/parity/upgrade.rs b/parity/upgrade.rs index 30c977df4..e976535b0 100644 --- a/parity/upgrade.rs +++ b/parity/upgrade.rs @@ -87,7 +87,7 @@ fn upgrade_from_version(previous_version: &Version) -> Result { if upgrade_key.is_applicable(previous_version, ¤t_version) { let upgrade_script = upgrades[upgrade_key]; try!(upgrade_script()); - count = count + 1; + count += 1; } } Ok(count) diff --git a/sync/src/chain.rs b/sync/src/chain.rs index bd94fb9be..6d7a76572 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -791,8 +791,8 @@ impl ChainSync { self.downloading_hashes.remove(&hash); } for b in &peer.asking_blocks { - self.downloading_headers.remove(&b); - self.downloading_bodies.remove(&b); + self.downloading_headers.remove(b); + self.downloading_bodies.remove(b); } peer.asking_blocks.clear(); } @@ -1255,7 +1255,7 @@ impl ChainSync { self.send_packet(io, peer_id, NEW_BLOCK_PACKET, rlp); self.peers.get_mut(&peer_id).unwrap().latest_hash = chain_info.best_block_hash.clone(); self.peers.get_mut(&peer_id).unwrap().latest_number = Some(chain_info.best_block_number); - sent = sent + 1; + sent += 1; } sent } @@ -1271,7 +1271,7 @@ impl ChainSync { // If we think peer is too far behind just send one latest hash peer_best = last_parent.clone(); } - sent = sent + match ChainSync::create_new_hashes_rlp(io.chain(), &peer_best, &chain_info.best_block_hash) { + sent += match ChainSync::create_new_hashes_rlp(io.chain(), &peer_best, &chain_info.best_block_hash) { Some(rlp) => { { let peer = self.peers.get_mut(&peer_id).unwrap(); @@ -1668,7 +1668,7 @@ mod tests { sync.propagate_new_hashes(&chain_info, &mut io); let data = &io.queue[0].data.clone(); - let result = sync.on_peer_new_hashes(&mut io, 0, &UntrustedRlp::new(&data)); + let result = sync.on_peer_new_hashes(&mut io, 0, &UntrustedRlp::new(data)); assert!(result.is_ok()); } @@ -1686,7 +1686,7 @@ mod tests { sync.propagate_blocks(&chain_info, &mut io); let data = &io.queue[0].data.clone(); - let result = sync.on_peer_new_block(&mut io, 0, &UntrustedRlp::new(&data)); + let result = sync.on_peer_new_block(&mut io, 0, &UntrustedRlp::new(data)); assert!(result.is_ok()); } diff --git a/sync/src/range_collection.rs b/sync/src/range_collection.rs index 0628df401..6b57f0a4b 100644 --- a/sync/src/range_collection.rs +++ b/sync/src/range_collection.rs @@ -70,7 +70,7 @@ impl<'c, K:'c, V:'c> Iterator for RangeIterator<'c, K, V> where K: Add { - Some((*k, &vec)) + Some((*k, vec)) }, None => None } diff --git a/sync/src/tests/chain.rs b/sync/src/tests/chain.rs index eebbdb164..4ed25325b 100644 --- a/sync/src/tests/chain.rs +++ b/sync/src/tests/chain.rs @@ -16,7 +16,6 @@ use util::*; use ethcore::client::{BlockChainClient, BlockId, EachBlockWith}; -use io::SyncIo; use chain::{SyncState}; use super::helpers::*; diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index 269362064..41eadf716 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -147,7 +147,7 @@ impl TestNet { let mut total_steps = 0; while !self.done() { self.sync_step(); - total_steps = total_steps + 1; + total_steps += 1; } total_steps } diff --git a/webapp/src/router/redirect.rs b/webapp/src/router/redirect.rs index f308635cd..6faf9d0c8 100644 --- a/webapp/src/router/redirect.rs +++ b/webapp/src/router/redirect.rs @@ -16,7 +16,6 @@ //! HTTP Redirection hyper handler -use std::io::Write; use hyper::{header, server, Decoder, Encoder, Next}; use hyper::net::HttpStream; use hyper::status::StatusCode; From 46f3b5f9137c67fdcd63ec8ff6a5ac0813844da3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 19 May 2016 00:41:41 +0200 Subject: [PATCH 2/3] Fix up the seal fields in RPC output. (#1096) Make Ethash::extra_info() work. Seal fields now decode the RLP. --- ethcore/src/ethereum/ethash.rs | 4 +++- rpc/src/v1/impls/eth.rs | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index e7a378483..0cf436d7c 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -93,7 +93,9 @@ impl Engine for Ethash { } /// Additional engine-specific information for the user/developer concerning `header`. - fn extra_info(&self, _header: &Header) -> HashMap { HashMap::new() } + fn extra_info(&self, header: &Header) -> HashMap { + hash_map!["nonce".to_owned() => format!("0x{}", header.nonce().hex()), "mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())] + } fn vm_factory(&self) -> &Factory { &self.factory diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 6fddf7b4f..6222d000d 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -27,7 +27,7 @@ use jsonrpc_core::*; use util::numbers::*; use util::sha3::*; use util::bytes::{ToPretty}; -use util::rlp::{encode, UntrustedRlp, View}; +use util::rlp::{encode, decode, UntrustedRlp, View}; use ethcore::client::*; use ethcore::block::IsBlock; use ethcore::views::*; @@ -97,7 +97,7 @@ impl EthClient timestamp: U256::from(view.timestamp()), difficulty: view.difficulty(), total_difficulty: total_difficulty, - seal_fields: view.seal().into_iter().map(Bytes::new).collect(), + seal_fields: view.seal().into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), uncles: block_view.uncle_hashes(), transactions: { if include_txs { @@ -142,7 +142,7 @@ impl EthClient 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(Bytes::new).collect(), + seal_fields: uncle.seal.into_iter().map(|f| decode(&f)).map(Bytes::new).collect(), uncles: vec![], transactions: BlockTransactions::Hashes(vec![]), }; From 6cff58055dc86f4bdb3382b22d445921da127125 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 19 May 2016 00:44:49 +0200 Subject: [PATCH 3/3] CLI option for using JITEVM (#1103) * easily configurable vm (in progress) * completely removed vm_factory from engine * --jitvm command line flag --- ethcore/src/basic_authority.rs | 15 ++---- ethcore/src/block.rs | 39 ++++++++------- ethcore/src/client/client.rs | 12 ++++- ethcore/src/client/config.rs | 3 ++ ethcore/src/client/mod.rs | 6 ++- ethcore/src/client/test_client.rs | 5 ++ ethcore/src/engine.rs | 5 +- ethcore/src/ethereum/ethash.rs | 20 ++------ ethcore/src/evm/factory.rs | 32 +++++++++---- ethcore/src/evm/mod.rs | 3 +- ethcore/src/executive.rs | 71 ++++++++++++++-------------- ethcore/src/externalities.rs | 27 +++++++---- ethcore/src/json_tests/executive.rs | 9 ++-- ethcore/src/json_tests/state.rs | 3 +- ethcore/src/null_engine.rs | 8 +--- ethcore/src/state.rs | 73 +++++++++++++++++------------ ethcore/src/tests/helpers.rs | 10 +--- miner/src/miner.rs | 4 +- parity/cli.rs | 4 ++ parity/configuration.rs | 10 +++- 20 files changed, 204 insertions(+), 155 deletions(-) diff --git a/ethcore/src/basic_authority.rs b/ethcore/src/basic_authority.rs index d56cbb638..fec23cf54 100644 --- a/ethcore/src/basic_authority.rs +++ b/ethcore/src/basic_authority.rs @@ -21,7 +21,7 @@ use util::keys::store::AccountProvider; use block::*; use spec::{CommonParams, Spec}; use engine::*; -use evm::{Schedule, Factory}; +use evm::Schedule; use ethjson; /// `BasicAuthority` params. @@ -51,7 +51,6 @@ pub struct BasicAuthority { params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap, - factory: Factory, } impl BasicAuthority { @@ -61,7 +60,6 @@ impl BasicAuthority { params: params, our_params: our_params, builtins: builtins, - factory: Factory::default(), } } } @@ -78,8 +76,6 @@ impl Engine for BasicAuthority { /// Additional engine-specific information for the user/developer concerning `header`. fn extra_info(&self, _header: &Header) -> HashMap { hash_map!["signature".to_owned() => "TODO".to_owned()] } - fn vm_factory(&self) -> &Factory { &self.factory } - fn schedule(&self, _env_info: &EnvInfo) -> Schedule { Schedule::new_homestead() } @@ -210,12 +206,6 @@ mod tests { assert!(engine.version().major >= 1); } - #[test] - fn can_return_factory() { - let engine = new_test_authority().engine; - engine.vm_factory(); - } - #[test] fn can_return_schedule() { let engine = new_test_authority().engine; @@ -287,7 +277,8 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; - let b = OpenBlock::new(engine.deref(), false, db, &genesis_header, last_hashes, addr.clone(), x!(3141562), vec![]); + let vm_factory = Default::default(); + let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, addr.clone(), x!(3141562), vec![]); let b = b.close_and_lock(); let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 17b0e7071..90d4eec2d 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -23,6 +23,7 @@ use engine::*; use state::*; use verification::PreverifiedBlock; use trace::Trace; +use evm::Factory as EvmFactory; /// A block, encoded as it is on the block chain. #[derive(Default, Debug, Clone)] @@ -190,6 +191,7 @@ impl IsBlock for ExecutedBlock { pub struct OpenBlock<'x> { block: ExecutedBlock, engine: &'x Engine, + vm_factory: &'x EvmFactory, last_hashes: LastHashes, } @@ -226,10 +228,11 @@ pub struct SealedBlock { impl<'x> OpenBlock<'x> { #[cfg_attr(feature="dev", allow(too_many_arguments))] /// Create a new `OpenBlock` ready for transaction pushing. - pub fn new(engine: &'x Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, author: Address, gas_floor_target: U256, extra_data: Bytes) -> Self { + pub fn new(engine: &'x Engine, vm_factory: &'x EvmFactory, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, author: Address, gas_floor_target: U256, extra_data: Bytes) -> Self { let mut r = OpenBlock { block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()), tracing), engine: engine, + vm_factory: vm_factory, last_hashes: last_hashes, }; @@ -308,7 +311,7 @@ impl<'x> OpenBlock<'x> { let env_info = self.env_info(); // info!("env_info says gas_used={}", env_info.gas_used); - match self.block.state.apply(&env_info, self.engine, &t, self.block.traces.is_some()) { + match self.block.state.apply(&env_info, self.engine, self.vm_factory, &t, self.block.traces.is_some()) { Ok(outcome) => { self.block.transactions_set.insert(h.unwrap_or_else(||t.hash())); self.block.base.transactions.push(t); @@ -393,13 +396,14 @@ impl ClosedBlock { } /// Given an engine reference, reopen the `ClosedBlock` into an `OpenBlock`. - pub fn reopen(self, engine: &Engine) -> OpenBlock { + pub fn reopen<'a>(self, engine: &'a Engine, vm_factory: &'a EvmFactory) -> OpenBlock<'a> { // 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, + vm_factory: vm_factory, last_hashes: self.last_hashes, } } @@ -457,7 +461,7 @@ impl IsBlock for SealedBlock { /// Enact the block given by block header, transactions and uncles #[cfg_attr(feature="dev", allow(too_many_arguments))] -pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes) -> Result { +pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result { { if ::log::max_log_level() >= ::log::LogLevel::Trace { let s = State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce()); @@ -465,7 +469,7 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head } } - let mut b = OpenBlock::new(engine, tracing, db, parent, last_hashes, header.author().clone(), x!(3141562), header.extra_data().clone()); + let mut b = OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, header.author().clone(), x!(3141562), header.extra_data().clone()); b.set_difficulty(*header.difficulty()); b.set_gas_limit(*header.gas_limit()); b.set_timestamp(header.timestamp()); @@ -475,22 +479,22 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head } /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header -pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes) -> Result { +pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result { let block = BlockView::new(block_bytes); let header = block.header(); - enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes) + enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, vm_factory) } /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header -pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes) -> Result { +pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result { let view = BlockView::new(&block.bytes); - enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes) + enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, vm_factory) } /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards -pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes) -> Result { +pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result { let header = BlockView::new(block_bytes).header_view(); - Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes)).seal(engine, header.seal()))) + Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, vm_factory)).seal(engine, header.seal()))) } #[cfg(test)] @@ -509,7 +513,8 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; - let b = OpenBlock::new(engine.deref(), false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); + let vm_factory = Default::default(); + let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); let b = b.close_and_lock(); let _ = b.seal(engine.deref(), vec![]); } @@ -524,14 +529,15 @@ 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 b = OpenBlock::new(engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]).close_and_lock().seal(engine.deref(), vec![]).unwrap(); + let vm_factory = Default::default(); + let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]).close_and_lock().seal(engine.deref(), vec![]).unwrap(); let orig_bytes = b.rlp_bytes(); let orig_db = b.drain(); 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()]).unwrap(); + let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], &Default::default()).unwrap(); assert_eq!(e.rlp_bytes(), orig_bytes); @@ -550,7 +556,8 @@ 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 mut open_block = OpenBlock::new(engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]); + let vm_factory = Default::default(); + let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]); let mut uncle1_header = Header::new(); uncle1_header.extra_data = b"uncle1".to_vec(); let mut uncle2_header = Header::new(); @@ -565,7 +572,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()]).unwrap(); + let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], &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 0d61325d9..cff9e5323 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -46,6 +46,7 @@ use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Databa use trace; pub use types::blockchain_info::BlockChainInfo; pub use types::block_status::BlockStatus; +use evm::Factory as EvmFactory; impl fmt::Display for BlockChainInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -87,6 +88,7 @@ pub struct Client where V: Verifier { import_lock: Mutex<()>, panic_handler: Arc, verifier: PhantomData, + vm_factory: Arc, } const HISTORY: u64 = 1200; @@ -151,6 +153,7 @@ impl Client where V: Verifier { import_lock: Mutex::new(()), panic_handler: panic_handler, verifier: PhantomData, + vm_factory: Arc::new(EvmFactory::new(config.vm_type)), }) } @@ -204,7 +207,7 @@ impl Client where V: Verifier { 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); + let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, &self.vm_factory); if let Err(e) = enact_result { warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); return Err(()); @@ -422,7 +425,7 @@ impl BlockChainClient for Client where V: Verifier { state.sub_balance(&sender, &balance); state.add_balance(&sender, &U256::max_value()); let options = TransactOptions { tracing: false, check_nonce: false }; - Executive::new(&mut state, &env_info, self.engine.deref().deref()).transact(t, options) + Executive::new(&mut state, &env_info, self.engine.deref().deref(), &self.vm_factory).transact(t, options) } // TODO [todr] Should be moved to miner crate eventually. @@ -434,6 +437,10 @@ impl BlockChainClient for Client where V: Verifier { self.engine.deref().deref() } + fn vm_factory(&self) -> &EvmFactory { + &self.vm_factory + } + // TODO [todr] Should be moved to miner crate eventually. fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec) -> (Option, HashSet) { @@ -443,6 +450,7 @@ impl BlockChainClient for Client where V: Verifier { let mut b = OpenBlock::new( engine, + &self.vm_factory, false, // TODO: this will need to be parameterised once we want to do immediate mining insertion. self.state_db.lock().unwrap().boxed_clone(), match self.chain.block_header(&h) { Some(ref x) => x, None => { return (None, invalid_transactions) } }, diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index df685f0d1..7acea0070 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -17,6 +17,7 @@ pub use block_queue::BlockQueueConfig; pub use blockchain::BlockChainConfig; pub use trace::{Config as TraceConfig, Switch}; +pub use evm::VMType; use util::journaldb; /// Client configuration. Includes configs for all sub-systems. @@ -28,6 +29,8 @@ pub struct ClientConfig { pub blockchain: BlockChainConfig, /// Trace configuration. pub tracing: TraceConfig, + /// VM type. + pub vm_type: VMType, /// The JournalDB ("pruning") algorithm to use. pub pruning: journaldb::Algorithm, /// The name of the client instance. diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index a748ff900..b6f6fde2d 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -22,7 +22,7 @@ mod test_client; mod trace; pub use self::client::*; -pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig, Switch}; +pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig, Switch, VMType}; pub use types::ids::*; pub use self::test_client::{TestBlockChainClient, EachBlockWith}; pub use self::trace::Filter as TraceFilter; @@ -45,6 +45,7 @@ use error::{ImportResult, ExecutionError}; use receipt::LocalizedReceipt; use engine::{Engine}; use trace::LocalizedTrace; +use evm::Factory as EvmFactory; /// Blockchain database client. Owns and manages a blockchain and a block queue. pub trait BlockChainClient : Sync + Send { @@ -140,6 +141,9 @@ pub trait BlockChainClient : Sync + Send { /// Executes a function providing it with a reference to an engine. fn engine(&self) -> &Engine; + /// Returns EvmFactory. + fn vm_factory(&self) -> &EvmFactory; + /// Returns traces matching given filter. fn filter_traces(&self, filter: TraceFilter) -> Option>; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 4ec993fe5..80bb1d63d 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -27,6 +27,7 @@ use log_entry::LocalizedLogEntry; use receipt::{Receipt, LocalizedReceipt}; use extras::BlockReceipts; use error::{ImportResult}; +use evm::Factory as EvmFactory; use block_queue::BlockQueueInfo; use block::{SealedBlock, ClosedBlock, LockedBlock}; @@ -434,6 +435,10 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } + fn vm_factory(&self) -> &EvmFactory { + unimplemented!(); + } + fn filter_traces(&self, _filter: TraceFilter) -> Option> { unimplemented!(); } diff --git a/ethcore/src/engine.rs b/ethcore/src/engine.rs index 344144c6e..d0c72f26c 100644 --- a/ethcore/src/engine.rs +++ b/ethcore/src/engine.rs @@ -18,7 +18,7 @@ use common::*; use util::keys::store::AccountProvider; use block::ExecutedBlock; use spec::CommonParams; -use evm::{Schedule, Factory}; +use evm::Schedule; /// A consensus mechanism for the chain. Generally either proof-of-work or proof-of-stake-based. /// Provides hooks into each of the major parts of block import. @@ -37,9 +37,6 @@ pub trait Engine : Sync + Send { /// Get the general parameters of the chain. fn params(&self) -> &CommonParams; - /// Get current EVM factory - fn vm_factory(&self) -> &Factory; - /// Get the EVM schedule for the given `env_info`. fn schedule(&self, env_info: &EnvInfo) -> Schedule; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 0cf436d7c..cb06959d0 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -21,7 +21,7 @@ use common::*; use block::*; use spec::CommonParams; use engine::*; -use evm::{Schedule, Factory}; +use evm::Schedule; use ethjson; /// Ethash params. @@ -64,7 +64,6 @@ pub struct Ethash { ethash_params: EthashParams, builtins: BTreeMap, pow: EthashManager, - factory: Factory, } impl Ethash { @@ -75,7 +74,6 @@ impl Ethash { ethash_params: ethash_params, builtins: builtins, pow: EthashManager::new(), - factory: Factory::default(), } } } @@ -97,10 +95,6 @@ impl Engine for Ethash { hash_map!["nonce".to_owned() => format!("0x{}", header.nonce().hex()), "mixHash".to_owned() => format!("0x{}", header.mix_hash().hex())] } - fn vm_factory(&self) -> &Factory { - &self.factory - } - fn schedule(&self, env_info: &EnvInfo) -> Schedule { trace!(target: "client", "Creating schedule. fCML={}", self.ethash_params.frontier_compatibility_mode_limit); @@ -313,7 +307,8 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; - let b = OpenBlock::new(engine.deref(), false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); + let vm_factory = Default::default(); + let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); let b = b.close(); assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap()); } @@ -327,7 +322,8 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; - let mut b = OpenBlock::new(engine.deref(), false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); + let vm_factory = Default::default(); + let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); let mut uncle = Header::new(); let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106"); uncle.author = uncle_author.clone(); @@ -345,12 +341,6 @@ mod tests { assert!(engine.version().major >= 1); } - #[test] - fn can_return_factory() { - let engine = new_morden().engine; - engine.vm_factory(); - } - #[test] fn can_return_schedule() { let engine = new_morden().engine; diff --git a/ethcore/src/evm/factory.rs b/ethcore/src/evm/factory.rs index 65add0050..3e60e8808 100644 --- a/ethcore/src/evm/factory.rs +++ b/ethcore/src/evm/factory.rs @@ -17,11 +17,10 @@ //! Evm factory. //! //! TODO: consider spliting it into two separate files. -#[cfg(test)] use std::fmt; use evm::Evm; -#[derive(Clone)] +#[derive(Debug, Clone)] /// Type of EVM to use. pub enum VMType { /// JIT EVM @@ -31,7 +30,6 @@ pub enum VMType { Interpreter } -#[cfg(test)] impl fmt::Display for VMType { #[cfg(feature="jit")] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -48,8 +46,12 @@ impl fmt::Display for VMType { } } -#[cfg(test)] -#[cfg(feature = "json-tests")] +impl Default for VMType { + fn default() -> Self { + VMType::Interpreter + } +} + impl VMType { /// Return all possible VMs (JIT, Interpreter) #[cfg(feature = "jit")] @@ -62,6 +64,18 @@ impl VMType { pub fn all() -> Vec { vec![VMType::Interpreter] } + + /// Return new jit if it's possible + #[cfg(not(feature = "jit"))] + pub fn jit() -> Option { + None + } + + /// Return new jit if it's possible + #[cfg(feature = "jit")] + pub fn jit() -> Option { + Some(VMType::Jit) + } } /// Evm factory. Creates appropriate Evm. @@ -80,7 +94,7 @@ impl Factory { VMType::Interpreter => { Box::new(super::interpreter::Interpreter) } - } + } } /// Create fresh instance of VM @@ -90,17 +104,17 @@ impl Factory { VMType::Interpreter => { Box::new(super::interpreter::Interpreter) } - } + } } /// Create new instance of specific `VMType` factory - #[cfg(test)] - pub fn new(evm: VMType) -> Factory { + pub fn new(evm: VMType) -> Self { Factory { evm: evm } } } + impl Default for Factory { /// Returns jitvm factory #[cfg(feature = "jit")] diff --git a/ethcore/src/evm/mod.rs b/ethcore/src/evm/mod.rs index 3e1dc5ed7..b7816b99c 100644 --- a/ethcore/src/evm/mod.rs +++ b/ethcore/src/evm/mod.rs @@ -31,6 +31,5 @@ mod tests; pub use self::evm::{Evm, Error, Result}; pub use self::ext::{Ext, ContractCreateResult, MessageCallResult}; -pub use self::factory::Factory; +pub use self::factory::{Factory, VMType}; pub use self::schedule::Schedule; -pub use self::factory::VMType; diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 74e0499c1..320a89cb8 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -18,7 +18,7 @@ use common::*; use state::*; use engine::*; -use evm::{self, Ext}; +use evm::{self, Ext, Factory}; use externalities::*; use substate::*; use trace::{Trace, Tracer, NoopTracer, ExecutiveTracer}; @@ -52,33 +52,36 @@ pub struct Executive<'a> { state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, + vm_factory: &'a Factory, depth: usize, } impl<'a> Executive<'a> { /// Basic constructor. - pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine) -> Self { + pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, vm_factory: &'a Factory) -> Self { Executive { state: state, info: info, engine: engine, + vm_factory: vm_factory, depth: 0, } } /// Populates executive from parent properties. Increments executive depth. - pub fn from_parent(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, parent_depth: usize) -> Self { + pub fn from_parent(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, vm_factory: &'a Factory, parent_depth: usize) -> Self { Executive { state: state, info: info, engine: engine, + vm_factory: vm_factory, depth: parent_depth + 1, } } /// Creates `Externalities` from `Executive`. pub fn as_externalities<'_, T>(&'_ mut self, origin_info: OriginInfo, substate: &'_ mut Substate, output: OutputPolicy<'_, '_>, tracer: &'_ mut T) -> Externalities<'_, T> where T: Tracer { - Externalities::new(self.state, self.info, self.engine, self.depth, origin_info, substate, output, tracer) + Externalities::new(self.state, self.info, self.engine, self.vm_factory, self.depth, origin_info, substate, output, tracer) } /// This function should be used to execute transaction. @@ -179,8 +182,8 @@ impl<'a> Executive<'a> { -> evm::Result where T: Tracer { // Ordinary execution - keep VM in same thread if (self.depth + 1) % MAX_VM_DEPTH_FOR_THREAD != 0 { + let vm_factory = self.vm_factory; let mut ext = self.as_externalities(OriginInfo::from(¶ms), unconfirmed_substate, output_policy, tracer); - let vm_factory = self.engine.vm_factory(); trace!(target: "executive", "ext.schedule.have_delegate_call: {}", ext.schedule().have_delegate_call); return vm_factory.create().exec(params, &mut ext); } @@ -189,8 +192,8 @@ impl<'a> Executive<'a> { // TODO [todr] No thread builder yet, so we need to reset once for a while // https://github.com/aturon/crossbeam/issues/16 crossbeam::scope(|scope| { + let vm_factory = self.vm_factory; let mut ext = self.as_externalities(OriginInfo::from(¶ms), unconfirmed_substate, output_policy, tracer); - let vm_factory = self.engine.vm_factory(); scope.spawn(move || { vm_factory.create().exec(params, &mut ext) @@ -458,11 +461,11 @@ mod tests { let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(0x100u64)); let info = EnvInfo::default(); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let mut substate = Substate::new(); let gas_left = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); ex.create(params, &mut substate, &mut NoopTracer).unwrap() }; @@ -517,11 +520,11 @@ mod tests { let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(100)); let info = EnvInfo::default(); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let mut substate = Substate::new(); let gas_left = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); ex.create(params, &mut substate, &mut NoopTracer).unwrap() }; @@ -572,12 +575,12 @@ mod tests { let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(100)); let info = EnvInfo::default(); - let engine = TestEngine::new(5, factory); + let engine = TestEngine::new(5); let mut substate = Substate::new(); let mut tracer = ExecutiveTracer::default(); let gas_left = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); let output = BytesRef::Fixed(&mut[0u8;0]); ex.call(params, &mut substate, output, &mut tracer).unwrap() }; @@ -644,12 +647,12 @@ mod tests { let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(100)); let info = EnvInfo::default(); - let engine = TestEngine::new(5, factory); + let engine = TestEngine::new(5); let mut substate = Substate::new(); let mut tracer = ExecutiveTracer::default(); let gas_left = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); ex.create(params.clone(), &mut substate, &mut tracer).unwrap() }; @@ -714,11 +717,11 @@ mod tests { let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(100)); let info = EnvInfo::default(); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let mut substate = Substate::new(); let gas_left = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); ex.create(params, &mut substate, &mut NoopTracer).unwrap() }; @@ -766,11 +769,11 @@ mod tests { let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from(100)); let info = EnvInfo::default(); - let engine = TestEngine::new(1024, factory); + let engine = TestEngine::new(1024); let mut substate = Substate::new(); { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); ex.create(params, &mut substate, &mut NoopTracer).unwrap(); } @@ -827,11 +830,11 @@ mod tests { state.add_balance(&sender, &U256::from(100_000)); let info = EnvInfo::default(); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let mut substate = Substate::new(); let gas_left = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); ex.call(params, &mut substate, BytesRef::Fixed(&mut []), &mut NoopTracer).unwrap() }; @@ -872,11 +875,11 @@ mod tests { let mut state = state_result.reference_mut(); state.init_code(&address, code.clone()); let info = EnvInfo::default(); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let mut substate = Substate::new(); let gas_left = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); ex.call(params, &mut substate, BytesRef::Fixed(&mut []), &mut NoopTracer).unwrap() }; @@ -906,10 +909,10 @@ mod tests { state.add_balance(&sender, &U256::from(18)); let mut info = EnvInfo::default(); info.gas_limit = U256::from(100_000); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let executed = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); let opts = TransactOptions { check_nonce: true, tracing: false }; ex.transact(&t, opts).unwrap() }; @@ -940,10 +943,10 @@ mod tests { let mut state = state_result.reference_mut(); let mut info = EnvInfo::default(); info.gas_limit = U256::from(100_000); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let res = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); let opts = TransactOptions { check_nonce: true, tracing: false }; ex.transact(&t, opts) }; @@ -972,10 +975,10 @@ mod tests { state.add_balance(&sender, &U256::from(17)); let mut info = EnvInfo::default(); info.gas_limit = U256::from(100_000); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let res = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); let opts = TransactOptions { check_nonce: true, tracing: false }; ex.transact(&t, opts) }; @@ -1006,10 +1009,10 @@ mod tests { let mut info = EnvInfo::default(); info.gas_used = U256::from(20_000); info.gas_limit = U256::from(100_000); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let res = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); let opts = TransactOptions { check_nonce: true, tracing: false }; ex.transact(&t, opts) }; @@ -1040,10 +1043,10 @@ mod tests { state.add_balance(&sender, &U256::from(100_017)); let mut info = EnvInfo::default(); info.gas_limit = U256::from(100_000); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let res = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); let opts = TransactOptions { check_nonce: true, tracing: false }; ex.transact(&t, opts) }; @@ -1074,11 +1077,11 @@ mod tests { let mut state = state_result.reference_mut(); state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap()); let info = EnvInfo::default(); - let engine = TestEngine::new(0, factory); + let engine = TestEngine::new(0); let mut substate = Substate::new(); let result = { - let mut ex = Executive::new(&mut state, &info, &engine); + let mut ex = Executive::new(&mut state, &info, &engine, &factory); ex.create(params, &mut substate, &mut NoopTracer) }; diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 4d868cba5..c936ac207 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -19,7 +19,7 @@ use common::*; use state::*; use engine::*; use executive::*; -use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult}; +use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory}; use substate::*; use trace::Tracer; @@ -59,6 +59,7 @@ pub struct Externalities<'a, T> where T: 'a + Tracer { state: &'a mut State, env_info: &'a EnvInfo, engine: &'a Engine, + vm_factory: &'a Factory, depth: usize, origin_info: OriginInfo, substate: &'a mut Substate, @@ -74,6 +75,7 @@ impl<'a, T> Externalities<'a, T> where T: 'a + Tracer { pub fn new(state: &'a mut State, env_info: &'a EnvInfo, engine: &'a Engine, + vm_factory: &'a Factory, depth: usize, origin_info: OriginInfo, substate: &'a mut Substate, @@ -84,6 +86,7 @@ impl<'a, T> Externalities<'a, T> where T: 'a + Tracer { state: state, env_info: env_info, engine: engine, + vm_factory: vm_factory, depth: depth, origin_info: origin_info, substate: substate, @@ -146,7 +149,7 @@ impl<'a, T> Ext for Externalities<'a, T> where T: 'a + Tracer { }; self.state.inc_nonce(&self.origin_info.address); - let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth); + let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.vm_factory, self.depth); // TODO: handle internal error separately match ex.create(params, self.substate, self.tracer) { @@ -185,7 +188,7 @@ impl<'a, T> Ext for Externalities<'a, T> where T: 'a + Tracer { params.value = ActionValue::Transfer(value); } - let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth); + let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.vm_factory, self.depth); match ex.call(params, self.substate, BytesRef::Fixed(output), self.tracer) { Ok(gas_left) => MessageCallResult::Success(gas_left), @@ -347,7 +350,8 @@ mod tests { let state = setup.state.reference_mut(); let mut tracer = NoopTracer; - let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); + let vm_factory = Default::default(); + let ext = Externalities::new(state, &setup.env_info, &*setup.engine, &vm_factory, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); assert_eq!(ext.env_info().number, 100); } @@ -358,7 +362,8 @@ mod tests { let state = setup.state.reference_mut(); let mut tracer = NoopTracer; - let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); + let vm_factory = Default::default(); + let ext = Externalities::new(state, &setup.env_info, &*setup.engine, &vm_factory, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); @@ -379,7 +384,8 @@ mod tests { let state = setup.state.reference_mut(); let mut tracer = NoopTracer; - let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); + let vm_factory = Default::default(); + let ext = Externalities::new(state, &setup.env_info, &*setup.engine, &vm_factory, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap()); @@ -393,7 +399,8 @@ mod tests { let state = setup.state.reference_mut(); let mut tracer = NoopTracer; - let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); + let vm_factory = Default::default(); + let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, &vm_factory, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); let mut output = vec![]; @@ -418,7 +425,8 @@ mod tests { let mut tracer = NoopTracer; { - let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); + let vm_factory = Default::default(); + let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, &vm_factory, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); ext.log(log_topics, &log_data); } @@ -434,7 +442,8 @@ mod tests { let mut tracer = NoopTracer; { - let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); + let vm_factory = Default::default(); + let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, &vm_factory, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None), &mut tracer); ext.suicide(&refund_account); } diff --git a/ethcore/src/json_tests/executive.rs b/ethcore/src/json_tests/executive.rs index ebffdbb15..9e9620169 100644 --- a/ethcore/src/json_tests/executive.rs +++ b/ethcore/src/json_tests/executive.rs @@ -58,6 +58,7 @@ impl<'a, T> TestExt<'a, T> where T: 'a + Tracer { fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, + vm_factory: &'a Factory, depth: usize, origin_info: OriginInfo, substate: &'a mut Substate, @@ -66,7 +67,7 @@ impl<'a, T> TestExt<'a, T> where T: 'a + Tracer { tracer: &'a mut T) -> Self { TestExt { contract_address: contract_address(&address, &state.nonce(&address)), - ext: Externalities::new(state, info, engine, depth, origin_info, substate, output, tracer), + ext: Externalities::new(state, info, engine, vm_factory, depth, origin_info, substate, output, tracer), callcreates: vec![] } } @@ -179,7 +180,8 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8]) -> Vec { let mut state = state_result.reference_mut(); state.populate_from(From::from(vm.pre_state.clone())); let info = From::from(vm.env); - let engine = TestEngine::new(1, Factory::new(vm_type.clone())); + let engine = TestEngine::new(1); + let vm_factory = Factory::new(vm_type.clone()); let params = ActionParams::from(vm.transaction); let mut substate = Substate::new(); @@ -192,6 +194,7 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8]) -> Vec { &mut state, &info, &engine, + &vm_factory, 0, OriginInfo::from(¶ms), &mut substate, @@ -199,7 +202,7 @@ fn do_json_test_for(vm_type: &VMType, json_data: &[u8]) -> Vec { params.address.clone(), &mut tracer, ); - let evm = engine.vm_factory().create(); + let evm = vm_factory.create(); let res = evm.exec(params, &mut ex); (res, ex.callcreates) }; diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index cf7f56ce1..5cc611491 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -63,7 +63,8 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { let mut state = state_result.reference_mut(); state.populate_from(pre); state.commit(); - let res = state.apply(&env, engine.deref(), &transaction, false); + let vm_factory = Default::default(); + let res = state.apply(&env, engine.deref(), &vm_factory, &transaction, false); if fail_unless(state.root() == &post_state_root) { println!("!!! {}: State mismatch (got: {}, expect: {}):", name, state.root(), post_state_root); diff --git a/ethcore/src/null_engine.rs b/ethcore/src/null_engine.rs index 58ae5baa9..a760bea93 100644 --- a/ethcore/src/null_engine.rs +++ b/ethcore/src/null_engine.rs @@ -19,14 +19,13 @@ use util::hash::Address; use builtin::Builtin; use engine::Engine; use spec::CommonParams; -use evm::{Schedule, Factory}; +use evm::Schedule; use env_info::EnvInfo; /// An engine which does not provide any consensus mechanism. pub struct NullEngine { params: CommonParams, builtins: BTreeMap, - factory: Factory, } impl NullEngine { @@ -35,16 +34,11 @@ impl NullEngine { NullEngine{ params: params, builtins: builtins, - factory: Factory::default() } } } impl Engine for NullEngine { - fn vm_factory(&self) -> &Factory { - &self.factory - } - fn name(&self) -> &str { "NullEngine" } diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index 391730a94..eabca24a8 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -17,6 +17,7 @@ use common::*; use engine::Engine; use executive::{Executive, TransactOptions}; +use evm::Factory as EvmFactory; use account_db::*; use trace::Trace; #[cfg(test)] @@ -218,11 +219,11 @@ impl State { /// Execute a given transaction. /// This will change the state accordingly. - pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &SignedTransaction, tracing: bool) -> ApplyResult { + pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, vm_factory: &EvmFactory, t: &SignedTransaction, tracing: bool) -> ApplyResult { // let old = self.to_pod(); let options = TransactOptions { tracing: tracing, check_nonce: true }; - let e = try!(Executive::new(self, env_info, engine).transact(t, options)); + let e = try!(Executive::new(self, env_info, engine, vm_factory).transact(t, options)); // TODO uncomment once to_pod() works correctly. // trace!("Applied transaction. Diff:\n{}\n", StateDiff::diff_pod(&old, &self.to_pod())); @@ -361,7 +362,6 @@ use util::common::*; use account::*; use tests::helpers::*; use devtools::*; -use evm::factory::*; use env_info::*; use spec::*; use transaction::*; @@ -378,7 +378,7 @@ fn should_apply_create_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -390,7 +390,8 @@ fn should_apply_create_transaction() { }.sign(&"".sha3()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Create(trace::Create { @@ -438,7 +439,7 @@ fn should_trace_failed_create_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -450,7 +451,8 @@ fn should_trace_failed_create_transaction() { }.sign(&"".sha3()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Create(trace::Create { @@ -475,7 +477,7 @@ fn should_trace_call_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -488,7 +490,8 @@ fn should_trace_call_transaction() { state.init_code(&x!(0xa), FromHex::from_hex("6000").unwrap()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { @@ -517,7 +520,7 @@ fn should_trace_basic_call_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -529,7 +532,8 @@ fn should_trace_basic_call_transaction() { }.sign(&"".sha3()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { @@ -569,7 +573,8 @@ fn should_trace_call_transaction_to_builtin() { data: vec![], }.sign(&"".sha3()); - let result = state.apply(&info, engine.deref(), &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap(); assert_eq!(result.trace, Some(Trace { depth: 0, @@ -609,7 +614,8 @@ fn should_not_trace_subcall_transaction_to_builtin() { }.sign(&"".sha3()); state.init_code(&x!(0xa), FromHex::from_hex("600060006000600060006001610be0f1").unwrap()); - let result = state.apply(&info, engine.deref(), &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, @@ -651,7 +657,8 @@ fn should_not_trace_callcode() { state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b611000f2").unwrap()); state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap()); - let result = state.apply(&info, engine.deref(), &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, @@ -696,7 +703,8 @@ fn should_not_trace_delegatecall() { state.init_code(&x!(0xa), FromHex::from_hex("6000600060006000600b618000f4").unwrap()); state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap()); - let result = state.apply(&info, engine.deref(), &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, @@ -725,7 +733,7 @@ fn should_trace_failed_call_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -738,7 +746,8 @@ fn should_trace_failed_call_transaction() { state.init_code(&x!(0xa), FromHex::from_hex("5b600056").unwrap()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { @@ -766,7 +775,7 @@ fn should_trace_call_with_subcall_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -780,7 +789,8 @@ fn should_trace_call_with_subcall_transaction() { state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap()); state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { @@ -823,7 +833,7 @@ fn should_trace_call_with_basic_subcall_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -836,7 +846,8 @@ fn should_trace_call_with_basic_subcall_transaction() { state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006045600b6000f1").unwrap()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { @@ -876,7 +887,7 @@ fn should_not_trace_call_with_invalid_basic_subcall_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -889,7 +900,8 @@ fn should_not_trace_call_with_invalid_basic_subcall_transaction() { state.init_code(&x!(0xa), FromHex::from_hex("600060006000600060ff600b6000f1").unwrap()); // not enough funds. state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { @@ -918,7 +930,7 @@ fn should_trace_failed_subcall_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -932,7 +944,8 @@ fn should_trace_failed_subcall_transaction() { state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap()); state.init_code(&x!(0xb), FromHex::from_hex("5b600056").unwrap()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { @@ -972,7 +985,7 @@ fn should_trace_call_with_subcall_with_subcall_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -987,7 +1000,8 @@ fn should_trace_call_with_subcall_with_subcall_transaction() { state.init_code(&x!(0xb), FromHex::from_hex("60006000600060006000600c602b5a03f1").unwrap()); state.init_code(&x!(0xc), FromHex::from_hex("6000").unwrap()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { @@ -1044,7 +1058,7 @@ fn should_trace_failed_subcall_with_subcall_transaction() { let mut info = EnvInfo::default(); info.gas_limit = x!(1_000_000); - let engine = TestEngine::new(5, Factory::default()); + let engine = TestEngine::new(5); let t = Transaction { nonce: x!(0), @@ -1059,7 +1073,8 @@ fn should_trace_failed_subcall_with_subcall_transaction() { state.init_code(&x!(0xb), FromHex::from_hex("60006000600060006000600c602b5a03f1505b601256").unwrap()); state.init_code(&x!(0xc), FromHex::from_hex("6000").unwrap()); state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); - let result = state.apply(&info, &engine, &t, true).unwrap(); + let vm_factory = Default::default(); + let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let expected_trace = Some(Trace { depth: 0, action: trace::Action::Call(trace::Call { diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 56e33d76b..6885a674b 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -19,7 +19,7 @@ use common::*; use spec::*; use blockchain::{BlockChain, BlockChainConfig}; use state::*; -use evm::{Schedule, Factory}; +use evm::Schedule; use engine::*; use ethereum; use devtools::*; @@ -51,15 +51,13 @@ impl GuardedTempResult { } pub struct TestEngine { - factory: Factory, engine: Box, max_depth: usize } impl TestEngine { - pub fn new(max_depth: usize, factory: Factory) -> TestEngine { + pub fn new(max_depth: usize) -> TestEngine { TestEngine { - factory: factory, engine: ethereum::new_frontier_test().engine, max_depth: max_depth } @@ -79,10 +77,6 @@ impl Engine for TestEngine { self.engine.builtins() } - fn vm_factory(&self) -> &Factory { - &self.factory - } - fn schedule(&self, _env_info: &EnvInfo) -> Schedule { let mut schedule = Schedule::new_frontier(); schedule.max_depth = self.max_depth; diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 33d21613f..35056bc03 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -113,7 +113,7 @@ impl Miner { // add transactions to old_block let e = chain.engine(); let mut invalid_transactions = HashSet::new(); - let mut block = old_block.reopen(e); + let mut block = old_block.reopen(e, chain.vm_factory()); let block_number = block.block().fields().header.number(); // TODO: push new uncles, too. @@ -267,7 +267,7 @@ impl MinerService for Miner { state.sub_balance(&sender, &balance); state.add_balance(&sender, &U256::max_value()); let options = TransactOptions { tracing: false, check_nonce: false }; - Executive::new(&mut state, &env_info, chain.engine()).transact(t, options) + Executive::new(&mut state, &env_info, chain.engine(), chain.vm_factory()).transact(t, options) }, None => { chain.call(t) diff --git a/parity/cli.rs b/parity/cli.rs index 90d7167dc..a33e53aeb 100644 --- a/parity/cli.rs +++ b/parity/cli.rs @@ -140,6 +140,9 @@ Footprint Options: the entire system, overrides other cache and queue options. +Virtual Machine Options: + --jitvm Enable the JIT VM. + Legacy Options: --geth Run in Geth-compatibility mode. Currently just sets the IPC path to be the same as Geth's. Overrides @@ -222,6 +225,7 @@ pub struct Args { pub flag_tx_limit: usize, pub flag_logging: Option, pub flag_version: bool, + pub flag_jitvm: bool, // legacy... pub flag_geth: bool, pub flag_nodekey: Option, diff --git a/parity/configuration.rs b/parity/configuration.rs index 92d69b068..fe9a7131b 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -26,7 +26,7 @@ use die::*; use util::*; use util::keys::store::AccountService; use util::network_settings::NetworkSettings; -use ethcore::client::{append_path, get_db_path, ClientConfig, Switch}; +use ethcore::client::{append_path, get_db_path, ClientConfig, Switch, VMType}; use ethcore::ethereum; use ethcore::spec::Spec; use ethsync::SyncConfig; @@ -201,6 +201,7 @@ impl Configuration { pub fn client_config(&self, spec: &Spec) -> ClientConfig { let mut client_config = ClientConfig::default(); + match self.args.flag_cache { Some(mb) => { client_config.blockchain.max_cache_size = mb * 1024 * 1024; @@ -211,12 +212,14 @@ impl Configuration { client_config.blockchain.max_cache_size = self.args.flag_cache_max_size; } } + client_config.tracing.enabled = match self.args.flag_tracing.as_str() { "auto" => Switch::Auto, "on" => Switch::On, "off" => Switch::Off, _ => { die!("Invalid tracing method given!") } }; + client_config.pruning = match self.args.flag_pruning.as_str() { "archive" => journaldb::Algorithm::Archive, "light" => journaldb::Algorithm::EarlyMerge, @@ -225,6 +228,11 @@ impl Configuration { "auto" => self.find_best_db(spec).unwrap_or(journaldb::Algorithm::OverlayRecent), _ => { die!("Invalid pruning method given."); } }; + + if self.args.flag_jitvm { + client_config.vm_type = VMType::jit().unwrap_or_else(|| die!("Parity built without jit vm.")) + } + trace!(target: "parity", "Using pruning strategy of {}", client_config.pruning); client_config.name = self.args.flag_identity.clone(); client_config.queue.max_mem_use = self.args.flag_queue_max_size;