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 header_td(&self, hash: BlockHash) -> ProviderResult<Option<U256>> {
368 let header = self.header(hash).map_err(ProviderError::other)?;
369
370 Ok(header.map(|b| b.difficulty()))
371 }
372
373 fn header_td_by_number(&self, number: BlockNumber) -> ProviderResult<Option<U256>> {
374 let header = self.header_by_number(number).map_err(ProviderError::other)?;
375
376 Ok(header.map(|b| b.difficulty()))
377 }
378
379 fn headers_range(
380 &self,
381 _range: impl RangeBounds<BlockNumber>,
382 ) -> ProviderResult<Vec<Self::Header>> {
383 Err(ProviderError::UnsupportedProvider)
384 }
385
386 fn sealed_header(
387 &self,
388 number: BlockNumber,
389 ) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
390 let block_response = self.block_on_async(async {
391 self.provider.get_block_by_number(number.into()).await.map_err(ProviderError::other)
392 })?;
393
394 let Some(block_response) = block_response else {
395 return Ok(None);
397 };
398 let block_hash = block_response.header().hash();
399
400 let block = <BlockTy<Node> as TryFromBlockResponse<N>>::from_block_response(block_response)
402 .map_err(ProviderError::other)?;
403
404 Ok(Some(SealedHeader::new(block.into_header(), block_hash)))
405 }
406
407 fn sealed_headers_while(
408 &self,
409 _range: impl RangeBounds<BlockNumber>,
410 _predicate: impl FnMut(&SealedHeader<Self::Header>) -> bool,
411 ) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
412 Err(ProviderError::UnsupportedProvider)
413 }
414}
415
416impl<P, Node, N> BlockBodyIndicesProvider for RpcBlockchainProvider<P, Node, N>
417where
418 P: Provider<N> + Clone + 'static,
419 N: Network,
420 Node: NodeTypes,
421{
422 fn block_body_indices(&self, _num: u64) -> ProviderResult<Option<StoredBlockBodyIndices>> {
423 Err(ProviderError::UnsupportedProvider)
424 }
425
426 fn block_body_indices_range(
427 &self,
428 _range: RangeInclusive<BlockNumber>,
429 ) -> ProviderResult<Vec<StoredBlockBodyIndices>> {
430 Err(ProviderError::UnsupportedProvider)
431 }
432}
433
434impl<P, Node, N> BlockReader for RpcBlockchainProvider<P, Node, N>
435where
436 P: Provider<N> + Clone + 'static,
437 N: Network,
438 Node: NodeTypes,
439 BlockTy<Node>: TryFromBlockResponse<N>,
440 TxTy<Node>: TryFromTransactionResponse<N>,
441 ReceiptTy<Node>: TryFromReceiptResponse<N>,
442{
443 type Block = BlockTy<Node>;
444
445 fn find_block_by_hash(
446 &self,
447 _hash: B256,
448 _source: BlockSource,
449 ) -> ProviderResult<Option<Self::Block>> {
450 Err(ProviderError::UnsupportedProvider)
451 }
452
453 fn block(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Self::Block>> {
454 let block_response = self.block_on_async(async {
455 self.provider.get_block(id.into()).full().await.map_err(ProviderError::other)
456 })?;
457
458 let Some(block_response) = block_response else {
459 return Ok(None);
461 };
462
463 let block = <BlockTy<Node> as TryFromBlockResponse<N>>::from_block_response(block_response)
465 .map_err(ProviderError::other)?;
466
467 Ok(Some(block))
468 }
469
470 fn pending_block(&self) -> ProviderResult<Option<RecoveredBlock<Self::Block>>> {
471 Err(ProviderError::UnsupportedProvider)
472 }
473
474 fn pending_block_and_receipts(
475 &self,
476 ) -> ProviderResult<Option<(RecoveredBlock<Self::Block>, Vec<Self::Receipt>)>> {
477 Err(ProviderError::UnsupportedProvider)
478 }
479
480 fn recovered_block(
481 &self,
482 _id: BlockHashOrNumber,
483 _transaction_kind: TransactionVariant,
484 ) -> ProviderResult<Option<RecoveredBlock<Self::Block>>> {
485 Err(ProviderError::UnsupportedProvider)
486 }
487
488 fn sealed_block_with_senders(
489 &self,
490 _id: BlockHashOrNumber,
491 _transaction_kind: TransactionVariant,
492 ) -> ProviderResult<Option<RecoveredBlock<Self::Block>>> {
493 Err(ProviderError::UnsupportedProvider)
494 }
495
496 fn block_range(&self, _range: RangeInclusive<BlockNumber>) -> ProviderResult<Vec<Self::Block>> {
497 Err(ProviderError::UnsupportedProvider)
498 }
499
500 fn block_with_senders_range(
501 &self,
502 _range: RangeInclusive<BlockNumber>,
503 ) -> ProviderResult<Vec<RecoveredBlock<Self::Block>>> {
504 Err(ProviderError::UnsupportedProvider)
505 }
506
507 fn recovered_block_range(
508 &self,
509 _range: RangeInclusive<BlockNumber>,
510 ) -> ProviderResult<Vec<RecoveredBlock<Self::Block>>> {
511 Err(ProviderError::UnsupportedProvider)
512 }
513
514 fn block_by_transaction_id(&self, _id: TxNumber) -> ProviderResult<Option<BlockNumber>> {
515 Err(ProviderError::UnsupportedProvider)
516 }
517}
518
519impl<P, Node, N> BlockReaderIdExt for RpcBlockchainProvider<P, Node, N>
520where
521 P: Provider<N> + Clone + 'static,
522 N: Network,
523 Node: NodeTypes,
524 BlockTy<Node>: TryFromBlockResponse<N>,
525 TxTy<Node>: TryFromTransactionResponse<N>,
526 ReceiptTy<Node>: TryFromReceiptResponse<N>,
527{
528 fn block_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Block>> {
529 match id {
530 BlockId::Hash(hash) => self.block_by_hash(hash.block_hash),
531 BlockId::Number(number_or_tag) => self.block_by_number_or_tag(number_or_tag),
532 }
533 }
534
535 fn sealed_header_by_id(
536 &self,
537 id: BlockId,
538 ) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
539 match id {
540 BlockId::Hash(hash) => self.sealed_header_by_hash(hash.block_hash),
541 BlockId::Number(number_or_tag) => self.sealed_header_by_number_or_tag(number_or_tag),
542 }
543 }
544
545 fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Header>> {
546 match id {
547 BlockId::Hash(hash) => self.header_by_hash_or_number(hash.block_hash.into()),
548 BlockId::Number(number_or_tag) => self.header_by_number_or_tag(number_or_tag),
549 }
550 }
551}
552
553impl<P, Node, N> ReceiptProvider for RpcBlockchainProvider<P, Node, N>
554where
555 P: Provider<N> + Clone + 'static,
556 N: Network,
557 Node: NodeTypes,
558 ReceiptTy<Node>: TryFromReceiptResponse<N>,
559{
560 type Receipt = ReceiptTy<Node>;
561
562 fn receipt(&self, _id: TxNumber) -> ProviderResult<Option<Self::Receipt>> {
563 Err(ProviderError::UnsupportedProvider)
564 }
565
566 fn receipt_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Receipt>> {
567 let receipt_response = self.block_on_async(async {
568 self.provider.get_transaction_receipt(hash).await.map_err(ProviderError::other)
569 })?;
570
571 let Some(receipt_response) = receipt_response else {
572 return Ok(None);
574 };
575
576 let receipt =
578 <ReceiptTy<Node> as TryFromReceiptResponse<N>>::from_receipt_response(receipt_response)
579 .map_err(ProviderError::other)?;
580
581 Ok(Some(receipt))
582 }
583
584 fn receipts_by_block(
585 &self,
586 block: BlockHashOrNumber,
587 ) -> ProviderResult<Option<Vec<Self::Receipt>>> {
588 self.block_on_async(async {
589 let receipts_response = self
590 .provider
591 .get_block_receipts(block.into())
592 .await
593 .map_err(ProviderError::other)?;
594
595 let Some(receipts) = receipts_response else {
596 return Ok(None);
598 };
599
600 let receipts = receipts
602 .into_iter()
603 .map(|receipt_response| {
604 <ReceiptTy<Node> as TryFromReceiptResponse<N>>::from_receipt_response(
605 receipt_response,
606 )
607 .map_err(ProviderError::other)
608 })
609 .collect::<Result<Vec<_>, _>>()?;
610
611 Ok(Some(receipts))
612 })
613 }
614
615 fn receipts_by_tx_range(
616 &self,
617 _range: impl RangeBounds<TxNumber>,
618 ) -> ProviderResult<Vec<Self::Receipt>> {
619 Err(ProviderError::UnsupportedProvider)
620 }
621
622 fn receipts_by_block_range(
623 &self,
624 _block_range: RangeInclusive<BlockNumber>,
625 ) -> ProviderResult<Vec<Vec<Self::Receipt>>> {
626 Err(ProviderError::UnsupportedProvider)
627 }
628}
629
630impl<P, Node, N> ReceiptProviderIdExt for RpcBlockchainProvider<P, Node, N>
631where
632 P: Provider<N> + Clone + 'static,
633 N: Network,
634 Node: NodeTypes,
635 ReceiptTy<Node>: TryFromReceiptResponse<N>,
636{
637}
638
639impl<P, Node, N> TransactionsProvider for RpcBlockchainProvider<P, Node, N>
640where
641 P: Provider<N> + Clone + 'static,
642 N: Network,
643 Node: NodeTypes,
644 BlockTy<Node>: TryFromBlockResponse<N>,
645 TxTy<Node>: TryFromTransactionResponse<N>,
646{
647 type Transaction = TxTy<Node>;
648
649 fn transaction_id(&self, _tx_hash: TxHash) -> ProviderResult<Option<TxNumber>> {
650 Err(ProviderError::UnsupportedProvider)
651 }
652
653 fn transaction_by_id(&self, _id: TxNumber) -> ProviderResult<Option<Self::Transaction>> {
654 Err(ProviderError::UnsupportedProvider)
655 }
656
657 fn transaction_by_id_unhashed(
658 &self,
659 _id: TxNumber,
660 ) -> ProviderResult<Option<Self::Transaction>> {
661 Err(ProviderError::UnsupportedProvider)
662 }
663
664 fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult<Option<Self::Transaction>> {
665 let transaction_response = self.block_on_async(async {
666 self.provider.get_transaction_by_hash(hash).await.map_err(ProviderError::other)
667 })?;
668
669 let Some(transaction_response) = transaction_response else {
670 return Ok(None);
672 };
673
674 let transaction = <TxTy<Node> as TryFromTransactionResponse<N>>::from_transaction_response(
676 transaction_response,
677 )
678 .map_err(ProviderError::other)?;
679
680 Ok(Some(transaction))
681 }
682
683 fn transaction_by_hash_with_meta(
684 &self,
685 _hash: TxHash,
686 ) -> ProviderResult<Option<(Self::Transaction, TransactionMeta)>> {
687 Err(ProviderError::UnsupportedProvider)
688 }
689
690 fn transaction_block(&self, _id: TxNumber) -> ProviderResult<Option<BlockNumber>> {
691 Err(ProviderError::UnsupportedProvider)
692 }
693
694 fn transactions_by_block(
695 &self,
696 block: BlockHashOrNumber,
697 ) -> ProviderResult<Option<Vec<Self::Transaction>>> {
698 let block_response = self.block_on_async(async {
699 self.provider.get_block(block.into()).full().await.map_err(ProviderError::other)
700 })?;
701
702 let Some(block_response) = block_response else {
703 return Ok(None);
705 };
706
707 let block = <BlockTy<Node> as TryFromBlockResponse<N>>::from_block_response(block_response)
709 .map_err(ProviderError::other)?;
710
711 Ok(Some(block.into_body().into_transactions()))
712 }
713
714 fn transactions_by_block_range(
715 &self,
716 _range: impl RangeBounds<BlockNumber>,
717 ) -> ProviderResult<Vec<Vec<Self::Transaction>>> {
718 Err(ProviderError::UnsupportedProvider)
719 }
720
721 fn transactions_by_tx_range(
722 &self,
723 _range: impl RangeBounds<TxNumber>,
724 ) -> ProviderResult<Vec<Self::Transaction>> {
725 Err(ProviderError::UnsupportedProvider)
726 }
727
728 fn senders_by_tx_range(
729 &self,
730 _range: impl RangeBounds<TxNumber>,
731 ) -> ProviderResult<Vec<Address>> {
732 Err(ProviderError::UnsupportedProvider)
733 }
734
735 fn transaction_sender(&self, _id: TxNumber) -> ProviderResult<Option<Address>> {
736 Err(ProviderError::UnsupportedProvider)
737 }
738}
739
740impl<P, Node, N> StateProviderFactory for RpcBlockchainProvider<P, Node, N>
741where
742 P: Provider<N> + Clone + 'static,
743 N: Network,
744 Node: NodeTypes,
745{
746 fn latest(&self) -> Result<StateProviderBox, ProviderError> {
747 Ok(Box::new(self.create_state_provider(self.best_block_number()?.into())))
748 }
749
750 fn state_by_block_id(&self, block_id: BlockId) -> Result<StateProviderBox, ProviderError> {
751 Ok(Box::new(self.create_state_provider(block_id)))
752 }
753
754 fn state_by_block_number_or_tag(
755 &self,
756 number_or_tag: alloy_rpc_types::BlockNumberOrTag,
757 ) -> Result<StateProviderBox, ProviderError> {
758 match number_or_tag {
759 alloy_rpc_types::BlockNumberOrTag::Latest => self.latest(),
760 alloy_rpc_types::BlockNumberOrTag::Pending => self.pending(),
761 alloy_rpc_types::BlockNumberOrTag::Number(num) => self.state_by_block_number(num),
762 _ => Err(ProviderError::UnsupportedProvider),
763 }
764 }
765
766 fn history_by_block_number(
767 &self,
768 block_number: BlockNumber,
769 ) -> Result<StateProviderBox, ProviderError> {
770 self.state_by_block_number(block_number)
771 }
772
773 fn history_by_block_hash(
774 &self,
775 block_hash: BlockHash,
776 ) -> Result<StateProviderBox, ProviderError> {
777 self.state_by_block_hash(block_hash)
778 }
779
780 fn state_by_block_hash(
781 &self,
782 block_hash: BlockHash,
783 ) -> Result<StateProviderBox, ProviderError> {
784 trace!(target: "alloy-provider", ?block_hash, "Getting state provider by block hash");
785
786 let block = self.block_on_async(async {
787 self.provider
788 .get_block_by_hash(block_hash)
789 .await
790 .map_err(ProviderError::other)?
791 .ok_or(ProviderError::BlockHashNotFound(block_hash))
792 })?;
793
794 let block_number = block.header().number();
795 Ok(Box::new(self.create_state_provider(BlockId::number(block_number))))
796 }
797
798 fn pending(&self) -> Result<StateProviderBox, ProviderError> {
799 trace!(target: "alloy-provider", "Getting pending state provider");
800 self.latest()
801 }
802
803 fn pending_state_by_hash(
804 &self,
805 _block_hash: B256,
806 ) -> Result<Option<StateProviderBox>, ProviderError> {
807 Err(ProviderError::UnsupportedProvider)
809 }
810
811 fn maybe_pending(&self) -> Result<Option<StateProviderBox>, ProviderError> {
812 Ok(None)
813 }
814}
815
816impl<P, Node, N> DatabaseProviderFactory for RpcBlockchainProvider<P, Node, N>
817where
818 P: Provider<N> + Clone + 'static,
819 N: Network,
820 Node: NodeTypes,
821{
822 type DB = DatabaseMock;
823 type Provider = RpcBlockchainStateProvider<P, Node, N>;
824 type ProviderRW = RpcBlockchainStateProvider<P, Node, N>;
825
826 fn database_provider_ro(&self) -> Result<Self::Provider, ProviderError> {
827 let block_number = self.block_on_async(async {
829 self.provider.get_block_number().await.map_err(ProviderError::other)
830 })?;
831
832 Ok(self.create_state_provider(BlockId::number(block_number)))
833 }
834
835 fn database_provider_rw(&self) -> Result<Self::ProviderRW, ProviderError> {
836 let block_number = self.block_on_async(async {
838 self.provider.get_block_number().await.map_err(ProviderError::other)
839 })?;
840
841 Ok(self.create_state_provider(BlockId::number(block_number)))
842 }
843}
844
845impl<P, Node, N> CanonChainTracker for RpcBlockchainProvider<P, Node, N>
846where
847 P: Provider<N> + Clone + 'static,
848 N: Network,
849 Node: NodeTypes,
850{
851 type Header = alloy_consensus::Header;
852 fn on_forkchoice_update_received(&self, _update: &ForkchoiceState) {
853 }
855
856 fn last_received_update_timestamp(&self) -> Option<std::time::Instant> {
857 None
858 }
859
860 fn set_canonical_head(&self, _header: SealedHeader<Self::Header>) {
861 }
863
864 fn set_safe(&self, _header: SealedHeader<Self::Header>) {
865 }
867
868 fn set_finalized(&self, _header: SealedHeader<Self::Header>) {
869 }
871}
872
873impl<P, Node, N> NodePrimitivesProvider for RpcBlockchainProvider<P, Node, N>
874where
875 P: Send + Sync,
876 N: Send + Sync,
877 Node: NodeTypes,
878{
879 type Primitives = PrimitivesTy<Node>;
880}
881
882impl<P, Node, N> CanonStateSubscriptions for RpcBlockchainProvider<P, Node, N>
883where
884 P: Provider<N> + Clone + 'static,
885 N: Network,
886 Node: NodeTypes,
887{
888 fn subscribe_to_canonical_state(&self) -> CanonStateNotifications<PrimitivesTy<Node>> {
889 trace!(target: "alloy-provider", "Subscribing to canonical state notifications");
890 self.canon_state_notification.subscribe()
891 }
892}
893
894impl<P, Node, N> ChainSpecProvider for RpcBlockchainProvider<P, Node, N>
895where
896 P: Send + Sync,
897 N: Send + Sync,
898 Node: NodeTypes,
899 Node::ChainSpec: Default,
900{
901 type ChainSpec = Node::ChainSpec;
902
903 fn chain_spec(&self) -> Arc<Self::ChainSpec> {
904 self.chain_spec.clone()
905 }
906}
907
908pub struct RpcBlockchainStateProvider<P, Node, N = alloy_network::AnyNetwork>
913where
914 Node: NodeTypes,
915{
916 provider: P,
918 block_id: BlockId,
920 node_types: std::marker::PhantomData<Node>,
922 network: std::marker::PhantomData<N>,
924 chain_spec: Option<Arc<Node::ChainSpec>>,
926 compute_state_root: bool,
928 code_store: RwLock<HashMap<B256, Bytecode>>,
932 reth_rpc_support: bool,
934}
935
936impl<P: std::fmt::Debug, Node: NodeTypes, N> std::fmt::Debug
937 for RpcBlockchainStateProvider<P, Node, N>
938{
939 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
940 f.debug_struct("RpcBlockchainStateProvider")
941 .field("provider", &self.provider)
942 .field("block_id", &self.block_id)
943 .finish()
944 }
945}
946
947impl<P: Clone, Node: NodeTypes, N> RpcBlockchainStateProvider<P, Node, N> {
948 pub fn new(
950 provider: P,
951 block_id: BlockId,
952 _primitives: std::marker::PhantomData<Node>,
953 ) -> Self {
954 Self {
955 provider,
956 block_id,
957 node_types: std::marker::PhantomData,
958 network: std::marker::PhantomData,
959 chain_spec: None,
960 compute_state_root: false,
961 code_store: RwLock::new(HashMap::default()),
962 reth_rpc_support: true,
963 }
964 }
965
966 pub fn with_chain_spec(
968 provider: P,
969 block_id: BlockId,
970 chain_spec: Arc<Node::ChainSpec>,
971 ) -> Self {
972 Self {
973 provider,
974 block_id,
975 node_types: std::marker::PhantomData,
976 network: std::marker::PhantomData,
977 chain_spec: Some(chain_spec),
978 compute_state_root: false,
979 code_store: RwLock::new(HashMap::default()),
980 reth_rpc_support: true,
981 }
982 }
983
984 fn block_on_async<F, T>(&self, fut: F) -> T
986 where
987 F: Future<Output = T>,
988 {
989 tokio::task::block_in_place(move || Handle::current().block_on(fut))
990 }
991
992 fn with_block_id(&self, block_id: BlockId) -> Self {
994 Self {
995 provider: self.provider.clone(),
996 block_id,
997 node_types: self.node_types,
998 network: self.network,
999 chain_spec: self.chain_spec.clone(),
1000 compute_state_root: self.compute_state_root,
1001 code_store: RwLock::new(HashMap::default()),
1002 reth_rpc_support: self.reth_rpc_support,
1003 }
1004 }
1005
1006 pub const fn with_compute_state_root(mut self, is_enable: bool) -> Self {
1011 self.compute_state_root = is_enable;
1012 self
1013 }
1014
1015 pub const fn with_reth_rpc_support(mut self, is_enable: bool) -> Self {
1021 self.reth_rpc_support = is_enable;
1022 self
1023 }
1024
1025 fn get_account(&self, address: Address) -> Result<Option<Account>, ProviderError>
1027 where
1028 P: Provider<N> + Clone + 'static,
1029 N: Network,
1030 {
1031 let account_info = self.block_on_async(async {
1032 if self.reth_rpc_support {
1034 return self
1035 .provider
1036 .get_account_info(address)
1037 .block_id(self.block_id)
1038 .await
1039 .map_err(ProviderError::other);
1040 }
1041 let nonce = self.provider.get_transaction_count(address).block_id(self.block_id);
1043 let balance = self.provider.get_balance(address).block_id(self.block_id);
1044 let code = self.provider.get_code_at(address).block_id(self.block_id);
1045
1046 let (nonce, balance, code) = tokio::join!(nonce, balance, code,);
1047
1048 let account_info = AccountInfo {
1049 balance: balance.map_err(ProviderError::other)?,
1050 nonce: nonce.map_err(ProviderError::other)?,
1051 code: code.map_err(ProviderError::other)?,
1052 };
1053
1054 let code_hash = account_info.code_hash();
1055 if code_hash != KECCAK_EMPTY {
1056 self.code_store
1058 .write()
1059 .insert(code_hash, Bytecode::new_raw(account_info.code.clone()));
1060 }
1061
1062 Ok(account_info)
1063 })?;
1064
1065 if account_info.balance.is_zero() && account_info.nonce == 0 && account_info.code.is_empty()
1067 {
1068 Ok(None)
1069 } else {
1070 let bytecode_hash =
1071 if account_info.code.is_empty() { None } else { Some(account_info.code_hash()) };
1072
1073 Ok(Some(Account {
1074 balance: account_info.balance,
1075 nonce: account_info.nonce,
1076 bytecode_hash,
1077 }))
1078 }
1079 }
1080}
1081
1082impl<P, Node, N> StateProvider for RpcBlockchainStateProvider<P, Node, N>
1083where
1084 P: Provider<N> + Clone + 'static,
1085 N: Network,
1086 Node: NodeTypes,
1087{
1088 fn storage(
1089 &self,
1090 address: Address,
1091 storage_key: StorageKey,
1092 ) -> Result<Option<U256>, ProviderError> {
1093 self.block_on_async(async {
1094 Ok(Some(
1095 self.provider
1096 .get_storage_at(address, storage_key.into())
1097 .block_id(self.block_id)
1098 .await
1099 .map_err(ProviderError::other)?,
1100 ))
1101 })
1102 }
1103
1104 fn account_code(&self, addr: &Address) -> Result<Option<Bytecode>, ProviderError> {
1105 self.block_on_async(async {
1106 let code = self
1107 .provider
1108 .get_code_at(*addr)
1109 .block_id(self.block_id)
1110 .await
1111 .map_err(ProviderError::other)?;
1112
1113 if code.is_empty() {
1114 Ok(None)
1115 } else {
1116 Ok(Some(Bytecode::new_raw(code)))
1117 }
1118 })
1119 }
1120
1121 fn account_balance(&self, addr: &Address) -> Result<Option<U256>, ProviderError> {
1122 self.get_account(*addr).map(|acc| acc.map(|a| a.balance))
1123 }
1124
1125 fn account_nonce(&self, addr: &Address) -> Result<Option<u64>, ProviderError> {
1126 self.get_account(*addr).map(|acc| acc.map(|a| a.nonce))
1127 }
1128}
1129
1130impl<P, Node, N> BytecodeReader for RpcBlockchainStateProvider<P, Node, N>
1131where
1132 P: Provider<N> + Clone + 'static,
1133 N: Network,
1134 Node: NodeTypes,
1135{
1136 fn bytecode_by_hash(&self, code_hash: &B256) -> Result<Option<Bytecode>, ProviderError> {
1137 if !self.reth_rpc_support {
1138 return Ok(self.code_store.read().get(code_hash).cloned());
1139 }
1140
1141 self.block_on_async(async {
1142 let code = self
1144 .provider
1145 .debug_code_by_hash(*code_hash, None)
1146 .await
1147 .map_err(ProviderError::other)?;
1148
1149 let Some(code) = code else {
1150 return Ok(None);
1152 };
1153
1154 Ok(Some(Bytecode::new_raw(code)))
1155 })
1156 }
1157}
1158
1159impl<P, Node, N> AccountReader for RpcBlockchainStateProvider<P, Node, N>
1160where
1161 P: Provider<N> + Clone + 'static,
1162 N: Network,
1163 Node: NodeTypes,
1164{
1165 fn basic_account(&self, address: &Address) -> Result<Option<Account>, ProviderError> {
1166 self.get_account(*address)
1167 }
1168}
1169
1170impl<P, Node, N> StateRootProvider for RpcBlockchainStateProvider<P, Node, N>
1171where
1172 P: Provider<N> + Clone + 'static,
1173 N: Network,
1174 Node: NodeTypes,
1175{
1176 fn state_root(&self, hashed_state: HashedPostState) -> Result<B256, ProviderError> {
1177 self.state_root_from_nodes(TrieInput::from_state(hashed_state))
1178 }
1179
1180 fn state_root_from_nodes(&self, _input: TrieInput) -> Result<B256, ProviderError> {
1181 warn!("state_root_from_nodes is not implemented and will return zero");
1182 Ok(B256::ZERO)
1183 }
1184
1185 fn state_root_with_updates(
1186 &self,
1187 hashed_state: HashedPostState,
1188 ) -> Result<(B256, TrieUpdates), ProviderError> {
1189 if !self.compute_state_root {
1190 return Ok((B256::ZERO, TrieUpdates::default()));
1191 }
1192
1193 self.block_on_async(async {
1194 self.provider
1195 .raw_request::<(HashedPostState, BlockId), (B256, TrieUpdates)>(
1196 "debug_stateRootWithUpdates".into(),
1197 (hashed_state, self.block_id),
1198 )
1199 .into_future()
1200 .await
1201 .map_err(ProviderError::other)
1202 })
1203 }
1204
1205 fn state_root_from_nodes_with_updates(
1206 &self,
1207 _input: TrieInput,
1208 ) -> Result<(B256, TrieUpdates), ProviderError> {
1209 warn!("state_root_from_nodes_with_updates is not implemented and will return zero");
1210 Ok((B256::ZERO, TrieUpdates::default()))
1211 }
1212}
1213
1214impl<P, Node, N> StorageReader for RpcBlockchainStateProvider<P, Node, N>
1215where
1216 P: Provider<N> + Clone + 'static,
1217 N: Network,
1218 Node: NodeTypes,
1219{
1220 fn plain_state_storages(
1221 &self,
1222 addresses_with_keys: impl IntoIterator<Item = (Address, impl IntoIterator<Item = StorageKey>)>,
1223 ) -> Result<Vec<(Address, Vec<reth_primitives::StorageEntry>)>, ProviderError> {
1224 let mut results = Vec::new();
1225
1226 for (address, keys) in addresses_with_keys {
1227 let mut values = Vec::new();
1228 for key in keys {
1229 let value = self.storage(address, key)?.unwrap_or_default();
1230 values.push(reth_primitives::StorageEntry::new(key, value));
1231 }
1232 results.push((address, values));
1233 }
1234
1235 Ok(results)
1236 }
1237
1238 fn changed_storages_with_range(
1239 &self,
1240 _range: RangeInclusive<BlockNumber>,
1241 ) -> Result<BTreeMap<Address, std::collections::BTreeSet<StorageKey>>, ProviderError> {
1242 Ok(BTreeMap::new())
1243 }
1244
1245 fn changed_storages_and_blocks_with_range(
1246 &self,
1247 _range: RangeInclusive<BlockNumber>,
1248 ) -> Result<BTreeMap<(Address, StorageKey), Vec<u64>>, ProviderError> {
1249 Ok(BTreeMap::new())
1250 }
1251}
1252
1253impl<P, Node, N> reth_storage_api::StorageRootProvider for RpcBlockchainStateProvider<P, Node, N>
1254where
1255 P: Provider<N> + Clone + 'static,
1256 N: Network,
1257 Node: NodeTypes,
1258{
1259 fn storage_root(
1260 &self,
1261 _address: Address,
1262 _hashed_storage: reth_trie::HashedStorage,
1263 ) -> Result<B256, ProviderError> {
1264 Err(ProviderError::UnsupportedProvider)
1266 }
1267
1268 fn storage_proof(
1269 &self,
1270 _address: Address,
1271 _slot: B256,
1272 _hashed_storage: reth_trie::HashedStorage,
1273 ) -> Result<reth_trie::StorageProof, ProviderError> {
1274 Err(ProviderError::UnsupportedProvider)
1275 }
1276
1277 fn storage_multiproof(
1278 &self,
1279 _address: Address,
1280 _slots: &[B256],
1281 _hashed_storage: reth_trie::HashedStorage,
1282 ) -> Result<reth_trie::StorageMultiProof, ProviderError> {
1283 Err(ProviderError::UnsupportedProvider)
1284 }
1285}
1286
1287impl<P, Node, N> reth_storage_api::StateProofProvider for RpcBlockchainStateProvider<P, Node, N>
1288where
1289 P: Provider<N> + Clone + 'static,
1290 N: Network,
1291 Node: NodeTypes,
1292{
1293 fn proof(
1294 &self,
1295 _input: TrieInput,
1296 _address: Address,
1297 _slots: &[B256],
1298 ) -> Result<AccountProof, ProviderError> {
1299 Err(ProviderError::UnsupportedProvider)
1300 }
1301
1302 fn multiproof(
1303 &self,
1304 _input: TrieInput,
1305 _targets: reth_trie::MultiProofTargets,
1306 ) -> Result<MultiProof, ProviderError> {
1307 Err(ProviderError::UnsupportedProvider)
1308 }
1309
1310 fn witness(
1311 &self,
1312 _input: TrieInput,
1313 _target: HashedPostState,
1314 ) -> Result<Vec<alloy_primitives::Bytes>, ProviderError> {
1315 Err(ProviderError::UnsupportedProvider)
1316 }
1317}
1318
1319impl<P, Node, N> reth_storage_api::HashedPostStateProvider
1320 for RpcBlockchainStateProvider<P, Node, N>
1321where
1322 P: Provider<N> + Clone + 'static,
1323 N: Network,
1324 Node: NodeTypes,
1325{
1326 fn hashed_post_state(&self, _bundle_state: &revm::database::BundleState) -> HashedPostState {
1327 HashedPostState::default()
1329 }
1330}
1331
1332impl<P, Node, N> StateReader for RpcBlockchainStateProvider<P, Node, N>
1333where
1334 P: Provider<N> + Clone + 'static,
1335 N: Network,
1336 Node: NodeTypes,
1337{
1338 type Receipt = ReceiptTy<Node>;
1339
1340 fn get_state(
1341 &self,
1342 _block: BlockNumber,
1343 ) -> Result<Option<reth_execution_types::ExecutionOutcome<Self::Receipt>>, ProviderError> {
1344 Err(ProviderError::UnsupportedProvider)
1346 }
1347}
1348
1349impl<P, Node, N> DBProvider for RpcBlockchainStateProvider<P, Node, N>
1350where
1351 P: Provider<N> + Clone + 'static,
1352 N: Network,
1353 Node: NodeTypes,
1354{
1355 type Tx = TxMock;
1356
1357 fn tx_ref(&self) -> &Self::Tx {
1358 unimplemented!("tx_ref not supported for RPC provider")
1361 }
1362
1363 fn tx_mut(&mut self) -> &mut Self::Tx {
1364 unimplemented!("tx_mut not supported for RPC provider")
1365 }
1366
1367 fn into_tx(self) -> Self::Tx {
1368 TxMock::default()
1369 }
1370
1371 fn disable_long_read_transaction_safety(self) -> Self {
1372 self
1374 }
1375
1376 fn commit(self) -> ProviderResult<bool> {
1377 unimplemented!("commit not supported for RPC provider")
1378 }
1379
1380 fn prune_modes_ref(&self) -> &reth_prune_types::PruneModes {
1381 unimplemented!("prune modes not supported for RPC provider")
1382 }
1383}
1384
1385impl<P, Node, N> BlockNumReader for RpcBlockchainStateProvider<P, Node, N>
1386where
1387 P: Provider<N> + Clone + 'static,
1388 N: Network,
1389 Node: NodeTypes,
1390{
1391 fn chain_info(&self) -> Result<ChainInfo, ProviderError> {
1392 self.block_on_async(async {
1393 let block = self
1394 .provider
1395 .get_block(self.block_id)
1396 .await
1397 .map_err(ProviderError::other)?
1398 .ok_or(ProviderError::HeaderNotFound(0.into()))?;
1399
1400 Ok(ChainInfo { best_hash: block.header().hash(), best_number: block.header().number() })
1401 })
1402 }
1403
1404 fn best_block_number(&self) -> Result<BlockNumber, ProviderError> {
1405 self.block_on_async(async {
1406 self.provider.get_block_number().await.map_err(ProviderError::other)
1407 })
1408 }
1409
1410 fn last_block_number(&self) -> Result<BlockNumber, ProviderError> {
1411 self.best_block_number()
1412 }
1413
1414 fn block_number(&self, hash: B256) -> Result<Option<BlockNumber>, ProviderError> {
1415 self.block_on_async(async {
1416 let block =
1417 self.provider.get_block_by_hash(hash).await.map_err(ProviderError::other)?;
1418
1419 Ok(block.map(|b| b.header().number()))
1420 })
1421 }
1422}
1423
1424impl<P, Node, N> BlockHashReader for RpcBlockchainStateProvider<P, Node, N>
1425where
1426 P: Provider<N> + Clone + 'static,
1427 N: Network,
1428 Node: NodeTypes,
1429{
1430 fn block_hash(&self, number: u64) -> Result<Option<B256>, ProviderError> {
1431 self.block_on_async(async {
1432 let block = self
1433 .provider
1434 .get_block_by_number(number.into())
1435 .await
1436 .map_err(ProviderError::other)?;
1437
1438 Ok(block.map(|b| b.header().hash()))
1439 })
1440 }
1441
1442 fn canonical_hashes_range(
1443 &self,
1444 _start: BlockNumber,
1445 _end: BlockNumber,
1446 ) -> Result<Vec<B256>, ProviderError> {
1447 Err(ProviderError::UnsupportedProvider)
1448 }
1449}
1450
1451impl<P, Node, N> BlockIdReader for RpcBlockchainStateProvider<P, Node, N>
1452where
1453 P: Provider<N> + Clone + 'static,
1454 N: Network,
1455 Node: NodeTypes,
1456{
1457 fn block_number_for_id(
1458 &self,
1459 _block_id: BlockId,
1460 ) -> Result<Option<BlockNumber>, ProviderError> {
1461 Err(ProviderError::UnsupportedProvider)
1462 }
1463
1464 fn pending_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1465 Err(ProviderError::UnsupportedProvider)
1466 }
1467
1468 fn safe_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1469 Err(ProviderError::UnsupportedProvider)
1470 }
1471
1472 fn finalized_block_num_hash(&self) -> Result<Option<alloy_eips::BlockNumHash>, ProviderError> {
1473 Err(ProviderError::UnsupportedProvider)
1474 }
1475}
1476
1477impl<P, Node, N> BlockReader for RpcBlockchainStateProvider<P, Node, N>
1478where
1479 P: Provider<N> + Clone + 'static,
1480 N: Network,
1481 Node: NodeTypes,
1482{
1483 type Block = BlockTy<Node>;
1484
1485 fn find_block_by_hash(
1486 &self,
1487 _hash: B256,
1488 _source: reth_provider::BlockSource,
1489 ) -> Result<Option<Self::Block>, ProviderError> {
1490 Err(ProviderError::UnsupportedProvider)
1491 }
1492
1493 fn block(
1494 &self,
1495 _id: alloy_rpc_types::BlockHashOrNumber,
1496 ) -> Result<Option<Self::Block>, ProviderError> {
1497 Err(ProviderError::UnsupportedProvider)
1498 }
1499
1500 fn pending_block(&self) -> Result<Option<RecoveredBlock<Self::Block>>, ProviderError> {
1501 Err(ProviderError::UnsupportedProvider)
1502 }
1503
1504 fn pending_block_and_receipts(
1505 &self,
1506 ) -> Result<Option<(RecoveredBlock<Self::Block>, Vec<Self::Receipt>)>, ProviderError> {
1507 Err(ProviderError::UnsupportedProvider)
1508 }
1509
1510 fn recovered_block(
1511 &self,
1512 _id: alloy_rpc_types::BlockHashOrNumber,
1513 _transaction_kind: TransactionVariant,
1514 ) -> Result<Option<RecoveredBlock<Self::Block>>, ProviderError> {
1515 Err(ProviderError::UnsupportedProvider)
1516 }
1517
1518 fn sealed_block_with_senders(
1519 &self,
1520 _id: alloy_rpc_types::BlockHashOrNumber,
1521 _transaction_kind: TransactionVariant,
1522 ) -> Result<Option<RecoveredBlock<BlockTy<Node>>>, ProviderError> {
1523 Err(ProviderError::UnsupportedProvider)
1524 }
1525
1526 fn block_range(
1527 &self,
1528 _range: RangeInclusive<BlockNumber>,
1529 ) -> Result<Vec<Self::Block>, ProviderError> {
1530 Err(ProviderError::UnsupportedProvider)
1531 }
1532
1533 fn block_with_senders_range(
1534 &self,
1535 _range: RangeInclusive<BlockNumber>,
1536 ) -> Result<Vec<RecoveredBlock<BlockTy<Node>>>, ProviderError> {
1537 Err(ProviderError::UnsupportedProvider)
1538 }
1539
1540 fn recovered_block_range(
1541 &self,
1542 _range: RangeInclusive<BlockNumber>,
1543 ) -> Result<Vec<RecoveredBlock<Self::Block>>, ProviderError> {
1544 Err(ProviderError::UnsupportedProvider)
1545 }
1546
1547 fn block_by_transaction_id(&self, _id: TxNumber) -> ProviderResult<Option<BlockNumber>> {
1548 Err(ProviderError::UnsupportedProvider)
1549 }
1550}
1551
1552impl<P, Node, N> TransactionsProvider for RpcBlockchainStateProvider<P, Node, N>
1553where
1554 P: Provider<N> + Clone + 'static,
1555 N: Network,
1556 Node: NodeTypes,
1557{
1558 type Transaction = TxTy<Node>;
1559
1560 fn transaction_id(&self, _tx_hash: B256) -> Result<Option<TxNumber>, ProviderError> {
1561 Err(ProviderError::UnsupportedProvider)
1562 }
1563
1564 fn transaction_by_id(&self, _id: TxNumber) -> Result<Option<Self::Transaction>, ProviderError> {
1565 Err(ProviderError::UnsupportedProvider)
1566 }
1567
1568 fn transaction_by_id_unhashed(
1569 &self,
1570 _id: TxNumber,
1571 ) -> Result<Option<Self::Transaction>, ProviderError> {
1572 Err(ProviderError::UnsupportedProvider)
1573 }
1574
1575 fn transaction_by_hash(&self, _hash: B256) -> Result<Option<Self::Transaction>, ProviderError> {
1576 Err(ProviderError::UnsupportedProvider)
1577 }
1578
1579 fn transaction_by_hash_with_meta(
1580 &self,
1581 _hash: B256,
1582 ) -> Result<Option<(Self::Transaction, TransactionMeta)>, ProviderError> {
1583 Err(ProviderError::UnsupportedProvider)
1584 }
1585
1586 fn transaction_block(&self, _id: TxNumber) -> Result<Option<BlockNumber>, ProviderError> {
1587 Err(ProviderError::UnsupportedProvider)
1588 }
1589
1590 fn transactions_by_block(
1591 &self,
1592 _block: alloy_rpc_types::BlockHashOrNumber,
1593 ) -> Result<Option<Vec<Self::Transaction>>, ProviderError> {
1594 Err(ProviderError::UnsupportedProvider)
1595 }
1596
1597 fn transactions_by_block_range(
1598 &self,
1599 _range: impl RangeBounds<BlockNumber>,
1600 ) -> Result<Vec<Vec<Self::Transaction>>, ProviderError> {
1601 Err(ProviderError::UnsupportedProvider)
1602 }
1603
1604 fn transactions_by_tx_range(
1605 &self,
1606 _range: impl RangeBounds<TxNumber>,
1607 ) -> Result<Vec<Self::Transaction>, ProviderError> {
1608 Err(ProviderError::UnsupportedProvider)
1609 }
1610
1611 fn senders_by_tx_range(
1612 &self,
1613 _range: impl RangeBounds<TxNumber>,
1614 ) -> Result<Vec<Address>, ProviderError> {
1615 Err(ProviderError::UnsupportedProvider)
1616 }
1617
1618 fn transaction_sender(&self, _id: TxNumber) -> Result<Option<Address>, ProviderError> {
1619 Err(ProviderError::UnsupportedProvider)
1620 }
1621}
1622
1623impl<P, Node, N> ReceiptProvider for RpcBlockchainStateProvider<P, Node, N>
1624where
1625 P: Provider<N> + Clone + 'static,
1626 N: Network,
1627 Node: NodeTypes,
1628{
1629 type Receipt = ReceiptTy<Node>;
1630
1631 fn receipt(&self, _id: TxNumber) -> Result<Option<Self::Receipt>, ProviderError> {
1632 Err(ProviderError::UnsupportedProvider)
1633 }
1634
1635 fn receipt_by_hash(&self, _hash: B256) -> Result<Option<Self::Receipt>, ProviderError> {
1636 Err(ProviderError::UnsupportedProvider)
1637 }
1638
1639 fn receipts_by_block(
1640 &self,
1641 _block: alloy_rpc_types::BlockHashOrNumber,
1642 ) -> Result<Option<Vec<Self::Receipt>>, ProviderError> {
1643 Err(ProviderError::UnsupportedProvider)
1644 }
1645
1646 fn receipts_by_tx_range(
1647 &self,
1648 _range: impl RangeBounds<TxNumber>,
1649 ) -> Result<Vec<Self::Receipt>, ProviderError> {
1650 Err(ProviderError::UnsupportedProvider)
1651 }
1652
1653 fn receipts_by_block_range(
1654 &self,
1655 _range: RangeInclusive<BlockNumber>,
1656 ) -> Result<Vec<Vec<Self::Receipt>>, ProviderError> {
1657 Err(ProviderError::UnsupportedProvider)
1658 }
1659}
1660
1661impl<P, Node, N> HeaderProvider for RpcBlockchainStateProvider<P, Node, N>
1662where
1663 P: Provider<N> + Clone + 'static,
1664 N: Network,
1665 Node: NodeTypes,
1666{
1667 type Header = HeaderTy<Node>;
1668
1669 fn header(&self, _block_hash: BlockHash) -> Result<Option<Self::Header>, ProviderError> {
1670 Err(ProviderError::UnsupportedProvider)
1671 }
1672
1673 fn header_by_number(&self, _num: BlockNumber) -> Result<Option<Self::Header>, ProviderError> {
1674 Err(ProviderError::UnsupportedProvider)
1675 }
1676
1677 fn header_td(&self, _hash: BlockHash) -> Result<Option<U256>, ProviderError> {
1678 Err(ProviderError::UnsupportedProvider)
1679 }
1680
1681 fn header_td_by_number(&self, _number: BlockNumber) -> Result<Option<U256>, ProviderError> {
1682 Err(ProviderError::UnsupportedProvider)
1683 }
1684
1685 fn headers_range(
1686 &self,
1687 _range: impl RangeBounds<BlockNumber>,
1688 ) -> Result<Vec<Self::Header>, ProviderError> {
1689 Err(ProviderError::UnsupportedProvider)
1690 }
1691
1692 fn sealed_header(
1693 &self,
1694 _number: BlockNumber,
1695 ) -> Result<Option<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1696 Err(ProviderError::UnsupportedProvider)
1697 }
1698
1699 fn sealed_headers_range(
1700 &self,
1701 _range: impl RangeBounds<BlockNumber>,
1702 ) -> Result<Vec<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1703 Err(ProviderError::UnsupportedProvider)
1704 }
1705
1706 fn sealed_headers_while(
1707 &self,
1708 _range: impl RangeBounds<BlockNumber>,
1709 _predicate: impl FnMut(&SealedHeader<HeaderTy<Node>>) -> bool,
1710 ) -> Result<Vec<SealedHeader<HeaderTy<Node>>>, ProviderError> {
1711 Err(ProviderError::UnsupportedProvider)
1712 }
1713}
1714
1715impl<P, Node, N> PruneCheckpointReader for RpcBlockchainStateProvider<P, Node, N>
1716where
1717 P: Provider<N> + Clone + 'static,
1718 N: Network,
1719 Node: NodeTypes,
1720{
1721 fn get_prune_checkpoint(
1722 &self,
1723 _segment: PruneSegment,
1724 ) -> Result<Option<PruneCheckpoint>, ProviderError> {
1725 Err(ProviderError::UnsupportedProvider)
1726 }
1727
1728 fn get_prune_checkpoints(&self) -> Result<Vec<(PruneSegment, PruneCheckpoint)>, ProviderError> {
1729 Err(ProviderError::UnsupportedProvider)
1730 }
1731}
1732
1733impl<P, Node, N> StageCheckpointReader for RpcBlockchainStateProvider<P, Node, N>
1734where
1735 P: Provider<N> + Clone + 'static,
1736 N: Network,
1737 Node: NodeTypes,
1738{
1739 fn get_stage_checkpoint(&self, _id: StageId) -> Result<Option<StageCheckpoint>, ProviderError> {
1740 Err(ProviderError::UnsupportedProvider)
1741 }
1742
1743 fn get_stage_checkpoint_progress(
1744 &self,
1745 _id: StageId,
1746 ) -> Result<Option<Vec<u8>>, ProviderError> {
1747 Err(ProviderError::UnsupportedProvider)
1748 }
1749
1750 fn get_all_checkpoints(&self) -> Result<Vec<(String, StageCheckpoint)>, ProviderError> {
1751 Err(ProviderError::UnsupportedProvider)
1752 }
1753}
1754
1755impl<P, Node, N> ChangeSetReader for RpcBlockchainStateProvider<P, Node, N>
1756where
1757 P: Provider<N> + Clone + 'static,
1758 N: Network,
1759 Node: NodeTypes,
1760{
1761 fn account_block_changeset(
1762 &self,
1763 _block_number: BlockNumber,
1764 ) -> Result<Vec<reth_db_api::models::AccountBeforeTx>, ProviderError> {
1765 Err(ProviderError::UnsupportedProvider)
1766 }
1767
1768 fn get_account_before_block(
1769 &self,
1770 _block_number: BlockNumber,
1771 _address: Address,
1772 ) -> ProviderResult<Option<reth_db_api::models::AccountBeforeTx>> {
1773 Err(ProviderError::UnsupportedProvider)
1774 }
1775}
1776
1777impl<P, Node, N> StateProviderFactory for RpcBlockchainStateProvider<P, Node, N>
1778where
1779 P: Provider<N> + Clone + 'static + Send + Sync,
1780 Node: NodeTypes + 'static,
1781 Node::ChainSpec: Send + Sync,
1782 N: Network,
1783 Self: Clone + 'static,
1784{
1785 fn latest(&self) -> Result<StateProviderBox, ProviderError> {
1786 Ok(Box::new(self.with_block_id(self.best_block_number()?.into())))
1787 }
1788
1789 fn state_by_block_id(&self, block_id: BlockId) -> Result<StateProviderBox, ProviderError> {
1790 Ok(Box::new(self.with_block_id(block_id)))
1791 }
1792
1793 fn state_by_block_number_or_tag(
1794 &self,
1795 number_or_tag: alloy_rpc_types::BlockNumberOrTag,
1796 ) -> Result<StateProviderBox, ProviderError> {
1797 match number_or_tag {
1798 alloy_rpc_types::BlockNumberOrTag::Latest => self.latest(),
1799 alloy_rpc_types::BlockNumberOrTag::Pending => self.pending(),
1800 alloy_rpc_types::BlockNumberOrTag::Number(num) => self.history_by_block_number(num),
1801 _ => Err(ProviderError::UnsupportedProvider),
1802 }
1803 }
1804
1805 fn history_by_block_number(
1806 &self,
1807 block_number: BlockNumber,
1808 ) -> Result<StateProviderBox, ProviderError> {
1809 Ok(Box::new(Self::new(
1810 self.provider.clone(),
1811 BlockId::number(block_number),
1812 self.node_types,
1813 )))
1814 }
1815
1816 fn history_by_block_hash(
1817 &self,
1818 block_hash: BlockHash,
1819 ) -> Result<StateProviderBox, ProviderError> {
1820 Ok(Box::new(self.with_block_id(BlockId::hash(block_hash))))
1821 }
1822
1823 fn state_by_block_hash(
1824 &self,
1825 block_hash: BlockHash,
1826 ) -> Result<StateProviderBox, ProviderError> {
1827 self.history_by_block_hash(block_hash)
1828 }
1829
1830 fn pending(&self) -> Result<StateProviderBox, ProviderError> {
1831 Ok(Box::new(self.clone()))
1832 }
1833
1834 fn pending_state_by_hash(
1835 &self,
1836 _block_hash: B256,
1837 ) -> Result<Option<StateProviderBox>, ProviderError> {
1838 Err(ProviderError::UnsupportedProvider)
1840 }
1841
1842 fn maybe_pending(&self) -> ProviderResult<Option<StateProviderBox>> {
1843 Ok(None)
1844 }
1845}
1846
1847impl<P, Node, N> ChainSpecProvider for RpcBlockchainStateProvider<P, Node, N>
1848where
1849 P: Send + Sync + std::fmt::Debug,
1850 N: Send + Sync,
1851 Node: NodeTypes,
1852 Node::ChainSpec: Default,
1853{
1854 type ChainSpec = Node::ChainSpec;
1855
1856 fn chain_spec(&self) -> Arc<Self::ChainSpec> {
1857 if let Some(chain_spec) = &self.chain_spec {
1858 chain_spec.clone()
1859 } else {
1860 Arc::new(Node::ChainSpec::default())
1862 }
1863 }
1864}
1865
1866impl<P, Node, N> StatsReader for RpcBlockchainStateProvider<P, Node, N>
1870where
1871 P: Provider<N> + Clone + 'static,
1872 N: Network,
1873 Node: NodeTypes,
1874{
1875 fn count_entries<T: reth_db_api::table::Table>(&self) -> Result<usize, ProviderError> {
1876 Ok(0)
1877 }
1878}
1879
1880impl<P, Node, N> BlockBodyIndicesProvider for RpcBlockchainStateProvider<P, Node, N>
1881where
1882 P: Provider<N> + Clone + 'static,
1883 N: Network,
1884 Node: NodeTypes,
1885{
1886 fn block_body_indices(
1887 &self,
1888 _num: u64,
1889 ) -> Result<Option<reth_db_api::models::StoredBlockBodyIndices>, ProviderError> {
1890 Err(ProviderError::UnsupportedProvider)
1891 }
1892
1893 fn block_body_indices_range(
1894 &self,
1895 _range: RangeInclusive<u64>,
1896 ) -> Result<Vec<reth_db_api::models::StoredBlockBodyIndices>, ProviderError> {
1897 Err(ProviderError::UnsupportedProvider)
1898 }
1899}
1900
1901impl<P, Node, N> NodePrimitivesProvider for RpcBlockchainStateProvider<P, Node, N>
1902where
1903 P: Send + Sync + std::fmt::Debug,
1904 N: Send + Sync,
1905 Node: NodeTypes,
1906{
1907 type Primitives = PrimitivesTy<Node>;
1908}
1909
1910impl<P, Node, N> ChainStateBlockReader for RpcBlockchainStateProvider<P, Node, N>
1911where
1912 P: Provider<N> + Clone + 'static,
1913 N: Network,
1914 Node: NodeTypes,
1915{
1916 fn last_finalized_block_number(&self) -> Result<Option<BlockNumber>, ProviderError> {
1917 Err(ProviderError::UnsupportedProvider)
1918 }
1919
1920 fn last_safe_block_number(&self) -> Result<Option<BlockNumber>, ProviderError> {
1921 Err(ProviderError::UnsupportedProvider)
1922 }
1923}
1924
1925impl<P, Node, N> ChainStateBlockWriter for RpcBlockchainStateProvider<P, Node, N>
1926where
1927 P: Provider<N> + Clone + 'static,
1928 N: Network,
1929 Node: NodeTypes,
1930{
1931 fn save_finalized_block_number(&self, _block_number: BlockNumber) -> Result<(), ProviderError> {
1932 Err(ProviderError::UnsupportedProvider)
1933 }
1934
1935 fn save_safe_block_number(&self, _block_number: BlockNumber) -> Result<(), ProviderError> {
1936 Err(ProviderError::UnsupportedProvider)
1937 }
1938}