From 93054ef24b590a8d854cd6b2d1de6567667d39da Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 30 May 2018 16:42:37 +0300 Subject: [PATCH 1/9] Add a deadlock detection thread (#8727) * Add a deadlock detection thread Expose it under a feature flag: `cargo build --features "deadlock_detection"` * Address Nicklas's comments --- Cargo.lock | 36 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + parity/lib.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c0aae6664f1..c8e60dce693 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1092,6 +1092,11 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fixedbitset" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "flate2" version = "1.0.1" @@ -1939,6 +1944,11 @@ dependencies = [ "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ordermap" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "owning_ref" version = "0.3.3" @@ -2420,10 +2430,13 @@ name = "parking_lot_core" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2454,6 +2467,15 @@ name = "percent-encoding" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "petgraph" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "phf" version = "0.7.21" @@ -3183,6 +3205,16 @@ dependencies = [ "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.4" @@ -3851,6 +3883,7 @@ dependencies = [ "checksum ethereum-types-serialize 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ac59a21a9ce98e188f3dace9eb67a6c4a3c67ec7fbc7218cb827852679dc002" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum fixed-hash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18d6fd718fb4396e7a9c93ac59ba7143501467ca7a143c145b5555a571d5576" +"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" @@ -3931,6 +3964,7 @@ dependencies = [ "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" "checksum order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "efa535d5117d3661134dbf1719b6f0ffe06f2375843b13935db186cd094105eb" "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f" +"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "261c025c67ba416e9fe63aa9b3236520ce3c74cfbe43590c9cdcec4ccc8180e4" "checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "" @@ -3943,6 +3977,7 @@ dependencies = [ "checksum parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd9d732f2de194336fb02fe11f9eed13d9e76f13f4315b4d88a14ca411750cd" "checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595" "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" +"checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" @@ -4021,6 +4056,7 @@ dependencies = [ "checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" +"checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" diff --git a/Cargo.toml b/Cargo.toml index de1a78bf4fa..24649eff454 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,6 +106,7 @@ evm-debug-tests = ["ethcore/evm-debug-tests"] slow-blocks = ["ethcore/slow-blocks"] secretstore = ["ethcore-secretstore"] final = ["parity-version/final"] +deadlock_detection = ["parking_lot/deadlock_detection"] [lib] path = "parity/lib.rs" diff --git a/parity/lib.rs b/parity/lib.rs index 4d9d1a2c95f..6ef332da65e 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -141,6 +141,35 @@ fn print_hash_of(maybe_file: Option) -> Result { } } +#[cfg(feature = "deadlock_detection")] +fn run_deadlock_detection_thread() { + use std::thread; + use std::time::Duration; + use parking_lot::deadlock; + + info!("Starting deadlock detection thread."); + // Create a background thread which checks for deadlocks every 10s + thread::spawn(move || { + loop { + thread::sleep(Duration::from_secs(10)); + let deadlocks = deadlock::check_deadlock(); + if deadlocks.is_empty() { + continue; + } + + warn!("{} {} detected", deadlocks.len(), Style::new().bold().paint("deadlock(s)")); + for (i, threads) in deadlocks.iter().enumerate() { + warn!("{} #{}", Style::new().bold().paint("Deadlock"), i); + for t in threads { + warn!("Thread Id {:#?}", t.thread_id()); + warn!("{:#?}", t.backtrace()); + } + } + } + }); +} + + /// Action that Parity performed when running `start`. pub enum ExecutionAction { /// The execution didn't require starting a node, and thus has finished. @@ -161,6 +190,9 @@ fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Res // they want let logger = setup_log(&command.logger).expect("Logger is initialized only once; qed"); + #[cfg(feature = "deadlock_detection")] + run_deadlock_detection_thread(); + match command.cmd { Cmd::Run(run_cmd) => { if run_cmd.ui_conf.enabled && !run_cmd.ui_conf.info_page_only { From 686bf443e6bcca085c897806a7f808fc891c655f Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 31 May 2018 15:06:22 +0800 Subject: [PATCH 2/9] Remove unused function new_pow_test_spec (#8735) --- ethcore/src/spec/spec.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index fa25c8894eb..98720647d8f 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -923,11 +923,6 @@ impl Spec { pub fn new_validator_multi() -> Self { load_bundled!("validator_multi") } - - /// Create a new spec for a PoW chain - pub fn new_pow_test_spec() -> Self { - load_bundled!("ethereum/olympic") - } } #[cfg(test)] From 6b9314eaa9df00b36afae4d7e8ab0f3d65e4fecb Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Thu, 31 May 2018 13:36:47 +0200 Subject: [PATCH 3/9] Add 'interface' option to cli (#8699) Additionally as to the port, the new command line option now allows the user to specify the network interface the P2P-Parity listens, too. With support for 'all' and 'local' like in all other versions of this flag. Default is 'all' (aka ). --- parity/cli/mod.rs | 7 +++++++ parity/configuration.rs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index a064baeac56..fea060d5933 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -438,6 +438,10 @@ usage! { "--port=[PORT]", "Override the port on which the node should listen.", + ARG arg_interface: (String) = "all", or |c: &Config| c.network.as_ref()?.interface.clone(), + "--interface=[IP]", + "Network interfaces. Valid values are 'all', 'local' or the ip of the interface you want parity to listen to.", + ARG arg_min_peers: (Option) = None, or |c: &Config| c.network.as_ref()?.min_peers.clone(), "--min-peers=[NUM]", "Try to maintain at least NUM peers.", @@ -1119,6 +1123,7 @@ struct Network { warp: Option, warp_barrier: Option, port: Option, + interface: Option, min_peers: Option, max_peers: Option, snapshot_peers: Option, @@ -1567,6 +1572,7 @@ mod tests { // -- Networking Options flag_no_warp: false, arg_port: 30303u16, + arg_interface: "all".into(), arg_min_peers: Some(25u16), arg_max_peers: Some(50u16), arg_max_pending_peers: 64u16, @@ -1823,6 +1829,7 @@ mod tests { warp: Some(false), warp_barrier: None, port: None, + interface: None, min_peers: Some(10), max_peers: Some(20), max_pending_peers: Some(30), diff --git a/parity/configuration.rs b/parity/configuration.rs index 3151621801c..6bec636e2cb 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -767,7 +767,7 @@ impl Configuration { fn net_addresses(&self) -> Result<(SocketAddr, Option), String> { let port = self.args.arg_ports_shift + self.args.arg_port; - let listen_address = SocketAddr::new("0.0.0.0".parse().unwrap(), port); + let listen_address = SocketAddr::new(self.interface(&self.args.arg_interface).parse().unwrap(), port); let public_address = if self.args.arg_nat.starts_with("extip:") { let host = &self.args.arg_nat[6..]; let host = host.parse().map_err(|_| format!("Invalid host given with `--nat extip:{}`", host))?; From 118588ef6ccdfca945fcc5733be3c7a5f857c728 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 May 2018 13:38:46 +0200 Subject: [PATCH 4/9] Fix some nits using clippy (#8731) * fix some nits using clippy * fix tests --- util/network-devp2p/src/handshake.rs | 10 +++--- util/network-devp2p/src/host.rs | 30 +++++++++--------- util/network-devp2p/src/ip_utils.rs | 42 ++++++++++++------------- util/network-devp2p/src/node_table.rs | 44 +++++++++++++-------------- util/network-devp2p/src/service.rs | 2 +- util/network-devp2p/src/session.rs | 16 +++++----- whisper/cli/src/main.rs | 3 ++ 7 files changed, 75 insertions(+), 72 deletions(-) diff --git a/util/network-devp2p/src/handshake.rs b/util/network-devp2p/src/handshake.rs index 7aef4d4f0d7..891dd7c2578 100644 --- a/util/network-devp2p/src/handshake.rs +++ b/util/network-devp2p/src/handshake.rs @@ -84,12 +84,12 @@ impl Handshake { /// Create a new handshake object pub fn new(token: StreamToken, id: Option<&NodeId>, socket: TcpStream, nonce: &H256) -> Result { Ok(Handshake { - id: if let Some(id) = id { id.clone()} else { NodeId::new() }, + id: if let Some(id) = id { *id } else { NodeId::new() }, connection: Connection::new(token, socket), originated: false, state: HandshakeState::New, ecdhe: Random.generate()?, - nonce: nonce.clone(), + nonce: *nonce, remote_ephemeral: Public::new(), remote_nonce: H256::new(), remote_version: PROTOCOL_VERSION, @@ -166,7 +166,7 @@ impl Handshake { self.remote_version = remote_version; let shared = *ecdh::agree(host_secret, &self.id)?; let signature = H520::from_slice(sig); - self.remote_ephemeral = recover(&signature.into(), &(&shared ^ &self.remote_nonce))?; + self.remote_ephemeral = recover(&signature.into(), &(shared ^ self.remote_nonce))?; Ok(()) } @@ -189,7 +189,7 @@ impl Handshake { } Err(_) => { // Try to interpret as EIP-8 packet - let total = (((data[0] as u16) << 8 | (data[1] as u16)) as usize) + 2; + let total = ((u16::from(data[0]) << 8 | (u16::from(data[1]))) as usize) + 2; if total < V4_AUTH_PACKET_SIZE { debug!(target: "network", "Wrong EIP8 auth packet size"); return Err(ErrorKind::BadProtocol.into()); @@ -232,7 +232,7 @@ impl Handshake { } Err(_) => { // Try to interpret as EIP-8 packet - let total = (((data[0] as u16) << 8 | (data[1] as u16)) as usize) + 2; + let total = (((u16::from(data[0])) << 8 | (u16::from(data[1]))) as usize) + 2; if total < V4_ACK_PACKET_SIZE { debug!(target: "network", "Wrong EIP8 ack packet size"); return Err(ErrorKind::BadProtocol.into()); diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 2f577821a7a..f9180700fe3 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -116,11 +116,11 @@ impl<'s> NetworkContext<'s> { ) -> NetworkContext<'s> { let id = session.as_ref().map(|s| s.lock().token()); NetworkContext { - io: io, - protocol: protocol, + io, + protocol, session_id: id, - session: session, - sessions: sessions, + session, + sessions, _reserved_peers: reserved_peers, } } @@ -280,7 +280,7 @@ impl Host { let tcp_listener = TcpListener::bind(&listen_address)?; listen_address = SocketAddr::new(listen_address.ip(), tcp_listener.local_addr()?.port()); debug!(target: "network", "Listening at {:?}", listen_address); - let udp_port = config.udp_port.unwrap_or(listen_address.port()); + let udp_port = config.udp_port.unwrap_or_else(|| listen_address.port()); let local_endpoint = NodeEndpoint { address: listen_address, udp_port: udp_port }; let boot_nodes = config.boot_nodes.clone(); @@ -325,7 +325,7 @@ impl Host { match Node::from_str(id) { Err(e) => { debug!(target: "network", "Could not add node {}: {:?}", id, e); }, Ok(n) => { - let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id.clone() }; + let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id }; self.nodes.write().add_node(n); if let Some(ref mut discovery) = *self.discovery.lock() { @@ -338,9 +338,9 @@ impl Host { pub fn add_reserved_node(&self, id: &str) -> Result<(), Error> { let n = Node::from_str(id)?; - let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id.clone() }; - self.reserved_nodes.write().insert(n.id.clone()); - self.nodes.write().add_node(Node::new(entry.id.clone(), entry.endpoint.clone())); + let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id }; + self.reserved_nodes.write().insert(n.id); + self.nodes.write().add_node(Node::new(entry.id, entry.endpoint.clone())); if let Some(ref mut discovery) = *self.discovery.lock() { discovery.add_node(entry); @@ -349,10 +349,10 @@ impl Host { Ok(()) } - pub fn set_non_reserved_mode(&self, mode: NonReservedPeerMode, io: &IoContext) { + pub fn set_non_reserved_mode(&self, mode: &NonReservedPeerMode, io: &IoContext) { let mut info = self.info.write(); - if info.config.non_reserved_mode != mode { + if &info.config.non_reserved_mode != mode { info.config.non_reserved_mode = mode.clone(); drop(info); if let NonReservedPeerMode::Deny = mode { @@ -388,12 +388,12 @@ impl Host { pub fn external_url(&self) -> Option { let info = self.info.read(); - info.public_endpoint.as_ref().map(|e| format!("{}", Node::new(info.id().clone(), e.clone()))) + info.public_endpoint.as_ref().map(|e| format!("{}", Node::new(*info.id(), e.clone()))) } pub fn local_url(&self) -> String { let info = self.info.read(); - format!("{}", Node::new(info.id().clone(), info.local_endpoint.clone())) + format!("{}", Node::new(*info.id(), info.local_endpoint.clone())) } pub fn stop(&self, io: &IoContext) { @@ -554,7 +554,7 @@ impl Host { // iterate over all nodes, reserved ones coming first. // if we are pinned to only reserved nodes, ignore all others. let nodes = reserved_nodes.iter().cloned().chain(if !pin { - self.nodes.read().nodes(allow_ips) + self.nodes.read().nodes(&allow_ips) } else { Vec::new() }); @@ -752,7 +752,7 @@ impl Host { let entry = NodeEntry { id: id, endpoint: endpoint }; let mut nodes = self.nodes.write(); if !nodes.contains(&entry.id) { - nodes.add_node(Node::new(entry.id.clone(), entry.endpoint.clone())); + nodes.add_node(Node::new(entry.id, entry.endpoint.clone())); let mut discovery = self.discovery.lock(); if let Some(ref mut discovery) = *discovery { discovery.add_node(entry); diff --git a/util/network-devp2p/src/ip_utils.rs b/util/network-devp2p/src/ip_utils.rs index 7c3d5c0fd3b..3d7d33a0661 100644 --- a/util/network-devp2p/src/ip_utils.rs +++ b/util/network-devp2p/src/ip_utils.rs @@ -109,7 +109,7 @@ impl SocketAddrExt for Ipv4Addr { fn is_within(&self, ipnet: &IpNetwork) -> bool { match ipnet { - &IpNetwork::V4(ipnet) => ipnet.contains(*self), + IpNetwork::V4(ipnet) => ipnet.contains(*self), _ => false } } @@ -167,7 +167,7 @@ impl SocketAddrExt for Ipv6Addr { fn is_within(&self, ipnet: &IpNetwork) -> bool { match ipnet { - &IpNetwork::V6(ipnet) => ipnet.contains(*self), + IpNetwork::V6(ipnet) => ipnet.contains(*self), _ => false } } @@ -212,28 +212,28 @@ impl SocketAddrExt for IpAddr { #[cfg(not(any(windows, target_os = "android")))] mod getinterfaces { - use std::{mem, io, ptr}; + use std::{mem, io}; use libc::{AF_INET, AF_INET6}; use libc::{getifaddrs, freeifaddrs, ifaddrs, sockaddr, sockaddr_in, sockaddr_in6}; use std::net::{Ipv4Addr, Ipv6Addr, IpAddr}; fn convert_sockaddr(sa: *mut sockaddr) -> Option { - if sa == ptr::null_mut() { return None; } + if sa.is_null() { return None; } - let (addr, _) = match unsafe { *sa }.sa_family as i32 { + let (addr, _) = match i32::from(unsafe { *sa }.sa_family) { AF_INET => { - let sa: *const sockaddr_in = unsafe { mem::transmute(sa) }; - let sa = & unsafe { *sa }; + let sa: *const sockaddr_in = sa as *const sockaddr_in; + let sa = unsafe { &*sa }; let (addr, port) = (sa.sin_addr.s_addr, sa.sin_port); (IpAddr::V4(Ipv4Addr::new( - (addr & 0x000000FF) as u8, - ((addr & 0x0000FF00) >> 8) as u8, - ((addr & 0x00FF0000) >> 16) as u8, - ((addr & 0xFF000000) >> 24) as u8)), + (addr & 0x0000_00FF) as u8, + ((addr & 0x0000_FF00) >> 8) as u8, + ((addr & 0x00FF_0000) >> 16) as u8, + ((addr & 0xFF00_0000) >> 24) as u8)), port) }, AF_INET6 => { - let sa: *const sockaddr_in6 = unsafe { mem::transmute(sa) }; + let sa: *const sockaddr_in6 = sa as *const sockaddr_in6; let sa = & unsafe { *sa }; let (addr, port) = (sa.sin6_addr.s6_addr, sa.sin6_port); let addr: [u16; 8] = unsafe { mem::transmute(addr) }; @@ -266,7 +266,7 @@ mod getinterfaces { let mut ret = Vec::new(); let mut cur: *mut ifaddrs = ifap; - while cur != ptr::null_mut() { + while !cur.is_null() { if let Some(ip_addr) = convert_ifaddrs(cur) { ret.push(ip_addr); } @@ -297,16 +297,16 @@ pub fn select_public_address(port: u16) -> SocketAddr { //prefer IPV4 bindings for addr in &list { //TODO: use better criteria than just the first in the list match addr { - &IpAddr::V4(a) if !a.is_reserved() => { - return SocketAddr::V4(SocketAddrV4::new(a, port)); + IpAddr::V4(a) if !a.is_reserved() => { + return SocketAddr::V4(SocketAddrV4::new(*a, port)); }, _ => {}, } } for addr in &list { match addr { - &IpAddr::V6(a) if !a.is_reserved() => { - return SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)); + IpAddr::V6(a) if !a.is_reserved() => { + return SocketAddr::V6(SocketAddrV6::new(*a, port, 0, 0)); }, _ => {}, } @@ -319,7 +319,7 @@ pub fn select_public_address(port: u16) -> SocketAddr { pub fn map_external_address(local: &NodeEndpoint) -> Option { if let SocketAddr::V4(ref local_addr) = local.address { - match search_gateway_from_timeout(local_addr.ip().clone(), Duration::new(5, 0)) { + match search_gateway_from_timeout(*local_addr.ip(), Duration::new(5, 0)) { Err(ref err) => debug!("Gateway search error: {}", err), Ok(gateway) => { match gateway.get_external_ip() { @@ -327,17 +327,17 @@ pub fn map_external_address(local: &NodeEndpoint) -> Option { debug!("IP request error: {}", err); }, Ok(external_addr) => { - match gateway.add_any_port(PortMappingProtocol::TCP, SocketAddrV4::new(local_addr.ip().clone(), local_addr.port()), 0, "Parity Node/TCP") { + match gateway.add_any_port(PortMappingProtocol::TCP, SocketAddrV4::new(*local_addr.ip(), local_addr.port()), 0, "Parity Node/TCP") { Err(ref err) => { debug!("Port mapping error: {}", err); }, Ok(tcp_port) => { - match gateway.add_any_port(PortMappingProtocol::UDP, SocketAddrV4::new(local_addr.ip().clone(), local.udp_port), 0, "Parity Node/UDP") { + match gateway.add_any_port(PortMappingProtocol::UDP, SocketAddrV4::new(*local_addr.ip(), local.udp_port), 0, "Parity Node/UDP") { Err(ref err) => { debug!("Port mapping error: {}", err); }, Ok(udp_port) => { - return Some(NodeEndpoint { address: SocketAddr::V4(SocketAddrV4::new(external_addr, tcp_port)), udp_port: udp_port }); + return Some(NodeEndpoint { address: SocketAddr::V4(SocketAddrV4::new(external_addr, tcp_port)), udp_port }); }, } }, diff --git a/util/network-devp2p/src/node_table.rs b/util/network-devp2p/src/node_table.rs index 8640901cd09..d5d0207ecd6 100644 --- a/util/network-devp2p/src/node_table.rs +++ b/util/network-devp2p/src/node_table.rs @@ -26,7 +26,7 @@ use std::hash::{Hash, Hasher}; use std::net::{SocketAddr, ToSocketAddrs, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr}; use std::path::PathBuf; use std::str::FromStr; -use std::{fs, mem, slice}; +use std::{fs, slice}; use std::time::{self, Duration, SystemTime}; use rand::{self, Rng}; @@ -45,8 +45,8 @@ pub struct NodeEndpoint { impl NodeEndpoint { pub fn udp_address(&self) -> SocketAddr { match self.address { - SocketAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a.ip().clone(), self.udp_port)), - SocketAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a.ip().clone(), self.udp_port, a.flowinfo(), a.scope_id())), + SocketAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(*a.ip(), self.udp_port)), + SocketAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(*a.ip(), self.udp_port, a.flowinfo(), a.scope_id())), } } @@ -61,10 +61,10 @@ impl NodeEndpoint { pub fn is_allowed_by_predefined(&self, filter: &AllowIP) -> bool { match filter { - &AllowIP::All => true, - &AllowIP::Private => self.address.ip().is_usable_private(), - &AllowIP::Public => self.address.ip().is_usable_public(), - &AllowIP::None => false, + AllowIP::All => true, + AllowIP::Private => self.address.ip().is_usable_private(), + AllowIP::Public => self.address.ip().is_usable_public(), + AllowIP::None => false, } } @@ -75,13 +75,13 @@ impl NodeEndpoint { let address = match addr_bytes.len() { 4 => Ok(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(addr_bytes[0], addr_bytes[1], addr_bytes[2], addr_bytes[3]), tcp_port))), 16 => unsafe { - let o: *const u16 = mem::transmute(addr_bytes.as_ptr()); + let o: *const u16 = addr_bytes.as_ptr() as *const u16; let o = slice::from_raw_parts(o, 8); Ok(SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(o[0], o[1], o[2], o[3], o[4], o[5], o[6], o[7]), tcp_port, 0, 0))) }, _ => Err(DecoderError::RlpInconsistentLengthAndData) }?; - Ok(NodeEndpoint { address: address, udp_port: udp_port }) + Ok(NodeEndpoint { address, udp_port }) } pub fn to_rlp(&self, rlp: &mut RlpStream) { @@ -90,7 +90,7 @@ impl NodeEndpoint { rlp.append(&(&a.ip().octets()[..])); } SocketAddr::V6(a) => unsafe { - let o: *const u8 = mem::transmute(a.ip().segments().as_ptr()); + let o: *const u8 = a.ip().segments().as_ptr() as *const u8; rlp.append(&slice::from_raw_parts(o, 16)); } }; @@ -184,8 +184,8 @@ pub struct Node { impl Node { pub fn new(id: NodeId, endpoint: NodeEndpoint) -> Node { Node { - id: id, - endpoint: endpoint, + id, + endpoint, peer_type: PeerType::Optional, last_contact: None, } @@ -214,8 +214,8 @@ impl FromStr for Node { }; Ok(Node { - id: id, - endpoint: endpoint, + id, + endpoint, peer_type: PeerType::Optional, last_contact: None, }) @@ -258,7 +258,7 @@ impl NodeTable { pub fn add_node(&mut self, mut node: Node) { // preserve node last_contact node.last_contact = self.nodes.get(&node.id).and_then(|n| n.last_contact); - self.nodes.insert(node.id.clone(), node); + self.nodes.insert(node.id, node); } /// Returns a list of ordered nodes according to their most recent contact @@ -315,7 +315,7 @@ impl NodeTable { /// Returns node ids sorted by failure percentage, for nodes with the same failure percentage the absolute number of /// failures is considered. - pub fn nodes(&self, filter: IpFilter) -> Vec { + pub fn nodes(&self, filter: &IpFilter) -> Vec { self.ordered_entries().iter() .filter(|n| n.endpoint.is_allowed(&filter)) .map(|n| n.id) @@ -327,7 +327,7 @@ impl NodeTable { pub fn entries(&self) -> Vec { self.ordered_entries().iter().map(|n| NodeEntry { endpoint: n.endpoint.clone(), - id: n.id.clone(), + id: n.id, }).collect() } @@ -344,7 +344,7 @@ impl NodeTable { /// Apply table changes coming from discovery pub fn update(&mut self, mut update: TableUpdates, reserved: &HashSet) { for (_, node) in update.added.drain() { - let entry = self.nodes.entry(node.id.clone()).or_insert_with(|| Node::new(node.id.clone(), node.endpoint.clone())); + let entry = self.nodes.entry(node.id).or_insert_with(|| Node::new(node.id, node.endpoint.clone())); entry.endpoint = node.endpoint; } for r in update.removed { @@ -389,7 +389,7 @@ impl NodeTable { return; } path.push(NODES_FILE); - let node_ids = self.nodes(IpFilter::default()); + let node_ids = self.nodes(&IpFilter::default()); let nodes = node_ids.into_iter() .map(|id| self.nodes.get(&id).expect("self.nodes() only returns node IDs from self.nodes")) .take(MAX_NODES) @@ -428,7 +428,7 @@ impl NodeTable { Ok(table) => { table.nodes.into_iter() .filter_map(|n| n.into_node()) - .map(|n| (n.id.clone(), n)) + .map(|n| (n.id, n)) .collect() }, Err(e) => { @@ -625,7 +625,7 @@ mod tests { // unknown - node 6 - let r = table.nodes(IpFilter::default()); + let r = table.nodes(&IpFilter::default()); assert_eq!(r[0][..], id4[..]); // most recent success assert_eq!(r[1][..], id3[..]); @@ -662,7 +662,7 @@ mod tests { { let table = NodeTable::new(Some(tempdir.path().to_str().unwrap().to_owned())); - let r = table.nodes(IpFilter::default()); + let r = table.nodes(&IpFilter::default()); assert_eq!(r[0][..], id2[..]); // latest success assert_eq!(r[1][..], id1[..]); // unknown assert_eq!(r[2][..], id3[..]); // oldest failure diff --git a/util/network-devp2p/src/service.rs b/util/network-devp2p/src/service.rs index 1b46ca1ae33..d8105f649c5 100644 --- a/util/network-devp2p/src/service.rs +++ b/util/network-devp2p/src/service.rs @@ -165,7 +165,7 @@ impl NetworkService { let host = self.host.read(); if let Some(ref host) = *host { let io_ctxt = IoContext::new(self.io_service.channel(), 0); - host.set_non_reserved_mode(mode, &io_ctxt); + host.set_non_reserved_mode(&mode, &io_ctxt); } } diff --git a/util/network-devp2p/src/session.rs b/util/network-devp2p/src/session.rs index 47eb2cf7283..cd8ef56bd4a 100644 --- a/util/network-devp2p/src/session.rs +++ b/util/network-devp2p/src/session.rs @@ -117,7 +117,7 @@ impl Session { capabilities: Vec::new(), peer_capabilities: Vec::new(), ping: None, - originated: originated, + originated, remote_address: "Handshake".to_owned(), local_address: local_addr, }, @@ -131,7 +131,7 @@ impl Session { fn complete_handshake(&mut self, io: &IoContext, host: &HostInfo) -> Result<(), Error> where Message: Send + Sync + Clone { let connection = if let State::Handshake(ref mut h) = self.state { - self.info.id = Some(h.id.clone()); + self.info.id = Some(h.id); self.info.remote_address = h.connection.remote_addr_str(); EncryptedConnection::new(h)? } else { @@ -204,7 +204,7 @@ impl Session { } } if let Some(data) = packet_data { - return Ok(self.read_packet(io, data, host)?); + return Ok(self.read_packet(io, &data, host)?); } if create_session { self.complete_handshake(io, host)?; @@ -277,7 +277,7 @@ impl Session { None => packet_id }; let mut rlp = RlpStream::new(); - rlp.append(&(pid as u32)); + rlp.append(&(u32::from(pid))); let mut compressed = Vec::new(); let mut payload = data; // create a reference with local lifetime if self.compression { @@ -329,7 +329,7 @@ impl Session { } } - fn read_packet(&mut self, io: &IoContext, packet: Packet, host: &HostInfo) -> Result + fn read_packet(&mut self, io: &IoContext, packet: &Packet, host: &HostInfo) -> Result where Message: Send + Sync + Clone { if packet.data.len() < 2 { return Err(ErrorKind::BadProtocol.into()); @@ -390,7 +390,7 @@ impl Session { match *self.protocol_states.entry(protocol).or_insert_with(|| ProtocolState::Pending(Vec::new())) { ProtocolState::Connected => { trace!(target: "network", "Packet {} mapped to {:?}:{}, i={}, capabilities={:?}", packet_id, protocol, protocol_packet_id, i, self.info.capabilities); - Ok(SessionData::Packet { data: data, protocol: protocol, packet_id: protocol_packet_id } ) + Ok(SessionData::Packet { data, protocol, packet_id: protocol_packet_id } ) } ProtocolState::Pending(ref mut pending) => { trace!(target: "network", "Packet {} deferred until protocol connection event completion", packet_id); @@ -468,11 +468,11 @@ impl Session { self.info.peer_capabilities = peer_caps; if self.info.capabilities.is_empty() { trace!(target: "network", "No common capabilities with peer."); - return Err(From::from(self.disconnect(io, DisconnectReason::UselessPeer))); + return Err(self.disconnect(io, DisconnectReason::UselessPeer)); } if protocol < MIN_PROTOCOL_VERSION { trace!(target: "network", "Peer protocol version mismatch: {}", protocol); - return Err(From::from(self.disconnect(io, DisconnectReason::UselessPeer))); + return Err(self.disconnect(io, DisconnectReason::UselessPeer)); } self.compression = protocol >= MIN_COMPRESSION_PROTOCOL_VERSION; self.send_ping(io)?; diff --git a/whisper/cli/src/main.rs b/whisper/cli/src/main.rs index f245e99e482..d76c216be46 100644 --- a/whisper/cli/src/main.rs +++ b/whisper/cli/src/main.rs @@ -19,6 +19,9 @@ //! Spawns an Ethereum network instance and attaches the Whisper protocol RPCs to it. //! +#![warn(missing_docs)] +#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] + extern crate docopt; extern crate ethcore_network_devp2p as devp2p; extern crate ethcore_network as net; From 1020560af632d6359dcf44c43314dc2df78e2b5b Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 May 2018 13:39:25 +0200 Subject: [PATCH 5/9] Remove a couple of unnecessary `transmute()` (#8736) --- ethash/src/compute.rs | 5 ++--- util/plain_hasher/src/lib.rs | 17 +++++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/ethash/src/compute.rs b/ethash/src/compute.rs index 48906b9edeb..de2b57637fa 100644 --- a/ethash/src/compute.rs +++ b/ethash/src/compute.rs @@ -25,9 +25,8 @@ use seed_compute::SeedHashCompute; use shared::*; use std::io; -use std::mem; +use std::{mem, ptr}; use std::path::Path; -use std::ptr; const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4; const MIX_NODES: usize = MIX_WORDS / NODE_WORDS; @@ -111,7 +110,7 @@ pub fn quick_get_difficulty(header_hash: &H256, nonce: u64, mix_hash: &H256) -> let mut buf: [u8; 64 + 32] = mem::uninitialized(); ptr::copy_nonoverlapping(header_hash.as_ptr(), buf.as_mut_ptr(), 32); - ptr::copy_nonoverlapping(mem::transmute(&nonce), buf[32..].as_mut_ptr(), 8); + ptr::copy_nonoverlapping(&nonce as *const u64 as *const u8, buf[32..].as_mut_ptr(), 8); keccak_512::unchecked(buf.as_mut_ptr(), 64, buf.as_ptr(), 40); ptr::copy_nonoverlapping(mix_hash.as_ptr(), buf[64..].as_mut_ptr(), 32); diff --git a/util/plain_hasher/src/lib.rs b/util/plain_hasher/src/lib.rs index 54bad92f47e..d08d4dd1aba 100644 --- a/util/plain_hasher/src/lib.rs +++ b/util/plain_hasher/src/lib.rs @@ -2,9 +2,9 @@ extern crate crunchy; extern crate ethereum_types; -use std::{hash, mem}; -use std::collections::{HashMap, HashSet}; use ethereum_types::H256; +use std::collections::{HashMap, HashSet}; +use std::hash; /// Specialized version of `HashMap` with H256 keys and fast hashing function. pub type H256FastMap = HashMap>; @@ -28,16 +28,13 @@ impl hash::Hasher for PlainHasher { #[allow(unused_assignments)] fn write(&mut self, bytes: &[u8]) { debug_assert!(bytes.len() == 32); + let mut bytes_ptr = bytes.as_ptr(); + let mut prefix_ptr = &mut self.prefix as *mut u64 as *mut u8; - unsafe { - let mut bytes_ptr = bytes.as_ptr(); - let prefix_u8: &mut [u8; 8] = mem::transmute(&mut self.prefix); - let mut prefix_ptr = prefix_u8.as_mut_ptr(); - - unroll! { - for _i in 0..8 { + unroll! { + for _i in 0..8 { + unsafe { *prefix_ptr ^= (*bytes_ptr ^ *bytes_ptr.offset(8)) ^ (*bytes_ptr.offset(16) ^ *bytes_ptr.offset(24)); - bytes_ptr = bytes_ptr.offset(1); prefix_ptr = prefix_ptr.offset(1); } From d32ce374847ba4ed09101535dfb66356b3a2ffe9 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 31 May 2018 13:53:09 +0200 Subject: [PATCH 6/9] bump tinykeccak to 1.4 (#8728) --- ethcore/crypto/Cargo.toml | 2 +- ethcore/private-tx/Cargo.toml | 2 +- ethkey/Cargo.toml | 2 +- ethstore/Cargo.toml | 2 +- rpc/Cargo.toml | 2 +- secret_store/Cargo.toml | 2 +- util/network-devp2p/Cargo.toml | 2 +- whisper/Cargo.toml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ethcore/crypto/Cargo.toml b/ethcore/crypto/Cargo.toml index 4fe023f25c4..b57b8497c0e 100644 --- a/ethcore/crypto/Cargo.toml +++ b/ethcore/crypto/Cargo.toml @@ -8,5 +8,5 @@ ethereum-types = "0.3" quick-error = "1.2" ring = "0.12" rust-crypto = "0.2.36" -tiny-keccak = "1.3" +tiny-keccak = "1.4" diff --git a/ethcore/private-tx/Cargo.toml b/ethcore/private-tx/Cargo.toml index 0fa11aec84b..8283ab314aa 100644 --- a/ethcore/private-tx/Cargo.toml +++ b/ethcore/private-tx/Cargo.toml @@ -33,5 +33,5 @@ rustc-hex = "1.0" serde = "1.0" serde_derive = "1.0" serde_json = "1.0" -tiny-keccak = "1.3" +tiny-keccak = "1.4" url = "1" diff --git a/ethkey/Cargo.toml b/ethkey/Cargo.toml index d6698f86d9f..952354739d5 100644 --- a/ethkey/Cargo.toml +++ b/ethkey/Cargo.toml @@ -16,4 +16,4 @@ parity-wordlist = "1.2" quick-error = "1.2" rand = "0.4" rustc-hex = "1.0" -tiny-keccak = "1.3" +tiny-keccak = "1.4" diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index 6330ce97ce7..6108143cb9e 100644 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -12,7 +12,7 @@ serde = "1.0" serde_json = "1.0" serde_derive = "1.0" rustc-hex = "1.0" -tiny-keccak = "1.3" +tiny-keccak = "1.4" time = "0.1.34" itertools = "0.5" parking_lot = "0.5" diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index 8fdb9ed5740..8a0b689c655 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -23,7 +23,7 @@ serde = "1.0" serde_derive = "1.0" serde_json = "1.0" tempdir = "0.3" -tiny-keccak = "1.3" +tiny-keccak = "1.4" tokio-timer = "0.1" transient-hashmap = "0.4" itertools = "0.5" diff --git a/secret_store/Cargo.toml b/secret_store/Cargo.toml index fee832d069c..261658903cc 100644 --- a/secret_store/Cargo.toml +++ b/secret_store/Cargo.toml @@ -16,7 +16,7 @@ serde_derive = "1.0" futures = "0.1" futures-cpupool = "0.1" rustc-hex = "1.0" -tiny-keccak = "1.3" +tiny-keccak = "1.4" tokio = "0.1" tokio-core = "0.1" tokio-io = "0.1" diff --git a/util/network-devp2p/Cargo.toml b/util/network-devp2p/Cargo.toml index f4889fe26d4..4a5d2d942ec 100644 --- a/util/network-devp2p/Cargo.toml +++ b/util/network-devp2p/Cargo.toml @@ -11,7 +11,7 @@ log = "0.3" mio = "0.6.8" bytes = "0.4" rand = "0.4" -tiny-keccak = "1.3" +tiny-keccak = "1.4" rust-crypto = "0.2.34" slab = "0.2" igd = "0.7" diff --git a/whisper/Cargo.toml b/whisper/Cargo.toml index ed370e38a2d..e503a74fd6d 100644 --- a/whisper/Cargo.toml +++ b/whisper/Cargo.toml @@ -23,7 +23,7 @@ serde_derive = "1.0" serde_json = "1.0" slab = "0.3" smallvec = "0.4" -tiny-keccak = "1.3" +tiny-keccak = "1.4" jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc.git", branch = "parity-1.11" } From 9053c0dfd9449ca8a83bac7964cd9d336e6d9f94 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 31 May 2018 15:07:35 +0300 Subject: [PATCH 7/9] ease tiny-keccak version requirements (1.4.1 -> 1.4) (#8726) --- util/hash/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/hash/Cargo.toml b/util/hash/Cargo.toml index e136ada305a..4ca503751aa 100644 --- a/util/hash/Cargo.toml +++ b/util/hash/Cargo.toml @@ -9,7 +9,7 @@ authors = ["Parity Technologies "] [dependencies] ethereum-types = "0.3" -tiny-keccak = "1.4.1" +tiny-keccak = "1.4" [dev-dependencies] tempdir = "0.3" From 581e510c2d91cfa9008ebf0de93fb4a42be3bd80 Mon Sep 17 00:00:00 2001 From: vrde Date: Thu, 31 May 2018 14:43:06 +0200 Subject: [PATCH 8/9] Remove -k/--insecure option from curl installer (#8719) Piping `curl` to `bash` while **disabling** certificate verification can lead to security problems. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9255d014b6c..8cba4205bdb 100644 --- a/README.md +++ b/README.md @@ -138,13 +138,13 @@ first. ## Simple one-line installer for Mac and Ubuntu ```bash -bash <(curl https://get.parity.io -Lk) +bash <(curl https://get.parity.io -L) ``` The one-line installer always defaults to the latest beta release. To install a stable release, run: ```bash -bash <(curl https://get.parity.io -Lk) -r stable +bash <(curl https://get.parity.io -L) -r stable ``` ## Start Parity From 00b209a29e96dc6827852de27d8c426189fd2f56 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 31 May 2018 21:28:25 +0800 Subject: [PATCH 9/9] Fix PoW blockchains sealing notifications in chain_new_blocks (#8656) --- ethcore/src/client/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 5cfe8fce82c..b469cf45180 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -2181,7 +2181,7 @@ impl ImportSealedBlock for Client { route }; let route = ChainRoute::from([route].as_ref()); - self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], route.enacted(), route.retracted(), true); + self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], route.enacted(), route.retracted(), self.engine.seals_internally().is_some()); self.notify(|notify| { notify.new_blocks( vec![h.clone()],