1pub 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#[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 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 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 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
136impl<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 let hash =
636 self.finalized_block_hash()?.ok_or(ProviderError::FinalizedBlockNotFound)?;
637
638 self.history_by_block_hash(hash)
640 }
641 BlockNumberOrTag::Safe => {
642 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}