Skip to main content

reth_rpc/eth/helpers/
state.rs

1//! Contains RPC handler implementations specific to state.
2
3use crate::EthApi;
4use reth_rpc_convert::RpcConvert;
5use reth_rpc_eth_api::{
6    helpers::{EthState, LoadPendingBlock, LoadState},
7    RpcNodeCore,
8};
9use reth_rpc_eth_types::EthApiError;
10
11impl<N, Rpc> EthState for EthApi<N, Rpc>
12where
13    N: RpcNodeCore,
14    Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
15    Self: LoadPendingBlock,
16{
17    fn max_proof_window(&self) -> u64 {
18        self.inner.eth_proof_window()
19    }
20}
21
22impl<N, Rpc> LoadState for EthApi<N, Rpc>
23where
24    N: RpcNodeCore,
25    Rpc: RpcConvert<Primitives = N::Primitives>,
26    Self: LoadPendingBlock,
27{
28}
29
30#[cfg(test)]
31mod tests {
32    use crate::eth::helpers::types::EthRpcConverter;
33
34    use super::*;
35    use alloy_primitives::{
36        map::{AddressMap, B256Map},
37        Address, StorageKey, StorageValue, U256,
38    };
39    use reth_chainspec::ChainSpec;
40    use reth_evm_ethereum::EthEvmConfig;
41    use reth_network_api::noop::NoopNetwork;
42    use reth_provider::{
43        test_utils::{ExtendedAccount, MockEthProvider, NoopProvider},
44        ChainSpecProvider,
45    };
46    use reth_rpc_eth_api::{helpers::EthState, node::RpcNodeCoreAdapter};
47    use reth_transaction_pool::test_utils::{testing_pool, TestPool};
48
49    fn noop_eth_api() -> EthApi<
50        RpcNodeCoreAdapter<NoopProvider, TestPool, NoopNetwork, EthEvmConfig>,
51        EthRpcConverter<ChainSpec>,
52    > {
53        let provider = NoopProvider::default();
54        let pool = testing_pool();
55        let evm_config = EthEvmConfig::mainnet();
56
57        EthApi::builder(provider, pool, NoopNetwork::default(), evm_config).build()
58    }
59
60    fn mock_eth_api(
61        accounts: AddressMap<ExtendedAccount>,
62    ) -> EthApi<
63        RpcNodeCoreAdapter<MockEthProvider, TestPool, NoopNetwork, EthEvmConfig>,
64        EthRpcConverter<ChainSpec>,
65    > {
66        let pool = testing_pool();
67        let mock_provider = MockEthProvider::default();
68
69        let evm_config = EthEvmConfig::new(mock_provider.chain_spec());
70        mock_provider.extend_accounts(accounts);
71
72        EthApi::builder(mock_provider, pool, NoopNetwork::default(), evm_config).build()
73    }
74
75    #[tokio::test]
76    async fn test_storage() {
77        // === Noop ===
78        let eth_api = noop_eth_api();
79        let address = Address::random();
80        let storage = eth_api.storage_at(address, U256::ZERO.into(), None).await.unwrap();
81        assert_eq!(storage, U256::ZERO.to_be_bytes());
82
83        // === Mock ===
84        let storage_value = StorageValue::from(1337);
85        let storage_key = StorageKey::random();
86        let storage: B256Map<_> = core::iter::once((storage_key, storage_value)).collect();
87
88        let accounts = AddressMap::from_iter([(
89            address,
90            ExtendedAccount::new(0, U256::ZERO).extend_storage(storage),
91        )]);
92        let eth_api = mock_eth_api(accounts);
93
94        let storage_key: U256 = storage_key.into();
95        let storage = eth_api.storage_at(address, storage_key.into(), None).await.unwrap();
96        assert_eq!(storage, storage_value.to_be_bytes());
97    }
98
99    #[tokio::test]
100    async fn test_get_account_missing() {
101        let eth_api = noop_eth_api();
102        let address = Address::random();
103        let account = eth_api.get_account(address, Default::default()).await.unwrap();
104        assert!(account.is_none());
105    }
106}