ab_client_block_verification/
lib.rs

1#![feature(array_windows)]
2
3pub mod beacon_chain;
4
5use ab_client_api::BlockOrigin;
6use ab_core_primitives::block::body::owned::GenericOwnedBlockBody;
7use ab_core_primitives::block::header::owned::GenericOwnedBlockHeader;
8use ab_core_primitives::block::owned::GenericOwnedBlock;
9use ab_core_primitives::hashes::Blake3Hash;
10use ab_core_primitives::segments::SegmentRoot;
11
12type GenericHeader<'a, Block> =
13    <<Block as GenericOwnedBlock>::Header as GenericOwnedBlockHeader>::Header<'a>;
14type GenericBody<'a, Block> =
15    <<Block as GenericOwnedBlock>::Body as GenericOwnedBlockBody>::Body<'a>;
16
17/// Error for [`BlockVerification`]
18#[derive(Debug, thiserror::Error)]
19pub enum BlockVerificationError {
20    /// Block is below archiving point
21    #[error("Block is below archiving point")]
22    BelowArchivingPoint,
23    /// Invalid header prefix
24    #[error("Invalid header prefix")]
25    InvalidHeaderPrefix,
26    /// Timestamp too far in the future
27    #[error("Timestamp too far in the future")]
28    TimestampTooFarInTheFuture,
29    /// Invalid seal
30    #[error("Invalid seal")]
31    InvalidSeal,
32    /// Invalid own segment roots
33    #[error("Invalid own segment roots")]
34    InvalidOwnSegmentRoots {
35        /// Expected segment roots (correct)
36        expected: Vec<SegmentRoot>,
37        /// Actual segment roots (invalid)
38        actual: Vec<SegmentRoot>,
39    },
40    /// Custom verification error
41    #[error("Custom verification error: {error}")]
42    Custom {
43        // Custom block verification error
44        #[from]
45        error: anyhow::Error,
46    },
47}
48
49/// Block verification interface
50pub trait BlockVerification<Block>: Send + Sync
51where
52    Block: GenericOwnedBlock,
53{
54    /// Verify provided block header/body, typically as part of the block import, without executing
55    /// the block.
56    ///
57    /// Expects (and doesn't check) that `parent_header` correspond to `header`'s parent root,
58    /// `header` corresponds to `body` and is internally consistent, see:
59    /// * [`Block::is_internally_consistent()`]
60    /// * [`BlockHeader::is_internally_consistent()`]
61    /// * [`BlockBody::is_internally_consistent()`]
62    ///
63    /// [`Block::is_internally_consistent()`]: ab_core_primitives::block::Block::is_internally_consistent()
64    /// [`BlockHeader::is_internally_consistent()`]: ab_core_primitives::block::header::BlockHeader::is_internally_consistent()
65    /// [`BlockBody::is_internally_consistent()`]: ab_core_primitives::block::body::BlockBody::is_internally_consistent()
66    ///
67    /// These invariants are not checked during verification.
68    ///
69    /// Since verification doesn't execute the block, state root is ignored and needs to be checked
70    /// separately after/if block is re-executed.
71    fn verify(
72        &self,
73        parent_header: &GenericHeader<'_, Block>,
74        parent_block_mmr_root: &Blake3Hash,
75        header: &GenericHeader<'_, Block>,
76        body: &GenericBody<'_, Block>,
77        origin: BlockOrigin,
78    ) -> impl Future<Output = Result<(), BlockVerificationError>> + Send;
79}