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