parent
603e243c18
commit
8f2ddef0a4
|
|
@ -2124,6 +2124,12 @@ version = "0.1.0"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zebra-consensus"
|
name = "zebra-consensus"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"futures",
|
||||||
|
"tower",
|
||||||
|
"zebra-chain",
|
||||||
|
"zebra-state",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zebra-network"
|
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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[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_logo_url = "https://www.zfnd.org/images/zebra-icon.png")]
|
||||||
#![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_consensus")]
|
#![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_consensus")]
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
#[cfg(test)]
|
pub mod verify;
|
||||||
mod tests {
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
assert_eq!(2 + 2, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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