From 80e23bbfb49e0b0b9217f7ff1912933e212b1365 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 27 Dec 2017 18:35:21 +0100 Subject: [PATCH] poll repeatedly when state changes --- substrate/candidate-agreement/src/bft/mod.rs | 35 +++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/substrate/candidate-agreement/src/bft/mod.rs b/substrate/candidate-agreement/src/bft/mod.rs index e2322cc38b..940a0a9e21 100644 --- a/substrate/candidate-agreement/src/bft/mod.rs +++ b/substrate/candidate-agreement/src/bft/mod.rs @@ -214,7 +214,7 @@ impl Locked { // the state of the local node during the current state of consensus. // // behavior is different when locked on a proposal. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq)] enum LocalState { Start, Proposed, @@ -327,6 +327,39 @@ impl Strategy { where C::RoundTimeout: Future, C::Proposal: Future, + { + let mut last_watermark = ( + self.current_accumulator.round_number(), + self.local_state + ); + + // poll until either completion or state doesn't change. + loop { + match self.poll_once(context, sending)? { + Async::Ready(x) => return Ok(Async::Ready(x)), + Async::NotReady => { + let new_watermark = ( + self.current_accumulator.round_number(), + self.local_state + ); + + if new_watermark == last_watermark { + return Ok(Async::NotReady) + } else { + last_watermark = new_watermark; + } + } + } + } + } + + // perform one round of polling: attempt to broadcast messages and change the state. + // if the round or internal round-state changes, this should be called again. + fn poll_once(&mut self, context: &C, sending: &mut Sending>) + -> Poll, E> + where + C::RoundTimeout: Future, + C::Proposal: Future, { self.propose(context, sending)?; self.prepare(context, sending);