reth_e2e_test_utils/
rpc.rs

1use alloy_consensus::TxEnvelope;
2use alloy_eips::{BlockId, BlockNumberOrTag};
3use alloy_network::eip2718::Decodable2718;
4use alloy_primitives::{Address, Bytes, B256};
5use alloy_rpc_types_eth::Account;
6use reth_chainspec::EthereumHardforks;
7use reth_node_api::{FullNodeComponents, NodePrimitives};
8use reth_node_builder::{rpc::RpcRegistry, NodeTypes};
9use reth_provider::BlockReader;
10use reth_rpc_api::DebugApiServer;
11use reth_rpc_eth_api::{
12    helpers::{EthApiSpec, EthState, FullEthApi, TraceExt},
13    EthApiTypes, RpcReceipt,
14};
15
16#[allow(missing_debug_implementations)]
17pub struct RpcTestContext<Node: FullNodeComponents, EthApi: EthApiTypes> {
18    pub inner: RpcRegistry<Node, EthApi>,
19}
20
21impl<Node, EthApi> RpcTestContext<Node, EthApi>
22where
23    Node: FullNodeComponents<
24        Types: NodeTypes<
25            ChainSpec: EthereumHardforks,
26            Primitives: NodePrimitives<
27                Block = reth_primitives::Block,
28                Receipt = reth_primitives::Receipt,
29            >,
30        >,
31    >,
32    EthApi:
33        EthApiSpec<Provider: BlockReader<Block = reth_primitives::Block>> + FullEthApi + TraceExt,
34{
35    /// Injects a raw transaction into the node tx pool via RPC server
36    pub async fn inject_tx(&self, raw_tx: Bytes) -> Result<B256, EthApi::Error> {
37        let eth_api = self.inner.eth_api();
38        eth_api.send_raw_transaction(raw_tx).await
39    }
40
41    /// Retrieves a transaction envelope by its hash
42    pub async fn envelope_by_hash(&self, hash: B256) -> eyre::Result<TxEnvelope> {
43        let tx = self.inner.debug_api().raw_transaction(hash).await?.unwrap();
44        let tx = tx.to_vec();
45        Ok(TxEnvelope::decode_2718(&mut tx.as_ref()).unwrap())
46    }
47
48    /// get transaction receipt
49    pub async fn transaction_receipt(
50        &self,
51        tx_hash: B256,
52    ) -> Result<Option<RpcReceipt<EthApi::NetworkTypes>>, EthApi::Error> {
53        let eth_api = self.inner.eth_api();
54        eth_api.transaction_receipt(tx_hash).await
55    }
56
57    /// get code
58    pub async fn get_code(
59        &self,
60        address: Address,
61        block_number: u64,
62    ) -> Result<Bytes, EthApi::Error> {
63        let eth_api = self.inner.eth_api();
64        EthState::get_code(
65            eth_api,
66            address,
67            Some(BlockId::Number(BlockNumberOrTag::Number(block_number.into()))),
68        )
69        .await
70    }
71
72    pub async fn get_account(
73        &self,
74        address: Address,
75        block_number: u64,
76    ) -> Result<Option<Account>, EthApi::Error> {
77        let eth_api = self.inner.eth_api();
78        EthState::get_account(
79            eth_api,
80            address,
81            BlockId::Number(BlockNumberOrTag::Number(block_number.into())),
82        )
83        .await
84    }
85}