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