moonbeam_service/rpc/
tracing.rs

1// Copyright 2019-2025 PureStake Inc.
2// This file is part of Moonbeam.
3
4// Moonbeam is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Moonbeam is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16
17use super::*;
18
19use moonbeam_rpc_debug::{DebugHandler, DebugRequester};
20use moonbeam_rpc_trace::{CacheRequester as TraceFilterCacheRequester, CacheTask};
21use substrate_prometheus_endpoint::Registry as PrometheusRegistry;
22use tokio::sync::Semaphore;
23
24#[derive(Clone)]
25pub struct RpcRequesters {
26	pub debug: Option<DebugRequester>,
27	pub trace: Option<TraceFilterCacheRequester>,
28}
29
30// Spawn the tasks that are required to run a Moonbeam tracing node.
31pub fn spawn_tracing_tasks<B, C, BE>(
32	rpc_config: &moonbeam_cli_opt::RpcConfig,
33	prometheus: Option<PrometheusRegistry>,
34	params: SpawnTasksParams<B, C, BE>,
35) -> RpcRequesters
36where
37	C: ProvideRuntimeApi<B> + BlockOf,
38	C: StorageProvider<B, BE>,
39	C: HeaderBackend<B> + HeaderMetadata<B, Error = BlockChainError> + 'static,
40	C: BlockchainEvents<B>,
41	C: Send + Sync + 'static,
42	C::Api: EthereumRuntimeRPCApi<B> + moonbeam_rpc_primitives_debug::DebugRuntimeApi<B>,
43	C::Api: BlockBuilder<B>,
44	B: BlockT<Hash = H256> + Send + Sync + 'static,
45	B::Header: HeaderT<Number = u32>,
46	BE: Backend<B> + 'static,
47	BE::State: StateBackend<BlakeTwo256>,
48{
49	let permit_pool = Arc::new(Semaphore::new(rpc_config.ethapi_max_permits as usize));
50
51	let (trace_filter_task, trace_filter_requester) =
52		if rpc_config.ethapi.contains(&EthApiCmd::Trace) {
53			let (trace_filter_task, trace_filter_requester) = CacheTask::create(
54				Arc::clone(&params.client),
55				Arc::clone(&params.substrate_backend),
56				Duration::from_secs(rpc_config.ethapi_trace_cache_duration),
57				Arc::clone(&permit_pool),
58				Arc::clone(&params.overrides),
59				prometheus,
60			);
61			(Some(trace_filter_task), Some(trace_filter_requester))
62		} else {
63			(None, None)
64		};
65
66	let (debug_task, debug_requester) = if rpc_config.ethapi.contains(&EthApiCmd::Debug) {
67		let (debug_task, debug_requester) = DebugHandler::task(
68			Arc::clone(&params.client),
69			Arc::clone(&params.substrate_backend),
70			match *params.frontier_backend {
71				fc_db::Backend::KeyValue(ref b) => b.clone(),
72				fc_db::Backend::Sql(ref b) => b.clone(),
73			},
74			Arc::clone(&permit_pool),
75			Arc::clone(&params.overrides),
76			rpc_config.tracing_raw_max_memory_usage,
77		);
78		(Some(debug_task), Some(debug_requester))
79	} else {
80		(None, None)
81	};
82
83	// `trace_filter` cache task. Essential.
84	// Proxies rpc requests to it's handler.
85	if let Some(trace_filter_task) = trace_filter_task {
86		params.task_manager.spawn_essential_handle().spawn(
87			"trace-filter-cache",
88			Some("eth-tracing"),
89			trace_filter_task,
90		);
91	}
92
93	// `debug` task if enabled. Essential.
94	// Proxies rpc requests to it's handler.
95	if let Some(debug_task) = debug_task {
96		params.task_manager.spawn_essential_handle().spawn(
97			"ethapi-debug",
98			Some("eth-tracing"),
99			debug_task,
100		);
101	}
102
103	RpcRequesters {
104		debug: debug_requester,
105		trace: trace_filter_requester,
106	}
107}