diff --git a/Cargo.lock b/Cargo.lock index c0aae6664f1..7c44401b301 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -386,7 +386,7 @@ version = "0.1.0" dependencies = [ "app_dirs 1.2.1 (git+https://github.com/paritytech/app-dirs-rs)", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "journaldb 0.1.0", + "journaldb 0.2.0", ] [[package]] @@ -537,10 +537,10 @@ dependencies = [ "evm 0.1.0", "fetch 0.1.0", "hardware-wallet 1.12.0", - "hashdb 0.1.1", + "hashdb 0.2.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "journaldb 0.1.0", + "journaldb 0.2.0", "keccak-hash 0.1.2", "kvdb 0.1.0", "kvdb-memorydb 0.1.0", @@ -550,7 +550,7 @@ dependencies = [ "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "memory-cache 0.1.0", - "memorydb 0.1.1", + "memorydb 0.2.0", "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-machine 0.1.0", @@ -630,7 +630,7 @@ dependencies = [ "ethcore-transaction 0.1.0", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hashdb 0.1.1", + "hashdb 0.2.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", @@ -638,10 +638,10 @@ dependencies = [ "kvdb-memorydb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "memory-cache 0.1.0", - "memorydb 0.1.1", + "memorydb 0.2.0", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.1.0", - "plain_hasher 0.1.0", + "plain_hasher 0.2.0", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1", "rlp_derive 0.1.0", @@ -881,7 +881,7 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "macros 0.1.0", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "plain_hasher 0.1.0", + "plain_hasher 0.2.0", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1191,10 +1191,13 @@ dependencies = [ [[package]] name = "hashdb" -version = "0.1.1" +version = "0.2.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1338,20 +1341,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "journaldb" -version = "0.1.0" +version = "0.2.0" dependencies = [ "ethcore-bytes 0.1.0", "ethcore-logger 1.12.0", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashdb 0.1.1", + "hashdb 0.2.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hash 0.1.2", "kvdb 0.1.0", "kvdb-memorydb 0.1.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "memorydb 0.1.1", + "memorydb 0.2.0", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "plain_hasher 0.1.0", + "plain_hasher 0.2.0", "rlp 0.2.1", "util-error 0.1.0", ] @@ -1523,6 +1526,13 @@ name = "lazycell" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "learn-generics" +version = "0.1.0" +dependencies = [ + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "libc" version = "0.2.36" @@ -1641,15 +1651,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memorydb" -version = "0.1.1" +version = "0.2.0" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashdb 0.1.1", + "hashdb 0.2.0", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak-hash 0.1.2", - "plain_hasher 0.1.0", + "plain_hasher 0.2.0", "rlp 0.2.1", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1985,7 +1995,7 @@ dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)", - "journaldb 0.1.0", + "journaldb 0.2.0", "jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.11)", "keccak-hash 0.1.2", "kvdb 0.1.0", @@ -2439,10 +2449,10 @@ dependencies = [ "ethcore-bytes 0.1.0", "ethcore-logger 1.12.0", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashdb 0.1.1", + "hashdb 0.2.0", "keccak-hash 0.1.2", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "memorydb 0.1.1", + "memorydb 0.2.0", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.2.1", "trie-standardmap 0.1.0", @@ -2491,10 +2501,11 @@ dependencies = [ [[package]] name = "plain_hasher" -version = "0.1.0" +version = "0.2.0" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hashdb 0.2.0", ] [[package]] @@ -2770,6 +2781,17 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rlp" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rlp_compress" version = "0.1.0" @@ -3973,6 +3995,7 @@ dependencies = [ "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum ring 0.12.1 (git+https://github.com/paritytech/ring)" = "" +"checksum rlp 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "89db7f8dfdd5eb7ab3ac3ece7a07fd273a680b4b224cb231181280e8996f9f0b" "checksum rocksdb 0.4.5 (git+https://github.com/paritytech/rust-rocksdb)" = "" "checksum rocksdb-sys 0.3.0 (git+https://github.com/paritytech/rust-rocksdb)" = "" "checksum rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b273c91bd242ca03ad6d71c143b6f17a48790e61f21a6c78568fa2b6774a24a4" diff --git a/Cargo.toml b/Cargo.toml index de1a78bf4fa..82506652961 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -136,6 +136,7 @@ members = [ "transaction-pool", "whisper", "whisper/cli", + "util/learn-generics", ] [patch.crates-io] diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index acd1b49ed04..36832e698e6 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -10,10 +10,20 @@ "minGasLimit": "0x1388", "networkID" : "0x11", "registrar" : "0x0000000000000000000000000000000000001337", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip155Transition": "0x0", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff", + "maxCodeSize": 24576, + "maxCodeSizeTransition": "0x0", "eip140Transition": "0x0", "eip211Transition": "0x0", "eip214Transition": "0x0", - "eip658Transition": "0x0" + "eip658Transition": "0x0", + "wasmActivationTransition": "0x0" }, "genesis": { "seal": { diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index 5f46799796a..f703329d611 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -29,7 +29,7 @@ use sync::PrivateTxHandler; use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage}; use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; -use ethcore::snapshot::{RestorationStatus}; +use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus}; use ethcore::spec::Spec; use ethcore::account_provider::AccountProvider; @@ -168,6 +168,11 @@ impl ClientService { /// Get a handle to the database. pub fn db(&self) -> Arc { self.database.clone() } + + /// Shutdown the Client Service + pub fn shutdown(&self) { + self.snapshot.shutdown(); + } } /// IO interface for the Client handler diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 17c362e0440..942015d0f10 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -743,6 +743,10 @@ impl SnapshotService for Service { trace!("Error sending snapshot service message: {:?}", e); } } + + fn shutdown(&self) { + self.abort_restore(); + } } impl Drop for Service { diff --git a/ethcore/src/snapshot/traits.rs b/ethcore/src/snapshot/traits.rs index 2b6ee9df9f4..d951f4c5341 100644 --- a/ethcore/src/snapshot/traits.rs +++ b/ethcore/src/snapshot/traits.rs @@ -54,4 +54,7 @@ pub trait SnapshotService : Sync + Send { /// Feed a raw block chunk to the service to be processed asynchronously. /// no-op if currently restoring. fn restore_block_chunk(&self, hash: H256, chunk: Bytes); + + /// Shutdown the Snapshot Service by aborting any ongoing restore + fn shutdown(&self); } diff --git a/ethcore/sync/src/tests/snapshot.rs b/ethcore/sync/src/tests/snapshot.rs index 864f3d4dc6e..ffb71d7a730 100644 --- a/ethcore/sync/src/tests/snapshot.rs +++ b/ethcore/sync/src/tests/snapshot.rs @@ -133,6 +133,10 @@ impl SnapshotService for TestSnapshotService { self.block_restoration_chunks.lock().insert(hash, chunk); } } + + fn shutdown(&self) { + self.abort_restore(); + } } #[test] diff --git a/miner/src/pool/scoring.rs b/miner/src/pool/scoring.rs index eaf06983328..aedc40e1f2c 100644 --- a/miner/src/pool/scoring.rs +++ b/miner/src/pool/scoring.rs @@ -107,6 +107,15 @@ impl txpool::Scoring for NonceAndGasPrice { } } + // Always kick out non-local transactions in favour of local ones. + if new.priority().is_local() && !old.priority().is_local() { + return true; + } + // And never kick out local transactions in favour of external ones. + if !new.priority().is_local() && old.priority.is_local() { + return false; + } + self.choose(old, new) == txpool::scoring::Choice::ReplaceOld } } @@ -119,6 +128,30 @@ mod tests { use pool::tests::tx::{Tx, TxExt}; use txpool::Scoring; + #[test] + fn should_replace_non_local_transaction_with_local_one() { + // given + let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly); + let tx1 = { + let tx = Tx::default().signed().verified(); + txpool::Transaction { + insertion_id: 0, + transaction: Arc::new(tx), + } + }; + let tx2 = { + let mut tx = Tx::default().signed().verified(); + tx.priority = ::pool::Priority::Local; + txpool::Transaction { + insertion_id: 0, + transaction: Arc::new(tx), + } + }; + + assert!(scoring.should_replace(&tx1, &tx2)); + assert!(!scoring.should_replace(&tx2, &tx1)); + } + #[test] fn should_calculate_score_correctly() { // given diff --git a/miner/src/pool/tests/mod.rs b/miner/src/pool/tests/mod.rs index 5d80c2d5bf6..85dedaaa45b 100644 --- a/miner/src/pool/tests/mod.rs +++ b/miner/src/pool/tests/mod.rs @@ -766,4 +766,35 @@ fn should_reject_big_transaction() { verifier::Transaction::Local(PendingTransaction::new(big_tx, transaction::Condition::Timestamp(1000).into())) ]); assert_eq!(res, vec![Err(transaction::Error::TooBig)]); -} \ No newline at end of file +} + +#[test] +fn should_include_local_transaction_to_a_full_pool() { + // given + let txq = TransactionQueue::new( + txpool::Options { + max_count: 1, + max_per_sender: 2, + max_mem_usage: 50 + }, + verifier::Options { + minimal_gas_price: 1.into(), + block_gas_limit: 1_000_000.into(), + tx_gas_limit: 1_000_000.into(), + }, + PrioritizationStrategy::GasPriceOnly, + ); + let tx1 = Tx::gas_price(10_000).signed().unverified(); + let tx2 = Tx::gas_price(1).signed().local(); + + let res = txq.import(TestClient::new().with_balance(1_000_000_000), vec![tx1]); + assert_eq!(res, vec![Ok(())]); + assert_eq!(txq.status().status.transaction_count, 1); + + // when + let res = txq.import(TestClient::new(), vec![tx2]); + assert_eq!(res, vec![Ok(())]); + + // then + assert_eq!(txq.status().status.transaction_count, 1); +} diff --git a/parity/run.rs b/parity/run.rs index fd16085c46c..31f8779c0fa 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -885,7 +885,8 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: rpc: rpc_direct, informant, client, - keep_alive: Box::new((watcher, service, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), + client_service: Arc::new(service), + keep_alive: Box::new((watcher, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), } }) } @@ -909,6 +910,7 @@ enum RunningClientInner { rpc: jsonrpc_core::MetaIoHandler>, informant: Arc>, client: Arc, + client_service: Arc, keep_alive: Box, }, } @@ -946,11 +948,14 @@ impl RunningClient { drop(client); wait_for_drop(weak_client); }, - RunningClientInner::Full { rpc, informant, client, keep_alive } => { + RunningClientInner::Full { rpc, informant, client, client_service, keep_alive } => { info!("Finishing work, please wait..."); // Create a weak reference to the client so that we can wait on shutdown // until it is dropped let weak_client = Arc::downgrade(&client); + // Shutdown and drop the ServiceClient + client_service.shutdown(); + drop(client_service); // drop this stuff as soon as exit detected. drop(rpc); drop(keep_alive); diff --git a/rpc/src/v1/tests/helpers/snapshot_service.rs b/rpc/src/v1/tests/helpers/snapshot_service.rs index 099773ab522..91cd14d73f1 100644 --- a/rpc/src/v1/tests/helpers/snapshot_service.rs +++ b/rpc/src/v1/tests/helpers/snapshot_service.rs @@ -50,4 +50,5 @@ impl SnapshotService for TestSnapshotService { fn abort_restore(&self) { } fn restore_state_chunk(&self, _hash: H256, _chunk: Bytes) { } fn restore_block_chunk(&self, _hash: H256, _chunk: Bytes) { } + fn shutdown(&self) { } } diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index fbbeb89ff8e..2f577821a7a 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -686,14 +686,17 @@ impl Host { Err(e) => { let s = session.lock(); trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e); - if let ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) = *e.kind() { - if let Some(id) = s.id() { - if !self.reserved_nodes.read().contains(id) { - let mut nodes = self.nodes.write(); - nodes.note_failure(&id); - nodes.mark_as_useless(id); + match *e.kind() { + ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) | ErrorKind::Disconnect(DisconnectReason::UselessPeer) => { + if let Some(id) = s.id() { + if !self.reserved_nodes.read().contains(id) { + let mut nodes = self.nodes.write(); + nodes.note_failure(&id); + nodes.mark_as_useless(id); + } } - } + }, + _ => {}, } kill = true; break; diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index eb2e9685d42..1b46ca1ae33 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -32,7 +32,7 @@ impl IoHandler for HostHandler { if let NetworkIoMessage::NetworkStarted(ref public_url) = *message { let mut url = self.public_url.write(); if url.as_ref().map_or(true, |uref| uref != public_url) { - info!(target: "network", "Public node URL: {}", Colour::White.bold().paint(public_url.as_ref())); + info!(target: "network", "Public node URL: {}", Colour::White.bold().paint(AsRef::::as_ref(public_url))); } *url = Some(public_url.to_owned()); } diff --git a/util/network/src/lib.rs b/util/network/src/lib.rs index f3012e4c376..207a05075d2 100644 --- a/util/network/src/lib.rs +++ b/util/network/src/lib.rs @@ -42,7 +42,7 @@ use std::sync::Arc; use std::time::Duration; use ipnetwork::{IpNetwork, IpNetworkError}; use ethkey::Secret; -use ethereum_types::{H256, H512}; +use ethereum_types::H512; use rlp::{Decodable, DecoderError, Rlp}; /// Protocol handler level packet id diff --git a/util/patricia_trie/src/triedb.rs b/util/patricia_trie/src/triedb.rs index 8418fabfc41..47449bdcda4 100644 --- a/util/patricia_trie/src/triedb.rs +++ b/util/patricia_trie/src/triedb.rs @@ -505,7 +505,7 @@ fn debug_output_supports_pretty_print() { t.root().clone() }; let t = TrieDB::new(&memdb, &root).unwrap(); - + assert_eq!(format!("{:?}", t), "TrieDB { hash_count: 0, root: Node::Extension { slice: 4, item: Node::Branch { nodes: [Node::Empty, Node::Branch { nodes: [Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Branch { nodes: [Node::Empty, Node::Leaf { slice: , value: [65, 65] }, Node::Leaf { slice: , value: [65, 66] }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: None }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: Some([65]) }, Node::Leaf { slice: , value: [66] }, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty, Node::Empty], value: None } } }"); assert_eq!(format!("{:#?}", t), "TrieDB { @@ -598,29 +598,27 @@ fn debug_output_supports_pretty_print() { }"); } -// Test will work once https://github.com/paritytech/parity/pull/8527 is merged and rlp::decode returns Result instead of panicking -//#[test] -//fn test_lookup_with_corrupt_data_returns_decoder_error() { -// use memorydb::*; -// use super::TrieMut; -// use super::triedbmut::*; -// use rlp; -// use ethereum_types::H512; -// -// let mut memdb = MemoryDB::new(); -// let mut root = H256::new(); -// { -// let mut t = TrieDBMut::new(&mut memdb, &mut root); -// t.insert(b"A", b"ABC").unwrap(); -// t.insert(b"B", b"ABCBA").unwrap(); -// } -// -// let t = TrieDB::new(&memdb, &root).unwrap(); -// -// // query for an invalid data type to trigger an error -// let q = rlp::decode::; -// let lookup = Lookup{ db: t.db, query: q, hash: root }; -// let query_result = lookup.look_up(NibbleSlice::new(b"A")); -// let expected = Box::new(TrieError::DecoderError(::rlp::DecoderError::RlpIsTooShort)); -// assert_eq!(query_result.unwrap_err(), expected); -//} +#[test] +fn test_lookup_with_corrupt_data_returns_decoder_error() { + use memorydb::*; + use super::TrieMut; + use super::triedbmut::*; + use rlp; + use ethereum_types::H512; + + let mut memdb = MemoryDB::new(); + let mut root = H256::new(); + { + let mut t = TrieDBMut::new(&mut memdb, &mut root); + t.insert(b"A", b"ABC").unwrap(); + t.insert(b"B", b"ABCBA").unwrap(); + } + + let t = TrieDB::new(&memdb, &root).unwrap(); + + // query for an invalid data type to trigger an error + let q = rlp::decode::; + let lookup = Lookup{ db: t.db, query: q, hash: root }; + let query_result = lookup.look_up(NibbleSlice::new(b"A")); + assert_eq!(query_result.unwrap().unwrap().unwrap_err(), rlp::DecoderError::RlpIsTooShort); +}