Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/voter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ pub struct Voter<H, N, E: Environment<H, N>, GlobalIn, GlobalOut> where
GlobalOut: Sink<SinkItem=CommunicationOut<H, N, E::Signature, E::Id>, SinkError=E::Error>,
{
env: Arc<E>,
voter_id: Option<E::Id>,
voters: VoterSet<E::Id>,
best_round: VotingRound<H, N, E>,
past_rounds: PastRounds<H, N, E>,
Expand Down Expand Up @@ -274,6 +275,7 @@ impl<H, N, E: Environment<H, N>, GlobalIn, GlobalOut> Voter<H, N, E, GlobalIn, G
/// messages.
pub fn new(
env: Arc<E>,
voter_id: Option<E::Id>,
voters: VoterSet<E::Id>,
global_comms: (GlobalIn, GlobalOut),
last_round_number: u64,
Expand All @@ -286,6 +288,7 @@ impl<H, N, E: Environment<H, N>, GlobalIn, GlobalOut> Voter<H, N, E, GlobalIn, G

let best_round = VotingRound::new(
last_round_number + 1,
voter_id.clone(),
voters.clone(),
last_finalized.clone(),
Some(last_round_state),
Expand All @@ -300,6 +303,7 @@ impl<H, N, E: Environment<H, N>, GlobalIn, GlobalOut> Voter<H, N, E, GlobalIn, G

Voter {
env,
voter_id,
voters,
best_round,
past_rounds: PastRounds::new(),
Expand Down Expand Up @@ -435,6 +439,7 @@ impl<H, N, E: Environment<H, N>, GlobalIn, GlobalOut> Voter<H, N, E, GlobalIn, G
// we set `last_round_state` to `None` so that no votes are cast
self.prospective_round = Some(VotingRound::new(
round_number + 1,
self.voter_id.clone(),
self.voters.clone(),
ghost_base,
None,
Expand Down Expand Up @@ -552,6 +557,7 @@ impl<H, N, E: Environment<H, N>, GlobalIn, GlobalOut> Voter<H, N, E, GlobalIn, G
let next_round = next_round.unwrap_or_else(||
VotingRound::new(
old_round_number + 1,
self.voter_id.clone(),
self.voters.clone(),
self.last_finalized_in_rounds.clone(),
Some(self.best_round.bridge_state()),
Expand All @@ -572,6 +578,7 @@ impl<H, N, E: Environment<H, N>, GlobalIn, GlobalOut> Voter<H, N, E, GlobalIn, G

self.best_round = VotingRound::new(
prospective_round.round_number() + 1,
self.voter_id.clone(),
self.voters.clone(),
// the finalized commit target that triggered
// the prospective round was used as base.
Expand Down Expand Up @@ -650,6 +657,7 @@ mod tests {
let finalized = env.finalized_stream();
let voter = Voter::new(
env.clone(),
None,
voters,
global_comms,
0,
Expand Down Expand Up @@ -696,6 +704,7 @@ mod tests {
let finalized = env.finalized_stream();
let voter = Voter::new(
env.clone(),
None,
voters.clone(),
network.make_global_comms(),
0,
Expand Down Expand Up @@ -739,6 +748,7 @@ mod tests {
// run voter in background. scheduling it to shut down at the end.
let voter = Voter::new(
env.clone(),
None,
voters.clone(),
global_comms,
0,
Expand Down Expand Up @@ -804,6 +814,7 @@ mod tests {
// run voter in background. scheduling it to shut down at the end.
let voter = Voter::new(
env.clone(),
None,
voters.clone(),
global_comms,
0,
Expand Down Expand Up @@ -891,6 +902,7 @@ mod tests {
// run voter in background. scheduling it to shut down at the end.
let voter = Voter::new(
env.clone(),
None,
voters.clone(),
global_comms,
1,
Expand Down Expand Up @@ -938,6 +950,7 @@ mod tests {

Voter::new(
env.clone(),
None,
voters.clone(),
network.make_global_comms(),
0,
Expand Down Expand Up @@ -971,6 +984,7 @@ mod tests {
// run voter in background starting at round 5. scheduling it to shut down when signalled.
let voter = Voter::new(
env.clone(),
None,
voters.clone(),
network.make_global_comms(),
5,
Expand Down
69 changes: 49 additions & 20 deletions src/voter/voting_round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use super::{Environment, Buffered};
/// The state of a voting round.
pub(super) enum State<T> {
Start(T, T),
Proposed(T, T),
Prevoted(T),
Precommitted,
}
Expand All @@ -41,6 +42,7 @@ impl<T> std::fmt::Debug for State<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
State::Start(..) => write!(f, "Start"),
State::Proposed(..) => write!(f, "Proposed"),
State::Prevoted(_) => write!(f, "Prevoted"),
State::Precommitted => write!(f, "Precommitted"),
}
Expand All @@ -53,6 +55,7 @@ pub(super) struct VotingRound<H, N, E: Environment<H, N>> where
N: Copy + BlockNumberOps + ::std::fmt::Debug,
{
env: Arc<E>,
voter_id: Option<E::Id>,
votes: Round<E::Id, H, N, E::Signature>,
incoming: E::In,
outgoing: Buffered<E::Out>,
Expand All @@ -71,6 +74,7 @@ impl<H, N, E: Environment<H, N>> VotingRound<H, N, E> where
/// Create a new voting round.
pub (super) fn new(
round_number: u64,
voter_id: Option<E::Id>,
voters: VoterSet<E::Id>,
base: (H, N),
last_round_state: Option<crate::bridge_state::LatterView<H, N>>,
Expand All @@ -85,6 +89,7 @@ impl<H, N, E: Environment<H, N>> VotingRound<H, N, E> where
};

VotingRound {
voter_id,
votes: Round::new(round_params),
incoming: round_data.incoming,
outgoing: Buffered::new(round_data.outgoing),
Expand Down Expand Up @@ -244,10 +249,12 @@ impl<H, N, E: Environment<H, N>> VotingRound<H, N, E> where
}

fn primary_propose(&mut self, last_round_state: &RoundState<H, N>) -> Result<(), E::Error> {
match self.state {
Some(State::Start(_, _)) => {
match self.state.take() {
Some(State::Start(prevote_timer, precommit_timer)) => {
let our_turn = self.voter_id.as_ref() == Some(&self.votes.primary_voter().0);
let maybe_estimate = last_round_state.estimate.clone();
if let Some(last_round_estimate) = maybe_estimate {

if let (Some(last_round_estimate), true) = (maybe_estimate, our_turn) {
let maybe_finalized = last_round_state.finalized.clone();

// Last round estimate has not been finalized.
Expand All @@ -260,37 +267,59 @@ impl<H, N, E: Environment<H, N>> VotingRound<H, N, E> where
target_number: last_round_estimate.1,
})
);
self.state = Some(State::Proposed(prevote_timer, precommit_timer));

return Ok(());
}
} else {
debug!(target: "afg", "Last round estimate does not exists, \
}

if our_turn {
debug!(target: "afg", "Last round estimate does not exist, \
not sending primary block hint for round {}", self.votes.number());
}
}
_ => { }

self.state = Some(State::Start(prevote_timer, precommit_timer));
},
x => { self.state = x; }
}

Ok(())
}

fn prevote(&mut self, last_round_state: &RoundState<H, N>) -> Result<(), E::Error> {
match self.state.take() {
Some(State::Start(mut prevote_timer, precommit_timer)) => {
let should_prevote = match prevote_timer.poll() {
Err(e) => return Err(e),
Ok(Async::Ready(())) => true,
Ok(Async::NotReady) => self.votes.completable(),
};
let state = self.state.take();

if should_prevote {
if let Some(prevote) = self.construct_prevote(last_round_state)? {
debug!(target: "afg", "Casting prevote for round {}", self.votes.number());
self.outgoing.push(Message::Prevote(prevote));
}
self.state = Some(State::Prevoted(precommit_timer));
let mut handle_prevote = |mut prevote_timer: E::Timer, precommit_timer: E::Timer, proposed| {
let should_prevote = match prevote_timer.poll() {
Err(e) => return Err(e),
Ok(Async::Ready(())) => true,
Ok(Async::NotReady) => self.votes.completable(),
};

if should_prevote {
if let Some(prevote) = self.construct_prevote(last_round_state)? {
debug!(target: "afg", "Casting prevote for round {}", self.votes.number());
self.outgoing.push(Message::Prevote(prevote));
}
self.state = Some(State::Prevoted(precommit_timer));
} else {
if proposed {
self.state = Some(State::Proposed(prevote_timer, precommit_timer));
} else {
self.state = Some(State::Start(prevote_timer, precommit_timer));
}
}

Ok(())
};

match state {
Some(State::Start(prevote_timer, precommit_timer)) => {
handle_prevote(prevote_timer, precommit_timer, false)?;
},
Some(State::Proposed(prevote_timer, precommit_timer)) => {
handle_prevote(prevote_timer, precommit_timer, true)?;
},
x => { self.state = x; }
}

Expand Down