ab_client_block_verification/
lib.rs

1pub mod beacon_chain;
2
3use ab_client_api::BlockOrigin;
4use ab_client_consensus_common::consensus_parameters::{
5    DeriveConsensusParametersChainInfo, ShardMembershipEntropySourceChainInfo,
6    ShardMembershipEntropySourceError,
7};
8use ab_core_primitives::block::body::owned::GenericOwnedBlockBody;
9use ab_core_primitives::block::header::owned::GenericOwnedBlockHeader;
10use ab_core_primitives::block::owned::GenericOwnedBlock;
11use ab_core_primitives::hashes::Blake3Hash;
12use ab_core_primitives::segments::SegmentRoot;
13
14type GenericHeader<'a, Block> =
15    <<Block as GenericOwnedBlock>::Header as GenericOwnedBlockHeader>::Header<'a>;
16type GenericBody<'a, Block> =
17    <<Block as GenericOwnedBlock>::Body as GenericOwnedBlockBody>::Body<'a>;
18
19/// Error for [`BlockVerification`]
20#[derive(Debug, thiserror::Error)]
21pub enum BlockVerificationError {
22    /// Block is below the archiving point
23    #[error("Block is below archiving point")]
24    BelowArchivingPoint,
25    /// Invalid header prefix
26    #[error("Invalid header prefix")]
27    InvalidHeaderPrefix,
28    /// Timestamp too far in the future
29    #[error("Timestamp too far in the future")]
30    TimestampTooFarInTheFuture,
31    /// Invalid seal
32    #[error("Invalid seal")]
33    InvalidSeal,
34    /// Invalid own segment roots
35    #[error("Invalid own segment roots")]
36    InvalidOwnSegmentRoots {
37        /// Expected segment roots (correct)
38        expected: Vec<SegmentRoot>,
39        /// Actual segment roots (invalid)
40        actual: Vec<SegmentRoot>,
41    },
42    /// Shard membership entropy source error
43    #[error("Shard membership entropy source error: {error}")]
44    ShardMembershipEntropySource {
45        /// Low-level error
46        #[from]
47        error: ShardMembershipEntropySourceError,
48    },
49    /// Custom verification error
50    #[error("Custom verification error: {error}")]
51    Custom {
52        // Custom block verification error
53        #[from]
54        error: anyhow::Error,
55    },
56}
57
58/// Block verification interface
59pub trait BlockVerification<Block>: Send + Sync
60where
61    Block: GenericOwnedBlock,
62{
63    /// Verify the provided block header/body, typically as part of the block import, without
64    /// executing the block.
65    ///
66    /// This method can be called concurrently even for interdependent blocks.
67    ///
68    /// Expects (and doesn't check) that `parent_header` corresponds to `header`'s parent root,
69    /// `header` corresponds to `body` and is internally consistent, see:
70    /// * [`Block::is_internally_consistent()`]
71    /// * [`BlockHeader::is_internally_consistent()`]
72    /// * [`BlockBody::is_internally_consistent()`]
73    ///
74    /// [`Block::is_internally_consistent()`]: ab_core_primitives::block::Block::is_internally_consistent()
75    /// [`BlockHeader::is_internally_consistent()`]: ab_core_primitives::block::header::BlockHeader::is_internally_consistent()
76    /// [`BlockBody::is_internally_consistent()`]: ab_core_primitives::block::body::BlockBody::is_internally_consistent()
77    ///
78    /// These invariants are not checked during verification.
79    ///
80    /// Since verification doesn't execute the block, the state root is ignored and needs to be
81    /// checked separately after/if the block is re-executed.
82    fn verify_concurrent<BCI>(
83        &self,
84        parent_header: &GenericHeader<'_, Block>,
85        parent_block_mmr_root: &Blake3Hash,
86        header: &GenericHeader<'_, Block>,
87        body: &GenericBody<'_, Block>,
88        origin: &BlockOrigin,
89        beacon_chain_info: &BCI,
90    ) -> impl Future<Output = Result<(), BlockVerificationError>> + Send
91    where
92        BCI: DeriveConsensusParametersChainInfo + ShardMembershipEntropySourceChainInfo;
93
94    /// Complementary to [`Self::verify_concurrent()`] that expects the parent block to be already
95    /// successfully imported.
96    fn verify_sequential(
97        &self,
98        parent_header: &GenericHeader<'_, Block>,
99        parent_block_mmr_root: &Blake3Hash,
100        header: &GenericHeader<'_, Block>,
101        body: &GenericBody<'_, Block>,
102        origin: &BlockOrigin,
103    ) -> impl Future<Output = Result<(), BlockVerificationError>> + Send;
104}