consensus: Add a block verification service

Part of #428.
This commit is contained in:
teor 2020-06-08 14:27:38 +10:00 committed by Henry de Valence
parent 603e243c18
commit 8f2ddef0a4
4 changed files with 94 additions and 7 deletions

6
Cargo.lock generated
View File

@ -2124,6 +2124,12 @@ version = "0.1.0"
[[package]]
name = "zebra-consensus"
version = "0.1.0"
dependencies = [
"futures",
"tower",
"zebra-chain",
"zebra-state",
]
[[package]]
name = "zebra-network"

View File

@ -8,3 +8,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
zebra-chain = { path = "../zebra-chain" }
zebra-state = { path = "../zebra-state" }
tower = "0.3.1"
futures = "0.3.5"

View File

@ -1,10 +1,15 @@
//! Consensus handling for Zebra.
//!
//! `verify::BlockVerifier` verifies blocks and their transactions, then adds them to
//! `zebra_state::ZebraState`.
//!
//! `mempool::ZebraMempool` verifies transactions, and adds them to the mempool state.
//!
//! Consensus handling is provided using `tower::Service`s, to support backpressure
//! and batch verification.
#![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")]
#![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_consensus")]
#![deny(missing_docs)]
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
pub mod verify;

View File

@ -0,0 +1,72 @@
//! Block verification and chain state updates for Zebra.
//!
//! Verification occurs in multiple stages:
//! - getting blocks (disk- or network-bound)
//! - context-free verification of signatures, proofs, and scripts (CPU-bound)
//! - context-dependent verification of the chain state (awaits a verified parent block)
//!
//! Verification is provided via a `tower::Service`, to support backpressure and batch
//! verification.
use std::{
error::Error,
future::Future,
pin::Pin,
task::{Context, Poll},
};
use tower::{buffer::Buffer, Service};
use zebra_chain::block::Block;
/// Block verification service.
///
/// After verification, blocks and their associated transactions are added to
/// `zebra_state::ZebraState`.
#[derive(Default)]
struct BlockVerifier {}
/// The result type for the BlockVerifier Service.
// TODO(teor): Response = BlockHeaderHash
type Response = ();
/// The error type for the BlockVerifier Service.
// TODO(jlusby): Error = Report ?
type ServiceError = Box<dyn Error + Send + Sync + 'static>;
/// The BlockVerifier service implementation.
impl Service<Block> for BlockVerifier {
type Response = Response;
type Error = ServiceError;
type Future =
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
fn poll_ready(&mut self, context: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
// TODO(teor): is this a shared state?
let mut state_service = zebra_state::in_memory::init();
state_service.poll_ready(context)
}
fn call(&mut self, block: Block) -> Self::Future {
let mut state_service = zebra_state::in_memory::init();
// Ignore errors, they are already handled correctly.
// AddBlock discards invalid blocks.
let _ = state_service.call(zebra_state::Request::AddBlock {
block: block.into(),
});
Box::pin(async { Ok(()) })
}
}
/// Initialise the BlockVerifier service.
pub fn init() -> impl Service<
Block,
Response = Response,
Error = ServiceError,
Future = impl Future<Output = Result<Response, ServiceError>>,
> + Send
+ Clone
+ 'static {
Buffer::new(BlockVerifier::default(), 1)
}