Advance AuRa step as far as we can and prevent invalid blocks. (#7451)

* Advance AuRa step as far as we can.

* Wait for future blocks.
This commit is contained in:
Tomasz Drwięga 2018-01-08 14:46:11 +01:00 committed by Robert Habermeier
parent 47b2b151ce
commit 33b8f28f62

View File

@ -147,11 +147,10 @@ impl Step {
} }
fn check_future(&self, given: usize) -> Result<(), Option<OutOfBounds<u64>>> { fn check_future(&self, given: usize) -> Result<(), Option<OutOfBounds<u64>>> {
const VALID_STEP_DRIFT: usize = 1;
const REJECTED_STEP_DRIFT: usize = 4; const REJECTED_STEP_DRIFT: usize = 4;
// Give one step slack if step is lagging, double vote is still not possible. // Verify if the step is correct.
if given <= self.load() + VALID_STEP_DRIFT { if given <= self.load() {
return Ok(()); return Ok(());
} }
@ -163,11 +162,11 @@ impl Step {
if given > current + REJECTED_STEP_DRIFT { if given > current + REJECTED_STEP_DRIFT {
Err(None) Err(None)
// wait a bit for blocks in near future // wait a bit for blocks in near future
} else if given > current + VALID_STEP_DRIFT { } else if given > current {
let d = self.duration as u64; let d = self.duration as u64;
Err(Some(OutOfBounds { Err(Some(OutOfBounds {
min: None, min: None,
max: Some(d * (current + VALID_STEP_DRIFT) as u64), max: Some(d * current as u64),
found: d * given as u64, found: d * given as u64,
})) }))
} else { } else {
@ -474,9 +473,15 @@ impl IoHandler<()> for TransitionHandler {
fn timeout(&self, io: &IoContext<()>, timer: TimerToken) { fn timeout(&self, io: &IoContext<()>, timer: TimerToken) {
if timer == ENGINE_TIMEOUT_TOKEN { if timer == ENGINE_TIMEOUT_TOKEN {
if let Some(engine) = self.engine.upgrade() { if let Some(engine) = self.engine.upgrade() {
engine.step(); // NOTE we might be lagging by couple of steps in case the timeout
let remaining = engine.step.duration_remaining(); // has not been called fast enough.
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, remaining.as_millis()) // Make sure to advance up to the actual step.
while engine.step.duration_remaining().as_millis() == 0 {
engine.step();
}
let next_run_at = engine.step.duration_remaining().as_millis() >> 2;
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, next_run_at)
.unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e)) .unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e))
} }
} }
@ -549,6 +554,13 @@ impl Engine<EthereumMachine> for AuthorityRound {
let expected_diff = calculate_score(parent_step, step.into()); let expected_diff = calculate_score(parent_step, step.into());
if header.difficulty() != &expected_diff { if header.difficulty() != &expected_diff {
debug!(target: "engine", "Aborting seal generation. The step has changed in the meantime. {:?} != {:?}",
header.difficulty(), expected_diff);
return Seal::None;
}
if parent_step > step.into() {
warn!(target: "engine", "Aborting seal generation for invalid step: {} > {}", parent_step, step);
return Seal::None; return Seal::None;
} }