alloy_provider/layers/
block_id.rs1use crate::{EthCall, Provider, ProviderLayer, RootProvider, RpcWithBlock};
2use alloy_eips::BlockId;
3use alloy_network::Network;
4use alloy_primitives::{Address, Bytes, StorageKey, StorageValue, U256, U64};
5use alloy_rpc_types_eth::{
6 simulate::{SimulatePayload, SimulatedBlock},
7 AccessListResult, EIP1186AccountProofResponse, StorageValuesRequest, StorageValuesResponse,
8};
9use std::marker::PhantomData;
10
11#[derive(Debug, Clone, Copy)]
26pub struct BlockIdLayer {
27 block_id: BlockId,
28}
29
30impl BlockIdLayer {
31 pub const fn new(block_id: BlockId) -> Self {
33 Self { block_id }
34 }
35}
36
37impl From<BlockId> for BlockIdLayer {
38 fn from(block_id: BlockId) -> Self {
39 Self::new(block_id)
40 }
41}
42
43impl<P, N> ProviderLayer<P, N> for BlockIdLayer
44where
45 P: Provider<N>,
46 N: Network,
47{
48 type Provider = BlockIdProvider<P, N>;
49
50 fn layer(&self, inner: P) -> Self::Provider {
51 BlockIdProvider::new(inner, self.block_id)
52 }
53}
54
55#[derive(Clone, Debug)]
57pub struct BlockIdProvider<P, N = alloy_network::Ethereum> {
58 inner: P,
59 block_id: BlockId,
60 _marker: PhantomData<N>,
61}
62
63impl<P: Provider<N>, N: Network> BlockIdProvider<P, N> {
64 pub const fn new(inner: P, block_id: BlockId) -> Self {
66 Self { inner, block_id, _marker: PhantomData }
67 }
68}
69
70impl<P: Provider<N>, N: Network> Provider<N> for BlockIdProvider<P, N> {
71 #[inline(always)]
72 fn root(&self) -> &RootProvider<N> {
73 self.inner.root()
74 }
75
76 fn call(&self, tx: N::TransactionRequest) -> EthCall<N, Bytes> {
77 EthCall::call(self.weak_client(), tx).block(self.block_id)
78 }
79
80 fn estimate_gas(&self, tx: N::TransactionRequest) -> EthCall<N, U64, u64> {
81 EthCall::gas_estimate(self.weak_client(), tx)
82 .block(self.block_id)
83 .map_resp(crate::utils::convert_u64)
84 }
85
86 fn simulate<'req>(
87 &self,
88 payload: &'req SimulatePayload,
89 ) -> RpcWithBlock<&'req SimulatePayload, Vec<SimulatedBlock<N::BlockResponse>>> {
90 self.inner.simulate(payload).block_id(self.block_id)
91 }
92
93 fn create_access_list<'a>(
94 &self,
95 request: &'a N::TransactionRequest,
96 ) -> RpcWithBlock<&'a N::TransactionRequest, AccessListResult> {
97 self.inner.create_access_list(request).block_id(self.block_id)
98 }
99
100 fn get_account_info(
101 &self,
102 address: Address,
103 ) -> RpcWithBlock<Address, alloy_rpc_types_eth::AccountInfo> {
104 self.inner.get_account_info(address).block_id(self.block_id)
105 }
106
107 fn get_account(&self, address: Address) -> RpcWithBlock<Address, alloy_consensus::TrieAccount> {
108 self.inner.get_account(address).block_id(self.block_id)
109 }
110
111 fn get_balance(&self, address: Address) -> RpcWithBlock<Address, U256, U256> {
112 self.inner.get_balance(address).block_id(self.block_id)
113 }
114
115 fn get_code_at(&self, address: Address) -> RpcWithBlock<Address, Bytes> {
116 self.inner.get_code_at(address).block_id(self.block_id)
117 }
118
119 fn get_proof(
120 &self,
121 address: Address,
122 keys: Vec<StorageKey>,
123 ) -> RpcWithBlock<(Address, Vec<StorageKey>), EIP1186AccountProofResponse> {
124 self.inner.get_proof(address, keys).block_id(self.block_id)
125 }
126
127 fn get_storage_at(
128 &self,
129 address: Address,
130 key: U256,
131 ) -> RpcWithBlock<(Address, U256), StorageValue> {
132 self.inner.get_storage_at(address, key).block_id(self.block_id)
133 }
134
135 fn get_storage_values(
136 &self,
137 requests: StorageValuesRequest,
138 ) -> RpcWithBlock<(StorageValuesRequest,), StorageValuesResponse> {
139 self.inner.get_storage_values(requests).block_id(self.block_id)
140 }
141
142 fn get_transaction_count(
143 &self,
144 address: Address,
145 ) -> RpcWithBlock<Address, U64, u64, fn(U64) -> u64> {
146 self.inner.get_transaction_count(address).block_id(self.block_id)
147 }
148}