ab_client_api/
lib.rs

1//! Client API
2
3#![expect(incomplete_features, reason = "generic_const_exprs")]
4// TODO: This feature is not actually used in this crate, but is added as a workaround for
5//  https://github.com/rust-lang/rust/issues/141492
6#![feature(generic_const_exprs)]
7
8use ab_core_primitives::block::owned::GenericOwnedBlock;
9use ab_core_primitives::block::{BlockNumber, BlockRoot};
10use ab_merkle_tree::mmr::MerkleMountainRange;
11use rclite::Arc;
12
13// TODO: This is a workaround for https://github.com/rust-lang/rust/issues/139866 that allows the
14//  code to compile. Constant 4294967295 is hardcoded here and below for compilation to succeed.
15const _: () = {
16    assert!(u32::MAX == 4294967295);
17};
18
19/// Type alias for Merkle Mountain Range with block roots
20pub type BlockMerkleMountainRange = MerkleMountainRange<4294967295>;
21
22// TODO: Probably move it elsewhere
23/// Origin
24#[derive(Debug, PartialEq, Eq, Clone, Copy)]
25pub enum BlockOrigin {
26    /// Created locally
27    Local,
28    /// Received during sync process
29    Sync,
30    /// Broadcast on the network during normal operation (not sync)
31    Broadcast,
32}
33
34/// Error for [`ChainInfoWrite::persist_block()`]
35#[derive(Debug, thiserror::Error)]
36pub enum PersistBlockError {
37    // TODO
38}
39
40// TODO: Split this into different more narrow traits
41/// Chain info
42pub trait ChainInfo<Block>: Clone + Send + Sync + 'static
43where
44    Block: GenericOwnedBlock,
45{
46    /// Best block root
47    fn best_root(&self) -> BlockRoot;
48
49    // TODO: Uncomment if/when necessary
50    // /// Find root of ancestor block number for descendant block root
51    // fn ancestor_root(
52    //     &self,
53    //     ancestor_block_number: BlockNumber,
54    //     descendant_block_root: &BlockRoot,
55    // ) -> Option<BlockRoot>;
56
57    /// Best block header
58    fn best_header(&self) -> Block::Header;
59
60    /// Get header of ancestor block number for descendant block root
61    fn ancestor_header(
62        &self,
63        ancestor_block_number: BlockNumber,
64        descendant_block_root: &BlockRoot,
65    ) -> Option<Block::Header>;
66
67    /// Block header
68    fn header(&self, block_root: &BlockRoot) -> Option<Block::Header>;
69
70    /// Merkle Mountain Range with block
71    fn mmr_with_block(&self, block_root: &BlockRoot) -> Option<Arc<BlockMerkleMountainRange>>;
72}
73
74/// [`ChainInfo`] extension for writing information
75pub trait ChainInfoWrite<Block>: ChainInfo<Block>
76where
77    Block: GenericOwnedBlock,
78{
79    /// Persist newly imported block
80    fn persist_block(
81        &self,
82        block: Block,
83        mmr_with_block: Arc<BlockMerkleMountainRange>,
84    ) -> impl Future<Output = Result<(), PersistBlockError>> + Send;
85}
86
87/// Chain sync status
88pub trait ChainSyncStatus: Clone + Send + Sync + 'static {
89    /// Block number that the sync process is targeting right now.
90    ///
91    /// Can be zero if not syncing actively.
92    fn target_block_number(&self) -> BlockNumber;
93
94    /// Returns `true` if the chain is currently syncing
95    fn is_syncing(&self) -> bool;
96
97    /// Returns `true` if the node is currently offline
98    fn is_offline(&self) -> bool;
99}