seismic_rpc_api/
utils.rs

1//! Utils for testing the seismic rpc api
2
3use alloy_consensus::transaction::ShieldableTransaction;
4use alloy_rpc_types::{BlockTransactions, TransactionRequest};
5use reth_rpc_eth_api::{helpers::FullEthApi, RpcBlock};
6
7/// Override the request for seismic calls
8pub fn seismic_override_call_request(request: &mut TransactionRequest) {
9    // If user calls with the standard (unsigned) eth_call,
10    // then disregard whatever they put in the from field
11    // They will still be able to read public contract functions,
12    // but they will not be able to spoof msg.sender in these calls
13    request.from = None;
14    request.gas_price = None; // preventing InsufficientFunds error
15    request.max_fee_per_gas = None; // preventing InsufficientFunds error
16    request.max_priority_fee_per_gas = None; // preventing InsufficientFunds error
17    request.max_fee_per_blob_gas = None; // preventing InsufficientFunds error
18    request.value = None; // preventing InsufficientFunds error
19}
20
21/// Shield the inputs of all shielded transactions in a block.
22pub fn shield_block_txs<T: FullEthApi>(
23    block_opt: Option<RpcBlock<T::NetworkTypes>>,
24) -> Option<RpcBlock<T::NetworkTypes>> {
25    match block_opt {
26        None => None,
27        Some(mut block) => {
28            match &mut block.transactions {
29                BlockTransactions::Full(txs) => {
30                    for tx in txs.iter_mut() {
31                        tx.shield_input();
32                    }
33                }
34                _ => {}
35            }
36            Some(block)
37        }
38    }
39}
40/// Test utils for the seismic rpc api
41/// copied from reth-rpc-api-builder
42#[cfg(test)]
43pub mod test_utils {
44    use std::{
45        net::{Ipv4Addr, SocketAddr, SocketAddrV4},
46        sync::Arc,
47    };
48
49    use alloy_rpc_types_engine::{ClientCode, ClientVersionV1};
50    use jsonrpsee::Methods;
51    use reth_beacon_consensus::BeaconConsensusEngineHandle;
52    use reth_chainspec::{ChainSpec, MAINNET};
53    use reth_consensus::noop::NoopConsensus;
54    use reth_ethereum_engine_primitives::{EthEngineTypes, EthereumEngineValidator};
55    use reth_evm::execute::BasicBlockExecutorProvider;
56    use reth_evm_ethereum::{execute::EthExecutionStrategyFactory, EthEvmConfig};
57    use reth_network_api::noop::NoopNetwork;
58    use reth_payload_builder::test_utils::spawn_test_payload_service;
59    use reth_provider::{
60        test_utils::{NoopProvider, TestCanonStateSubscriptions},
61        BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory,
62    };
63    use reth_rpc::EthApi;
64    use reth_rpc_builder::{
65        auth::{AuthRpcModule, AuthServerConfig, AuthServerHandle},
66        RpcModuleBuilder, RpcServerConfig, RpcServerHandle, TransportRpcModuleConfig,
67    };
68    use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi};
69    use reth_rpc_eth_types::{
70        EthStateCache, FeeHistoryCache, FeeHistoryCacheConfig, GasCap, GasPriceOracle,
71    };
72    use reth_rpc_layer::JwtSecret;
73    use reth_rpc_server_types::{
74        constants::{DEFAULT_ETH_PROOF_WINDOW, DEFAULT_MAX_SIMULATE_BLOCKS, DEFAULT_PROOF_PERMITS},
75        RpcModuleSelection,
76    };
77    use reth_tasks::{pool::BlockingTaskPool, TokioTaskExecutor};
78    use reth_transaction_pool::{
79        noop::NoopTransactionPool,
80        test_utils::{testing_pool, TestPool, TestPoolBuilder},
81    };
82    use tokio::sync::mpsc::unbounded_channel;
83
84    /// Localhost with port 0 so a free port is used.
85    pub const fn test_address() -> SocketAddr {
86        SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0))
87    }
88
89    /// Launches a new server for the auth module
90    pub async fn launch_auth(secret: JwtSecret) -> AuthServerHandle {
91        let config = AuthServerConfig::builder(secret).socket_addr(test_address()).build();
92        let (tx, _rx) = unbounded_channel();
93        let beacon_engine_handle =
94            BeaconConsensusEngineHandle::<EthEngineTypes>::new(tx, Default::default());
95        let client = ClientVersionV1 {
96            code: ClientCode::RH,
97            name: "Reth".to_string(),
98            version: "v0.2.0-beta.5".to_string(),
99            commit: "defa64b2".to_string(),
100        };
101
102        let engine_api = EngineApi::new(
103            NoopProvider::default(),
104            MAINNET.clone(),
105            beacon_engine_handle,
106            spawn_test_payload_service().into(),
107            NoopTransactionPool::default(),
108            Box::<TokioTaskExecutor>::default(),
109            client,
110            EngineCapabilities::default(),
111            EthereumEngineValidator::new(MAINNET.clone()),
112        );
113        let module = AuthRpcModule::new(engine_api);
114        module.start_server(config).await.unwrap()
115    }
116
117    /// Launches a new server with http only with the given modules
118    pub async fn launch_http(modules: impl Into<Methods>) -> RpcServerHandle {
119        let builder = test_rpc_builder();
120        let mut server = builder.build(
121            TransportRpcModuleConfig::set_http(RpcModuleSelection::Standard),
122            Box::new(EthApi::with_spawner),
123            Arc::new(EthereumEngineValidator::new(MAINNET.clone())),
124        );
125        server.replace_configured(modules).unwrap();
126        RpcServerConfig::http(Default::default())
127            .with_http_address(test_address())
128            .start(&server)
129            .await
130            .unwrap()
131    }
132
133    /// Returns an [`RpcModuleBuilder`] with testing components.
134    pub fn test_rpc_builder() -> RpcModuleBuilder<
135        NoopProvider,
136        TestPool,
137        NoopNetwork,
138        TokioTaskExecutor,
139        TestCanonStateSubscriptions,
140        EthEvmConfig,
141        BasicBlockExecutorProvider<EthExecutionStrategyFactory>,
142        NoopConsensus,
143    > {
144        RpcModuleBuilder::default()
145            .with_provider(NoopProvider::default())
146            .with_pool(TestPoolBuilder::default().into())
147            .with_network(NoopNetwork::default())
148            .with_executor(TokioTaskExecutor::default())
149            .with_events(TestCanonStateSubscriptions::default())
150            .with_evm_config(EthEvmConfig::new(MAINNET.clone()))
151            .with_block_executor(BasicBlockExecutorProvider::new(
152                EthExecutionStrategyFactory::mainnet(),
153            ))
154            .with_consensus(NoopConsensus::default())
155    }
156
157    /// Builds a test eth api
158    pub fn build_test_eth_api<
159        P: BlockReaderIdExt<
160                Block = reth_primitives::Block,
161                Receipt = reth_primitives::Receipt,
162                Header = reth_primitives::Header,
163            > + BlockReader
164            + ChainSpecProvider<ChainSpec = ChainSpec>
165            + EvmEnvProvider
166            + StateProviderFactory
167            + Unpin
168            + Clone
169            + 'static,
170    >(
171        provider: P,
172    ) -> EthApi<P, TestPool, NoopNetwork, EthEvmConfig> {
173        let evm_config = EthEvmConfig::new(provider.chain_spec());
174        let cache = EthStateCache::spawn(provider.clone(), Default::default());
175        let fee_history_cache = FeeHistoryCache::new(FeeHistoryCacheConfig::default());
176
177        EthApi::new(
178            provider.clone(),
179            testing_pool(),
180            NoopNetwork::default(),
181            cache.clone(),
182            GasPriceOracle::new(provider, Default::default(), cache),
183            GasCap::default(),
184            DEFAULT_MAX_SIMULATE_BLOCKS,
185            DEFAULT_ETH_PROOF_WINDOW,
186            BlockingTaskPool::build().expect("failed to build tracing pool"),
187            fee_history_cache,
188            evm_config,
189            DEFAULT_PROOF_PERMITS,
190        )
191    }
192}