Skip to content

Commit

Permalink
Do not wait when empty block is proposed
Browse files Browse the repository at this point in the history
  • Loading branch information
HoOngEe committed Nov 25, 2019
1 parent 3d9711e commit feeae37
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 118 deletions.
3 changes: 0 additions & 3 deletions core/src/consensus/tendermint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,8 @@ use ChainNotify;

/// Timer token representing the consensus step timeouts.
const ENGINE_TIMEOUT_TOKEN_NONCE_BASE: TimerToken = 23;
/// Timer token for empty proposal blocks.
const ENGINE_TIMEOUT_EMPTY_PROPOSAL: TimerToken = 22;
/// Timer token for broadcasting step state.
const ENGINE_TIMEOUT_BROADCAST_STEP_STATE: TimerToken = 21;

/// Unit: second
const ENGINE_TIMEOUT_BROADCAT_STEP_STATE_INTERVAL: u64 = 1;

Expand Down
25 changes: 2 additions & 23 deletions core/src/consensus/tendermint/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ use super::worker;
use crate::consensus::{EngineError, Priority};

use super::{
ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_BROADCAT_STEP_STATE_INTERVAL, ENGINE_TIMEOUT_EMPTY_PROPOSAL,
ENGINE_TIMEOUT_TOKEN_NONCE_BASE,
ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_BROADCAT_STEP_STATE_INTERVAL, ENGINE_TIMEOUT_TOKEN_NONCE_BASE,
};

pub struct TendermintExtension {
Expand Down Expand Up @@ -218,19 +217,11 @@ impl TendermintExtension {
}

fn set_timer_step(&self, step: Step, view: View, expired_token_nonce: TimerToken) {
self.api.clear_timer(ENGINE_TIMEOUT_EMPTY_PROPOSAL).expect("Timer clear succeeds");
self.api.clear_timer(expired_token_nonce).expect("Timer clear succeeds");
self.api
.set_timer_once(expired_token_nonce + 1, self.timeouts.timeout(step, view))
.expect("Timer set succeeds");
}

fn set_timer_empty_proposal(&self, view: View) {
self.api.clear_timer(ENGINE_TIMEOUT_EMPTY_PROPOSAL).expect("Timer clear succeeds");
self.api
.set_timer_once(ENGINE_TIMEOUT_EMPTY_PROPOSAL, self.timeouts.timeout(Step::Propose, view) / 2)
.expect("Timer set succeeds");
}
}

impl NetworkExtension<Event> for TendermintExtension {
Expand Down Expand Up @@ -419,11 +410,7 @@ impl NetworkExtension<Event> for TendermintExtension {
}

fn on_timeout(&mut self, token: TimerToken) {
debug_assert!(
token >= ENGINE_TIMEOUT_TOKEN_NONCE_BASE
|| token == ENGINE_TIMEOUT_EMPTY_PROPOSAL
|| token == ENGINE_TIMEOUT_BROADCAST_STEP_STATE
);
debug_assert!(token >= ENGINE_TIMEOUT_TOKEN_NONCE_BASE || token == ENGINE_TIMEOUT_BROADCAST_STEP_STATE);
self.inner.send(worker::Event::OnTimeout(token)).unwrap();
}

Expand Down Expand Up @@ -459,11 +446,6 @@ impl NetworkExtension<Event> for TendermintExtension {
view,
expired_token_nonce,
} => self.set_timer_step(step, view, expired_token_nonce),
Event::SetTimerEmptyProposal {
view,
} => {
self.set_timer_empty_proposal(view);
}
Event::BroadcastProposalBlock {
signature,
sortition_info,
Expand Down Expand Up @@ -499,9 +481,6 @@ pub enum Event {
view: View,
expired_token_nonce: TimerToken,
},
SetTimerEmptyProposal {
view: View,
},
BroadcastProposalBlock {
signature: SchnorrSignature,
sortition_info: SortitionInfo,
Expand Down
28 changes: 0 additions & 28 deletions core/src/consensus/tendermint/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ pub enum TendermintState {
ProposeWaitImported {
block: Box<SealedBlock>,
},
ProposeWaitEmptyBlockTimer {
block: Box<SealedBlock>,
},
Prevote,
Precommit,
Commit {
Expand All @@ -64,9 +61,6 @@ impl TendermintState {
TendermintState::ProposeWaitImported {
..
} => Step::Propose,
TendermintState::ProposeWaitEmptyBlockTimer {
..
} => Step::Propose,
TendermintState::Prevote => Step::Prevote,
TendermintState::Precommit => Step::Precommit,
TendermintState::Commit {
Expand All @@ -78,15 +72,6 @@ impl TendermintState {
}
}

pub fn is_propose_wait_empty_block_timer(&self) -> bool {
match self {
TendermintState::ProposeWaitEmptyBlockTimer {
..
} => true,
_ => false,
}
}

pub fn is_commit(&self) -> bool {
match self {
TendermintState::Commit {
Expand Down Expand Up @@ -125,9 +110,6 @@ impl TendermintState {
TendermintState::ProposeWaitImported {
..
} => None,
TendermintState::ProposeWaitEmptyBlockTimer {
..
} => None,
TendermintState::Prevote => None,
TendermintState::Precommit => None,
}
Expand All @@ -144,9 +126,6 @@ impl fmt::Debug for TendermintState {
TendermintState::ProposeWaitImported {
block,
} => write!(f, "TendermintState::ProposeWaitImported({})", block.header().hash()),
TendermintState::ProposeWaitEmptyBlockTimer {
block,
} => write!(f, "TendermintState::ProposeWaitEmptyBlockTimer({})", block.header().hash()),
TendermintState::Prevote => write!(f, "TendermintState::Prevote"),
TendermintState::Precommit => write!(f, "TendermintState::Precommit"),
TendermintState::Commit {
Expand Down Expand Up @@ -355,11 +334,4 @@ impl Proposal {
Proposal::None => None,
}
}

pub fn is_none(&self) -> bool {
match self {
Proposal::None => true,
_ => false,
}
}
}
72 changes: 8 additions & 64 deletions core/src/consensus/tendermint/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ use super::stake::CUSTOM_ACTION_HANDLER_ID;
use super::types::{Height, Proposal, Step, TendermintSealView, TendermintState, TwoThirdsMajority, View};
use super::vote_collector::{DoubleVote, VoteCollector};
use super::vote_regression_checker::VoteRegressionChecker;
use super::{
ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_EMPTY_PROPOSAL, ENGINE_TIMEOUT_TOKEN_NONCE_BASE, SEAL_FIELDS,
};
use super::{ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_TOKEN_NONCE_BASE, SEAL_FIELDS};
use crate::account_provider::AccountProvider;
use crate::block::*;
use crate::client::ConsensusClient;
Expand Down Expand Up @@ -1020,29 +1018,14 @@ impl Worker {
TendermintState::ProposeWaitImported {
block,
} => {
if !block.transactions().is_empty() {
cinfo!(ENGINE, "Submitting proposal block {}", block.header().hash());
self.move_to_step(TendermintState::Prevote, false);
self.broadcast_proposal_block(
self.view,
self.sortition_infos.get_highest_priority(&self.current_sortition_round()).unwrap(),
encoded::Block::new(block.rlp_bytes()),
);
} else {
ctrace!(ENGINE, "Empty proposal is generated, set timer");
self.step = TendermintState::ProposeWaitEmptyBlockTimer {
block,
};
self.extension
.send(network::Event::SetTimerEmptyProposal {
view: self.view,
})
.unwrap();
}
cinfo!(ENGINE, "Submitting proposal block {}", block.header().hash());
self.move_to_step(TendermintState::Prevote, false);
self.broadcast_proposal_block(
self.view,
self.sortition_infos.get_highest_priority(&self.current_sortition_round()).unwrap(),
encoded::Block::new(block.rlp_bytes()),
);
}
TendermintState::ProposeWaitEmptyBlockTimer {
..
} => unreachable!(),
_ => {}
};
} else if current_height < height {
Expand Down Expand Up @@ -1323,39 +1306,6 @@ impl Worker {
}

fn on_timeout(&mut self, token: usize) {
// Timeout from empty block generation
if token == ENGINE_TIMEOUT_EMPTY_PROPOSAL {
let block = if self.step.is_propose_wait_empty_block_timer() {
let previous = mem::replace(&mut self.step, TendermintState::Propose);
match previous {
TendermintState::ProposeWaitEmptyBlockTimer {
block,
} => block,
_ => unreachable!(),
}
} else {
cwarn!(ENGINE, "Empty proposal timer was not cleared.");
return
};

// When self.height != block.header().number() && "propose timeout" is already called,
// the state is stuck and can't move to Prevote. We should change the step to Prevote.
self.move_to_step(TendermintState::Prevote, false);
if self.height == block.header().number() {
cdebug!(ENGINE, "Empty proposal timer is finished, go to the prevote step and broadcast the block");
cinfo!(ENGINE, "Submitting proposal block {}", block.header().hash());
self.broadcast_proposal_block(
self.view,
self.sortition_infos.get_highest_priority(&self.current_sortition_round()).unwrap(),
encoded::Block::new(block.rlp_bytes()),
);
} else {
cwarn!(ENGINE, "Empty proposal timer was for previous height.");
}

return
}

if token == ENGINE_TIMEOUT_BROADCAST_STEP_STATE {
if let Some(votes_received) = self.votes_received.borrow_if_mutated() {
self.broadcast_state(
Expand Down Expand Up @@ -1391,12 +1341,6 @@ impl Worker {
cwarn!(ENGINE, "Propose timed out but still waiting for the block imported");
return
}
TendermintState::ProposeWaitEmptyBlockTimer {
..
} => {
cwarn!(ENGINE, "Propose timed out but still waiting for the empty block");
return
}
TendermintState::Prevote if self.has_enough_any_votes() => {
cinfo!(ENGINE, "Prevote timeout.");
TendermintState::Precommit
Expand Down

0 comments on commit feeae37

Please sign in to comment.