consensus: minimize API, clean docs

This reduces the API surface to the minimum required for functionality,
and cleans up module documentation.  The stub mempool module is deleted
entirely, since it will need to be redone later anyways.
This commit is contained in:
Henry de Valence 2020-10-16 16:44:30 -07:00 committed by Deirdre Connolly
parent d4ce3eb054
commit eb43893de0
9 changed files with 55 additions and 87 deletions

View File

@ -1,12 +1,11 @@
//! Block verification for Zebra. //! Consensus-based block verification.
//! //!
//! Verification occurs in multiple stages: //! In contrast to checkpoint verification, which only checks hardcoded
//! - getting blocks (disk- or network-bound) //! hashes, block verification checks all Zcash consensus rules.
//! - context-free verification of signatures, proofs, and scripts (CPU-bound)
//! - context-dependent verification of the chain state (depends on previous blocks)
//! //!
//! Verification is provided via a `tower::Service`, to support backpressure and batch //! The block verifier performs all of the semantic validation checks.
//! verification. //! If accepted, the block is sent to the state service for contextual
//! verification, where it may be accepted or rejected.
use std::{ use std::{
future::Future, future::Future,
@ -40,16 +39,12 @@ mod subsidy;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
/// A service that verifies blocks. /// Asynchronous block verification.
#[derive(Debug)] #[derive(Debug)]
pub struct BlockVerifier<S> { pub struct BlockVerifier<S> {
/// The network to be verified. /// The network to be verified.
network: Network, network: Network,
/// The underlying state service, possibly wrapped in other services.
state_service: S, state_service: S,
/// The transaction verification service
transaction_verifier: transaction::Verifier<S>, transaction_verifier: transaction::Verifier<S>,
} }

View File

@ -1,17 +1,17 @@
//! Checkpoint-based block verification for Zebra. //! Checkpoint-based block verification.
//! //!
//! Checkpoint-based verification uses a list of checkpoint hashes to speed up the //! Checkpoint-based verification uses a list of checkpoint hashes to
//! initial chain sync for Zebra. This list is distributed with Zebra. //! speed up the initial chain sync for Zebra. This list is distributed
//! with Zebra.
//! //!
//! The CheckpointVerifier queues pending blocks. Once there is a chain from the //! The checkpoint verifier queues pending blocks. Once there is a
//! previous checkpoint to a target checkpoint, it verifies all the blocks in //! chain from the previous checkpoint to a target checkpoint, it
//! that chain. //! verifies all the blocks in that chain, and sends accepted blocks to
//! the state service as finalized chain state, skipping contextual
//! verification checks.
//! //!
//! Verification starts at the first checkpoint, which is the genesis block for the //! Verification starts at the first checkpoint, which is the genesis
//! configured network. //! block for the configured network.
//!
//! Verification is provided via a `tower::Service`, to support backpressure and batch
//! verification.
use std::{ use std::{
collections::BTreeMap, collections::BTreeMap,

View File

@ -1,5 +1,3 @@
//! Configuration for zebra-consensus
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Consensus configuration. /// Consensus configuration.

View File

@ -1,4 +1,9 @@
//! Consensus validation errors //! Errors that can occur when checking consensus rules.
//!
//! Each error variant corresponds to a consensus rule, so enumerating
//! all possible verification failures enumerates the consensus rules we
//! implement, and ensures that we don't reject blocks or transactions
//! for a non-enumerated reason.
use thiserror::Error; use thiserror::Error;

View File

@ -37,20 +37,20 @@
//#![deny(missing_docs)] //#![deny(missing_docs)]
#![allow(clippy::try_err)] #![allow(clippy::try_err)]
pub mod block; mod block;
pub mod chain; mod checkpoint;
pub mod checkpoint; mod config;
pub mod config; mod parameters;
pub mod error;
pub mod mempool;
pub mod parameters;
pub mod script;
#[allow(dead_code)] // Remove this once transaction verification is implemented #[allow(dead_code)] // Remove this once transaction verification is implemented
mod primitives; mod primitives;
mod script;
mod transaction; mod transaction;
pub use crate::config::Config; pub mod chain;
pub mod error;
pub use checkpoint::MAX_CHECKPOINT_HEIGHT_GAP;
pub use config::Config;
/// A boxed [`std::error::Error`]. /// A boxed [`std::error::Error`].
pub type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>; pub type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;

View File

@ -1,29 +0,0 @@
//! Mempool transaction verification and state for Zebra.
//!
//! Mempool updates occur in multiple stages:
//! - getting transactions (disk- or network-bound)
//! - context-free verification of signatures, proofs, and scripts (CPU-bound)
//! - context-dependent verification of mempool transactions against the chain state
//! (awaits an up-to-date chain)
//! - adding transactions to the mempool
//!
//! The mempool is provided via a `tower::Service`, to support backpressure and batch
//! verification.
/// Mempool state.
///
/// New transactions are verified, checked against the chain state, then added to the
/// mempool.
///
/// `ZebraMempoolState` is not yet implemented.
#[derive(Default)]
struct ZebraMempoolState {}
/// Mempool transaction verification.
///
/// New transactions are verified, checked against the chain state, then added to the
/// mempool.
///
/// `MempoolTransactionVerifier` is not yet implemented.
#[derive(Default)]
struct MempoolTransactionVerifier {}

View File

@ -1,17 +1,3 @@
//! Script verification for Zebra.
//!
//! Verification occurs in multiple stages:
//! - getting transactions from blocks or the mempool (disk- or network-bound)
//! - context-free verification of scripts, signatures, and proofs (CPU-bound)
//! - context-dependent verification of transactions against the chain state
//! (awaits an up-to-date chain)
//!
//! Verification is provided via a `tower::Service`, to support backpressure and batch
//! verification.
//!
//! This is an internal module. Use `verify::BlockVerifier` for blocks and their
//! transactions, or `mempool::MempoolTransactionVerifier` for mempool transactions.
use std::{pin::Pin, sync::Arc}; use std::{pin::Pin, sync::Arc};
use std::future::Future; use std::future::Future;
@ -19,10 +5,17 @@ use zebra_chain::{parameters::ConsensusBranchId, transaction::Transaction, trans
use crate::BoxError; use crate::BoxError;
/// Internal script verification service. /// Asynchronous script verification.
/// ///
/// After verification, the script future completes. State changes are handled by /// The verifier asynchronously requests the UTXO a transaction attempts
/// `BlockVerifier` or `MempoolTransactionVerifier`. /// to use as an input, and verifies the script as soon as it becomes
/// available. This allows script verification to be performed
/// asynchronously, rather than requiring that the entire chain up to
/// the previous block is ready.
///
/// The asynchronous script verification design is documented in [RFC4].
///
/// [RFC4]: https://zebra.zfnd.org/dev/rfcs/0004-asynchronous-script-verification.html
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Verifier<ZS> { pub struct Verifier<ZS> {
state: ZS, state: ZS,
@ -35,6 +28,13 @@ impl<ZS> Verifier<ZS> {
} }
} }
/// A script verification request.
///
/// Ideally, this would supply only an `Outpoint` and the unlock script,
/// rather than the entire `Transaction`, but we call a C++
/// implementation, and its FFI requires the entire transaction.
/// At some future point, we could investigate reducing the size of the
/// request.
#[derive(Debug)] #[derive(Debug)]
pub struct Request { pub struct Request {
pub transaction: Arc<Transaction>, pub transaction: Arc<Transaction>,

View File

@ -152,7 +152,7 @@ fn main() -> Result<()> {
// check if checkpoint // check if checkpoint
if height == block::Height(0) if height == block::Height(0)
|| cumulative_bytes >= MAX_CHECKPOINT_BYTE_COUNT || cumulative_bytes >= MAX_CHECKPOINT_BYTE_COUNT
|| height_gap.0 >= zebra_consensus::checkpoint::MAX_CHECKPOINT_HEIGHT_GAP as u32 || height_gap.0 >= zebra_consensus::MAX_CHECKPOINT_HEIGHT_GAP as u32
{ {
// print to output // print to output
println!("{} {}", height.0, &hex::encode(hash.0),); println!("{} {}", height.0, &hex::encode(hash.0),);

View File

@ -13,13 +13,12 @@ use zebra_chain::{
block::{self, Block}, block::{self, Block},
parameters::{genesis_hash, Network}, parameters::{genesis_hash, Network},
}; };
use zebra_consensus::checkpoint;
use zebra_network as zn; use zebra_network as zn;
use zebra_state as zs; use zebra_state as zs;
/// Controls the number of peers used for each ObtainTips and ExtendTips request. /// Controls the number of peers used for each ObtainTips and ExtendTips request.
// XXX in the future, we may not be able to access the checkpoint module. const FANOUT: usize = 4;
const FANOUT: usize = checkpoint::MAX_QUEUED_BLOCKS_PER_HEIGHT;
/// Controls how many times we will retry each block download. /// Controls how many times we will retry each block download.
/// ///
/// If all the retries fail, then the syncer will reset, and start downloading /// If all the retries fail, then the syncer will reset, and start downloading
@ -40,7 +39,7 @@ const BLOCK_DOWNLOAD_RETRY_LIMIT: usize = 5;
/// ///
/// Some checkpoints contain larger blocks, so the maximum checkpoint gap can /// Some checkpoints contain larger blocks, so the maximum checkpoint gap can
/// represent multiple gigabytes of data. /// represent multiple gigabytes of data.
const LOOKAHEAD_LIMIT: usize = checkpoint::MAX_CHECKPOINT_HEIGHT_GAP * 2; const LOOKAHEAD_LIMIT: usize = zebra_consensus::MAX_CHECKPOINT_HEIGHT_GAP * 2;
/// Controls how long we wait for a tips response to return. /// Controls how long we wait for a tips response to return.
/// ///