1use crate::{
2 BlockBodyIndicesProvider, BlockNumReader, HeaderProvider, OmmersProvider, ReceiptProvider,
3 ReceiptProviderIdExt, TransactionVariant, TransactionsProvider, WithdrawalsProvider,
4};
5use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag};
6use alloy_primitives::{BlockNumber, B256};
7use reth_primitives::{BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader};
8use reth_storage_errors::provider::ProviderResult;
9use std::ops::RangeInclusive;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
16pub enum BlockSource {
17 #[default]
22 Any,
23 Pending,
26 Canonical,
28}
29
30impl BlockSource {
31 pub const fn is_pending(&self) -> bool {
33 matches!(self, Self::Pending | Self::Any)
34 }
35
36 pub const fn is_canonical(&self) -> bool {
38 matches!(self, Self::Canonical | Self::Any)
39 }
40}
41
42pub type ProviderBlock<P> = <P as BlockReader>::Block;
44
45pub trait BlockReader:
50 BlockNumReader
51 + HeaderProvider
52 + BlockBodyIndicesProvider
53 + TransactionsProvider
54 + ReceiptProvider
55 + WithdrawalsProvider
56 + OmmersProvider
57 + Send
58 + Sync
59{
60 type Block: reth_primitives_traits::Block<
62 Body: reth_primitives_traits::BlockBody<Transaction = Self::Transaction>,
63 Header = Self::Header,
64 >;
65
66 fn find_block_by_hash(
72 &self,
73 hash: B256,
74 source: BlockSource,
75 ) -> ProviderResult<Option<Self::Block>>;
76
77 fn block(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Self::Block>>;
81
82 fn pending_block(&self) -> ProviderResult<Option<SealedBlockFor<Self::Block>>>;
87
88 fn pending_block_with_senders(
93 &self,
94 ) -> ProviderResult<Option<SealedBlockWithSenders<Self::Block>>>;
95
96 #[allow(clippy::type_complexity)]
98 fn pending_block_and_receipts(
99 &self,
100 ) -> ProviderResult<Option<(SealedBlockFor<Self::Block>, Vec<Self::Receipt>)>>;
101
102 fn block_by_hash(&self, hash: B256) -> ProviderResult<Option<Self::Block>> {
106 self.block(hash.into())
107 }
108
109 fn block_by_number(&self, num: u64) -> ProviderResult<Option<Self::Block>> {
113 self.block(num.into())
114 }
115
116 fn block_with_senders(
122 &self,
123 id: BlockHashOrNumber,
124 transaction_kind: TransactionVariant,
125 ) -> ProviderResult<Option<BlockWithSenders<Self::Block>>>;
126
127 fn sealed_block_with_senders(
133 &self,
134 id: BlockHashOrNumber,
135 transaction_kind: TransactionVariant,
136 ) -> ProviderResult<Option<SealedBlockWithSenders<Self::Block>>>;
137
138 fn block_range(&self, range: RangeInclusive<BlockNumber>) -> ProviderResult<Vec<Self::Block>>;
142
143 fn block_with_senders_range(
146 &self,
147 range: RangeInclusive<BlockNumber>,
148 ) -> ProviderResult<Vec<BlockWithSenders<Self::Block>>>;
149
150 fn sealed_block_with_senders_range(
153 &self,
154 range: RangeInclusive<BlockNumber>,
155 ) -> ProviderResult<Vec<SealedBlockWithSenders<Self::Block>>>;
156}
157
158impl<T: BlockReader> BlockReader for std::sync::Arc<T> {
159 type Block = T::Block;
160
161 fn find_block_by_hash(
162 &self,
163 hash: B256,
164 source: BlockSource,
165 ) -> ProviderResult<Option<Self::Block>> {
166 T::find_block_by_hash(self, hash, source)
167 }
168 fn block(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Self::Block>> {
169 T::block(self, id)
170 }
171 fn pending_block(&self) -> ProviderResult<Option<SealedBlockFor<Self::Block>>> {
172 T::pending_block(self)
173 }
174 fn pending_block_with_senders(
175 &self,
176 ) -> ProviderResult<Option<SealedBlockWithSenders<Self::Block>>> {
177 T::pending_block_with_senders(self)
178 }
179 fn pending_block_and_receipts(
180 &self,
181 ) -> ProviderResult<Option<(SealedBlockFor<Self::Block>, Vec<Self::Receipt>)>> {
182 T::pending_block_and_receipts(self)
183 }
184 fn block_by_hash(&self, hash: B256) -> ProviderResult<Option<Self::Block>> {
185 T::block_by_hash(self, hash)
186 }
187 fn block_by_number(&self, num: u64) -> ProviderResult<Option<Self::Block>> {
188 T::block_by_number(self, num)
189 }
190 fn block_with_senders(
191 &self,
192 id: BlockHashOrNumber,
193 transaction_kind: TransactionVariant,
194 ) -> ProviderResult<Option<BlockWithSenders<Self::Block>>> {
195 T::block_with_senders(self, id, transaction_kind)
196 }
197 fn sealed_block_with_senders(
198 &self,
199 id: BlockHashOrNumber,
200 transaction_kind: TransactionVariant,
201 ) -> ProviderResult<Option<SealedBlockWithSenders<Self::Block>>> {
202 T::sealed_block_with_senders(self, id, transaction_kind)
203 }
204 fn block_range(&self, range: RangeInclusive<BlockNumber>) -> ProviderResult<Vec<Self::Block>> {
205 T::block_range(self, range)
206 }
207 fn block_with_senders_range(
208 &self,
209 range: RangeInclusive<BlockNumber>,
210 ) -> ProviderResult<Vec<BlockWithSenders<Self::Block>>> {
211 T::block_with_senders_range(self, range)
212 }
213 fn sealed_block_with_senders_range(
214 &self,
215 range: RangeInclusive<BlockNumber>,
216 ) -> ProviderResult<Vec<SealedBlockWithSenders<Self::Block>>> {
217 T::sealed_block_with_senders_range(self, range)
218 }
219}
220
221impl<T: BlockReader> BlockReader for &T {
222 type Block = T::Block;
223
224 fn find_block_by_hash(
225 &self,
226 hash: B256,
227 source: BlockSource,
228 ) -> ProviderResult<Option<Self::Block>> {
229 T::find_block_by_hash(self, hash, source)
230 }
231 fn block(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Self::Block>> {
232 T::block(self, id)
233 }
234 fn pending_block(&self) -> ProviderResult<Option<SealedBlockFor<Self::Block>>> {
235 T::pending_block(self)
236 }
237 fn pending_block_with_senders(
238 &self,
239 ) -> ProviderResult<Option<SealedBlockWithSenders<Self::Block>>> {
240 T::pending_block_with_senders(self)
241 }
242 fn pending_block_and_receipts(
243 &self,
244 ) -> ProviderResult<Option<(SealedBlockFor<Self::Block>, Vec<Self::Receipt>)>> {
245 T::pending_block_and_receipts(self)
246 }
247 fn block_by_hash(&self, hash: B256) -> ProviderResult<Option<Self::Block>> {
248 T::block_by_hash(self, hash)
249 }
250 fn block_by_number(&self, num: u64) -> ProviderResult<Option<Self::Block>> {
251 T::block_by_number(self, num)
252 }
253 fn block_with_senders(
254 &self,
255 id: BlockHashOrNumber,
256 transaction_kind: TransactionVariant,
257 ) -> ProviderResult<Option<BlockWithSenders<Self::Block>>> {
258 T::block_with_senders(self, id, transaction_kind)
259 }
260 fn sealed_block_with_senders(
261 &self,
262 id: BlockHashOrNumber,
263 transaction_kind: TransactionVariant,
264 ) -> ProviderResult<Option<SealedBlockWithSenders<Self::Block>>> {
265 T::sealed_block_with_senders(self, id, transaction_kind)
266 }
267 fn block_range(&self, range: RangeInclusive<BlockNumber>) -> ProviderResult<Vec<Self::Block>> {
268 T::block_range(self, range)
269 }
270 fn block_with_senders_range(
271 &self,
272 range: RangeInclusive<BlockNumber>,
273 ) -> ProviderResult<Vec<BlockWithSenders<Self::Block>>> {
274 T::block_with_senders_range(self, range)
275 }
276 fn sealed_block_with_senders_range(
277 &self,
278 range: RangeInclusive<BlockNumber>,
279 ) -> ProviderResult<Vec<SealedBlockWithSenders<Self::Block>>> {
280 T::sealed_block_with_senders_range(self, range)
281 }
282}
283
284pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
295 fn block_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult<Option<Self::Block>> {
299 self.convert_block_number(id)?.map_or_else(|| Ok(None), |num| self.block(num.into()))
300 }
301
302 fn pending_header(&self) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
307 self.sealed_header_by_id(BlockNumberOrTag::Pending.into())
308 }
309
310 fn latest_header(&self) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
315 self.sealed_header_by_id(BlockNumberOrTag::Latest.into())
316 }
317
318 fn safe_header(&self) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
323 self.sealed_header_by_id(BlockNumberOrTag::Safe.into())
324 }
325
326 fn finalized_header(&self) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
331 self.sealed_header_by_id(BlockNumberOrTag::Finalized.into())
332 }
333
334 fn block_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Block>>;
338
339 fn block_with_senders_by_id(
345 &self,
346 id: BlockId,
347 transaction_kind: TransactionVariant,
348 ) -> ProviderResult<Option<BlockWithSenders<Self::Block>>> {
349 match id {
350 BlockId::Hash(hash) => {
351 self.block_with_senders(hash.block_hash.into(), transaction_kind)
352 }
353 BlockId::Number(num) => self.convert_block_number(num)?.map_or_else(
354 || Ok(None),
355 |num| self.block_with_senders(num.into(), transaction_kind),
356 ),
357 }
358 }
359
360 fn header_by_number_or_tag(
364 &self,
365 id: BlockNumberOrTag,
366 ) -> ProviderResult<Option<Self::Header>> {
367 self.convert_block_number(id)?
368 .map_or_else(|| Ok(None), |num| self.header_by_hash_or_number(num.into()))
369 }
370
371 fn sealed_header_by_number_or_tag(
375 &self,
376 id: BlockNumberOrTag,
377 ) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
378 self.convert_block_number(id)?
379 .map_or_else(|| Ok(None), |num| self.header_by_hash_or_number(num.into()))?
380 .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h))))
381 }
382
383 fn sealed_header_by_id(
387 &self,
388 id: BlockId,
389 ) -> ProviderResult<Option<SealedHeader<Self::Header>>>;
390
391 fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Header>>;
395
396 fn ommers_by_number_or_tag(
398 &self,
399 id: BlockNumberOrTag,
400 ) -> ProviderResult<Option<Vec<Self::Header>>> {
401 self.convert_block_number(id)?.map_or_else(|| Ok(None), |num| self.ommers(num.into()))
402 }
403
404 fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<Self::Header>>>;
408}
409
410pub trait ChainStateBlockReader: Send + Sync {
412 fn last_finalized_block_number(&self) -> ProviderResult<Option<BlockNumber>>;
416 fn last_safe_block_number(&self) -> ProviderResult<Option<BlockNumber>>;
420}
421
422pub trait ChainStateBlockWriter: Send + Sync {
424 fn save_finalized_block_number(&self, block_number: BlockNumber) -> ProviderResult<()>;
426
427 fn save_safe_block_number(&self, block_number: BlockNumber) -> ProviderResult<()>;
429}