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

            
17
use super::*;
18

            
19
use moonbeam_rpc_debug::{DebugHandler, DebugRequester};
20
use moonbeam_rpc_trace::{CacheRequester as TraceFilterCacheRequester, CacheTask};
21
use substrate_prometheus_endpoint::Registry as PrometheusRegistry;
22
use tokio::sync::Semaphore;
23

            
24
#[derive(Clone)]
25
pub 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.
31
pub 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
36
where
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
}