1use blockgen::BlockGeneratorTestApi;
6use cfx_config::Configuration;
7use cfx_rpc_builder::{
8 CfxRpcModule, CfxRpcModuleBuilder, CfxRpcModuleSelection,
9 CfxRpcServerConfig, CfxTransportRpcModuleConfig, CfxTransportRpcModules,
10 RpcModuleBuilder, RpcServerConfig, RpcServerHandle,
11 TransportRpcModuleConfig,
12};
13use cfx_rpc_cfx_api::{
14 CfxDebugRpcServer, CfxRpcServer, DebugRpcServer, PubSubApiServer,
15 TestRpcServer,
16};
17use cfx_rpc_cfx_types::apis::ApiSet;
18use cfx_tasks::TaskExecutor;
19use cfxcore::{
20 block_data_manager::BlockDataManager, consensus::pos_handler::PosVerifier,
21 LightQueryService, Notifications, SharedConsensusGraph,
22 SharedSynchronizationService, SharedTransactionPool,
23};
24use jsonrpsee::RpcModule;
25use log::{info, warn};
26use network::NetworkService;
27use parking_lot::{Condvar, Mutex};
28use std::sync::Arc;
29use txgen::{DirectTransactionGenerator, TransactionGenerator};
30
31pub async fn launch_async_rpc_servers(
33 consensus: SharedConsensusGraph, sync: SharedSynchronizationService,
34 tx_pool: SharedTransactionPool, notifications: Arc<Notifications>,
35 executor: TaskExecutor, conf: &Configuration,
36) -> Result<Option<RpcServerHandle>, String> {
37 let http_config = conf.eth_http_config();
38 let ws_config = conf.eth_ws_config();
39 let apis = conf.raw_conf.public_evm_rpc_apis.clone();
40
41 let (transport_rpc_module_config, server_config) =
42 match (http_config.enabled, ws_config.enabled) {
43 (true, true) => {
44 let transport_rpc_module_config =
45 TransportRpcModuleConfig::set_http(apis.clone())
46 .with_ws(apis.clone());
47
48 let server_config =
49 RpcServerConfig::http(conf.jsonrpsee_server_builder())
50 .with_ws(conf.jsonrpsee_server_builder())
51 .with_cors(http_config.cors.clone())
52 .with_ws_cors(ws_config.cors.clone())
53 .with_http_address(http_config.address)
54 .with_ws_address(ws_config.address);
55 (transport_rpc_module_config, server_config)
56 }
57 (true, false) => {
58 let transport_rpc_module_config =
59 TransportRpcModuleConfig::set_http(apis.clone());
60 let server_config =
61 RpcServerConfig::http(conf.jsonrpsee_server_builder())
62 .with_http_address(http_config.address)
63 .with_cors(http_config.cors.clone());
64 (transport_rpc_module_config, server_config)
65 }
66 (false, true) => {
67 let transport_rpc_module_config =
68 TransportRpcModuleConfig::set_ws(apis.clone());
69 let server_config =
70 RpcServerConfig::ws(conf.jsonrpsee_server_builder())
71 .with_ws_address(ws_config.address)
72 .with_ws_cors(ws_config.cors.clone());
73 (transport_rpc_module_config, server_config)
74 }
75 _ => return Ok(None),
76 };
77
78 info!("Enabled evm async rpc modules: {:?}", apis.into_selection());
79 let rpc_conf = conf.rpc_impl_config();
80 let enable_metrics = rpc_conf.enable_metrics;
81
82 let rpc_module_builder = RpcModuleBuilder::new(
83 rpc_conf,
84 consensus,
85 sync,
86 tx_pool,
87 executor,
88 notifications,
89 );
90
91 let transport_rpc_modules =
92 rpc_module_builder.build(transport_rpc_module_config);
93
94 let throttling_conf_file = conf.raw_conf.throttling_conf.clone();
95 let server_handle = server_config
96 .start(&transport_rpc_modules, throttling_conf_file, enable_metrics)
97 .await
98 .map_err(|e| e.to_string())?;
99
100 Ok(Some(server_handle))
101}
102
103pub async fn launch_cfx_async_rpc_servers(
105 consensus: SharedConsensusGraph, sync: SharedSynchronizationService,
106 tx_pool: SharedTransactionPool, data_man: Arc<BlockDataManager>,
107 network: Arc<NetworkService>, pos_handler: Arc<PosVerifier>,
108 notifications: Arc<Notifications>, executor: TaskExecutor,
109 accounts: Arc<cfxcore_accounts::AccountProvider>,
110 exit: Arc<(parking_lot::Mutex<bool>, parking_lot::Condvar)>,
111 block_gen: BlockGeneratorTestApi,
112 maybe_txgen: Option<Arc<TransactionGenerator>>,
113 maybe_direct_txgen: Option<Arc<Mutex<DirectTransactionGenerator>>>,
114 conf: &Configuration, apis: ApiSet, is_debug: bool,
115) -> Result<Option<RpcServerHandle>, String> {
116 let (http_config, ws_config) = if !is_debug {
117 (conf.http_config(), conf.ws_config())
118 } else {
119 (conf.local_http_config(), conf.local_ws_config())
120 };
121
122 let (transport_rpc_module_config, server_config) =
123 match (http_config.enabled, ws_config.enabled) {
124 (true, true) => {
125 let transport_rpc_module_config =
126 CfxTransportRpcModuleConfig::set_http(apis.clone())
127 .with_ws(apis.clone());
128
129 let server_config =
130 CfxRpcServerConfig::http(conf.jsonrpsee_server_builder())
131 .with_ws(conf.jsonrpsee_server_builder())
132 .with_cors(http_config.cors.clone())
133 .with_ws_cors(ws_config.cors.clone())
134 .with_http_address(http_config.address)
135 .with_ws_address(ws_config.address);
136 (transport_rpc_module_config, server_config)
137 }
138 (true, false) => {
139 let transport_rpc_module_config =
140 CfxTransportRpcModuleConfig::set_http(apis.clone());
141 let server_config =
142 CfxRpcServerConfig::http(conf.jsonrpsee_server_builder())
143 .with_http_address(http_config.address)
144 .with_cors(http_config.cors.clone());
145 (transport_rpc_module_config, server_config)
146 }
147 (false, true) => {
148 let transport_rpc_module_config =
149 CfxTransportRpcModuleConfig::set_ws(apis.clone());
150 let server_config =
151 CfxRpcServerConfig::ws(conf.jsonrpsee_server_builder())
152 .with_ws_address(ws_config.address)
153 .with_ws_cors(ws_config.cors.clone());
154 (transport_rpc_module_config, server_config)
155 }
156 _ => return Ok(None),
157 };
158
159 info!(
160 "Enabled cfx async rpc modules: {:?}",
161 CfxRpcModuleSelection::from(apis).into_selection()
162 );
163
164 let rpc_conf = conf.rpc_impl_config();
165 let enable_metrics = rpc_conf.enable_metrics;
166 let rpc_module_builder = CfxRpcModuleBuilder::new(
167 rpc_conf,
168 consensus,
169 sync,
170 tx_pool,
171 executor,
172 data_man,
173 network,
174 pos_handler,
175 notifications,
176 accounts,
177 exit,
178 block_gen,
179 maybe_txgen,
180 maybe_direct_txgen,
181 );
182
183 let transport_rpc_modules =
184 rpc_module_builder.build(transport_rpc_module_config);
185
186 let throttling_conf_file = conf.raw_conf.throttling_conf.clone();
187 let throttling_section = if is_debug { "rpc_local" } else { "rpc" };
188
189 let server_handle = server_config
190 .start(
191 &transport_rpc_modules,
192 throttling_conf_file,
193 throttling_section,
194 enable_metrics,
195 )
196 .await
197 .map_err(|e| e.to_string())?;
198
199 Ok(Some(server_handle))
200}
201
202pub async fn launch_cfx_light_async_rpc_servers(
204 consensus: SharedConsensusGraph, tx_pool: SharedTransactionPool,
205 data_man: Arc<BlockDataManager>, network: Arc<NetworkService>,
206 pos_handler: Arc<PosVerifier>,
207 accounts: Arc<cfxcore_accounts::AccountProvider>,
208 light: Arc<LightQueryService>, exit: Arc<(Mutex<bool>, Condvar)>,
209 executor: TaskExecutor, notifications: Arc<Notifications>,
210 conf: &Configuration, apis: ApiSet, is_debug: bool,
211) -> Result<Option<RpcServerHandle>, String> {
212 use cfx_rpc_cfx_impl::{
213 common::CommonRpcImpl,
214 light::{
215 LightCfxHandler, LightDebugHandler, LightTestHandler,
216 RpcImpl as LightRpcImpl,
217 },
218 PubSubHandler,
219 };
220
221 let (http_config, ws_config) = if is_debug {
222 (conf.local_http_config(), conf.local_ws_config())
223 } else {
224 (conf.http_config(), conf.ws_config())
225 };
226 let apis = CfxRpcModuleSelection::from(apis);
227
228 let server_config = match (http_config.enabled, ws_config.enabled) {
229 (true, true) => {
230 CfxRpcServerConfig::http(conf.jsonrpsee_server_builder())
231 .with_ws(conf.jsonrpsee_server_builder())
232 .with_cors(http_config.cors.clone())
233 .with_ws_cors(ws_config.cors.clone())
234 .with_http_address(http_config.address)
235 .with_ws_address(ws_config.address)
236 }
237 (true, false) => {
238 CfxRpcServerConfig::http(conf.jsonrpsee_server_builder())
239 .with_cors(http_config.cors.clone())
240 .with_http_address(http_config.address)
241 }
242 (false, true) => {
243 CfxRpcServerConfig::ws(conf.jsonrpsee_server_builder())
244 .with_ws_cors(ws_config.cors.clone())
245 .with_ws_address(ws_config.address)
246 }
247 _ => return Ok(None),
248 };
249
250 let common_rpc_impl = Arc::new(CommonRpcImpl::new(
251 exit,
252 consensus.clone(),
253 network.clone(),
254 tx_pool,
255 accounts.clone(),
256 pos_handler.clone(),
257 ));
258
259 let light_rpc_impl = Arc::new(LightRpcImpl::new(
260 light,
261 accounts,
262 consensus.clone(),
263 data_man,
264 ));
265
266 let mut module = RpcModule::new(());
267
268 for api in apis.iter_selection() {
269 match api {
270 CfxRpcModule::Cfx => {
271 let handler = LightCfxHandler::new(
272 light_rpc_impl.clone(),
273 common_rpc_impl.clone(),
274 );
275 module
276 .merge(CfxRpcServer::into_rpc(handler))
277 .expect("No conflicts for Cfx module");
278 }
279 CfxRpcModule::Debug => {
280 let cfx_debug_handler = LightCfxHandler::new(
281 light_rpc_impl.clone(),
282 common_rpc_impl.clone(),
283 );
284 module
285 .merge(CfxDebugRpcServer::into_rpc(cfx_debug_handler))
286 .expect("No conflicts for CfxDebug module");
287
288 let debug_handler =
289 LightDebugHandler::new(common_rpc_impl.clone());
290 module
291 .merge(DebugRpcServer::into_rpc(debug_handler))
292 .expect("No conflicts for Debug module");
293 }
294 CfxRpcModule::Test => {
295 let handler = LightTestHandler::new(common_rpc_impl.clone());
296 module
297 .merge(TestRpcServer::into_rpc(handler))
298 .expect("No conflicts for Test module");
299 }
300 CfxRpcModule::PubSub => {
301 let pubsub_handler = PubSubHandler::new(
302 notifications.clone(),
303 executor.clone(),
304 consensus.clone(),
305 *network.get_network_type(),
306 );
307 module
308 .merge(PubSubApiServer::into_rpc(pubsub_handler))
309 .expect("No conflicts for PubSub module");
310 }
311 CfxRpcModule::Trace => {
312 warn!("Light nodes do not support trace RPC");
313 }
314 CfxRpcModule::Txpool => {
315 warn!("Light nodes do not support txpool RPC");
316 }
317 CfxRpcModule::Pos => {
318 warn!("Light nodes do not support PoS RPC");
319 }
320 }
321 }
322
323 info!(
324 "Enabled cfx light async rpc modules: {:?}",
325 apis.to_selection()
326 );
327
328 let mut transport_modules = CfxTransportRpcModules::default();
329
330 match (http_config.enabled, ws_config.enabled) {
331 (true, true) => {
332 transport_modules.config =
333 CfxTransportRpcModuleConfig::set_http(apis.clone())
334 .with_ws(apis);
335 transport_modules.http = Some(module.clone());
336 transport_modules.ws = Some(module);
337 }
338 (true, false) => {
339 transport_modules.config =
340 CfxTransportRpcModuleConfig::set_http(apis);
341 transport_modules.http = Some(module);
342 }
343 (false, true) => {
344 transport_modules.config =
345 CfxTransportRpcModuleConfig::set_ws(apis);
346 transport_modules.ws = Some(module);
347 }
348 _ => unreachable!(),
349 }
350
351 let rpc_conf = conf.rpc_impl_config();
352 let enable_metrics = rpc_conf.enable_metrics;
353 let throttling_conf_file = conf.raw_conf.throttling_conf.clone();
354 let throttling_section = if is_debug { "rpc_local" } else { "rpc" };
355
356 let server_handle = server_config
357 .start(
358 &transport_modules,
359 throttling_conf_file,
360 throttling_section,
361 enable_metrics,
362 )
363 .await
364 .map_err(|e| e.to_string())?;
365
366 Ok(Some(server_handle))
367}