timeout loading

This commit is contained in:
keorn 2016-11-15 15:25:30 +00:00
parent 7d0eafd5cd
commit 1c958695c3
3 changed files with 54 additions and 23 deletions

View File

@ -17,7 +17,7 @@
//! Tendermint specific parameters. //! Tendermint specific parameters.
use ethjson; use ethjson;
use super::timeout::DefaultTimeouts; use super::timeout::TendermintTimeouts;
use util::{Address, U256}; use util::{Address, U256};
/// `Tendermint` params. /// `Tendermint` params.
@ -30,7 +30,7 @@ pub struct TendermintParams {
/// Number of authorities. /// Number of authorities.
pub authority_n: usize, pub authority_n: usize,
/// Timeout durations for different steps. /// Timeout durations for different steps.
pub timeouts: DefaultTimeouts, pub timeouts: TendermintTimeouts,
} }
impl Default for TendermintParams { impl Default for TendermintParams {
@ -54,7 +54,13 @@ impl From<ethjson::spec::TendermintParams> for TendermintParams {
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(), gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
authorities: val, authorities: val,
authority_n: val_n, authority_n: val_n,
timeouts: DefaultTimeouts::default() let dt = TendermintTimeouts::default();
timeouts: TendermintTimeouts {
propose: p.timeout_propose.unwrap_or(dt.propose),
prevote: p.timeout_prevote.unwrap_or(dt.prevote),
precommit: p.timeout_precommit.unwrap_or(dt.precommit),
commit: p.timeout_commit.unwrap_or(dt.commit)
}
} }
} }
} }

View File

@ -20,7 +20,8 @@ use std::sync::atomic::{Ordering as AtomicOrdering};
use std::sync::Weak; use std::sync::Weak;
use io::{IoContext, IoHandler, TimerToken}; use io::{IoContext, IoHandler, TimerToken};
use super::{Tendermint, Step}; use super::{Tendermint, Step};
use time::get_time; use time::{get_time, Duration};
use service::ClientIoMessage;
pub struct TimerHandler { pub struct TimerHandler {
engine: Weak<Tendermint>, engine: Weak<Tendermint>,
@ -28,41 +29,50 @@ pub struct TimerHandler {
/// Base timeout of each step in ms. /// Base timeout of each step in ms.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DefaultTimeouts { pub struct TendermintTimeouts {
pub propose: Ms, propose: Duration,
pub prevote: Ms, prevote: Duartion,
pub precommit: Ms, precommit: Duration,
pub commit: Ms commit: Duration
} }
impl Default for DefaultTimeouts { impl TendermintTimeouts {
pub fn for_step(step: Step) -> Duration {
match step {
Step::Propose => self.propose,
Step::Prevote => self.prevote,
Step::Precommit => self.precommit,
Step::Commit => self.commit,
}
}
}
impl Default for TendermintTimeouts {
fn default() -> Self { fn default() -> Self {
DefaultTimeouts { DefaultTimeouts {
propose: 1000, propose: Duration::milliseconds(1000),
prevote: 1000, prevote: Duration::milliseconds(1000),
precommit: 1000, precommit: Duration::milliseconds(1000),
commit: 1000 commit: Duration::milliseconds(1000)
} }
} }
} }
pub type Ms = usize;
#[derive(Clone)] #[derive(Clone)]
pub struct NextStep; pub struct NextStep;
/// Timer token representing the consensus step timeouts. /// Timer token representing the consensus step timeouts.
pub const ENGINE_TIMEOUT_TOKEN: TimerToken = 0; pub const ENGINE_TIMEOUT_TOKEN: TimerToken = 23;
impl IoHandler<NextStep> for TimerHandler { impl IoHandler<NextStep> for TimerHandler {
fn initialize(&self, io: &IoContext<BlockArrived>) { fn initialize(&self, io: &IoContext<NextStep>) {
if let Some(engine) = self.engine.upgrade() { if let Some(engine) = self.engine.upgrade() {
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.remaining_step_duration().as_millis()) io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.remaining_step_duration().as_millis())
.unwrap_or_else(|e| warn!(target: "poa", "Failed to start consensus step timer: {}.", e)) .unwrap_or_else(|e| warn!(target: "poa", "Failed to start consensus step timer: {}.", e))
} }
} }
fn timeout(&self, io: &IoContext<BlockArrived>, timer: TimerToken) { fn timeout(&self, io: &IoContext<NextStep>, 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.fetch_add(1, AtomicOrdering::SeqCst); engine.step.fetch_add(1, AtomicOrdering::SeqCst);
@ -77,14 +87,17 @@ impl IoHandler<NextStep> for TimerHandler {
}, },
}; };
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.next_timeout().as_millis())
.unwrap_or_else(|e| warn!(target: "poa", "Failed to restart consensus step timer: {}.", e))
if let Some(ref channel) = *engine.message_channel.lock() { if let Some(ref channel) = *engine.message_channel.lock() {
match channel.send(ClientIoMessage::UpdateSealing) { match channel.send(ClientIoMessage::UpdateSealing) {
Ok(_) => trace!(target: "poa", "timeout: UpdateSealing message sent for step {}.", engine.step.load(AtomicOrdering::Relaxed)), Ok(_) => trace!(target: "poa", "timeout: UpdateSealing message sent for step {}.", engine.step.),
Err(err) => trace!(target: "poa", "timeout: Could not send a sealing message {} for step {}.", err, engine.step.load(AtomicOrdering::Relaxed)), Err(err) => trace!(target: "poa", "timeout: Could not send a sealing message {} for step {}.", err, engine.step.load(AtomicOrdering::Relaxed)),
} }
} }
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.next_timeout().as_millis())
.unwrap_or_else(|e| warn!(target: "poa", "Failed to restart consensus step timer: {}.", e))
} }
} }
} }

View File

@ -27,6 +27,18 @@ pub struct TendermintParams {
pub gas_limit_bound_divisor: Uint, pub gas_limit_bound_divisor: Uint,
/// Valid authorities /// Valid authorities
pub authorities: Vec<Address>, pub authorities: Vec<Address>,
/// Propose step timeout in milliseconds.
#[serde(rename="timeoutPropose")]
pub timeout_propose: Option<Uint>,
/// Prevote step timeout in milliseconds.
#[serde(rename="timeoutPrevote")]
pub timeout_prevote: Option<Uint>,
/// Precommit step timeout in milliseconds.
#[serde(rename="timeoutPrecommit")]
pub timeout_precommit: Option<Uint>,
/// Commit step timeout in milliseconds.
#[serde(rename="timeoutCommit")]
pub timeout_commit: Option<Uint>,
} }
/// Tendermint engine deserialization. /// Tendermint engine deserialization.