parent
603e243c18
commit
8f2ddef0a4
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue