reth_storage_api/
block_id.rs1use crate::BlockHashReader;
2use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag};
3use alloy_primitives::{BlockNumber, B256};
4use reth_chainspec::ChainInfo;
5use reth_storage_errors::provider::{ProviderError, ProviderResult};
6
7#[auto_impl::auto_impl(&, Arc)]
12pub trait BlockNumReader: BlockHashReader + Send + Sync {
13 fn chain_info(&self) -> ProviderResult<ChainInfo>;
15
16 fn best_block_number(&self) -> ProviderResult<BlockNumber>;
18
19 fn last_block_number(&self) -> ProviderResult<BlockNumber>;
21
22 fn earliest_block_number(&self) -> ProviderResult<BlockNumber> {
24 Ok(0)
25 }
26
27 fn block_number(&self, hash: B256) -> ProviderResult<Option<BlockNumber>>;
29
30 fn convert_hash_or_number(&self, id: BlockHashOrNumber) -> ProviderResult<Option<BlockNumber>> {
33 match id {
34 BlockHashOrNumber::Hash(hash) => self.block_number(hash),
35 BlockHashOrNumber::Number(num) => Ok(Some(num)),
36 }
37 }
38
39 fn convert_number(&self, id: BlockHashOrNumber) -> ProviderResult<Option<B256>> {
42 match id {
43 BlockHashOrNumber::Hash(hash) => Ok(Some(hash)),
44 BlockHashOrNumber::Number(num) => self.block_hash(num),
45 }
46 }
47}
48
49#[auto_impl::auto_impl(&, Arc)]
59pub trait BlockIdReader: BlockNumReader + Send + Sync {
60 fn convert_block_number(&self, num: BlockNumberOrTag) -> ProviderResult<Option<BlockNumber>> {
62 let num = match num {
63 BlockNumberOrTag::Latest => self.best_block_number()?,
64 BlockNumberOrTag::Earliest => self.earliest_block_number()?,
65 BlockNumberOrTag::Pending => {
66 return self
67 .pending_block_num_hash()
68 .map(|res_opt| res_opt.map(|num_hash| num_hash.number))
69 }
70 BlockNumberOrTag::Number(num) => num,
71 BlockNumberOrTag::Finalized => {
72 self.finalized_block_number()?.ok_or(ProviderError::FinalizedBlockNotFound)?
73 }
74 BlockNumberOrTag::Safe => {
75 self.safe_block_number()?.ok_or(ProviderError::SafeBlockNotFound)?
76 }
77 };
78 Ok(Some(num))
79 }
80
81 fn block_hash_for_id(&self, block_id: BlockId) -> ProviderResult<Option<B256>> {
83 match block_id {
84 BlockId::Hash(hash) => Ok(Some(hash.into())),
85 BlockId::Number(num) => match num {
86 BlockNumberOrTag::Latest => Ok(Some(self.chain_info()?.best_hash)),
87 BlockNumberOrTag::Pending => self
88 .pending_block_num_hash()
89 .map(|res_opt| res_opt.map(|num_hash| num_hash.hash)),
90 BlockNumberOrTag::Finalized => self.finalized_block_hash(),
91 BlockNumberOrTag::Safe => self.safe_block_hash(),
92 BlockNumberOrTag::Earliest => self.block_hash(self.earliest_block_number()?),
93 BlockNumberOrTag::Number(num) => self.block_hash(num),
94 },
95 }
96 }
97
98 fn block_number_for_id(&self, block_id: BlockId) -> ProviderResult<Option<BlockNumber>> {
100 match block_id {
101 BlockId::Hash(hash) => self.block_number(hash.into()),
102 BlockId::Number(num) => self.convert_block_number(num),
103 }
104 }
105
106 fn pending_block_num_hash(&self) -> ProviderResult<Option<alloy_eips::BlockNumHash>>;
108
109 fn safe_block_num_hash(&self) -> ProviderResult<Option<alloy_eips::BlockNumHash>>;
111
112 fn finalized_block_num_hash(&self) -> ProviderResult<Option<alloy_eips::BlockNumHash>>;
114
115 fn safe_block_number(&self) -> ProviderResult<Option<BlockNumber>> {
117 self.safe_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.number))
118 }
119
120 fn finalized_block_number(&self) -> ProviderResult<Option<BlockNumber>> {
122 self.finalized_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.number))
123 }
124
125 fn safe_block_hash(&self) -> ProviderResult<Option<B256>> {
127 self.safe_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.hash))
128 }
129
130 fn finalized_block_hash(&self) -> ProviderResult<Option<B256>> {
132 self.finalized_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.hash))
133 }
134}
135
136#[cfg(test)]
137fn _object_safe(_: Box<dyn BlockIdReader>) {}