consensus: Make the state service pluggable in block verification
We want to allow different state service implementations, and wrapped state services. So we make verify::init() take a state_service, and store that service in the BlockVerifier state_service field. Part of #428.
This commit is contained in:
parent
8072d5b7e8
commit
d0a833f3fb
|
|
@ -21,12 +21,27 @@ use zebra_chain::block::{Block, BlockHeaderHash};
|
||||||
mod script;
|
mod script;
|
||||||
mod transaction;
|
mod transaction;
|
||||||
|
|
||||||
|
/// The trait constraints that we expect from `zebra_state::ZebraState` errors.
|
||||||
|
type ZSE = Box<dyn error::Error + Send + Sync + 'static>;
|
||||||
|
/// The trait constraints that we expect from the `zebra_state::ZebraState` service.
|
||||||
|
/// `ZSF` is the `Future` type for `zebra_state::ZebraState`. This type is generic,
|
||||||
|
/// because `tower::Service` function calls require a `Sized` future type.
|
||||||
|
type ZS<ZSF> = Box<
|
||||||
|
dyn Service<zebra_state::Request, Response = zebra_state::Response, Error = ZSE, Future = ZSF>
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
>;
|
||||||
|
|
||||||
/// Block verification service.
|
/// Block verification service.
|
||||||
///
|
///
|
||||||
/// After verification, blocks and their associated transactions are added to
|
/// After verification, blocks and their associated transactions are added to
|
||||||
/// `zebra_state::ZebraState`.
|
/// `zebra_state::ZebraState`.
|
||||||
#[derive(Default)]
|
struct BlockVerifier<ZSF>
|
||||||
struct BlockVerifier {}
|
where
|
||||||
|
ZSF: Future<Output = Result<zebra_state::Response, ZSE>> + Send + 'static,
|
||||||
|
{
|
||||||
|
state_service: ZS<ZSF>,
|
||||||
|
}
|
||||||
|
|
||||||
/// The result type for the BlockVerifier Service.
|
/// The result type for the BlockVerifier Service.
|
||||||
type Response = BlockHeaderHash;
|
type Response = BlockHeaderHash;
|
||||||
|
|
@ -36,21 +51,20 @@ type Response = BlockHeaderHash;
|
||||||
type Error = Box<dyn error::Error + Send + Sync + 'static>;
|
type Error = Box<dyn error::Error + Send + Sync + 'static>;
|
||||||
|
|
||||||
/// The BlockVerifier service implementation.
|
/// The BlockVerifier service implementation.
|
||||||
impl Service<Block> for BlockVerifier {
|
impl<ZSF> Service<Block> for BlockVerifier<ZSF>
|
||||||
|
where
|
||||||
|
ZSF: Future<Output = Result<zebra_state::Response, ZSE>> + Send + 'static,
|
||||||
|
{
|
||||||
type Response = Response;
|
type Response = Response;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future =
|
type Future =
|
||||||
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
|
Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, context: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, context: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
// TODO(teor): is this a shared state?
|
self.state_service.poll_ready(context)
|
||||||
let mut state_service = zebra_state::in_memory::init();
|
|
||||||
state_service.poll_ready(context)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, block: Block) -> Self::Future {
|
fn call(&mut self, block: Block) -> Self::Future {
|
||||||
let mut state_service = zebra_state::in_memory::init();
|
|
||||||
|
|
||||||
let header_hash: BlockHeaderHash = (&block).into();
|
let header_hash: BlockHeaderHash = (&block).into();
|
||||||
|
|
||||||
// Ignore errors for now.
|
// Ignore errors for now.
|
||||||
|
|
@ -58,7 +72,7 @@ impl Service<Block> for BlockVerifier {
|
||||||
// TODO(teor):
|
// TODO(teor):
|
||||||
// - handle chain reorgs, adjust state_service "unique block height" conditions
|
// - handle chain reorgs, adjust state_service "unique block height" conditions
|
||||||
// - handle block validation errors (including errors in the block's transactions)
|
// - handle block validation errors (including errors in the block's transactions)
|
||||||
let _ = state_service.call(zebra_state::Request::AddBlock {
|
let _: ZSF = self.state_service.call(zebra_state::Request::AddBlock {
|
||||||
block: block.into(),
|
block: block.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -67,13 +81,18 @@ impl Service<Block> for BlockVerifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialise the BlockVerifier service.
|
/// Initialise the BlockVerifier service.
|
||||||
pub fn init() -> impl Service<
|
pub fn init<ZSF>(
|
||||||
|
state_service: ZS<ZSF>,
|
||||||
|
) -> impl Service<
|
||||||
Block,
|
Block,
|
||||||
Response = Response,
|
Response = Response,
|
||||||
Error = Error,
|
Error = Error,
|
||||||
Future = impl Future<Output = Result<Response, Error>>,
|
Future = impl Future<Output = Result<Response, Error>>,
|
||||||
> + Send
|
> + Send
|
||||||
+ Clone
|
+ Clone
|
||||||
+ 'static {
|
+ 'static
|
||||||
Buffer::new(BlockVerifier::default(), 1)
|
where
|
||||||
|
ZSF: Future<Output = Result<zebra_state::Response, ZSE>> + Send + 'static,
|
||||||
|
{
|
||||||
|
Buffer::new(BlockVerifier::<ZSF> { state_service }, 1)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue