consensus: change verifier poll_ready handling.

This makes the component verifiers both always return `poll_ready`,
because they do not exert backpressure and cannot fail.

The checkpoint verifier now immediately rejects any blocks that arrive
after it finishes checkpointing, instead of marking the service itself
as failed.

The chain verifier is agnostic to the readiness behavior of its
components, and reports readiness when they are both ready.
This commit is contained in:
Henry de Valence 2020-09-10 14:29:27 -07:00
parent 526f771ceb
commit 93586867bc
2 changed files with 15 additions and 9 deletions

View File

@ -50,11 +50,15 @@ where
type Future =
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
// We don't expect the verifiers to exert backpressure on our
// users, so we don't need to call the verifier's `poll_ready` here.
// (And we don't know which verifier to choose at this point, anyway.)
Poll::Ready(Ok(()))
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match (self.checkpoint.poll_ready(cx), self.block.poll_ready(cx)) {
// First, fail if either service fails.
(Poll::Ready(Err(e)), _) | (_, Poll::Ready(Err(e))) => Poll::Ready(Err(e)),
// Second, we're unready if either service is unready.
(Poll::Pending, _) | (_, Poll::Pending) => Poll::Pending,
// Finally, we're ready if both services are ready and OK.
(Poll::Ready(Ok(())), Poll::Ready(Ok(()))) => Poll::Ready(Ok(())),
}
}
fn call(&mut self, block: Arc<Block>) -> Self::Future {

View File

@ -763,13 +763,15 @@ where
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.previous_checkpoint_height() {
FinalCheckpoint => Poll::Ready(Err("there are no checkpoints left to verify".into())),
_ => Poll::Ready(Ok(())),
}
Poll::Ready(Ok(()))
}
fn call(&mut self, block: Arc<Block>) -> Self::Future {
// Immediately reject all incoming blocks that arrive after we've finished.
if let FinalCheckpoint = self.previous_checkpoint_height() {
return async { Err("checkpoint request after checkpointing finished".into()) }.boxed();
}
// Queue the block for verification, until we receive all the blocks for
// the current checkpoint range.
let rx = self.queue_block(block.clone());