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}