1#![doc(
20 html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
21 html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
22 issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
23)]
24#![cfg_attr(not(test), warn(unused_crate_dependencies))]
25#![cfg_attr(docsrs, feature(doc_cfg))]
26
27use alloy_consensus::{constants::KECCAK_EMPTY, transaction::TransactionMeta, BlockHeader};
28use alloy_eips::{BlockHashOrNumber, BlockNumberOrTag};
29use alloy_network::{primitives::HeaderResponse, BlockResponse};
30use alloy_primitives::{Address, BlockHash, BlockNumber, StorageKey, TxHash, TxNumber, B256, U256};
31use alloy_provider::{ext::DebugApi, network::Network, Provider};
32use alloy_rpc_types::{AccountInfo, BlockId};
33use alloy_rpc_types_engine::ForkchoiceState;
34use dashmap::DashMap;
35use reth_chainspec::{ChainInfo, ChainSpecProvider};
36use reth_db_api::{
37 mock::{DatabaseMock, TxMock},
38 models::StoredBlockBodyIndices,
39};
40use reth_errors::{ProviderError, ProviderResult};
41use reth_node_types::{
42 Block, BlockBody, BlockTy, HeaderTy, NodeTypes, PrimitivesTy, ReceiptTy, TxTy,
43};
44use reth_primitives_traits::{Account, Bytecode, RecoveredBlock, SealedHeader};
45use reth_provider::{
46 AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BytecodeReader,
47 CanonChainTracker, CanonStateNotification, CanonStateNotifications, CanonStateSubscriptions,
48 ChainStateBlockReader, ChainStateBlockWriter, ChangeSetReader, DatabaseProviderFactory,
49 HeaderProvider, PruneCheckpointReader, ReceiptProvider, StageCheckpointReader, StateProvider,
50 StateProviderBox, StateProviderFactory, StateReader, StateRootProvider, StorageReader,
51 TransactionVariant, TransactionsProvider,
52};
53use reth_prune_types::{PruneCheckpoint, PruneSegment};
54pub mod rpc_response;
55use reth_stages_types::{StageCheckpoint, StageId};
56use reth_storage_api::{
57 BlockBodyIndicesProvider, BlockReaderIdExt, BlockSource, DBProvider, NodePrimitivesProvider,
58 ReceiptProviderIdExt, StatsReader,
59};
60use reth_trie::{
61 updates::TrieUpdates, AccountProof, HashedPostState, KeccakKeyHasher, MultiProof, TrieInput,
62};
63pub use rpc_response::{EthRpcConverter, RpcResponseConverter};
64use std::{
65 collections::BTreeMap,
66 future::{Future, IntoFuture},
67 ops::{RangeBounds, RangeInclusive},
68 sync::Arc,
69};
70use tokio::{runtime::Handle, sync::broadcast};
71use tracing::{trace, warn};
72
73#[derive(Debug, Clone)]
75pub struct RpcBlockchainProviderConfig {
76 pub compute_state_root: bool,
78 pub reth_rpc_support: bool,
84}
85
86impl Default for RpcBlockchainProviderConfig {
87 fn default() -> Self {
88 Self { compute_state_root: false, reth_rpc_support: true }
89 }
90}
91
92impl RpcBlockchainProviderConfig {
93 pub const fn with_compute_state_root(mut self, compute: bool) -> Self {
95 self.compute_state_root = compute;
96 self
97 }
98
99 pub const fn with_reth_rpc_support(mut self, support: bool) -> Self {
101 self.reth_rpc_support = support;
102 self
103 }
104}
105
106type DynRpcConverter<Node, N> = dyn RpcResponseConverter<
108 N,
109 Block = BlockTy<Node>,
110 Transaction = TxTy<Node>,
111 Receipt = ReceiptTy<Node>,
112>;
113
114#[derive(Clone)]
130pub struct RpcBlockchainProvider<P, Node, N = alloy_network::AnyNetwork>
131where
132 Node: NodeTypes,
133 N: Network,
134{
135 provider: P,
137 node_types: std::marker::PhantomData<Node>,
139 network: std::marker::PhantomData<N>,
141 canon_state_notification: broadcast::Sender<CanonStateNotification<PrimitivesTy<Node>>>,
143 config: RpcBlockchainProviderConfig,
145 chain_spec: Arc<Node::ChainSpec>,
147 converter: Arc<DynRpcConverter<Node, N>>,
149}
150
151impl<P, Node: NodeTypes, N: Network> std::fmt::Debug for RpcBlockchainProvider<P, Node, N> {
152 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
153 f.debug_struct("RpcBlockchainProvider").field("config", &self.config).finish()
154 }
155}
156
157impl<P, Node: NodeTypes, N: Network> RpcBlockchainProvider<P, Node, N>
158where
159 EthRpcConverter: RpcResponseConverter<
160 N,
161 Block = BlockTy<Node>,
162 Transaction = TxTy<Node>,
163 Receipt = ReceiptTy<Node>,
164 >,
165{
166 pub fn new(provider: P) -> Self
168 where
169 Node::ChainSpec: Default,
170 {
171 Self::new_with_converter(provider, EthRpcConverter)
172 }
173}
174
175impl<P, Node: NodeTypes, N: Network> RpcBlockchainProvider<P, Node, N> {
176 pub fn new_with_converter(
178 provider: P,
179 converter: impl RpcResponseConverter<
180 N,
181 Block = BlockTy<Node>,
182 Transaction = TxTy<Node>,
183 Receipt = ReceiptTy<Node>,
184 >,
185 ) -> Self
186 where
187 Node::ChainSpec: Default,
188 {
189 Self::new_with_converter_and_config(
190 provider,
191 converter,
192 RpcBlockchainProviderConfig::default(),
193 )
194 }
195
196 pub fn new_with_converter_and_config(
198 provider: P,
199 converter: impl RpcResponseConverter<
200 N,
201 Block = BlockTy<Node>,
202 Transaction = TxTy<Node>,
203 Receipt = ReceiptTy<Node>,
204 >,
205 config: RpcBlockchainProviderConfig,
206 ) -> Self
207 where
208 Node::ChainSpec: Default,
209 {
210 let (canon_state_notification, _) = broadcast::channel(1);
211 Self {
212 provider,
213 node_types: std::marker::PhantomData,
214 network: std::marker::PhantomData,
215 canon_state_notification,
216 config,
217 chain_spec: Arc::new(Node::ChainSpec::default()),
218 converter: Arc::new(converter),
219 }
220 }
221
222 pub fn with_chain_spec(self, chain_spec: Arc<Node::ChainSpec>) -> Self {
224 Self { chain_spec, ..self }
225 }
226
227 fn block_on_async<F, T>(&self, fut: F) -> T
229 where
230 F: Future<Output = T>,
231 {
232 tokio::task::block_in_place(move || Handle::current().block_on(fut))
233 }
234
235 pub const fn canon_state_notification(
237 &self,
238 ) -> &broadcast::Sender<CanonStateNotification<PrimitivesTy<Node>>> {
239 &self.canon_state_notification
240 }
241}
242
243impl<P, Node, N> RpcBlockchainProvider<P, Node, N>
244where
245 P: Provider<N> + Clone + 'static,
246 N: Network,
247 Node: NodeTypes,
248{
249 fn create_state_provider(&self, block_id: BlockId) -> RpcBlockchainStateProvider<P, Node, N> {
251 RpcBlockchainStateProvider::with_chain_spec(
252 self.provider.clone(),
253 block_id,
254 self.chain_spec.clone(),
255 )
256 .with_compute_state_root(self.config.compute_state_root)
257 .with_reth_rpc_support(self.config.reth_rpc_support)
258 }
259
260 fn state_by_block_number(
262 &self,
263 block_number: BlockNumber,
264 ) -> Result<StateProviderBox, ProviderError> {
265 Ok(Box::new(self.create_state_provider(BlockId::number(block_number))))
266 }
267}
268
269impl<P, Node, N> BlockHashReader for RpcBlockchainProvider<P, Node, N>
275where
276 P: Provider<N> + Clone + 'static,
277 N: Network,
278 Node: NodeTypes,
279{
280 fn block_hash(&self, number: BlockNumber) -> Result<Option<B256>, ProviderError> {
281 let block = self.block_on_async(async {
282 self.provider.get_block_by_number(number.into()).await.map_err(ProviderError::other)
283 })?;
284 Ok(block.map(|b| b.header().hash()))
285 }
286
287 fn canonical_hashes_range(
288 &self,
289 _start: BlockNumber,
290 _end: BlockNumber,
291 ) -> Result<Vec<B256>, ProviderError> {
292 Err(ProviderError::UnsupportedProvider)
294 }
295}
296
297impl<P, Node, N> BlockNumReader for RpcBlockchainProvider<P, Node, N>
298where
299 P: Provider<N> + Clone + 'static,
300 N: Network,
301 Node: NodeTypes,
302{
303 fn chain_info(&self) -> Result<reth_chainspec::ChainInfo, ProviderError> {
304 self.block_on_async(async {
305 let block = self
306 .provider
307 .get_block(BlockId::Number(BlockNumberOrTag::Latest))
308 .await
309 .map_err(ProviderError::other)?
310 .ok_or(ProviderError::HeaderNotFound(0.into()))?;
311
312 Ok(ChainInfo { best_hash: block.header().hash(), best_number: block.header().number() })
313 })
314 }
315
316 fn best_block_number(&self) -> Result<BlockNumber, ProviderError> {
317 self.block_on_async(async {
318 self.provider.get_block_number().await.map_err(ProviderError::other)
319 })
320 }
321
322 fn last_block_number(&self) -> Result<BlockNumber, ProviderError> {
323 self.best_block_number()
324 }
325
326 fn block_number(&self, hash: B256) -> Result<Option<BlockNumber>, ProviderError> {
327 let block = self.block_on_async(async {
328 self.provider.get_block_by_hash(hash).await.map_err(ProviderError::other)
329 })?;
330 Ok(block.map(|b| b.header().number()))
331 }
332}
333
334impl<P, Node, N> BlockIdReader for RpcBlockchainProvider<P, Node, N>
335where
336 P: Provider<N> + Clone + 'static,
337 N: Network,
338 Node: NodeTypes,
339{
340 fn block_number_for_id(&self, block_id: BlockId) -> Result<Option<BlockNumber>, ProviderError> {
341 match block_id {
342 BlockId::Hash(hash) => {
343 let block = self.block_on_async(async {
344 self.provider
345 .get_block_by_hash(hash.block_hash)
346 .await
347 .map_err(ProviderError::other)
348 })?;
349 Ok(block.map(|b| b.header().number()))
350 }
351 BlockId::Number(number_or_tag) => match number_or_tag {
352 alloy_rpc_types::BlockNumberOrTag::Number(num) => Ok(Some(num)),
353 alloy_rpc_types::BlockNumberOrTag::Latest => self.block_on_async(async {
354 self.provider.get_block_number().await.map(Some).map_err(ProviderError::other)
355 }),
356 _ => Ok(None),
357 },
358 }
359 }
360
361 fn pending_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
362 Err(ProviderError::UnsupportedProvider)
364 }
365
366 fn safe_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
367 Err(ProviderError::UnsupportedProvider)
369 }
370
371 fn finalized_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
372 Err(ProviderError::UnsupportedProvider)
374 }
375}
376
377impl<P, Node, N> HeaderProvider for RpcBlockchainProvider<P, Node, N>
378where
379 P: Provider<N> + Clone + 'static,
380 N: Network,
381 Node: NodeTypes,
382{
383 type Header = HeaderTy<Node>;
384
385 fn header(&self, block_hash: BlockHash) -> ProviderResult<Option<Self::Header>> {
386 let block_response = self.block_on_async(async {
387 self.provider.get_block_by_hash(block_hash).await.map_err(ProviderError::other)
388 })?;
389
390 let Some(block_response) = block_response else {
391 return Ok(None);
393 };
394
395 let block = self.converter.block(block_response).map_err(ProviderError::other)?;
397
398 Ok(Some(block.into_header()))
399 }
400
401 fn header_by_number(&self, num: u64) -> ProviderResult<Option<Self::Header>> {
402 let Some(sealed_header) = self.sealed_header(num)? else {
403 return Ok(None);
405 };
406
407 Ok(Some(sealed_header.into_header()))
408 }
409
410 fn headers_range(
411 &self,
412 _range: impl RangeBounds<BlockNumber>,
413 ) -> ProviderResult<Vec<Self::Header>> {
414 Err(ProviderError::UnsupportedProvider)
415 }
416
417 fn sealed_header(
418 &self,
419 number: BlockNumber,
420 ) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
421 let block_response = self.block_on_async(async {
422 self.provider.get_block_by_number(number.into()).await.map_err(ProviderError::other)
423 })?;
424
425 let Some(block_response) = block_response else {
426 return Ok(None);
428 };
429 let block_hash = block_response.header().hash();
430
431 let block = self.converter.block(block_response).map_err(ProviderError::other)?;
433
434 Ok(Some(SealedHeader::new(block.into_header(), block_hash)))
435 }
436
437 fn sealed_headers_while(
438 &self,
439 _range: impl RangeBounds<BlockNumber>,
440 _predicate: impl FnMut(&SealedHeader<Self::Header>) -> bool,
441 ) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
442 Err(ProviderError::UnsupportedProvider)
443 }
444}
445
446impl<P, Node, N> BlockBodyIndicesProvider for RpcBlockchainProvider<P, Node, N>
447where
448 P: Provider<N> + Clone + 'static,
449 N: Network,
450 Node: NodeTypes,
451{
452 fn block_body_indices(&self, _num: u64) -> ProviderResult<Option<StoredBlockBodyIndices>> {
453 Err(ProviderError::UnsupportedProvider)
454 }
455
456 fn block_body_indices_range(
457 &self,
458 _range: RangeInclusive<BlockNumber>,
459 ) -> ProviderResult<Vec<StoredBlockBodyIndices>> {
460 Err(ProviderError::UnsupportedProvider)
461 }
462}
463
464impl<P, Node, N> BlockReader for RpcBlockchainProvider<P, Node, N>
465where
466 P: Provider<N> + Clone + 'static,
467 N: Network,
468 Node: NodeTypes,
469{
470 type Block = BlockTy<Node>;
471
472 fn find_block_by_hash(
473 &self,
474 _hash: B256,
475 _source: BlockSource,
476 ) -> ProviderResult<Option<Self::Block>> {
477 Err(ProviderError::UnsupportedProvider)
478 }
479
480 fn block(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Self::Block>> {
481 let block_response = self.block_on_async(async {
482 self.provider.get_block(id.into()).full().await.map_err(ProviderError::other)
483 })?;
484
485 let Some(block_response) = block_response else {
486 return Ok(None);
488 };
489
490 let block = self.converter.block(block_response).map_err(ProviderError::other)?;
492
493 Ok(Some(block))
494 }
495
496 fn pending_block(&self) -> ProviderResult<Option<RecoveredBlock<Self::Block>>> {
497 Err(ProviderError::UnsupportedProvider)
498 }
499
500 fn pending_block_and_receipts(
501 &self,
502 ) -> ProviderResult<Option<(RecoveredBlock<Self::Block>, Vec<Self::Receipt>)>> {
503 Err(ProviderError::UnsupportedProvider)
504 }
505
506 fn recovered_block(
507 &self,
508 _id: BlockHashOrNumber,
509 _transaction_kind: TransactionVariant,
510 ) -> ProviderResult<Option<RecoveredBlock<Self::Block>>> {
511 Err(ProviderError::UnsupportedProvider)
512 }
513
514 fn sealed_block_with_senders(
515 &self,
516 _id: BlockHashOrNumber,
517 _transaction_kind: TransactionVariant,
518 ) -> ProviderResult<Option<RecoveredBlock<Self::Block>>> {
519 Err(ProviderError::UnsupportedProvider)
520 }
521
522 fn block_range(&self, _range: RangeInclusive<BlockNumber>) -> ProviderResult<Vec<Self::Block>> {
523 Err(ProviderError::UnsupportedProvider)
524 }
525
526 fn block_with_senders_range(
527 &self,
528 _range: RangeInclusive<BlockNumber>,
529 ) -> ProviderResult<Vec<RecoveredBlock<Self::Block>>> {
530 Err(ProviderError::UnsupportedProvider)
531 }
532
533 fn recovered_block_range(
534 &self,
535 _range: RangeInclusive<BlockNumber>,
536 ) -> ProviderResult<Vec<RecoveredBlock<Self::Block>>> {
537 Err(ProviderError::UnsupportedProvider)
538 }
539
540 fn block_by_transaction_id(&self, _id: TxNumber) -> ProviderResult<Option<BlockNumber>> {
541 Err(ProviderError::UnsupportedProvider)
542 }
543}
544
545impl<P, Node, N> BlockReaderIdExt for RpcBlockchainProvider<P, Node, N>
546where
547 P: Provider<N> + Clone + 'static,
548 N: Network,
549 Node: NodeTypes,
550{
551 fn block_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Block>> {
552 match id {
553 BlockId::Hash(hash) => self.block_by_hash(hash.block_hash),
554 BlockId::Number(number_or_tag) => self.block_by_number_or_tag(number_or_tag),
555 }
556 }
557
558 fn sealed_header_by_id(
559 &self,
560 id: BlockId,
561 ) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
562 match id {
563 BlockId::Hash(hash) => self.sealed_header_by_hash(hash.block_hash),
564 BlockId::Number(number_or_tag) => self.sealed_header_by_number_or_tag(number_or_tag),
565 }
566 }
567
568 fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Header>> {
569 match id {
570 BlockId::Hash(hash) => self.header_by_hash_or_number(hash.block_hash.into()),
571 BlockId::Number(number_or_tag) => self.header_by_number_or_tag(number_or_tag),
572 }
573 }
574}
575
576impl<P, Node, N> ReceiptProvider for RpcBlockchainProvider<P, Node, N>
577where
578 P: Provider<N> + Clone + 'static,
579 N: Network,
580 Node: NodeTypes,
581{
582 type Receipt = ReceiptTy<Node>;
583
584 fn receipt(&self, _id: TxNumber) -> ProviderResult<Option<Self::Receipt>> {
585 Err(ProviderError::UnsupportedProvider)
586 }
587
588 fn receipt_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Receipt>> {
589 let receipt_response = self.block_on_async(async {
590 self.provider.get_transaction_receipt(hash).await.map_err(ProviderError::other)
591 })?;
592
593 let Some(receipt_response) = receipt_response else {
594 return Ok(None);
595 };
596
597 let receipt = self.converter.receipt(receipt_response).map_err(ProviderError::other)?;
598 Ok(Some(receipt))
599 }
600
601 fn receipts_by_block(
602 &self,
603 block: BlockHashOrNumber,
604 ) -> ProviderResult<Option<Vec<Self::Receipt>>> {
605 self.block_on_async(async {
606 let receipts_response = self
607 .provider
608 .get_block_receipts(block.into())
609 .await
610 .map_err(ProviderError::other)?;
611
612 let Some(receipts) = receipts_response else {
613 return Ok(None);
614 };
615
616 let receipts = receipts
617 .into_iter()
618 .map(|r| self.converter.receipt(r).map_err(ProviderError::other))
619 .collect::<Result<Vec<_>, _>>()?;
620
621 Ok(Some(receipts))
622 })
623 }
624
625 fn receipts_by_tx_range(
626 &self,
627 _range: impl RangeBounds<TxNumber>,
628 ) -> ProviderResult<Vec<Self::Receipt>> {
629 Err(ProviderError::UnsupportedProvider)
630 }
631
632 fn receipts_by_block_range(
633 &self,
634 _block_range: RangeInclusive<BlockNumber>,
635 ) -> ProviderResult<Vec<Vec<Self::Receipt>>> {
636 Err(ProviderError::UnsupportedProvider)
637 }
638}
639
640impl<P, Node, N> ReceiptProviderIdExt for RpcBlockchainProvider<P, Node, N>
641where
642 P: Provider<N> + Clone + 'static,
643 N: Network,
644 Node: NodeTypes,
645{
646}
647
648impl<P, Node, N> TransactionsProvider for RpcBlockchainProvider<P, Node, N>
649where
650 P: Provider<N> + Clone + 'static,
651 N: Network,
652 Node: NodeTypes,
653{
654 type Transaction = TxTy<Node>;
655
656 fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
657 Err(ProviderError::UnsupportedProvider)
658 }
659
660 fn transaction_by_id(&self, _id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
661 Err(ProviderError::UnsupportedProvider)
662 }
663
664 fn transaction_by_id_unhashed(
665 &self,
666 _id: TxNumber,
667 ) -> ProviderResult<Option<Self::Transaction>> {
668 Err(ProviderError::UnsupportedProvider)
669 }
670
671 fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
672 let transaction_response = self.block_on_async(async {
673 self.provider.get_transaction_by_hash(hash).await.map_err(ProviderError::other)
674 })?;
675
676 let Some(transaction_response) = transaction_response else {
677 return Ok(None);
678 };
679
680 let transaction =
681 self.converter.transaction(transaction_response).map_err(ProviderError::other)?;
682 Ok(Some(transaction))
683 }
684
685 fn transaction_by_hash_with_meta(
686 &self,
687 _hash: TxHash,
688 ) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
689 Err(ProviderError::UnsupportedProvider)
690 }
691
692 fn transactions_by_block(
693 &self,
694 block: BlockHashOrNumber,
695 ) -> ProviderResult<Option<Vec<Self::Transaction>>> {
696 let block_response = self.block_on_async(async {
697 self.provider.get_block(block.into()).full().await.map_err(ProviderError::other)
698 })?;
699
700 let Some(block_response) = block_response else {
701 return Ok(None);
702 };
703
704 let block = self.converter.block(block_response).map_err(ProviderError::other)?;
705 Ok(Some(block.into_body().into_transactions()))
706 }
707
708 fn transactions_by_block_range(
709 &self,
710 _range: impl RangeBounds<BlockNumber>,
711 ) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
712 Err(ProviderError::UnsupportedProvider)
713 }
714
715 fn transactions_by_tx_range(
716 &self,
717 _range: impl RangeBounds<TxNumber>,
718 ) -> ProviderResult<Vec<Self::Transaction>> {
719 Err(ProviderError::UnsupportedProvider)
720 }
721
722 fn senders_by_tx_range(
723 &self,
724 _range: impl RangeBounds<TxNumber>,
725 ) -> ProviderResult<Vec<Address>> {
726 Err(ProviderError::UnsupportedProvider)
727 }
728
729 fn transaction_sender(&self, _id: TxNumber) -> ProviderResult<Option<Address>> {
730 Err(ProviderError::UnsupportedProvider)
731 }
732}
733
734impl<P, Node, N> StateProviderFactory for RpcBlockchainProvider<P, Node, N>
735where
736 P: Provider<N> + Clone + 'static,
737 N: Network,
738 Node: NodeTypes,
739{
740 fn latest(&self) -> Result<StateProviderBox, ProviderError> {
741 Ok(Box::new(self.create_state_provider(self.best_block_number()?.into())))
742 }
743
744 fn state_by_block_id(&self, block_id: BlockId) -> Result<StateProviderBox, ProviderError> {
745 Ok(Box::new(self.create_state_provider(block_id)))
746 }
747
748 fn state_by_block_number_or_tag(
749 &self,
750 number_or_tag: alloy_rpc_types::BlockNumberOrTag,
751 ) -> Result<StateProviderBox, ProviderError> {
752 match number_or_tag {
753 alloy_rpc_types::BlockNumberOrTag::Latest => self.latest(),
754 alloy_rpc_types::BlockNumberOrTag::Pending => self.pending(),
755 alloy_rpc_types::BlockNumberOrTag::Number(num) => self.state_by_block_number(num),
756 _ => Err(ProviderError::UnsupportedProvider),
757 }
758 }
759
760 fn history_by_block_number(
761 &self,
762 block_number: BlockNumber,
763 ) -> Result<StateProviderBox, ProviderError> {
764 self.state_by_block_number(block_number)
765 }
766
767 fn history_by_block_hash(
768 &self,
769 block_hash: BlockHash,
770 ) -> Result<StateProviderBox, ProviderError> {
771 self.state_by_block_hash(block_hash)
772 }
773
774 fn state_by_block_hash(
775 &self,
776 block_hash: BlockHash,
777 ) -> Result<StateProviderBox, ProviderError> {
778 trace!(target: "alloy-provider", ?block_hash, "Getting state provider by block hash");
779
780 let block = self.block_on_async(async {
781 self.provider
782 .get_block_by_hash(block_hash)
783 .await
784 .map_err(ProviderError::other)?
785 .ok_or(ProviderError::BlockHashNotFound(block_hash))
786 })?;
787
788 let block_number = block.header().number();
789 Ok(Box::new(self.create_state_provider(BlockId::number(block_number))))
790 }
791
792 fn pending(&self) -> Result<StateProviderBox, ProviderError> {
793 trace!(target: "alloy-provider", "Getting pending state provider");
794 self.latest()
795 }
796
797 fn pending_state_by_hash(
798 &self,
799 _block_hash: B256,
800 ) -> Result<Option<StateProviderBox>, ProviderError> {
801 Err(ProviderError::UnsupportedProvider)
803 }
804
805 fn maybe_pending(&self) -> Result<Option<StateProviderBox>, ProviderError> {
806 Ok(None)
807 }
808}
809
810impl<P, Node, N> DatabaseProviderFactory for RpcBlockchainProvider<P, Node, N>
811where
812 P: Provider<N> + Clone + 'static,
813 N: Network,
814 Node: NodeTypes,
815{
816 type DB = DatabaseMock;
817 type Provider = RpcBlockchainStateProvider<P, Node, N>;
818 type ProviderRW = RpcBlockchainStateProvider<P, Node, N>;
819
820 fn database_provider_ro(&self) -> Result<Self::Provider, ProviderError> {
821 let block_number = self.block_on_async(async {
823 self.provider.get_block_number().await.map_err(ProviderError::other)
824 })?;
825
826 Ok(self.create_state_provider(BlockId::number(block_number)))
827 }
828
829 fn database_provider_rw(&self) -> Result<Self::ProviderRW, ProviderError> {
830 let block_number = self.block_on_async(async {
832 self.provider.get_block_number().await.map_err(ProviderError::other)
833 })?;
834
835 Ok(self.create_state_provider(BlockId::number(block_number)))
836 }
837}
838
839impl<P, Node, N> CanonChainTracker for RpcBlockchainProvider<P, Node, N>
840where
841 P: Provider<N> + Clone + 'static,
842 N: Network,
843 Node: NodeTypes,
844{
845 type Header = alloy_consensus::Header;
846 fn on_forkchoice_update_received(&self, _update: &ForkchoiceState) {
847 }
849
850 fn last_received_update_timestamp(&self) -> Option<std::time::Instant> {
851 None
852 }
853
854 fn set_canonical_head(&self, _header: SealedHeader<Self::Header>) {
855 }
857
858 fn set_safe(&self, _header: SealedHeader<Self::Header>) {
859 }
861
862 fn set_finalized(&self, _header: SealedHeader<Self::Header>) {
863 }
865}
866
867impl<P, Node, N> NodePrimitivesProvider for RpcBlockchainProvider<P, Node, N>
868where
869 P: Send + Sync,
870 N: Network,
871 Node: NodeTypes,
872{
873 type Primitives = PrimitivesTy<Node>;
874}
875
876impl<P, Node, N> CanonStateSubscriptions for RpcBlockchainProvider<P, Node, N>
877where
878 P: Provider<N> + Clone + 'static,
879 N: Network,
880 Node: NodeTypes,
881{
882 fn subscribe_to_canonical_state(&self) -> CanonStateNotifications<PrimitivesTy<Node>> {
883 trace!(target: "alloy-provider", "Subscribing to canonical state notifications");
884 self.canon_state_notification.subscribe()
885 }
886}
887
888impl<P, Node, N> ChainSpecProvider for RpcBlockchainProvider<P, Node, N>
889where
890 P: Send + Sync,
891 N: Network,
892 Node: NodeTypes,
893 Node::ChainSpec: Default,
894{
895 type ChainSpec = Node::ChainSpec;
896
897 fn chain_spec(&self) -> Arc<Self::ChainSpec> {
898 self.chain_spec.clone()
899 }
900}
901
902pub struct RpcBlockchainStateProvider<P, Node, N = alloy_network::AnyNetwork>
907where
908 Node: NodeTypes,
909{
910 provider: P,
912 block_id: BlockId,
914 node_types: std::marker::PhantomData<Node>,
916 network: std::marker::PhantomData<N>,
918 chain_spec: Option<Arc<Node::ChainSpec>>,
920 compute_state_root: bool,
922 code_store: DashMap<B256, Bytecode>,
926 reth_rpc_support: bool,
928}
929
930impl<P: std::fmt::Debug, Node: NodeTypes, N> std::fmt::Debug
931 for RpcBlockchainStateProvider<P, Node, N>
932{
933 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
934 f.debug_struct("RpcBlockchainStateProvider")
935 .field("provider", &self.provider)
936 .field("block_id", &self.block_id)
937 .finish()
938 }
939}
940
941impl<P: Clone, Node: NodeTypes, N> RpcBlockchainStateProvider<P, Node, N> {
942 pub fn new(
944 provider: P,
945 block_id: BlockId,
946 _primitives: std::marker::PhantomData<Node>,
947 ) -> Self {
948 Self {
949 provider,
950 block_id,
951 node_types: std::marker::PhantomData,
952 network: std::marker::PhantomData,
953 chain_spec: None,
954 compute_state_root: false,
955 code_store: Default::default(),
956 reth_rpc_support: true,
957 }
958 }
959
960 pub fn with_chain_spec(
962 provider: P,
963 block_id: BlockId,
964 chain_spec: Arc<Node::ChainSpec>,
965 ) -> Self {
966 Self {
967 provider,
968 block_id,
969 node_types: std::marker::PhantomData,
970 network: std::marker::PhantomData,
971 chain_spec: Some(chain_spec),
972 compute_state_root: false,
973 code_store: Default::default(),
974 reth_rpc_support: true,
975 }
976 }
977
978 fn block_on_async<F, T>(&self, fut: F) -> T
980 where
981 F: Future<Output = T>,
982 {
983 tokio::task::block_in_place(move || Handle::current().block_on(fut))
984 }
985
986 fn with_block_id(&self, block_id: BlockId) -> Self {
988 Self {
989 provider: self.provider.clone(),
990 block_id,
991 node_types: self.node_types,
992 network: self.network,
993 chain_spec: self.chain_spec.clone(),
994 compute_state_root: self.compute_state_root,
995 code_store: Default::default(),
996 reth_rpc_support: self.reth_rpc_support,
997 }
998 }
999
1000 pub const fn with_compute_state_root(mut self, is_enable: bool) -> Self {
1005 self.compute_state_root = is_enable;
1006 self
1007 }
1008
1009 pub const fn with_reth_rpc_support(mut self, is_enable: bool) -> Self {
1015 self.reth_rpc_support = is_enable;
1016 self
1017 }
1018
1019 fn get_account(&self, address: Address) -> Result<Option<Account>, ProviderError>
1021 where
1022 P: Provider<N> + Clone + 'static,
1023 N: Network,
1024 {
1025 let account_info = self.block_on_async(async {
1026 if self.reth_rpc_support {
1028 return self
1029 .provider
1030 .get_account_info(address)
1031 .block_id(self.block_id)
1032 .await
1033 .map_err(ProviderError::other);
1034 }
1035 let nonce = self.provider.get_transaction_count(address).block_id(self.block_id);
1037 let balance = self.provider.get_balance(address).block_id(self.block_id);
1038 let code = self.provider.get_code_at(address).block_id(self.block_id);
1039
1040 let (nonce, balance, code) = tokio::join!(nonce, balance, code,);
1041
1042 let account_info = AccountInfo {
1043 balance: balance.map_err(ProviderError::other)?,
1044 nonce: nonce.map_err(ProviderError::other)?,
1045 code: code.map_err(ProviderError::other)?,
1046 };
1047
1048 let code_hash = account_info.code_hash();
1049 if code_hash != KECCAK_EMPTY {
1050 self.code_store.insert(code_hash, Bytecode::new_raw(account_info.code.clone()));
1052 }
1053
1054 Ok(account_info)
1055 })?;
1056
1057 if account_info.balance.is_zero() && account_info.nonce == 0 && account_info.code.is_empty()
1059 {
1060 Ok(None)
1061 } else {
1062 let bytecode_hash =
1063 if account_info.code.is_empty() { None } else { Some(account_info.code_hash()) };
1064
1065 Ok(Some(Account {
1066 balance: account_info.balance,
1067 nonce: account_info.nonce,
1068 bytecode_hash,
1069 }))
1070 }
1071 }
1072}
1073
1074impl<P, Node, N> StateProvider for RpcBlockchainStateProvider<P, Node, N>
1075where
1076 P: Provider<N> + Clone + 'static,
1077 N: Network,
1078 Node: NodeTypes,
1079{
1080 fn storage(
1081 &self,
1082 address: Address,
1083 storage_key: StorageKey,
1084 ) -> Result<Option<U256>, ProviderError> {
1085 self.block_on_async(async {
1086 Ok(Some(
1087 self.provider
1088 .get_storage_at(address, storage_key.into())
1089 .block_id(self.block_id)
1090 .await
1091 .map_err(ProviderError::other)?,
1092 ))
1093 })
1094 }
1095
1096 fn account_code(&self, addr: &Address) -> Result<Option<Bytecode>, ProviderError> {
1097 self.block_on_async(async {
1098 let code = self
1099 .provider
1100 .get_code_at(*addr)
1101 .block_id(self.block_id)
1102 .await
1103 .map_err(ProviderError::other)?;
1104
1105 if code.is_empty() {
1106 Ok(None)
1107 } else {
1108 Ok(Some(Bytecode::new_raw(code)))
1109 }
1110 })
1111 }
1112
1113 fn account_balance(&self, addr: &Address) -> Result<Option<U256>, ProviderError> {
1114 self.get_account(*addr).map(|acc| acc.map(|a| a.balance))
1115 }
1116
1117 fn account_nonce(&self, addr: &Address) -> Result<Option<u64>, ProviderError> {
1118 self.get_account(*addr).map(|acc| acc.map(|a| a.nonce))
1119 }
1120}
1121
1122impl<P, Node, N> BytecodeReader for RpcBlockchainStateProvider<P, Node, N>
1123where
1124 P: Provider<N> + Clone + 'static,
1125 N: Network,
1126 Node: NodeTypes,
1127{
1128 fn bytecode_by_hash(&self, code_hash: &B256) -> Result<Option<Bytecode>, ProviderError> {
1129 if !self.reth_rpc_support {
1130 return Ok(self.code_store.get(code_hash).map(|entry| entry.value().clone()));
1131 }
1132
1133 self.block_on_async(async {
1134 let code = self
1136 .provider
1137 .debug_code_by_hash(*code_hash, None)
1138 .await
1139 .map_err(ProviderError::other)?;
1140
1141 let Some(code) = code else {
1142 return Ok(None);
1144 };
1145
1146 Ok(Some(Bytecode::new_raw(code)))
1147 })
1148 }
1149}
1150
1151impl<P, Node, N> AccountReader for RpcBlockchainStateProvider<P, Node, N>
1152where
1153 P: Provider<N> + Clone + 'static,
1154 N: Network,
1155 Node: NodeTypes,
1156{
1157 fn basic_account(&self, address: &Address) -> Result<Option<Account>, ProviderError> {
1158 self.get_account(*address)
1159 }
1160}
1161
1162impl<P, Node, N> StateRootProvider for RpcBlockchainStateProvider<P, Node, N>
1163where
1164 P: Provider<N> + Clone + 'static,
1165 N: Network,
1166 Node: NodeTypes,
1167{
1168 fn state_root(&self, hashed_state: HashedPostState) -> Result<B256, ProviderError> {
1169 self.state_root_with_updates(hashed_state).map(|(root, _)| root)
1170 }
1171
1172 fn state_root_from_nodes(&self, _input: TrieInput) -> Result<B256, ProviderError> {
1173 warn!("state_root_from_nodes is not implemented and will return zero");
1174 Ok(B256::ZERO)
1175 }
1176
1177 fn state_root_with_updates(
1178 &self,
1179 hashed_state: HashedPostState,
1180 ) -> Result<(B256, TrieUpdates), ProviderError> {
1181 if !self.compute_state_root {
1182 return Ok((B256::ZERO, TrieUpdates::default()));
1183 }
1184
1185 self.block_on_async(async {
1186 self.provider
1187 .raw_request::<(HashedPostState, BlockId), (B256, TrieUpdates)>(
1188 "debug_stateRootWithUpdates".into(),
1189 (hashed_state, self.block_id),
1190 )
1191 .into_future()
1192 .await
1193 .map_err(ProviderError::other)
1194 })
1195 }
1196
1197 fn state_root_from_nodes_with_updates(
1198 &self,
1199 _input: TrieInput,
1200 ) -> Result<(B256, TrieUpdates), ProviderError> {
1201 warn!("state_root_from_nodes_with_updates is not implemented and will return zero");
1202 Ok((B256::ZERO, TrieUpdates::default()))
1203 }
1204}
1205
1206impl<P, Node, N> StorageReader for RpcBlockchainStateProvider<P, Node, N>
1207where
1208 P: Provider<N> + Clone + 'static,
1209 N: Network,
1210 Node: NodeTypes,
1211{
1212 fn plain_state_storages(
1213 &self,
1214 addresses_with_keys: impl IntoIterator<Item = (Address, impl IntoIterator<Item = StorageKey>)>,
1215 ) -> Result<Vec<(Address, Vec<reth_primitives_traits::StorageEntry>)>, ProviderError> {
1216 let mut results = Vec::new();
1217
1218 for (address, keys) in addresses_with_keys {
1219 let mut values = Vec::new();
1220 for key in keys {
1221 let value = self.storage(address, key)?.unwrap_or_default();
1222 values.push(reth_primitives_traits::StorageEntry::new(key, value));
1223 }
1224 results.push((address, values));
1225 }
1226
1227 Ok(results)
1228 }
1229
1230 fn changed_storages_with_range(
1231 &self,
1232 _range: RangeInclusive<BlockNumber>,
1233 ) -> Result<BTreeMap<Address, std::collections::BTreeSet<StorageKey>>, ProviderError> {
1234 Ok(BTreeMap::new())
1235 }
1236
1237 fn changed_storages_and_blocks_with_range(
1238 &self,
1239 _range: RangeInclusive<BlockNumber>,
1240 ) -> Result<BTreeMap<(Address, StorageKey), Vec<u64>>, ProviderError> {
1241 Ok(BTreeMap::new())
1242 }
1243}
1244
1245impl<P, Node, N> reth_storage_api::StorageRootProvider for RpcBlockchainStateProvider<P, Node, N>
1246where
1247 P: Provider<N> + Clone + 'static,
1248 N: Network,
1249 Node: NodeTypes,
1250{
1251 fn storage_root(
1252 &self,
1253 _address: Address,
1254 _hashed_storage: reth_trie::HashedStorage,
1255 ) -> Result<B256, ProviderError> {
1256 Err(ProviderError::UnsupportedProvider)
1258 }
1259
1260 fn storage_proof(
1261 &self,
1262 _address: Address,
1263 _slot: B256,
1264 _hashed_storage: reth_trie::HashedStorage,
1265 ) -> Result<reth_trie::StorageProof, ProviderError> {
1266 Err(ProviderError::UnsupportedProvider)
1267 }
1268
1269 fn storage_multiproof(
1270 &self,
1271 _address: Address,
1272 _slots: &[B256],
1273 _hashed_storage: reth_trie::HashedStorage,
1274 ) -> Result<reth_trie::StorageMultiProof, ProviderError> {
1275 Err(ProviderError::UnsupportedProvider)
1276 }
1277}
1278
1279impl<P, Node, N> reth_storage_api::StateProofProvider for RpcBlockchainStateProvider<P, Node, N>
1280where
1281 P: Provider<N> + Clone + 'static,
1282 N: Network,
1283 Node: NodeTypes,
1284{
1285 fn proof(
1286 &self,
1287 _input: TrieInput,
1288 _address: Address,
1289 _slots: &[B256],
1290 ) -> Result<AccountProof, ProviderError> {
1291 Err(ProviderError::UnsupportedProvider)
1292 }
1293
1294 fn multiproof(
1295 &self,
1296 _input: TrieInput,
1297 _targets: reth_trie::MultiProofTargets,
1298 ) -> Result<MultiProof, ProviderError> {
1299 Err(ProviderError::UnsupportedProvider)
1300 }
1301
1302 fn witness(
1303 &self,
1304 _input: TrieInput,
1305 _target: HashedPostState,
1306 ) -> Result<Vec<alloy_primitives::Bytes>, ProviderError> {
1307 Err(ProviderError::UnsupportedProvider)
1308 }
1309}
1310
1311impl<P, Node, N> reth_storage_api::HashedPostStateProvider
1312 for RpcBlockchainStateProvider<P, Node, N>
1313where
1314 P: Provider<N> + Clone + 'static,
1315 N: Network,
1316 Node: NodeTypes,
1317{
1318 fn hashed_post_state(&self, bundle_state: &revm::database::BundleState) -> HashedPostState {
1319 HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
1320 }
1321}
1322
1323impl<P, Node, N> StateReader for RpcBlockchainStateProvider<P, Node, N>
1324where
1325 P: Provider<N> + Clone + 'static,
1326 N: Network,
1327 Node: NodeTypes,
1328{
1329 type Receipt = ReceiptTy<Node>;
1330
1331 fn get_state(
1332 &self,
1333 _block: BlockNumber,
1334 ) -> Result<Option<reth_execution_types::ExecutionOutcome<Self::Receipt>>, ProviderError> {
1335 Err(ProviderError::UnsupportedProvider)
1337 }
1338}
1339
1340impl<P, Node, N> DBProvider for RpcBlockchainStateProvider<P, Node, N>
1341where
1342 P: Provider<N> + Clone + 'static,
1343 N: Network,
1344 Node: NodeTypes,
1345{
1346 type Tx = TxMock;
1347
1348 fn tx_ref(&self) -> &Self::Tx {
1349 unimplemented!("tx_ref not supported for RPC provider")
1352 }
1353
1354 fn tx_mut(&mut self) -> &mut Self::Tx {
1355 unimplemented!("tx_mut not supported for RPC provider")
1356 }
1357
1358 fn into_tx(self) -> Self::Tx {
1359 TxMock::default()
1360 }
1361
1362 fn disable_long_read_transaction_safety(self) -> Self {
1363 self
1365 }
1366
1367 fn commit(self) -> ProviderResult<()> {
1368 unimplemented!("commit not supported for RPC provider")
1369 }
1370
1371 fn prune_modes_ref(&self) -> &reth_prune_types::PruneModes {
1372 unimplemented!("prune modes not supported for RPC provider")
1373 }
1374}
1375
1376impl<P, Node, N> BlockNumReader for RpcBlockchainStateProvider<P, Node, N>
1377where
1378 P: Provider<N> + Clone + 'static,
1379 N: Network,
1380 Node: NodeTypes,
1381{
1382 fn chain_info(&self) -> Result<ChainInfo, ProviderError> {
1383 self.block_on_async(async {
1384 let block = self
1385 .provider
1386 .get_block(self.block_id)
1387 .await
1388 .map_err(ProviderError::other)?
1389 .ok_or(ProviderError::HeaderNotFound(0.into()))?;
1390
1391 Ok(ChainInfo { best_hash: block.header().hash(), best_number: block.header().number() })
1392 })
1393 }
1394
1395 fn best_block_number(&self) -> Result<BlockNumber, ProviderError> {
1396 self.block_on_async(async {
1397 self.provider.get_block_number().await.map_err(ProviderError::other)
1398 })
1399 }
1400
1401 fn last_block_number(&self) -> Result<BlockNumber, ProviderError> {
1402 self.best_block_number()
1403 }
1404
1405 fn block_number(&self, hash: B256) -> Result<Option<BlockNumber>, ProviderError> {
1406 self.block_on_async(async {
1407 let block =
1408 self.provider.get_block_by_hash(hash).await.map_err(ProviderError::other)?;
1409
1410 Ok(block.map(|b| b.header().number()))
1411 })
1412 }
1413}
1414
1415impl<P, Node, N> BlockHashReader for RpcBlockchainStateProvider<P, Node, N>
1416where
1417 P: Provider<N> + Clone + 'static,
1418 N: Network,
1419 Node: NodeTypes,
1420{
1421 fn block_hash(&self, number: u64) -> Result<Option<B256>, ProviderError> {
1422 self.block_on_async(async {
1423 let block = self
1424 .provider
1425 .get_block_by_number(number.into())
1426 .await
1427 .map_err(ProviderError::other)?;
1428
1429 Ok(block.map(|b| b.header().hash()))
1430 })
1431 }
1432
1433 fn canonical_hashes_range(
1434 &self,
1435 _start: BlockNumber,
1436 _end: BlockNumber,
1437 ) -> Result<Vec<B256>, ProviderError> {
1438 Err(ProviderError::UnsupportedProvider)
1439 }
1440}
1441
1442impl<P, Node, N> BlockIdReader for RpcBlockchainStateProvider<P, Node, N>
1443where
1444 P: Provider<N> + Clone + 'static,
1445 N: Network,
1446 Node: NodeTypes,
1447{
1448 fn block_number_for_id(
1449 &self,
1450 _block_id: BlockId,
1451 ) -> Result<Option<BlockNumber>, ProviderError> {
1452 Err(ProviderError::UnsupportedProvider)
1453 }
1454
1455 fn pending_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1456 Err(ProviderError::UnsupportedProvider)
1457 }
1458
1459 fn safe_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1460 Err(ProviderError::UnsupportedProvider)
1461 }
1462
1463 fn finalized_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1464 Err(ProviderError::UnsupportedProvider)
1465 }
1466}
1467
1468impl<P, Node, N> BlockReader for RpcBlockchainStateProvider<P, Node, N>
1469where
1470 P: Provider<N> + Clone + 'static,
1471 N: Network,
1472 Node: NodeTypes,
1473{
1474 type Block = BlockTy<Node>;
1475
1476 fn find_block_by_hash(
1477 &self,
1478 _hash: B256,
1479 _source: reth_provider::BlockSource,
1480 ) -> Result<Option<Self::Block>, ProviderError> {
1481 Err(ProviderError::UnsupportedProvider)
1482 }
1483
1484 fn block(
1485 &self,
1486 _id: alloy_rpc_types::BlockHashOrNumber,
1487 ) -> Result<Option<Self::Block>, ProviderError> {
1488 Err(ProviderError::UnsupportedProvider)
1489 }
1490
1491 fn pending_block(&self) -> Result<Option<RecoveredBlock<Self::Block>>, ProviderError> {
1492 Err(ProviderError::UnsupportedProvider)
1493 }
1494
1495 fn pending_block_and_receipts(
1496 &self,
1497 ) -> Result<Option<(RecoveredBlock<Self::Block>, Vec<Self::Receipt>)>, ProviderError> {
1498 Err(ProviderError::UnsupportedProvider)
1499 }
1500
1501 fn recovered_block(
1502 &self,
1503 _id: alloy_rpc_types::BlockHashOrNumber,
1504 _transaction_kind: TransactionVariant,
1505 ) -> Result<Option<RecoveredBlock<Self::Block>>, ProviderError> {
1506 Err(ProviderError::UnsupportedProvider)
1507 }
1508
1509 fn sealed_block_with_senders(
1510 &self,
1511 _id: alloy_rpc_types::BlockHashOrNumber,
1512 _transaction_kind: TransactionVariant,
1513 ) -> Result<Option<RecoveredBlock<BlockTy<Node>>>, ProviderError> {
1514 Err(ProviderError::UnsupportedProvider)
1515 }
1516
1517 fn block_range(
1518 &self,
1519 _range: RangeInclusive<BlockNumber>,
1520 ) -> Result<Vec<Self::Block>, ProviderError> {
1521 Err(ProviderError::UnsupportedProvider)
1522 }
1523
1524 fn block_with_senders_range(
1525 &self,
1526 _range: RangeInclusive<BlockNumber>,
1527 ) -> Result<Vec<RecoveredBlock<BlockTy<Node>>>, ProviderError> {
1528 Err(ProviderError::UnsupportedProvider)
1529 }
1530
1531 fn recovered_block_range(
1532 &self,
1533 _range: RangeInclusive<BlockNumber>,
1534 ) -> Result<Vec<RecoveredBlock<Self::Block>>, ProviderError> {
1535 Err(ProviderError::UnsupportedProvider)
1536 }
1537
1538 fn block_by_transaction_id(&self, _id: TxNumber) -> ProviderResult<Option<BlockNumber>> {
1539 Err(ProviderError::UnsupportedProvider)
1540 }
1541}
1542
1543impl<P, Node, N> TransactionsProvider for RpcBlockchainStateProvider<P, Node, N>
1544where
1545 P: Provider<N> + Clone + 'static,
1546 N: Network,
1547 Node: NodeTypes,
1548{
1549 type Transaction = TxTy<Node>;
1550
1551 fn transaction_id(&self, _tx_hash: B256) -> Result<Option<TxNumber>, ProviderError> {
1552 Err(ProviderError::UnsupportedProvider)
1553 }
1554
1555 fn transaction_by_id(&self, _id: TxNumber) -> Result<Option<Self::Transaction>, ProviderError> {
1556 Err(ProviderError::UnsupportedProvider)
1557 }
1558
1559 fn transaction_by_id_unhashed(
1560 &self,
1561 _id: TxNumber,
1562 ) -> Result<Option<Self::Transaction>, ProviderError> {
1563 Err(ProviderError::UnsupportedProvider)
1564 }
1565
1566 fn transaction_by_hash(&self, _hash: B256) -> Result<Option<Self::Transaction>, ProviderError> {
1567 Err(ProviderError::UnsupportedProvider)
1568 }
1569
1570 fn transaction_by_hash_with_meta(
1571 &self,
1572 _hash: B256,
1573 ) -> Result<Option<(Self::Transaction, TransactionMeta)>, ProviderError> {
1574 Err(ProviderError::UnsupportedProvider)
1575 }
1576
1577 fn transactions_by_block(
1578 &self,
1579 _block: alloy_rpc_types::BlockHashOrNumber,
1580 ) -> Result<Option<Vec<Self::Transaction>>, ProviderError> {
1581 Err(ProviderError::UnsupportedProvider)
1582 }
1583
1584 fn transactions_by_block_range(
1585 &self,
1586 _range: impl RangeBounds<BlockNumber>,
1587 ) -> Result<Vec<Vec<Self::Transaction>>, ProviderError> {
1588 Err(ProviderError::UnsupportedProvider)
1589 }
1590
1591 fn transactions_by_tx_range(
1592 &self,
1593 _range: impl RangeBounds<TxNumber>,
1594 ) -> Result<Vec<Self::Transaction>, ProviderError> {
1595 Err(ProviderError::UnsupportedProvider)
1596 }
1597
1598 fn senders_by_tx_range(
1599 &self,
1600 _range: impl RangeBounds<TxNumber>,
1601 ) -> Result<Vec<Address>, ProviderError> {
1602 Err(ProviderError::UnsupportedProvider)
1603 }
1604
1605 fn transaction_sender(&self, _id: TxNumber) -> Result<Option<Address>, ProviderError> {
1606 Err(ProviderError::UnsupportedProvider)
1607 }
1608}
1609
1610impl<P, Node, N> ReceiptProvider for RpcBlockchainStateProvider<P, Node, N>
1611where
1612 P: Provider<N> + Clone + 'static,
1613 N: Network,
1614 Node: NodeTypes,
1615{
1616 type Receipt = ReceiptTy<Node>;
1617
1618 fn receipt(&self, _id: TxNumber) -> Result<Option<Self::Receipt>, ProviderError> {
1619 Err(ProviderError::UnsupportedProvider)
1620 }
1621
1622 fn receipt_by_hash(&self, _hash: B256) -> Result<Option<Self::Receipt>, ProviderError> {
1623 Err(ProviderError::UnsupportedProvider)
1624 }
1625
1626 fn receipts_by_block(
1627 &self,
1628 _block: alloy_rpc_types::BlockHashOrNumber,
1629 ) -> Result<Option<Vec<Self::Receipt>>, ProviderError> {
1630 Err(ProviderError::UnsupportedProvider)
1631 }
1632
1633 fn receipts_by_tx_range(
1634 &self,
1635 _range: impl RangeBounds<TxNumber>,
1636 ) -> Result<Vec<Self::Receipt>, ProviderError> {
1637 Err(ProviderError::UnsupportedProvider)
1638 }
1639
1640 fn receipts_by_block_range(
1641 &self,
1642 _range: RangeInclusive<BlockNumber>,
1643 ) -> Result<Vec<Vec<Self::Receipt>>, ProviderError> {
1644 Err(ProviderError::UnsupportedProvider)
1645 }
1646}
1647
1648impl<P, Node, N> HeaderProvider for RpcBlockchainStateProvider<P, Node, N>
1649where
1650 P: Provider<N> + Clone + 'static,
1651 N: Network,
1652 Node: NodeTypes,
1653{
1654 type Header = HeaderTy<Node>;
1655
1656 fn header(&self, _block_hash: BlockHash) -> Result<Option<Self::Header>, ProviderError> {
1657 Err(ProviderError::UnsupportedProvider)
1658 }
1659
1660 fn header_by_number(&self, _num: BlockNumber) -> Result<Option<Self::Header>, ProviderError> {
1661 Err(ProviderError::UnsupportedProvider)
1662 }
1663
1664 fn headers_range(
1665 &self,
1666 _range: impl RangeBounds<BlockNumber>,
1667 ) -> Result<Vec<Self::Header>, ProviderError> {
1668 Err(ProviderError::UnsupportedProvider)
1669 }
1670
1671 fn sealed_header(
1672 &self,
1673 _number: BlockNumber,
1674 ) -> Result<Option<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1675 Err(ProviderError::UnsupportedProvider)
1676 }
1677
1678 fn sealed_headers_range(
1679 &self,
1680 _range: impl RangeBounds<BlockNumber>,
1681 ) -> Result<Vec<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1682 Err(ProviderError::UnsupportedProvider)
1683 }
1684
1685 fn sealed_headers_while(
1686 &self,
1687 _range: impl RangeBounds<BlockNumber>,
1688 _predicate: impl FnMut(&SealedHeader<HeaderTy<Node>>) -> bool,
1689 ) -> Result<Vec<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1690 Err(ProviderError::UnsupportedProvider)
1691 }
1692}
1693
1694impl<P, Node, N> PruneCheckpointReader for RpcBlockchainStateProvider<P, Node, N>
1695where
1696 P: Provider<N> + Clone + 'static,
1697 N: Network,
1698 Node: NodeTypes,
1699{
1700 fn get_prune_checkpoint(
1701 &self,
1702 _segment: PruneSegment,
1703 ) -> Result<Option<PruneCheckpoint>, ProviderError> {
1704 Err(ProviderError::UnsupportedProvider)
1705 }
1706
1707 fn get_prune_checkpoints(&self) -> Result<Vec<(PruneSegment, PruneCheckpoint)>, ProviderError> {
1708 Err(ProviderError::UnsupportedProvider)
1709 }
1710}
1711
1712impl<P, Node, N> StageCheckpointReader for RpcBlockchainStateProvider<P, Node, N>
1713where
1714 P: Provider<N> + Clone + 'static,
1715 N: Network,
1716 Node: NodeTypes,
1717{
1718 fn get_stage_checkpoint(&self, _id: StageId) -> Result<Option<StageCheckpoint>, ProviderError> {
1719 Err(ProviderError::UnsupportedProvider)
1720 }
1721
1722 fn get_stage_checkpoint_progress(
1723 &self,
1724 _id: StageId,
1725 ) -> Result<Option<Vec<u8>>, ProviderError> {
1726 Err(ProviderError::UnsupportedProvider)
1727 }
1728
1729 fn get_all_checkpoints(&self) -> Result<Vec<(String, StageCheckpoint)>, ProviderError> {
1730 Err(ProviderError::UnsupportedProvider)
1731 }
1732}
1733
1734impl<P, Node, N> ChangeSetReader for RpcBlockchainStateProvider<P, Node, N>
1735where
1736 P: Provider<N> + Clone + 'static,
1737 N: Network,
1738 Node: NodeTypes,
1739{
1740 fn account_block_changeset(
1741 &self,
1742 _block_number: BlockNumber,
1743 ) -> Result<Vec<reth_db_api::models::AccountBeforeTx>, ProviderError> {
1744 Err(ProviderError::UnsupportedProvider)
1745 }
1746
1747 fn get_account_before_block(
1748 &self,
1749 _block_number: BlockNumber,
1750 _address: Address,
1751 ) -> ProviderResult<Option<reth_db_api::models::AccountBeforeTx>> {
1752 Err(ProviderError::UnsupportedProvider)
1753 }
1754
1755 fn account_changesets_range(
1756 &self,
1757 _range: impl std::ops::RangeBounds<BlockNumber>,
1758 ) -> ProviderResult<Vec<(BlockNumber, reth_db_api::models::AccountBeforeTx)>> {
1759 Err(ProviderError::UnsupportedProvider)
1760 }
1761
1762 fn account_changeset_count(&self) -> ProviderResult<usize> {
1763 Err(ProviderError::UnsupportedProvider)
1764 }
1765}
1766
1767impl<P, Node, N> StateProviderFactory for RpcBlockchainStateProvider<P, Node, N>
1768where
1769 P: Provider<N> + Clone + 'static + Send + Sync,
1770 Node: NodeTypes + 'static,
1771 Node::ChainSpec: Send + Sync,
1772 N: Network,
1773 Self: Clone + 'static,
1774{
1775 fn latest(&self) -> Result<StateProviderBox, ProviderError> {
1776 Ok(Box::new(self.with_block_id(self.best_block_number()?.into())))
1777 }
1778
1779 fn state_by_block_id(&self, block_id: BlockId) -> Result<StateProviderBox, ProviderError> {
1780 Ok(Box::new(self.with_block_id(block_id)))
1781 }
1782
1783 fn state_by_block_number_or_tag(
1784 &self,
1785 number_or_tag: alloy_rpc_types::BlockNumberOrTag,
1786 ) -> Result<StateProviderBox, ProviderError> {
1787 match number_or_tag {
1788 alloy_rpc_types::BlockNumberOrTag::Latest => self.latest(),
1789 alloy_rpc_types::BlockNumberOrTag::Pending => self.pending(),
1790 alloy_rpc_types::BlockNumberOrTag::Number(num) => self.history_by_block_number(num),
1791 _ => Err(ProviderError::UnsupportedProvider),
1792 }
1793 }
1794
1795 fn history_by_block_number(
1796 &self,
1797 block_number: BlockNumber,
1798 ) -> Result<StateProviderBox, ProviderError> {
1799 Ok(Box::new(Self::new(
1800 self.provider.clone(),
1801 BlockId::number(block_number),
1802 self.node_types,
1803 )))
1804 }
1805
1806 fn history_by_block_hash(
1807 &self,
1808 block_hash: BlockHash,
1809 ) -> Result<StateProviderBox, ProviderError> {
1810 Ok(Box::new(self.with_block_id(BlockId::hash(block_hash))))
1811 }
1812
1813 fn state_by_block_hash(
1814 &self,
1815 block_hash: BlockHash,
1816 ) -> Result<StateProviderBox, ProviderError> {
1817 self.history_by_block_hash(block_hash)
1818 }
1819
1820 fn pending(&self) -> Result<StateProviderBox, ProviderError> {
1821 Ok(Box::new(self.clone()))
1822 }
1823
1824 fn pending_state_by_hash(
1825 &self,
1826 _block_hash: B256,
1827 ) -> Result<Option<StateProviderBox>, ProviderError> {
1828 Err(ProviderError::UnsupportedProvider)
1830 }
1831
1832 fn maybe_pending(&self) -> ProviderResult<Option<StateProviderBox>> {
1833 Ok(None)
1834 }
1835}
1836
1837impl<P, Node, N> ChainSpecProvider for RpcBlockchainStateProvider<P, Node, N>
1838where
1839 P: Send + Sync + std::fmt::Debug,
1840 N: Network,
1841 Node: NodeTypes,
1842 Node::ChainSpec: Default,
1843{
1844 type ChainSpec = Node::ChainSpec;
1845
1846 fn chain_spec(&self) -> Arc<Self::ChainSpec> {
1847 if let Some(chain_spec) = &self.chain_spec {
1848 chain_spec.clone()
1849 } else {
1850 Arc::new(Node::ChainSpec::default())
1852 }
1853 }
1854}
1855
1856impl<P, Node, N> StatsReader for RpcBlockchainStateProvider<P, Node, N>
1860where
1861 P: Provider<N> + Clone + 'static,
1862 N: Network,
1863 Node: NodeTypes,
1864{
1865 fn count_entries<T: reth_db_api::table::Table>(&self) -> Result<usize, ProviderError> {
1866 Ok(0)
1867 }
1868}
1869
1870impl<P, Node, N> BlockBodyIndicesProvider for RpcBlockchainStateProvider<P, Node, N>
1871where
1872 P: Provider<N> + Clone + 'static,
1873 N: Network,
1874 Node: NodeTypes,
1875{
1876 fn block_body_indices(
1877 &self,
1878 _num: u64,
1879 ) -> Result<Option<reth_db_api::models::StoredBlockBodyIndices>, ProviderError> {
1880 Err(ProviderError::UnsupportedProvider)
1881 }
1882
1883 fn block_body_indices_range(
1884 &self,
1885 _range: RangeInclusive<u64>,
1886 ) -> Result<Vec<reth_db_api::models::StoredBlockBodyIndices>, ProviderError> {
1887 Err(ProviderError::UnsupportedProvider)
1888 }
1889}
1890
1891impl<P, Node, N> NodePrimitivesProvider for RpcBlockchainStateProvider<P, Node, N>
1892where
1893 P: Send + Sync + std::fmt::Debug,
1894 N: Network,
1895 Node: NodeTypes,
1896{
1897 type Primitives = PrimitivesTy<Node>;
1898}
1899
1900impl<P, Node, N> ChainStateBlockReader for RpcBlockchainStateProvider<P, Node, N>
1901where
1902 P: Provider<N> + Clone + 'static,
1903 N: Network,
1904 Node: NodeTypes,
1905{
1906 fn last_finalized_block_number(&self) -> Result<Option<BlockNumber>, ProviderError> {
1907 Err(ProviderError::UnsupportedProvider)
1908 }
1909
1910 fn last_safe_block_number(&self) -> Result<Option<BlockNumber>, ProviderError> {
1911 Err(ProviderError::UnsupportedProvider)
1912 }
1913}
1914
1915impl<P, Node, N> ChainStateBlockWriter for RpcBlockchainStateProvider<P, Node, N>
1916where
1917 P: Provider<N> + Clone + 'static,
1918 N: Network,
1919 Node: NodeTypes,
1920{
1921 fn save_finalized_block_number(&self, _block_number: BlockNumber) -> Result<(), ProviderError> {
1922 Err(ProviderError::UnsupportedProvider)
1923 }
1924
1925 fn save_safe_block_number(&self, _block_number: BlockNumber) -> Result<(), ProviderError> {
1926 Err(ProviderError::UnsupportedProvider)
1927 }
1928}