Skip to main content

ab_client_block_verification/
lib.rs

1pub mod beacon_chain;
2mod shared;
3
4use ab_client_api::BlockOrigin;
5use ab_client_consensus_common::consensus_parameters::{
6    DeriveConsensusParametersChainInfo, ShardMembershipEntropySourceChainInfo,
7    ShardMembershipEntropySourceError,
8};
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::pot::SlotNumber;
13use ab_core_primitives::segments::{LocalSegmentIndex, SegmentRoot};
14
15type GenericHeader<'a, Block> =
16    <<Block as GenericOwnedBlock>::Header as GenericOwnedBlockHeader>::Header<'a>;
17
18/// Error for [`BlockVerification`]
19#[derive(Debug, thiserror::Error)]
20pub enum BlockVerificationError {
21    /// Block is below the archiving point.
22    ///
23    /// The block being verified is at or below the block number of the block that the next best
24    /// block (the child of the current best block) confirms, so it is a fork that can't become a
25    /// part of the best chain anymore, see [`ConsensusConstants::block_confirmation_depth`].
26    ///
27    /// [`ConsensusConstants::block_confirmation_depth`]: ab_client_consensus_common::ConsensusConstants::block_confirmation_depth
28    #[error("Block is below archiving point")]
29    BelowArchivingPoint,
30    /// Invalid header prefix
31    #[error("Invalid header prefix")]
32    InvalidHeaderPrefix,
33    /// Timestamp too far in the future
34    #[error("Timestamp too far in the future")]
35    TimestampTooFarInTheFuture,
36    /// Invalid slot.
37    ///
38    /// The slot must be above the parent block's slot, and adding the block authoring delay to it
39    /// must not overflow.
40    #[error("Invalid slot {slot} (parent slot {parent_slot})")]
41    InvalidSlot {
42        /// Block's slot
43        slot: SlotNumber,
44        /// Parent block's slot
45        parent_slot: SlotNumber,
46    },
47    /// Invalid seal
48    #[error("Invalid seal")]
49    InvalidSeal,
50    /// Invalid own segments
51    #[error("Invalid own segments")]
52    InvalidOwnSegments {
53        /// Expected first local segment index (correct)
54        expected_first_local_segment_index: Option<LocalSegmentIndex>,
55        /// Expected segment roots (correct)
56        expected_segment_roots: Vec<SegmentRoot>,
57        /// Actual first local segment index (invalid)
58        actual_first_local_segment_index: Option<LocalSegmentIndex>,
59        /// Actual segment roots (invalid)
60        actual_segment_roots: Vec<SegmentRoot>,
61    },
62    /// Shard membership entropy source error
63    #[error("Shard membership entropy source error: {error}")]
64    ShardMembershipEntropySource {
65        /// Low-level error
66        #[from]
67        error: ShardMembershipEntropySourceError,
68    },
69    /// Custom verification error
70    #[error("Custom verification error: {error}")]
71    Custom {
72        // Custom block verification error
73        #[from]
74        error: anyhow::Error,
75    },
76}
77
78/// Block verification interface
79pub trait BlockVerification<Block, ExtraBlockVerificationDetails>: Send + Sync
80where
81    Block: GenericOwnedBlock,
82{
83    /// Verify the provided block, typically as part of the block import, without executing it.
84    ///
85    /// This method can be called concurrently even for interdependent blocks.
86    ///
87    /// Expects (and doesn't check) that `parent_header` corresponds to the block's parent root.
88    ///
89    /// Since verification doesn't execute the block, the state root is ignored and needs to be
90    /// checked separately after/if the block is re-executed.
91    fn verify_concurrent<BCI>(
92        &self,
93        parent_header: &GenericHeader<'_, Block>,
94        parent_block_mmr_root: &Blake3Hash,
95        block: &Block,
96        origin: &BlockOrigin,
97        beacon_chain_info: &BCI,
98    ) -> impl Future<Output = Result<(), BlockVerificationError>> + Send
99    where
100        BCI: DeriveConsensusParametersChainInfo + ShardMembershipEntropySourceChainInfo;
101
102    /// Complementary to [`Self::verify_concurrent()`] that expects the parent block to be already
103    /// successfully imported.
104    fn verify_sequential(
105        &self,
106        parent_header: &GenericHeader<'_, Block>,
107        parent_block_mmr_root: &Blake3Hash,
108        block: &Block,
109        origin: &BlockOrigin,
110    ) -> impl Future<Output = Result<ExtraBlockVerificationDetails, BlockVerificationError>> + Send;
111}