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:
//! - getting blocks (disk- or network-bound)
//! - context-free verification of signatures, proofs, and scripts (CPU-bound)
//! - context-dependent verification of the chain state (depends on previous blocks)
//! In contrast to checkpoint verification, which only checks hardcoded
//! hashes, block verification checks all Zcash consensus rules.
//!
//! Verification is provided via a `tower::Service`, to support backpressure and batch
//! verification.
//! The block verifier performs all of the semantic validation checks.
//! If accepted, the block is sent to the state service for contextual
//! verification, where it may be accepted or rejected.
use std::{
future::Future,
@ -40,16 +39,12 @@ mod subsidy;
#[cfg(test)]
mod tests;
/// A service that verifies blocks.
/// Asynchronous block verification.
#[derive(Debug)]
pub struct BlockVerifier<S> {
/// The network to be verified.
network: Network,
/// The underlying state service, possibly wrapped in other services.
state_service: S,
/// The transaction verification service
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
//! initial chain sync for Zebra. This list is distributed with Zebra.
//! Checkpoint-based verification uses a list of checkpoint hashes to
//! 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
//! previous checkpoint to a target checkpoint, it verifies all the blocks in
//! that chain.
//! The checkpoint verifier queues pending blocks. Once there is a
//! chain from the previous checkpoint to a target checkpoint, it
//! 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
//! configured network.
//!
//! Verification is provided via a `tower::Service`, to support backpressure and batch
//! verification.
//! Verification starts at the first checkpoint, which is the genesis
//! block for the configured network.
use std::{
collections::BTreeMap,

View File

@ -1,5 +1,3 @@
//! Configuration for zebra-consensus
use serde::{Deserialize, Serialize};
/// 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;

View File

@ -37,20 +37,20 @@
//#![deny(missing_docs)]
#![allow(clippy::try_err)]
pub mod block;
pub mod chain;
pub mod checkpoint;
pub mod config;
pub mod error;
pub mod mempool;
pub mod parameters;
pub mod script;
mod block;
mod checkpoint;
mod config;
mod parameters;
#[allow(dead_code)] // Remove this once transaction verification is implemented
mod primitives;
mod script;
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`].
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::future::Future;
@ -19,10 +5,17 @@ use zebra_chain::{parameters::ConsensusBranchId, transaction::Transaction, trans
use crate::BoxError;
/// Internal script verification service.
/// Asynchronous script verification.
///
/// After verification, the script future completes. State changes are handled by
/// `BlockVerifier` or `MempoolTransactionVerifier`.
/// The verifier asynchronously requests the UTXO a transaction attempts
/// 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)]
pub struct Verifier<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)]
pub struct Request {
pub transaction: Arc<Transaction>,

View File

@ -152,7 +152,7 @@ fn main() -> Result<()> {
// check if checkpoint
if height == block::Height(0)
|| 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
println!("{} {}", height.0, &hex::encode(hash.0),);

View File

@ -13,13 +13,12 @@ use zebra_chain::{
block::{self, Block},
parameters::{genesis_hash, Network},
};
use zebra_consensus::checkpoint;
use zebra_network as zn;
use zebra_state as zs;
/// 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 = checkpoint::MAX_QUEUED_BLOCKS_PER_HEIGHT;
const FANOUT: usize = 4;
/// Controls how many times we will retry each block download.
///
/// 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
/// 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.
///