authority_round: Fix next_step_time_duration. (#11379)

It's supposed to find the first step at or after `time`.
To compute that step's timestamp, it needs to add the total length
of all steps since the previous transitions to the timestamp of the
previous transition, not to `time`.
This commit is contained in:
Andreas Fackler 2020-01-13 22:42:14 +01:00 committed by Andronik Ordian
parent 73354d8d93
commit ea8e7fcf73

View File

@ -215,7 +215,7 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
} }
/// A triple containing the first step number and the starting timestamp of the given step duration. /// A triple containing the first step number and the starting timestamp of the given step duration.
#[derive(Clone, Debug)] #[derive(Clone, Copy, Debug)]
struct StepDurationInfo { struct StepDurationInfo {
transition_step: u64, transition_step: u64,
transition_timestamp: u64, transition_timestamp: u64,
@ -1896,9 +1896,10 @@ fn next_step_time_duration(info: StepDurationInfo, time: u64) -> Option<(u64, u6
.checked_sub(1)? .checked_sub(1)?
.checked_sub(info.transition_timestamp)? .checked_sub(info.transition_timestamp)?
.checked_div(info.step_duration)?; .checked_div(info.step_duration)?;
let time_diff = step_diff.checked_mul(info.step_duration)?;
Some(( Some((
info.transition_step.checked_add(step_diff)?, info.transition_step.checked_add(step_diff)?,
step_diff.checked_mul(info.step_duration)?.checked_add(time)?, info.transition_timestamp.checked_add(time_diff)?,
)) ))
} }
@ -1940,7 +1941,7 @@ mod tests {
use super::{ use super::{
AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, StepDurationInfo, AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, StepDurationInfo,
calculate_score, util::BoundContract, calculate_score, util::BoundContract, next_step_time_duration,
}; };
fn build_aura<F>(f: F) -> Arc<AuthorityRound> where fn build_aura<F>(f: F) -> Arc<AuthorityRound> where
@ -2304,6 +2305,22 @@ mod tests {
step.duration_remaining(); step.duration_remaining();
} }
#[test]
fn test_next_step_time_duration() {
// At step 7 (time 1000), we transitioned to step duration 10.
let info = StepDurationInfo {
step_duration: 10,
transition_step: 7,
transition_timestamp: 1000,
};
// So the next transition can happen e.g. at step 12 (time 1050) or 13 (time 1060).
assert_eq!(Some((12, 1050)), next_step_time_duration(info, 1050));
assert_eq!(Some((13, 1060)), next_step_time_duration(info, 1051));
assert_eq!(Some((13, 1060)), next_step_time_duration(info, 1055));
// The next transition could also happen immediately.
assert_eq!(Some((7, 1000)), next_step_time_duration(info, 1000));
}
#[test] #[test]
fn test_change_step_duration() { fn test_change_step_duration() {
use super::Step; use super::Step;