Skip to main content

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::{LocalSegmentIndex, 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 segments
35    #[error("Invalid own segments")]
36    InvalidOwnSegments {
37        /// Expected first local segment index (correct)
38        expected_first_local_segment_index: Option<LocalSegmentIndex>,
39        /// Expected segment roots (correct)
40        expected_segment_roots: Vec<SegmentRoot>,
41        /// Actual first local segment index (invalid)
42        actual_first_local_segment_index: Option<LocalSegmentIndex>,
43        /// Actual segment roots (invalid)
44        actual_segment_roots: Vec<SegmentRoot>,
45    },
46    /// Shard membership entropy source error
47    #[error("Shard membership entropy source error: {error}")]
48    ShardMembershipEntropySource {
49        /// Low-level error
50        #[from]
51        error: ShardMembershipEntropySourceError,
52    },
53    /// Custom verification error
54    #[error("Custom verification error: {error}")]
55    Custom {
56        // Custom block verification error
57        #[from]
58        error: anyhow::Error,
59    },
60}
61
62/// Block verification interface
63pub trait BlockVerification<Block>: Send + Sync
64where
65    Block: GenericOwnedBlock,
66{
67    /// Verify the provided block header/body, typically as part of the block import, without
68    /// executing the block.
69    ///
70    /// This method can be called concurrently even for interdependent blocks.
71    ///
72    /// Expects (and doesn't check) that `parent_header` corresponds to `header`'s parent root,
73    /// `header` corresponds to `body` and is internally consistent, see:
74    /// * [`Block::is_internally_consistent()`]
75    /// * [`BlockHeader::is_internally_consistent()`]
76    /// * [`BlockBody::is_internally_consistent()`]
77    ///
78    /// [`Block::is_internally_consistent()`]: ab_core_primitives::block::Block::is_internally_consistent()
79    /// [`BlockHeader::is_internally_consistent()`]: ab_core_primitives::block::header::BlockHeader::is_internally_consistent()
80    /// [`BlockBody::is_internally_consistent()`]: ab_core_primitives::block::body::BlockBody::is_internally_consistent()
81    ///
82    /// These invariants are not checked during verification.
83    ///
84    /// Since verification doesn't execute the block, the state root is ignored and needs to be
85    /// checked separately after/if the block is re-executed.
86    fn verify_concurrent<BCI>(
87        &self,
88        parent_header: &GenericHeader<'_, Block>,
89        parent_block_mmr_root: &Blake3Hash,
90        header: &GenericHeader<'_, Block>,
91        body: &GenericBody<'_, Block>,
92        origin: &BlockOrigin,
93        beacon_chain_info: &BCI,
94    ) -> impl Future<Output = Result<(), BlockVerificationError>> + Send
95    where
96        BCI: DeriveConsensusParametersChainInfo + ShardMembershipEntropySourceChainInfo;
97
98    /// Complementary to [`Self::verify_concurrent()`] that expects the parent block to be already
99    /// successfully imported.
100    fn verify_sequential(
101        &self,
102        parent_header: &GenericHeader<'_, Block>,
103        parent_block_mmr_root: &Blake3Hash,
104        header: &GenericHeader<'_, Block>,
105        body: &GenericBody<'_, Block>,
106        origin: &BlockOrigin,
107    ) -> impl Future<Output = Result<(), BlockVerificationError>> + Send;
108}