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