Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit ebe4890

Browse files
authored
[stable]: backport #10691 and #10683 (#11143)
* Fix compiler warning (that will become an error) (#10683) * Remove annoying compiler warnings * Fix compiler warning (that will become an error) Fixes #10648 I'm not sure this fix is Good™ but rustc seems happy enough. There's a deeper issue which may or may not be related to this: the Engine is not shutdown properly and the `StepService` thread keeps running indefinitely after Ctrl-C (so `update_sealing()` is called repeatedly for 300sec). I don't think this is related to Clique as I've seen this happen on mainnet as well, but I wonder if the effects of it are worse for a PoA network where the node can create new blocks all on its own? * Use saturating_sub * WIP * Fix warning, second attempt The idea here is to avoid using `Arc::get_mut()` (which does not work: fails every time here) and instead trust `drop()` to do the right thing. This is a conservative change. I think this can be reformed further, e.g. by `impl Drop for StepService` and halt the thread there, or even skip `join()`ing the thread entirely and trust the `AtomicBool` to signal shutdown. I also have doubts abut the `Option<StepService>`: seems a bit much to have an `Option` there and it makes things cumbersome. * Refactor Clique stepping (#10691) * Use Drop to shutdown stepper thread Make period == 0 an error and remove the Option from step_service * Remove StepService Remove StepService and spawn the stepping thread in `Clique::new()`. Don't store the thread handle and instead trust the `AtomicBool` to signal shutdown time. Don't check for `period > 0`: we assume a valid chainspec file. * Don't shutdown the stepper thread at all, just let it run until exit Also: fix a few warnings and tests * Put kvdb_memorydb back * Warn&exit when engine is dropped Don't sleep too long! * Don't delay stepping thread * Better formatting
1 parent 4b295aa commit ebe4890

File tree

4 files changed

+29
-116
lines changed

4 files changed

+29
-116
lines changed

ethcore/src/client/client.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2558,16 +2558,6 @@ impl ProvingBlockChainClient for Client {
25582558

25592559
impl SnapshotClient for Client {}
25602560

2561-
impl Drop for Client {
2562-
fn drop(&mut self) {
2563-
if let Some(c) = Arc::get_mut(&mut self.engine) {
2564-
c.stop()
2565-
} else {
2566-
warn!(target: "shutdown", "unable to get mut ref for engine for shutdown.");
2567-
}
2568-
}
2569-
}
2570-
25712561
/// Returns `LocalizedReceipt` given `LocalizedTransaction`
25722562
/// and a vector of receipts from given block up to transaction index.
25732563
fn transaction_receipt(

ethcore/src/engines/clique/mod.rs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use std::collections::VecDeque;
6464
use std::sync::{Arc, Weak};
6565
use std::thread;
6666
use std::time;
67-
use std::time::{Duration, SystemTime, UNIX_EPOCH};
67+
use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH};
6868

6969
use block::ExecutedBlock;
7070
use bytes::Bytes;
@@ -88,11 +88,9 @@ use types::header::{ExtendedHeader, Header};
8888

8989
use self::block_state::CliqueBlockState;
9090
use self::params::CliqueParams;
91-
use self::step_service::StepService;
9291

9392
mod params;
9493
mod block_state;
95-
mod step_service;
9694
mod util;
9795

9896
// TODO(niklasad1): extract tester types into a separate mod to be shared in the code base
@@ -167,7 +165,6 @@ pub struct Clique {
167165
block_state_by_hash: RwLock<LruCache<H256, CliqueBlockState>>,
168166
proposals: RwLock<HashMap<Address, VoteType>>,
169167
signer: RwLock<Option<Box<EngineSigner>>>,
170-
step_service: Option<Arc<StepService>>,
171168
}
172169

173170
#[cfg(test)]
@@ -180,30 +177,45 @@ pub struct Clique {
180177
pub block_state_by_hash: RwLock<LruCache<H256, CliqueBlockState>>,
181178
pub proposals: RwLock<HashMap<Address, VoteType>>,
182179
pub signer: RwLock<Option<Box<EngineSigner>>>,
183-
pub step_service: Option<Arc<StepService>>,
184180
}
185181

186182
impl Clique {
187183
/// Initialize Clique engine from empty state.
188-
pub fn new(our_params: CliqueParams, machine: EthereumMachine) -> Result<Arc<Self>, Error> {
189-
let mut engine = Clique {
190-
epoch_length: our_params.epoch,
191-
period: our_params.period,
184+
pub fn new(params: CliqueParams, machine: EthereumMachine) -> Result<Arc<Self>, Error> {
185+
/// Step Clique at most every 2 seconds
186+
const SEALING_FREQ: Duration = Duration::from_secs(2);
187+
188+
let engine = Clique {
189+
epoch_length: params.epoch,
190+
period: params.period,
192191
client: Default::default(),
193192
block_state_by_hash: RwLock::new(LruCache::new(STATE_CACHE_NUM)),
194193
proposals: Default::default(),
195194
signer: Default::default(),
196195
machine,
197-
step_service: None,
198196
};
197+
let engine = Arc::new(engine);
198+
let weak_eng = Arc::downgrade(&engine);
199199

200-
let res = Arc::new(engine);
201-
202-
if our_params.period > 0 {
203-
engine.step_service = Some(StepService::start(Arc::downgrade(&res) as Weak<Engine<_>>));
204-
}
200+
thread::Builder::new().name("StepService".into())
201+
.spawn(move || {
202+
loop {
203+
let next_step_at = Instant::now() + SEALING_FREQ;
204+
trace!(target: "miner", "StepService: triggering sealing");
205+
if let Some(eng) = weak_eng.upgrade() {
206+
eng.step()
207+
} else {
208+
warn!(target: "shutdown", "StepService: engine is dropped; exiting.");
209+
break;
210+
}
205211

206-
Ok(res)
212+
let now = Instant::now();
213+
if now < next_step_at {
214+
thread::sleep(next_step_at - now);
215+
}
216+
}
217+
})?;
218+
Ok(engine)
207219
}
208220

209221
#[cfg(test)]
@@ -221,7 +233,6 @@ impl Clique {
221233
proposals: Default::default(),
222234
signer: Default::default(),
223235
machine: Spec::new_test_machine(),
224-
step_service: None,
225236
}
226237
}
227238

@@ -695,7 +706,7 @@ impl Engine<EthereumMachine> for Clique {
695706
trace!(target: "engine", "populate_from_parent in sealing");
696707

697708
// It's unclear how to prevent creating new blocks unless we are authorized, the best way (and geth does this too)
698-
// it's just to ignore setting an correct difficulty here, we will check authorization in next step in generate_seal anyway.
709+
// it's just to ignore setting a correct difficulty here, we will check authorization in next step in generate_seal anyway.
699710
if let Some(signer) = self.signer.read().as_ref() {
700711
let state = match self.state(&parent) {
701712
Err(e) => {
@@ -744,14 +755,6 @@ impl Engine<EthereumMachine> for Clique {
744755
}
745756
}
746757

747-
fn stop(&mut self) {
748-
if let Some(mut s) = self.step_service.as_mut() {
749-
Arc::get_mut(&mut s).map(|x| x.stop());
750-
} else {
751-
warn!(target: "engine", "Stopping `CliqueStepService` failed requires mutable access");
752-
}
753-
}
754-
755758
/// Clique timestamp is set to parent + period , or current time which ever is higher.
756759
fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 {
757760
let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default();

ethcore/src/engines/clique/step_service.rs

Lines changed: 0 additions & 77 deletions
This file was deleted.

ethcore/src/engines/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,6 @@ pub trait Engine<M: Machine>: Sync + Send {
425425
/// Trigger next step of the consensus engine.
426426
fn step(&self) {}
427427

428-
/// Stops any services that the may hold the Engine and makes it safe to drop.
429-
fn stop(&mut self) {}
430-
431428
/// Create a factory for building snapshot chunks and restoring from them.
432429
/// Returning `None` indicates that this engine doesn't support snapshot creation.
433430
fn snapshot_components(&self) -> Option<Box<SnapshotComponents>> {

0 commit comments

Comments
 (0)