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 _mode: reth_trie::ExecutionWitnessMode,
1307 ) -> Result<Vec<alloy_primitives::Bytes>, ProviderError> {
1308 Err(ProviderError::UnsupportedProvider)
1309 }
1310}
1311
1312impl<P, Node, N> reth_storage_api::HashedPostStateProvider
1313 for RpcBlockchainStateProvider<P, Node, N>
1314where
1315 P: Provider<N> + Clone + 'static,
1316 N: Network,
1317 Node: NodeTypes,
1318{
1319 fn hashed_post_state(&self, bundle_state: &revm::database::BundleState) -> HashedPostState {
1320 HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
1321 }
1322}
1323
1324impl<P, Node, N> StateReader for RpcBlockchainStateProvider<P, Node, N>
1325where
1326 P: Provider<N> + Clone + 'static,
1327 N: Network,
1328 Node: NodeTypes,
1329{
1330 type Receipt = ReceiptTy<Node>;
1331
1332 fn get_state(
1333 &self,
1334 _block: BlockNumber,
1335 ) -> Result<Option<reth_execution_types::ExecutionOutcome<Self::Receipt>>, ProviderError> {
1336 Err(ProviderError::UnsupportedProvider)
1338 }
1339}
1340
1341impl<P, Node, N> DBProvider for RpcBlockchainStateProvider<P, Node, N>
1342where
1343 P: Provider<N> + Clone + 'static,
1344 N: Network,
1345 Node: NodeTypes,
1346{
1347 type Tx = TxMock;
1348
1349 fn tx_ref(&self) -> &Self::Tx {
1350 unimplemented!("tx_ref not supported for RPC provider")
1353 }
1354
1355 fn tx_mut(&mut self) -> &mut Self::Tx {
1356 unimplemented!("tx_mut not supported for RPC provider")
1357 }
1358
1359 fn into_tx(self) -> Self::Tx {
1360 TxMock::default()
1361 }
1362
1363 fn disable_long_read_transaction_safety(self) -> Self {
1364 self
1366 }
1367
1368 fn commit(self) -> ProviderResult<()> {
1369 unimplemented!("commit not supported for RPC provider")
1370 }
1371
1372 fn prune_modes_ref(&self) -> &reth_prune_types::PruneModes {
1373 unimplemented!("prune modes not supported for RPC provider")
1374 }
1375}
1376
1377impl<P, Node, N> BlockNumReader for RpcBlockchainStateProvider<P, Node, N>
1378where
1379 P: Provider<N> + Clone + 'static,
1380 N: Network,
1381 Node: NodeTypes,
1382{
1383 fn chain_info(&self) -> Result<ChainInfo, ProviderError> {
1384 self.block_on_async(async {
1385 let block = self
1386 .provider
1387 .get_block(self.block_id)
1388 .await
1389 .map_err(ProviderError::other)?
1390 .ok_or(ProviderError::HeaderNotFound(0.into()))?;
1391
1392 Ok(ChainInfo { best_hash: block.header().hash(), best_number: block.header().number() })
1393 })
1394 }
1395
1396 fn best_block_number(&self) -> Result<BlockNumber, ProviderError> {
1397 self.block_on_async(async {
1398 self.provider.get_block_number().await.map_err(ProviderError::other)
1399 })
1400 }
1401
1402 fn last_block_number(&self) -> Result<BlockNumber, ProviderError> {
1403 self.best_block_number()
1404 }
1405
1406 fn block_number(&self, hash: B256) -> Result<Option<BlockNumber>, ProviderError> {
1407 self.block_on_async(async {
1408 let block =
1409 self.provider.get_block_by_hash(hash).await.map_err(ProviderError::other)?;
1410
1411 Ok(block.map(|b| b.header().number()))
1412 })
1413 }
1414}
1415
1416impl<P, Node, N> BlockHashReader for RpcBlockchainStateProvider<P, Node, N>
1417where
1418 P: Provider<N> + Clone + 'static,
1419 N: Network,
1420 Node: NodeTypes,
1421{
1422 fn block_hash(&self, number: u64) -> Result<Option<B256>, ProviderError> {
1423 self.block_on_async(async {
1424 let block = self
1425 .provider
1426 .get_block_by_number(number.into())
1427 .await
1428 .map_err(ProviderError::other)?;
1429
1430 Ok(block.map(|b| b.header().hash()))
1431 })
1432 }
1433
1434 fn canonical_hashes_range(
1435 &self,
1436 _start: BlockNumber,
1437 _end: BlockNumber,
1438 ) -> Result<Vec<B256>, ProviderError> {
1439 Err(ProviderError::UnsupportedProvider)
1440 }
1441}
1442
1443impl<P, Node, N> BlockIdReader for RpcBlockchainStateProvider<P, Node, N>
1444where
1445 P: Provider<N> + Clone + 'static,
1446 N: Network,
1447 Node: NodeTypes,
1448{
1449 fn block_number_for_id(
1450 &self,
1451 _block_id: BlockId,
1452 ) -> Result<Option<BlockNumber>, ProviderError> {
1453 Err(ProviderError::UnsupportedProvider)
1454 }
1455
1456 fn pending_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1457 Err(ProviderError::UnsupportedProvider)
1458 }
1459
1460 fn safe_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1461 Err(ProviderError::UnsupportedProvider)
1462 }
1463
1464 fn finalized_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1465 Err(ProviderError::UnsupportedProvider)
1466 }
1467}
1468
1469impl<P, Node, N> BlockReader for RpcBlockchainStateProvider<P, Node, N>
1470where
1471 P: Provider<N> + Clone + 'static,
1472 N: Network,
1473 Node: NodeTypes,
1474{
1475 type Block = BlockTy<Node>;
1476
1477 fn find_block_by_hash(
1478 &self,
1479 _hash: B256,
1480 _source: reth_provider::BlockSource,
1481 ) -> Result<Option<Self::Block>, ProviderError> {
1482 Err(ProviderError::UnsupportedProvider)
1483 }
1484
1485 fn block(
1486 &self,
1487 _id: alloy_rpc_types::BlockHashOrNumber,
1488 ) -> Result<Option<Self::Block>, ProviderError> {
1489 Err(ProviderError::UnsupportedProvider)
1490 }
1491
1492 fn pending_block(&self) -> Result<Option<RecoveredBlock<Self::Block>>, ProviderError> {
1493 Err(ProviderError::UnsupportedProvider)
1494 }
1495
1496 fn pending_block_and_receipts(
1497 &self,
1498 ) -> Result<Option<(RecoveredBlock<Self::Block>, Vec<Self::Receipt>)>, ProviderError> {
1499 Err(ProviderError::UnsupportedProvider)
1500 }
1501
1502 fn recovered_block(
1503 &self,
1504 _id: alloy_rpc_types::BlockHashOrNumber,
1505 _transaction_kind: TransactionVariant,
1506 ) -> Result<Option<RecoveredBlock<Self::Block>>, ProviderError> {
1507 Err(ProviderError::UnsupportedProvider)
1508 }
1509
1510 fn sealed_block_with_senders(
1511 &self,
1512 _id: alloy_rpc_types::BlockHashOrNumber,
1513 _transaction_kind: TransactionVariant,
1514 ) -> Result<Option<RecoveredBlock<BlockTy<Node>>>, ProviderError> {
1515 Err(ProviderError::UnsupportedProvider)
1516 }
1517
1518 fn block_range(
1519 &self,
1520 _range: RangeInclusive<BlockNumber>,
1521 ) -> Result<Vec<Self::Block>, ProviderError> {
1522 Err(ProviderError::UnsupportedProvider)
1523 }
1524
1525 fn block_with_senders_range(
1526 &self,
1527 _range: RangeInclusive<BlockNumber>,
1528 ) -> Result<Vec<RecoveredBlock<BlockTy<Node>>>, ProviderError> {
1529 Err(ProviderError::UnsupportedProvider)
1530 }
1531
1532 fn recovered_block_range(
1533 &self,
1534 _range: RangeInclusive<BlockNumber>,
1535 ) -> Result<Vec<RecoveredBlock<Self::Block>>, ProviderError> {
1536 Err(ProviderError::UnsupportedProvider)
1537 }
1538
1539 fn block_by_transaction_id(&self, _id: TxNumber) -> ProviderResult<Option<BlockNumber>> {
1540 Err(ProviderError::UnsupportedProvider)
1541 }
1542}
1543
1544impl<P, Node, N> TransactionsProvider for RpcBlockchainStateProvider<P, Node, N>
1545where
1546 P: Provider<N> + Clone + 'static,
1547 N: Network,
1548 Node: NodeTypes,
1549{
1550 type Transaction = TxTy<Node>;
1551
1552 fn transaction_id(&self, _tx_hash: B256) -> Result<Option<TxNumber>, ProviderError> {
1553 Err(ProviderError::UnsupportedProvider)
1554 }
1555
1556 fn transaction_by_id(&self, _id: TxNumber) -> Result<Option<Self::Transaction>, ProviderError> {
1557 Err(ProviderError::UnsupportedProvider)
1558 }
1559
1560 fn transaction_by_id_unhashed(
1561 &self,
1562 _id: TxNumber,
1563 ) -> Result<Option<Self::Transaction>, ProviderError> {
1564 Err(ProviderError::UnsupportedProvider)
1565 }
1566
1567 fn transaction_by_hash(&self, _hash: B256) -> Result<Option<Self::Transaction>, ProviderError> {
1568 Err(ProviderError::UnsupportedProvider)
1569 }
1570
1571 fn transaction_by_hash_with_meta(
1572 &self,
1573 _hash: B256,
1574 ) -> Result<Option<(Self::Transaction, TransactionMeta)>, ProviderError> {
1575 Err(ProviderError::UnsupportedProvider)
1576 }
1577
1578 fn transactions_by_block(
1579 &self,
1580 _block: alloy_rpc_types::BlockHashOrNumber,
1581 ) -> Result<Option<Vec<Self::Transaction>>, ProviderError> {
1582 Err(ProviderError::UnsupportedProvider)
1583 }
1584
1585 fn transactions_by_block_range(
1586 &self,
1587 _range: impl RangeBounds<BlockNumber>,
1588 ) -> Result<Vec<Vec<Self::Transaction>>, ProviderError> {
1589 Err(ProviderError::UnsupportedProvider)
1590 }
1591
1592 fn transactions_by_tx_range(
1593 &self,
1594 _range: impl RangeBounds<TxNumber>,
1595 ) -> Result<Vec<Self::Transaction>, ProviderError> {
1596 Err(ProviderError::UnsupportedProvider)
1597 }
1598
1599 fn senders_by_tx_range(
1600 &self,
1601 _range: impl RangeBounds<TxNumber>,
1602 ) -> Result<Vec<Address>, ProviderError> {
1603 Err(ProviderError::UnsupportedProvider)
1604 }
1605
1606 fn transaction_sender(&self, _id: TxNumber) -> Result<Option<Address>, ProviderError> {
1607 Err(ProviderError::UnsupportedProvider)
1608 }
1609}
1610
1611impl<P, Node, N> ReceiptProvider for RpcBlockchainStateProvider<P, Node, N>
1612where
1613 P: Provider<N> + Clone + 'static,
1614 N: Network,
1615 Node: NodeTypes,
1616{
1617 type Receipt = ReceiptTy<Node>;
1618
1619 fn receipt(&self, _id: TxNumber) -> Result<Option<Self::Receipt>, ProviderError> {
1620 Err(ProviderError::UnsupportedProvider)
1621 }
1622
1623 fn receipt_by_hash(&self, _hash: B256) -> Result<Option<Self::Receipt>, ProviderError> {
1624 Err(ProviderError::UnsupportedProvider)
1625 }
1626
1627 fn receipts_by_block(
1628 &self,
1629 _block: alloy_rpc_types::BlockHashOrNumber,
1630 ) -> Result<Option<Vec<Self::Receipt>>, ProviderError> {
1631 Err(ProviderError::UnsupportedProvider)
1632 }
1633
1634 fn receipts_by_tx_range(
1635 &self,
1636 _range: impl RangeBounds<TxNumber>,
1637 ) -> Result<Vec<Self::Receipt>, ProviderError> {
1638 Err(ProviderError::UnsupportedProvider)
1639 }
1640
1641 fn receipts_by_block_range(
1642 &self,
1643 _range: RangeInclusive<BlockNumber>,
1644 ) -> Result<Vec<Vec<Self::Receipt>>, ProviderError> {
1645 Err(ProviderError::UnsupportedProvider)
1646 }
1647}
1648
1649impl<P, Node, N> HeaderProvider for RpcBlockchainStateProvider<P, Node, N>
1650where
1651 P: Provider<N> + Clone + 'static,
1652 N: Network,
1653 Node: NodeTypes,
1654{
1655 type Header = HeaderTy<Node>;
1656
1657 fn header(&self, _block_hash: BlockHash) -> Result<Option<Self::Header>, ProviderError> {
1658 Err(ProviderError::UnsupportedProvider)
1659 }
1660
1661 fn header_by_number(&self, _num: BlockNumber) -> Result<Option<Self::Header>, ProviderError> {
1662 Err(ProviderError::UnsupportedProvider)
1663 }
1664
1665 fn headers_range(
1666 &self,
1667 _range: impl RangeBounds<BlockNumber>,
1668 ) -> Result<Vec<Self::Header>, ProviderError> {
1669 Err(ProviderError::UnsupportedProvider)
1670 }
1671
1672 fn sealed_header(
1673 &self,
1674 _number: BlockNumber,
1675 ) -> Result<Option<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1676 Err(ProviderError::UnsupportedProvider)
1677 }
1678
1679 fn sealed_headers_range(
1680 &self,
1681 _range: impl RangeBounds<BlockNumber>,
1682 ) -> Result<Vec<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1683 Err(ProviderError::UnsupportedProvider)
1684 }
1685
1686 fn sealed_headers_while(
1687 &self,
1688 _range: impl RangeBounds<BlockNumber>,
1689 _predicate: impl FnMut(&SealedHeader<HeaderTy<Node>>) -> bool,
1690 ) -> Result<Vec<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1691 Err(ProviderError::UnsupportedProvider)
1692 }
1693}
1694
1695impl<P, Node, N> PruneCheckpointReader for RpcBlockchainStateProvider<P, Node, N>
1696where
1697 P: Provider<N> + Clone + 'static,
1698 N: Network,
1699 Node: NodeTypes,
1700{
1701 fn get_prune_checkpoint(
1702 &self,
1703 _segment: PruneSegment,
1704 ) -> Result<Option<PruneCheckpoint>, ProviderError> {
1705 Err(ProviderError::UnsupportedProvider)
1706 }
1707
1708 fn get_prune_checkpoints(&self) -> Result<Vec<(PruneSegment, PruneCheckpoint)>, ProviderError> {
1709 Err(ProviderError::UnsupportedProvider)
1710 }
1711}
1712
1713impl<P, Node, N> StageCheckpointReader for RpcBlockchainStateProvider<P, Node, N>
1714where
1715 P: Provider<N> + Clone + 'static,
1716 N: Network,
1717 Node: NodeTypes,
1718{
1719 fn get_stage_checkpoint(&self, _id: StageId) -> Result<Option<StageCheckpoint>, ProviderError> {
1720 Err(ProviderError::UnsupportedProvider)
1721 }
1722
1723 fn get_stage_checkpoint_progress(
1724 &self,
1725 _id: StageId,
1726 ) -> Result<Option<Vec<u8>>, ProviderError> {
1727 Err(ProviderError::UnsupportedProvider)
1728 }
1729
1730 fn get_all_checkpoints(&self) -> Result<Vec<(String, StageCheckpoint)>, ProviderError> {
1731 Err(ProviderError::UnsupportedProvider)
1732 }
1733}
1734
1735impl<P, Node, N> ChangeSetReader for RpcBlockchainStateProvider<P, Node, N>
1736where
1737 P: Provider<N> + Clone + 'static,
1738 N: Network,
1739 Node: NodeTypes,
1740{
1741 fn account_block_changeset(
1742 &self,
1743 _block_number: BlockNumber,
1744 ) -> Result<Vec<reth_db_api::models::AccountBeforeTx>, ProviderError> {
1745 Err(ProviderError::UnsupportedProvider)
1746 }
1747
1748 fn get_account_before_block(
1749 &self,
1750 _block_number: BlockNumber,
1751 _address: Address,
1752 ) -> ProviderResult<Option<reth_db_api::models::AccountBeforeTx>> {
1753 Err(ProviderError::UnsupportedProvider)
1754 }
1755
1756 fn account_changesets_range(
1757 &self,
1758 _range: impl std::ops::RangeBounds<BlockNumber>,
1759 ) -> ProviderResult<Vec<(BlockNumber, reth_db_api::models::AccountBeforeTx)>> {
1760 Err(ProviderError::UnsupportedProvider)
1761 }
1762}
1763
1764impl<P, Node, N> StateProviderFactory for RpcBlockchainStateProvider<P, Node, N>
1765where
1766 P: Provider<N> + Clone + 'static + Send + Sync,
1767 Node: NodeTypes + 'static,
1768 Node::ChainSpec: Send + Sync,
1769 N: Network,
1770 Self: Clone + 'static,
1771{
1772 fn latest(&self) -> Result<StateProviderBox, ProviderError> {
1773 Ok(Box::new(self.with_block_id(self.best_block_number()?.into())))
1774 }
1775
1776 fn state_by_block_id(&self, block_id: BlockId) -> Result<StateProviderBox, ProviderError> {
1777 Ok(Box::new(self.with_block_id(block_id)))
1778 }
1779
1780 fn state_by_block_number_or_tag(
1781 &self,
1782 number_or_tag: alloy_rpc_types::BlockNumberOrTag,
1783 ) -> Result<StateProviderBox, ProviderError> {
1784 match number_or_tag {
1785 alloy_rpc_types::BlockNumberOrTag::Latest => self.latest(),
1786 alloy_rpc_types::BlockNumberOrTag::Pending => self.pending(),
1787 alloy_rpc_types::BlockNumberOrTag::Number(num) => self.history_by_block_number(num),
1788 _ => Err(ProviderError::UnsupportedProvider),
1789 }
1790 }
1791
1792 fn history_by_block_number(
1793 &self,
1794 block_number: BlockNumber,
1795 ) -> Result<StateProviderBox, ProviderError> {
1796 Ok(Box::new(Self::new(
1797 self.provider.clone(),
1798 BlockId::number(block_number),
1799 self.node_types,
1800 )))
1801 }
1802
1803 fn history_by_block_hash(
1804 &self,
1805 block_hash: BlockHash,
1806 ) -> Result<StateProviderBox, ProviderError> {
1807 Ok(Box::new(self.with_block_id(BlockId::hash(block_hash))))
1808 }
1809
1810 fn state_by_block_hash(
1811 &self,
1812 block_hash: BlockHash,
1813 ) -> Result<StateProviderBox, ProviderError> {
1814 self.history_by_block_hash(block_hash)
1815 }
1816
1817 fn pending(&self) -> Result<StateProviderBox, ProviderError> {
1818 Ok(Box::new(self.clone()))
1819 }
1820
1821 fn pending_state_by_hash(
1822 &self,
1823 _block_hash: B256,
1824 ) -> Result<Option<StateProviderBox>, ProviderError> {
1825 Err(ProviderError::UnsupportedProvider)
1827 }
1828
1829 fn maybe_pending(&self) -> ProviderResult<Option<StateProviderBox>> {
1830 Ok(None)
1831 }
1832}
1833
1834impl<P, Node, N> ChainSpecProvider for RpcBlockchainStateProvider<P, Node, N>
1835where
1836 P: Send + Sync + std::fmt::Debug,
1837 N: Network,
1838 Node: NodeTypes,
1839 Node::ChainSpec: Default,
1840{
1841 type ChainSpec = Node::ChainSpec;
1842
1843 fn chain_spec(&self) -> Arc<Self::ChainSpec> {
1844 if let Some(chain_spec) = &self.chain_spec {
1845 chain_spec.clone()
1846 } else {
1847 Arc::new(Node::ChainSpec::default())
1849 }
1850 }
1851}
1852
1853impl<P, Node, N> StatsReader for RpcBlockchainStateProvider<P, Node, N>
1857where
1858 P: Provider<N> + Clone + 'static,
1859 N: Network,
1860 Node: NodeTypes,
1861{
1862 fn count_entries<T: reth_db_api::table::Table>(&self) -> Result<usize, ProviderError> {
1863 Ok(0)
1864 }
1865}
1866
1867impl<P, Node, N> BlockBodyIndicesProvider for RpcBlockchainStateProvider<P, Node, N>
1868where
1869 P: Provider<N> + Clone + 'static,
1870 N: Network,
1871 Node: NodeTypes,
1872{
1873 fn block_body_indices(
1874 &self,
1875 _num: u64,
1876 ) -> Result<Option<reth_db_api::models::StoredBlockBodyIndices>, ProviderError> {
1877 Err(ProviderError::UnsupportedProvider)
1878 }
1879
1880 fn block_body_indices_range(
1881 &self,
1882 _range: RangeInclusive<u64>,
1883 ) -> Result<Vec<reth_db_api::models::StoredBlockBodyIndices>, ProviderError> {
1884 Err(ProviderError::UnsupportedProvider)
1885 }
1886}
1887
1888impl<P, Node, N> NodePrimitivesProvider for RpcBlockchainStateProvider<P, Node, N>
1889where
1890 P: Send + Sync + std::fmt::Debug,
1891 N: Network,
1892 Node: NodeTypes,
1893{
1894 type Primitives = PrimitivesTy<Node>;
1895}
1896
1897impl<P, Node, N> ChainStateBlockReader for RpcBlockchainStateProvider<P, Node, N>
1898where
1899 P: Provider<N> + Clone + 'static,
1900 N: Network,
1901 Node: NodeTypes,
1902{
1903 fn last_finalized_block_number(&self) -> Result<Option<BlockNumber>, ProviderError> {
1904 Err(ProviderError::UnsupportedProvider)
1905 }
1906
1907 fn last_safe_block_number(&self) -> Result<Option<BlockNumber>, ProviderError> {
1908 Err(ProviderError::UnsupportedProvider)
1909 }
1910}
1911
1912impl<P, Node, N> ChainStateBlockWriter for RpcBlockchainStateProvider<P, Node, N>
1913where
1914 P: Provider<N> + Clone + 'static,
1915 N: Network,
1916 Node: NodeTypes,
1917{
1918 fn save_finalized_block_number(&self, _block_number: BlockNumber) -> Result<(), ProviderError> {
1919 Err(ProviderError::UnsupportedProvider)
1920 }
1921
1922 fn save_safe_block_number(&self, _block_number: BlockNumber) -> Result<(), ProviderError> {
1923 Err(ProviderError::UnsupportedProvider)
1924 }
1925}