Skip to main content

reth_storage_api/
noop.rs

1//! Various noop implementations for traits.
2
3pub use crate::bal::NoopBalStore;
4
5use crate::{
6    AccountReader, BalProvider, BalStoreHandle, BlockBodyIndicesProvider, BlockHashReader,
7    BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, BytecodeReader,
8    ChangeSetReader, HashedPostStateProvider, HeaderProvider, NodePrimitivesProvider,
9    PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader,
10    StateProofProvider, StateProvider, StateProviderBox, StateProviderFactory,
11    StateRangeProviderFactory, StateRangeView, StateReader, StateRootProvider, StorageRootProvider,
12    TransactionVariant, TransactionsProvider,
13};
14
15#[cfg(feature = "db-api")]
16use crate::{
17    DBProvider, DatabaseProviderFactory, DbTxProvider, HistoryInfo, HistoryReader,
18    StorageChangeSetReader, StorageSettingsCache,
19};
20use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
21use alloy_consensus::transaction::TransactionMeta;
22use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag};
23use alloy_primitives::{
24    Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256,
25};
26use core::{
27    fmt::Debug,
28    marker::PhantomData,
29    ops::{RangeBounds, RangeInclusive},
30};
31#[cfg(feature = "chain-state")]
32use reth_chain_state::{
33    CanonStateNotifications, CanonStateSubscriptions, ExecutedBlock, ForkChoiceNotifications,
34    ForkChoiceSubscriptions, PersistedBlockNotifications, PersistedBlockSubscriptions,
35};
36use reth_chainspec::{ChainInfo, ChainSpecProvider, EthChainSpec, MAINNET};
37#[cfg(feature = "db-api")]
38use reth_db_api::mock::{DatabaseMock, TxMock};
39use reth_db_models::{AccountBeforeTx, StoredBlockBodyIndices};
40use reth_ethereum_primitives::EthPrimitives;
41use reth_execution_types::{ExecutionOutcome, RecoveredBlockAndExecutionOutput};
42use reth_primitives_traits::{Account, Bytecode, NodePrimitives, RecoveredBlock, SealedHeader};
43#[cfg(feature = "db-api")]
44use reth_prune_types::PruneModes;
45use reth_prune_types::{PruneCheckpoint, PruneSegment};
46use reth_stages_types::{StageCheckpoint, StageId};
47use reth_storage_errors::provider::{ProviderError, ProviderResult};
48use reth_trie_common::{
49    updates::TrieUpdates, AccountProof, DecodedMultiProofV2, ExecutionWitnessMode, HashedPostState,
50    HashedStorage, MultiProof, MultiProofTargets, MultiProofTargetsV2, StorageMultiProof,
51    StorageProof, TrieInput,
52};
53
54/// Supports various api interfaces for testing purposes.
55#[derive(Debug)]
56#[non_exhaustive]
57pub struct NoopProvider<ChainSpec = reth_chainspec::ChainSpec, N = EthPrimitives> {
58    chain_spec: Arc<ChainSpec>,
59    bal_store: BalStoreHandle,
60    #[cfg(feature = "db-api")]
61    tx: TxMock,
62    #[cfg(feature = "db-api")]
63    prune_modes: PruneModes,
64    _phantom: PhantomData<N>,
65}
66
67impl<ChainSpec, N> NoopProvider<ChainSpec, N> {
68    /// Create a new instance for specific primitive types.
69    pub fn new(chain_spec: Arc<ChainSpec>) -> Self {
70        Self {
71            chain_spec,
72            bal_store: BalStoreHandle::default(),
73            #[cfg(feature = "db-api")]
74            tx: TxMock::default(),
75            #[cfg(feature = "db-api")]
76            prune_modes: PruneModes::default(),
77            _phantom: Default::default(),
78        }
79    }
80}
81
82impl<ChainSpec> NoopProvider<ChainSpec> {
83    /// Create a new instance of the `NoopBlockReader`.
84    pub fn eth(chain_spec: Arc<ChainSpec>) -> Self {
85        Self {
86            chain_spec,
87            bal_store: BalStoreHandle::default(),
88            #[cfg(feature = "db-api")]
89            tx: TxMock::default(),
90            #[cfg(feature = "db-api")]
91            prune_modes: PruneModes::default(),
92            _phantom: Default::default(),
93        }
94    }
95}
96
97impl NoopProvider {
98    /// Create a new instance of the [`NoopProvider`] with the mainnet chain spec.
99    pub fn mainnet() -> Self {
100        Self::eth(MAINNET.clone())
101    }
102}
103
104impl Default for NoopProvider {
105    fn default() -> Self {
106        Self::mainnet()
107    }
108}
109
110impl<ChainSpec, N> Clone for NoopProvider<ChainSpec, N> {
111    fn clone(&self) -> Self {
112        Self {
113            chain_spec: Arc::clone(&self.chain_spec),
114            bal_store: self.bal_store.clone(),
115            #[cfg(feature = "db-api")]
116            tx: self.tx.clone(),
117            #[cfg(feature = "db-api")]
118            prune_modes: self.prune_modes.clone(),
119            _phantom: Default::default(),
120        }
121    }
122}
123
124impl<ChainSpec, N> BalProvider for NoopProvider<ChainSpec, N> {
125    fn bal_store(&self) -> &BalStoreHandle {
126        &self.bal_store
127    }
128}
129
130impl<ChainSpec, N> StateRangeProviderFactory for NoopProvider<ChainSpec, N> {
131    fn state_range_provider(&self, _state_root: B256) -> ProviderResult<Option<StateRangeView>> {
132        Ok(None)
133    }
134}
135
136/// Noop implementation for testing purposes
137impl<ChainSpec: Send + Sync, N: Send + Sync> BlockHashReader for NoopProvider<ChainSpec, N> {
138    fn block_hash(&self, _number: u64) -> ProviderResult<Option<B256>> {
139        Ok(None)
140    }
141
142    fn canonical_hashes_range(
143        &self,
144        _start: BlockNumber,
145        _end: BlockNumber,
146    ) -> ProviderResult<Vec<B256>> {
147        Ok(Vec::new())
148    }
149}
150
151impl<ChainSpec: Send + Sync, N: Send + Sync> BlockNumReader for NoopProvider<ChainSpec, N> {
152    fn chain_info(&self) -> ProviderResult<ChainInfo> {
153        Ok(ChainInfo::default())
154    }
155
156    fn best_block_number(&self) -> ProviderResult<BlockNumber> {
157        Ok(0)
158    }
159
160    fn last_block_number(&self) -> ProviderResult<BlockNumber> {
161        Ok(0)
162    }
163
164    fn block_number(&self, _hash: B256) -> ProviderResult<Option<BlockNumber>> {
165        Ok(None)
166    }
167}
168
169impl<ChainSpec: EthChainSpec + 'static, N: Debug + Send + Sync + 'static> ChainSpecProvider
170    for NoopProvider<ChainSpec, N>
171{
172    type ChainSpec = ChainSpec;
173
174    fn chain_spec(&self) -> Arc<Self::ChainSpec> {
175        self.chain_spec.clone()
176    }
177}
178
179impl<C: Send + Sync, N: NodePrimitives> BlockIdReader for NoopProvider<C, N> {
180    fn pending_block_num_hash(&self) -> ProviderResult<Option<alloy_eips::BlockNumHash>> {
181        Ok(None)
182    }
183
184    fn safe_block_num_hash(&self) -> ProviderResult<Option<alloy_eips::BlockNumHash>> {
185        Ok(None)
186    }
187
188    fn finalized_block_num_hash(&self) -> ProviderResult<Option<alloy_eips::BlockNumHash>> {
189        Ok(None)
190    }
191}
192
193impl<C: Send + Sync, N: NodePrimitives> BlockReaderIdExt for NoopProvider<C, N> {
194    fn block_by_id(&self, _id: BlockId) -> ProviderResult<Option<N::Block>> {
195        Ok(None)
196    }
197
198    fn sealed_header_by_id(
199        &self,
200        _id: BlockId,
201    ) -> ProviderResult<Option<SealedHeader<N::BlockHeader>>> {
202        Ok(None)
203    }
204
205    fn header_by_id(&self, _id: BlockId) -> ProviderResult<Option<N::BlockHeader>> {
206        Ok(None)
207    }
208}
209
210impl<C: Send + Sync, N: NodePrimitives> BlockReader for NoopProvider<C, N> {
211    type Block = N::Block;
212
213    fn find_block_by_hash(
214        &self,
215        _hash: B256,
216        _source: BlockSource,
217    ) -> ProviderResult<Option<Self::Block>> {
218        Ok(None)
219    }
220
221    fn block(&self, _id: BlockHashOrNumber) -> ProviderResult<Option<Self::Block>> {
222        Ok(None)
223    }
224
225    fn pending_block(&self) -> ProviderResult<Option<Arc<RecoveredBlock<Self::Block>>>> {
226        Ok(None)
227    }
228
229    fn pending_block_and_receipts(
230        &self,
231    ) -> ProviderResult<Option<RecoveredBlockAndExecutionOutput<Self::Block, Self::Receipt>>> {
232        Ok(None)
233    }
234
235    fn recovered_block(
236        &self,
237        _id: BlockHashOrNumber,
238        _transaction_kind: TransactionVariant,
239    ) -> ProviderResult<Option<RecoveredBlock<Self::Block>>> {
240        Ok(None)
241    }
242
243    fn sealed_block_with_senders(
244        &self,
245        _id: BlockHashOrNumber,
246        _transaction_kind: TransactionVariant,
247    ) -> ProviderResult<Option<RecoveredBlock<Self::Block>>> {
248        Ok(None)
249    }
250
251    fn block_range(&self, _range: RangeInclusive<BlockNumber>) -> ProviderResult<Vec<Self::Block>> {
252        Ok(Vec::new())
253    }
254
255    fn block_with_senders_range(
256        &self,
257        _range: RangeInclusive<BlockNumber>,
258    ) -> ProviderResult<Vec<RecoveredBlock<Self::Block>>> {
259        Ok(Vec::new())
260    }
261
262    fn recovered_block_range(
263        &self,
264        _range: RangeInclusive<BlockNumber>,
265    ) -> ProviderResult<Vec<RecoveredBlock<Self::Block>>> {
266        Ok(Vec::new())
267    }
268
269    fn block_by_transaction_id(&self, _id: TxNumber) -> ProviderResult<Option<BlockNumber>> {
270        Ok(None)
271    }
272}
273
274impl<C: Send + Sync, N: NodePrimitives> TransactionsProvider for NoopProvider<C, N> {
275    type Transaction = N::SignedTx;
276
277    fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
278        Ok(None)
279    }
280
281    fn transaction_by_id(&self, _id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
282        Ok(None)
283    }
284
285    fn transaction_by_id_unhashed(
286        &self,
287        _id: TxNumber,
288    ) -> ProviderResult<Option<Self::Transaction>> {
289        Ok(None)
290    }
291
292    fn transaction_by_hash(&self, _hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
293        Ok(None)
294    }
295
296    fn transaction_by_hash_with_meta(
297        &self,
298        _hash: TxHash,
299    ) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
300        Ok(None)
301    }
302
303    fn transactions_by_block(
304        &self,
305        _block_id: BlockHashOrNumber,
306    ) -> ProviderResult<Option<Vec<Self::Transaction>>> {
307        Ok(None)
308    }
309
310    fn transactions_by_block_range(
311        &self,
312        _range: impl RangeBounds<BlockNumber>,
313    ) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
314        Ok(Vec::default())
315    }
316
317    fn transactions_by_tx_range(
318        &self,
319        _range: impl RangeBounds<TxNumber>,
320    ) -> ProviderResult<Vec<Self::Transaction>> {
321        Ok(Vec::default())
322    }
323
324    fn senders_by_tx_range(
325        &self,
326        _range: impl RangeBounds<TxNumber>,
327    ) -> ProviderResult<Vec<Address>> {
328        Ok(Vec::default())
329    }
330
331    fn transaction_sender(&self, _id: TxNumber) -> ProviderResult<Option<Address>> {
332        Ok(None)
333    }
334}
335
336impl<C: Send + Sync, N: NodePrimitives> ReceiptProvider for NoopProvider<C, N> {
337    type Receipt = N::Receipt;
338
339    fn receipt(&self, _id: TxNumber) -> ProviderResult<Option<Self::Receipt>> {
340        Ok(None)
341    }
342
343    fn receipt_by_hash(&self, _hash: TxHash) -> ProviderResult<Option<Self::Receipt>> {
344        Ok(None)
345    }
346
347    fn receipts_by_block(
348        &self,
349        _block: BlockHashOrNumber,
350    ) -> ProviderResult<Option<Vec<Self::Receipt>>> {
351        Ok(None)
352    }
353
354    fn receipts_by_tx_range(
355        &self,
356        _range: impl RangeBounds<TxNumber>,
357    ) -> ProviderResult<Vec<Self::Receipt>> {
358        Ok(Vec::new())
359    }
360
361    fn receipts_by_block_range(
362        &self,
363        _block_range: RangeInclusive<BlockNumber>,
364    ) -> ProviderResult<Vec<Vec<Self::Receipt>>> {
365        Ok(Vec::new())
366    }
367}
368
369impl<C: Send + Sync, N: NodePrimitives> ReceiptProviderIdExt for NoopProvider<C, N> {}
370
371impl<C: Send + Sync, N: NodePrimitives> HeaderProvider for NoopProvider<C, N> {
372    type Header = N::BlockHeader;
373
374    fn header(&self, _block_hash: BlockHash) -> ProviderResult<Option<Self::Header>> {
375        Ok(None)
376    }
377
378    fn header_by_number(&self, _num: u64) -> ProviderResult<Option<Self::Header>> {
379        Ok(None)
380    }
381
382    fn headers_range(
383        &self,
384        _range: impl RangeBounds<BlockNumber>,
385    ) -> ProviderResult<Vec<Self::Header>> {
386        Ok(Vec::new())
387    }
388
389    fn sealed_header(
390        &self,
391        _number: BlockNumber,
392    ) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
393        Ok(None)
394    }
395
396    fn sealed_headers_while(
397        &self,
398        _range: impl RangeBounds<BlockNumber>,
399        _predicate: impl FnMut(&SealedHeader<Self::Header>) -> bool,
400    ) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
401        Ok(Vec::new())
402    }
403}
404
405impl<C: Send + Sync, N: NodePrimitives> AccountReader for NoopProvider<C, N> {
406    fn basic_account(&self, _address: &Address) -> ProviderResult<Option<Account>> {
407        Ok(None)
408    }
409}
410
411impl<C: Send + Sync, N: NodePrimitives> ChangeSetReader for NoopProvider<C, N> {
412    fn account_block_changeset(
413        &self,
414        _block_number: BlockNumber,
415    ) -> ProviderResult<Vec<AccountBeforeTx>> {
416        Ok(Vec::default())
417    }
418
419    fn get_account_before_block(
420        &self,
421        _block_number: BlockNumber,
422        _address: Address,
423    ) -> ProviderResult<Option<AccountBeforeTx>> {
424        Ok(None)
425    }
426
427    fn account_changesets_range(
428        &self,
429        _range: impl core::ops::RangeBounds<BlockNumber>,
430    ) -> ProviderResult<Vec<(BlockNumber, AccountBeforeTx)>> {
431        Ok(Vec::default())
432    }
433}
434
435#[cfg(feature = "db-api")]
436impl<C: Send + Sync, N: NodePrimitives> HistoryReader for NoopProvider<C, N> {
437    fn account_history_info(
438        &self,
439        _address: Address,
440        _block_number: BlockNumber,
441        _lowest_available_block_number: Option<BlockNumber>,
442    ) -> ProviderResult<HistoryInfo> {
443        Ok(HistoryInfo::NotYetWritten)
444    }
445
446    fn storage_history_info(
447        &self,
448        _address: Address,
449        _storage_key: B256,
450        _block_number: BlockNumber,
451        _lowest_available_block_number: Option<BlockNumber>,
452    ) -> ProviderResult<HistoryInfo> {
453        Ok(HistoryInfo::NotYetWritten)
454    }
455}
456
457#[cfg(feature = "db-api")]
458impl<C: Send + Sync, N: NodePrimitives> StorageChangeSetReader for NoopProvider<C, N> {
459    fn storage_changeset(
460        &self,
461        _block_number: BlockNumber,
462    ) -> ProviderResult<
463        Vec<(reth_db_api::models::BlockNumberAddress, reth_primitives_traits::StorageEntry)>,
464    > {
465        Ok(Vec::default())
466    }
467
468    fn get_storage_before_block(
469        &self,
470        _block_number: BlockNumber,
471        _address: Address,
472        _storage_key: B256,
473    ) -> ProviderResult<Option<reth_primitives_traits::StorageEntry>> {
474        Ok(None)
475    }
476
477    fn storage_changesets_range(
478        &self,
479        _range: impl core::ops::RangeBounds<BlockNumber>,
480    ) -> ProviderResult<
481        Vec<(reth_db_api::models::BlockNumberAddress, reth_primitives_traits::StorageEntry)>,
482    > {
483        Ok(Vec::default())
484    }
485}
486
487impl<C: Send + Sync, N: NodePrimitives> StateRootProvider for NoopProvider<C, N> {
488    fn state_root(&self, _state: HashedPostState) -> ProviderResult<B256> {
489        Ok(B256::default())
490    }
491
492    fn state_root_from_nodes(&self, _input: TrieInput) -> ProviderResult<B256> {
493        Ok(B256::default())
494    }
495
496    fn state_root_with_updates(
497        &self,
498        _state: HashedPostState,
499    ) -> ProviderResult<(B256, TrieUpdates)> {
500        Ok((B256::default(), TrieUpdates::default()))
501    }
502
503    fn state_root_from_nodes_with_updates(
504        &self,
505        _input: TrieInput,
506    ) -> ProviderResult<(B256, TrieUpdates)> {
507        Ok((B256::default(), TrieUpdates::default()))
508    }
509}
510
511impl<C: Send + Sync, N: NodePrimitives> StorageRootProvider for NoopProvider<C, N> {
512    fn storage_root(
513        &self,
514        _address: Address,
515        _hashed_storage: HashedStorage,
516    ) -> ProviderResult<B256> {
517        Ok(B256::default())
518    }
519
520    fn storage_proof(
521        &self,
522        _address: Address,
523        slot: B256,
524        _hashed_storage: HashedStorage,
525    ) -> ProviderResult<StorageProof> {
526        Ok(StorageProof::new(slot))
527    }
528
529    fn storage_multiproof(
530        &self,
531        _address: Address,
532        _slots: &[B256],
533        _hashed_storage: HashedStorage,
534    ) -> ProviderResult<StorageMultiProof> {
535        Ok(StorageMultiProof::empty())
536    }
537}
538
539impl<C: Send + Sync, N: NodePrimitives> StateProofProvider for NoopProvider<C, N> {
540    fn proof(
541        &self,
542        _input: TrieInput,
543        address: Address,
544        _slots: &[B256],
545    ) -> ProviderResult<AccountProof> {
546        Ok(AccountProof::new(address))
547    }
548
549    fn multiproof(
550        &self,
551        _input: TrieInput,
552        _targets: MultiProofTargets,
553    ) -> ProviderResult<MultiProof> {
554        Ok(MultiProof::default())
555    }
556
557    fn multiproof_v2(
558        &self,
559        _input: TrieInput,
560        _targets: MultiProofTargetsV2,
561    ) -> ProviderResult<DecodedMultiProofV2> {
562        Ok(DecodedMultiProofV2::default())
563    }
564
565    fn witness(
566        &self,
567        _input: TrieInput,
568        _target: HashedPostState,
569        _mode: ExecutionWitnessMode,
570    ) -> ProviderResult<Vec<Bytes>> {
571        Ok(Vec::default())
572    }
573}
574
575impl<C: Send + Sync, N: NodePrimitives> HashedPostStateProvider for NoopProvider<C, N> {
576    fn hashed_post_state(
577        &self,
578        _bundle_state: &revm::database::BundleState,
579    ) -> ProviderResult<HashedPostState> {
580        Ok(HashedPostState::default())
581    }
582}
583
584impl<C: Send + Sync, N: NodePrimitives> StateReader for NoopProvider<C, N> {
585    type Receipt = N::Receipt;
586
587    fn get_state(
588        &self,
589        _block: BlockNumber,
590    ) -> ProviderResult<Option<ExecutionOutcome<Self::Receipt>>> {
591        Ok(None)
592    }
593}
594
595impl<C: Send + Sync, N: NodePrimitives> StateProvider for NoopProvider<C, N> {
596    fn storage(
597        &self,
598        _account: Address,
599        _storage_key: StorageKey,
600    ) -> ProviderResult<Option<StorageValue>> {
601        Ok(None)
602    }
603}
604
605impl<C: Send + Sync, N: NodePrimitives> BytecodeReader for NoopProvider<C, N> {
606    fn bytecode_by_hash(&self, _code_hash: &B256) -> ProviderResult<Option<Bytecode>> {
607        Ok(None)
608    }
609}
610
611impl<C: Send + Sync + 'static, N: NodePrimitives> StateProviderFactory for NoopProvider<C, N> {
612    type Primitives = N;
613
614    fn latest(&self) -> ProviderResult<StateProviderBox> {
615        Ok(Box::new(self.clone()))
616    }
617
618    #[cfg(feature = "chain-state")]
619    fn state_with_block_appended(
620        &self,
621        _parent_hash: BlockHash,
622        _block: ExecutedBlock<N>,
623    ) -> ProviderResult<StateProviderBox> {
624        Ok(Box::new(self.clone()))
625    }
626
627    fn state_by_block_number_or_tag(
628        &self,
629        number_or_tag: BlockNumberOrTag,
630    ) -> ProviderResult<StateProviderBox> {
631        match number_or_tag {
632            BlockNumberOrTag::Latest => self.latest(),
633            BlockNumberOrTag::Finalized => {
634                // we can only get the finalized state by hash, not by num
635                let hash =
636                    self.finalized_block_hash()?.ok_or(ProviderError::FinalizedBlockNotFound)?;
637
638                // only look at historical state
639                self.history_by_block_hash(hash)
640            }
641            BlockNumberOrTag::Safe => {
642                // we can only get the safe state by hash, not by num
643                let hash = self.safe_block_hash()?.ok_or(ProviderError::SafeBlockNotFound)?;
644
645                self.history_by_block_hash(hash)
646            }
647            BlockNumberOrTag::Earliest => {
648                self.history_by_block_number(self.earliest_block_number()?)
649            }
650            BlockNumberOrTag::Pending => self.pending(),
651            BlockNumberOrTag::Number(num) => self.history_by_block_number(num),
652        }
653    }
654
655    fn history_by_block_number(&self, _block: BlockNumber) -> ProviderResult<StateProviderBox> {
656        Ok(Box::new(self.clone()))
657    }
658
659    fn history_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox> {
660        Ok(Box::new(self.clone()))
661    }
662
663    fn state_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox> {
664        Ok(Box::new(self.clone()))
665    }
666
667    fn pending(&self) -> ProviderResult<StateProviderBox> {
668        Ok(Box::new(self.clone()))
669    }
670
671    fn pending_state_by_hash(&self, _block_hash: B256) -> ProviderResult<Option<StateProviderBox>> {
672        Ok(Some(Box::new(self.clone())))
673    }
674
675    fn maybe_pending(&self) -> ProviderResult<Option<StateProviderBox>> {
676        Ok(Some(Box::new(self.clone())))
677    }
678}
679
680#[cfg(feature = "chain-state")]
681impl<C: Send + Sync, N: NodePrimitives> CanonStateSubscriptions for NoopProvider<C, N> {
682    type Primitives = N;
683
684    fn subscribe_to_canonical_state(&self) -> CanonStateNotifications<N> {
685        tokio::sync::broadcast::channel(1).1
686    }
687}
688
689#[cfg(feature = "chain-state")]
690impl<C: Send + Sync, N: NodePrimitives> ForkChoiceSubscriptions for NoopProvider<C, N> {
691    type Header = N::BlockHeader;
692
693    fn subscribe_safe_block(&self) -> ForkChoiceNotifications<N::BlockHeader> {
694        let (_, rx) = tokio::sync::watch::channel(None);
695        ForkChoiceNotifications(rx)
696    }
697
698    fn subscribe_finalized_block(&self) -> ForkChoiceNotifications<N::BlockHeader> {
699        let (_, rx) = tokio::sync::watch::channel(None);
700        ForkChoiceNotifications(rx)
701    }
702}
703
704#[cfg(feature = "chain-state")]
705impl<C: Send + Sync, N: NodePrimitives> PersistedBlockSubscriptions for NoopProvider<C, N> {
706    fn subscribe_persisted_block(&self) -> PersistedBlockNotifications {
707        let (_, rx) = tokio::sync::watch::channel(None);
708        PersistedBlockNotifications(rx)
709    }
710}
711
712impl<C: Send + Sync, N: NodePrimitives> StageCheckpointReader for NoopProvider<C, N> {
713    fn get_stage_checkpoint(&self, _id: StageId) -> ProviderResult<Option<StageCheckpoint>> {
714        Ok(None)
715    }
716
717    fn get_stage_checkpoint_progress(&self, _id: StageId) -> ProviderResult<Option<Vec<u8>>> {
718        Ok(None)
719    }
720
721    fn get_all_checkpoints(&self) -> ProviderResult<Vec<(String, StageCheckpoint)>> {
722        Ok(Vec::new())
723    }
724}
725
726impl<C: Send + Sync, N: NodePrimitives> PruneCheckpointReader for NoopProvider<C, N> {
727    fn get_prune_checkpoint(
728        &self,
729        _segment: PruneSegment,
730    ) -> ProviderResult<Option<PruneCheckpoint>> {
731        Ok(None)
732    }
733
734    fn get_prune_checkpoints(&self) -> ProviderResult<Vec<(PruneSegment, PruneCheckpoint)>> {
735        Ok(Vec::new())
736    }
737}
738
739impl<C: Send + Sync, N: NodePrimitives> NodePrimitivesProvider for NoopProvider<C, N> {
740    type Primitives = N;
741}
742
743impl<C: Send + Sync, N: Send + Sync> BlockBodyIndicesProvider for NoopProvider<C, N> {
744    fn block_body_indices(&self, _num: u64) -> ProviderResult<Option<StoredBlockBodyIndices>> {
745        Ok(None)
746    }
747
748    fn block_body_indices_range(
749        &self,
750        _range: RangeInclusive<BlockNumber>,
751    ) -> ProviderResult<Vec<StoredBlockBodyIndices>> {
752        Ok(Vec::new())
753    }
754}
755
756#[cfg(feature = "db-api")]
757impl<ChainSpec: Send + Sync, N: NodePrimitives> DbTxProvider for NoopProvider<ChainSpec, N> {
758    type Tx = TxMock;
759
760    fn tx(&self) -> &Self::Tx {
761        &self.tx
762    }
763}
764
765#[cfg(feature = "db-api")]
766impl<ChainSpec: Send + Sync, N: NodePrimitives> DBProvider for NoopProvider<ChainSpec, N> {
767    fn tx_mut(&mut self) -> &mut Self::Tx {
768        &mut self.tx
769    }
770
771    fn into_tx(self) -> Self::Tx {
772        self.tx
773    }
774
775    fn prune_modes_ref(&self) -> &PruneModes {
776        &self.prune_modes
777    }
778
779    fn commit(self) -> ProviderResult<()> {
780        use reth_db_api::transaction::DbTx;
781
782        Ok(self.tx.commit()?)
783    }
784}
785
786#[cfg(feature = "db-api")]
787impl<ChainSpec: Send + Sync, N: NodePrimitives> DatabaseProviderFactory
788    for NoopProvider<ChainSpec, N>
789{
790    type DB = DatabaseMock;
791    type Provider = Self;
792    type ProviderRW = Self;
793
794    fn database_provider_ro(&self) -> ProviderResult<Self::Provider> {
795        Ok(self.clone())
796    }
797
798    fn database_provider_rw(&self) -> ProviderResult<Self::ProviderRW> {
799        Ok(self.clone())
800    }
801}
802
803#[cfg(feature = "db-api")]
804impl<ChainSpec: Send + Sync, N: Send + Sync> StorageSettingsCache for NoopProvider<ChainSpec, N> {
805    fn cached_storage_settings(&self) -> reth_db_api::models::StorageSettings {
806        reth_db_api::models::StorageSettings::default()
807    }
808
809    fn set_storage_settings_cache(&self, _settings: reth_db_api::models::StorageSettings) {}
810}