1use fc_rpc::{
22 Eth, EthApiServer, EthBlockDataCacheTask, EthFilter, EthFilterApiServer, EthPubSub,
23 EthPubSubApiServer, Net, NetApiServer, TxPool, TxPoolApiServer, Web3, Web3ApiServer,
24};
25use fc_rpc_core::types::{FeeHistoryCache, FilterPool};
26use fc_storage::{StorageOverride, StorageOverrideHandler};
27use jsonrpsee::RpcModule;
28use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
29use std::path::Path;
30
31use sc_client_api::{
32 AuxStore, Backend, BlockchainEvents, StateBackend, StorageProvider, UsageProvider,
33};
34use sc_network::service::traits::NetworkService;
35use sc_network_sync::SyncingService;
36use sc_rpc::dev::DevApiServer;
37pub use sc_rpc::SubscriptionTaskExecutor;
38use sc_transaction_pool_api::TransactionPool;
39use sp_api::{CallApiAt, ProvideRuntimeApi};
40use sp_block_builder::BlockBuilder;
41use sp_blockchain::{
42 Backend as BlockchainBackend, Error as BlockChainError, HeaderBackend, HeaderMetadata,
43};
44use sp_consensus_aura::{sr25519::AuthorityId as AuraId, AuraApi};
45use sp_runtime::traits::{BlakeTwo256, Block as BlockT};
46use std::sync::Arc;
47use substrate_frame_rpc_system::{System, SystemApiServer};
48
49use moonbeam_rpc_debug::{Debug, DebugServer};
50use moonbeam_rpc_trace::{Trace, TraceServer};
51
52use crate::evm_tracing_types::{FrontierBackendConfig, FrontierConfig};
53use astar_primitives::*;
54
55pub mod tracing;
56
57type HashFor<Block> = <Block as BlockT>::Hash;
58
59#[derive(Clone)]
60pub struct EvmTracingConfig {
61 pub tracing_requesters: tracing::RpcRequesters,
62 pub trace_filter_max_count: u32,
63 pub enable_txpool: bool,
64}
65
66#[derive(Debug, Copy, Clone, Default, clap::ValueEnum)]
68pub enum FrontierBackendType {
69 #[default]
71 KeyValue,
72 Sql,
74}
75
76pub fn open_frontier_backend<C, BE>(
79 client: Arc<C>,
80 config: &sc_service::Configuration,
81 rpc_config: &FrontierConfig,
82) -> Result<fc_db::Backend<Block, C>, String>
83where
84 C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,
85 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,
86 C: Send + Sync + 'static,
87 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
88 BE: Backend<Block> + 'static,
89 BE::State: StateBackend<BlakeTwo256>,
90{
91 let config_dir = config.base_path.config_dir(config.chain_spec.id());
92 let path = config_dir.join("frontier").join("db");
93
94 let frontier_backend = match rpc_config.frontier_backend_config {
95 FrontierBackendConfig::KeyValue => {
96 fc_db::Backend::KeyValue(Arc::new(fc_db::kv::Backend::<Block, C>::new(
97 client,
98 &fc_db::kv::DatabaseSettings {
99 source: fc_db::DatabaseSource::RocksDb {
100 path,
101 cache_size: 0,
102 },
103 },
104 )?))
105 }
106 FrontierBackendConfig::Sql {
107 pool_size,
108 num_ops_timeout,
109 thread_count,
110 cache_size,
111 } => {
112 let overrides = Arc::new(StorageOverrideHandler::new(client.clone()));
113 std::fs::create_dir_all(&path).expect("failed creating sql db directory");
114 let backend = futures::executor::block_on(fc_db::sql::Backend::new(
115 fc_db::sql::BackendConfig::Sqlite(fc_db::sql::SqliteBackendConfig {
116 path: Path::new("sqlite:///")
117 .join(path)
118 .join("frontier.db3")
119 .to_str()
120 .expect("frontier sql path error"),
121 create_if_missing: true,
122 thread_count: thread_count,
123 cache_size: cache_size,
124 }),
125 pool_size,
126 std::num::NonZeroU32::new(num_ops_timeout),
127 overrides.clone(),
128 ))
129 .unwrap_or_else(|err| panic!("failed creating sql backend: {:?}", err));
130 fc_db::Backend::Sql(Arc::new(backend))
131 }
132 };
133
134 Ok(frontier_backend)
135}
136
137pub struct AstarEthConfig<C, BE>(std::marker::PhantomData<(C, BE)>);
138
139impl<C, BE> fc_rpc::EthConfig<Block, C> for AstarEthConfig<C, BE>
140where
141 C: sc_client_api::StorageProvider<Block, BE> + Sync + Send + 'static,
142 BE: Backend<Block> + 'static,
143{
144 type EstimateGasAdapter = ();
147 type RuntimeStorageOverride =
149 fc_rpc::frontier_backend_client::SystemAccountId32StorageOverride<Block, C, BE>;
150}
151
152pub struct FullDeps<C, P> {
154 pub client: Arc<C>,
156 pub pool: Arc<P>,
158 pub graph: Arc<P>,
160 pub network: Arc<dyn NetworkService>,
162 pub sync: Arc<SyncingService<Block>>,
164 pub is_authority: bool,
166 pub frontier_backend: Arc<dyn fc_api::Backend<Block>>,
168 pub filter_pool: FilterPool,
170 pub fee_history_limit: u64,
172 pub fee_history_cache: FeeHistoryCache,
174 pub storage_override: Arc<dyn StorageOverride<Block>>,
176 pub block_data_cache: Arc<EthBlockDataCacheTask<Block>>,
178 pub enable_evm_rpc: bool,
180 #[cfg(feature = "manual-seal")]
182 pub command_sink:
183 Option<futures::channel::mpsc::Sender<sc_consensus_manual_seal::EngineCommand<Hash>>>,
184}
185
186pub fn create_full<C, P, BE>(
188 deps: FullDeps<C, P>,
189 subscription_task_executor: SubscriptionTaskExecutor,
190 pubsub_notification_sinks: Arc<
191 fc_mapping_sync::EthereumBlockNotificationSinks<
192 fc_mapping_sync::EthereumBlockNotification<Block>,
193 >,
194 >,
195 tracing_config: EvmTracingConfig,
196) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
197where
198 C: ProvideRuntimeApi<Block>
199 + HeaderBackend<Block>
200 + UsageProvider<Block>
201 + CallApiAt<Block>
202 + AuxStore
203 + StorageProvider<Block, BE>
204 + HeaderMetadata<Block, Error = BlockChainError>
205 + BlockchainEvents<Block>
206 + Send
207 + Sync
208 + 'static,
209 C: sc_client_api::BlockBackend<Block>,
210 C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>
211 + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>
212 + fp_rpc::ConvertTransactionRuntimeApi<Block>
213 + fp_rpc::EthereumRuntimeRPCApi<Block>
214 + BlockBuilder<Block>
215 + AuraApi<Block, AuraId>
216 + moonbeam_rpc_primitives_debug::DebugRuntimeApi<Block>
217 + moonbeam_rpc_primitives_txpool::TxPoolRuntimeApi<Block>,
218 P: TransactionPool<Block = Block, Hash = HashFor<Block>> + Sync + Send + 'static,
219 BE: Backend<Block> + 'static,
220 BE::State: StateBackend<BlakeTwo256>,
221 BE::Blockchain: BlockchainBackend<Block>,
222{
223 let client = Arc::clone(&deps.client);
224 let graph = Arc::clone(&deps.graph);
225
226 let mut io = create_full_rpc(deps, subscription_task_executor, pubsub_notification_sinks)?;
227
228 if tracing_config.enable_txpool {
229 io.merge(TxPool::new(Arc::clone(&client), graph).into_rpc())?;
230 }
231
232 if let Some(trace_filter_requester) = tracing_config.tracing_requesters.trace {
233 io.merge(
234 Trace::new(
235 client,
236 trace_filter_requester,
237 tracing_config.trace_filter_max_count,
238 )
239 .into_rpc(),
240 )?;
241 }
242
243 if let Some(debug_requester) = tracing_config.tracing_requesters.debug {
244 io.merge(Debug::new(debug_requester).into_rpc())?;
245 }
246
247 Ok(io)
248}
249
250fn create_full_rpc<C, P, BE>(
251 deps: FullDeps<C, P>,
252 subscription_task_executor: SubscriptionTaskExecutor,
253 pubsub_notification_sinks: Arc<
254 fc_mapping_sync::EthereumBlockNotificationSinks<
255 fc_mapping_sync::EthereumBlockNotification<Block>,
256 >,
257 >,
258) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
259where
260 C: ProvideRuntimeApi<Block>
261 + UsageProvider<Block>
262 + HeaderBackend<Block>
263 + CallApiAt<Block>
264 + AuxStore
265 + StorageProvider<Block, BE>
266 + HeaderMetadata<Block, Error = BlockChainError>
267 + BlockchainEvents<Block>
268 + Send
269 + Sync
270 + 'static,
271 C: sc_client_api::BlockBackend<Block>,
272 C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>
273 + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>
274 + fp_rpc::ConvertTransactionRuntimeApi<Block>
275 + fp_rpc::EthereumRuntimeRPCApi<Block>
276 + BlockBuilder<Block>
277 + AuraApi<Block, AuraId>,
278 P: TransactionPool<Block = Block, Hash = HashFor<Block>> + Sync + Send + 'static,
279 BE: Backend<Block> + 'static,
280 BE::State: StateBackend<BlakeTwo256>,
281 BE::Blockchain: BlockchainBackend<Block>,
282{
283 let mut io = RpcModule::new(());
284 let FullDeps {
285 client,
286 pool,
287 graph,
288 network,
289 sync,
290 is_authority,
291 frontier_backend,
292 filter_pool,
293 fee_history_limit,
294 fee_history_cache,
295 storage_override,
296 block_data_cache,
297 enable_evm_rpc,
298 #[cfg(feature = "manual-seal")]
299 command_sink,
300 } = deps;
301
302 io.merge(System::new(client.clone(), pool.clone()).into_rpc())?;
303 io.merge(TransactionPayment::new(client.clone()).into_rpc())?;
304 io.merge(sc_rpc::dev::Dev::new(client.clone()).into_rpc())?;
305
306 #[cfg(feature = "manual-seal")]
307 if let Some(command_sink) = command_sink {
308 use sc_consensus_manual_seal::rpc::ManualSealApiServer;
309 io.merge(sc_consensus_manual_seal::rpc::ManualSeal::new(command_sink).into_rpc())?;
310 }
311
312 if !enable_evm_rpc {
313 return Ok(io);
314 }
315
316 let no_tx_converter: Option<fp_rpc::NoTransactionConverter> = None;
317
318 io.merge(
319 Eth::<_, _, _, _, _, _, ()>::new(
320 client.clone(),
321 pool.clone(),
322 graph.clone(),
323 no_tx_converter,
324 sync.clone(),
325 Default::default(),
326 storage_override.clone(),
327 frontier_backend.clone(),
328 is_authority,
329 block_data_cache.clone(),
330 fee_history_cache,
331 fee_history_limit,
332 10,
334 None,
335 crate::parachain::PendingCrateInherentDataProvider::new(client.clone()),
336 Some(Box::new(
337 crate::parachain::AuraConsensusDataProviderFallback::new(client.clone()),
338 )),
339 )
340 .replace_config::<AstarEthConfig<C, BE>>()
341 .into_rpc(),
342 )?;
343
344 let max_past_logs: u32 = 10_000;
345 let max_block_range: u32 = 1024;
346 let max_stored_filters: usize = 500;
347 io.merge(
348 EthFilter::new(
349 client.clone(),
350 frontier_backend,
351 graph.clone(),
352 filter_pool,
353 max_stored_filters,
354 max_past_logs,
355 max_block_range,
356 block_data_cache,
357 )
358 .into_rpc(),
359 )?;
360
361 io.merge(Net::new(client.clone(), network.clone(), true).into_rpc())?;
362
363 io.merge(Web3::new(client.clone()).into_rpc())?;
364
365 io.merge(
366 EthPubSub::new(
367 pool,
368 client.clone(),
369 sync,
370 subscription_task_executor,
371 storage_override,
372 pubsub_notification_sinks,
373 )
374 .into_rpc(),
375 )?;
376
377 Ok(io)
378}