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}