frontier_template_node/rpc/
eth.rs

1use std::{collections::BTreeMap, sync::Arc};
2
3use jsonrpsee::RpcModule;
4// Substrate
5use sc_client_api::{
6	backend::{Backend, StorageProvider},
7	client::BlockchainEvents,
8	AuxStore, UsageProvider,
9};
10use sc_network::service::traits::NetworkService;
11use sc_network_sync::SyncingService;
12use sc_rpc::SubscriptionTaskExecutor;
13use sc_transaction_pool_api::TransactionPool;
14use sp_api::{CallApiAt, ProvideRuntimeApi};
15use sp_block_builder::BlockBuilder as BlockBuilderApi;
16use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
17use sp_consensus_aura::{sr25519::AuthorityId as AuraId, AuraApi};
18use sp_core::H256;
19use sp_inherents::CreateInherentDataProviders;
20use sp_runtime::traits::Block as BlockT;
21// Frontier
22pub use fc_rpc::{EthBlockDataCacheTask, EthConfig};
23pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool};
24use fc_storage::StorageOverride;
25use fp_rpc::{ConvertTransaction, ConvertTransactionRuntimeApi, EthereumRuntimeRPCApi};
26
27/// Extra dependencies for Ethereum compatibility.
28pub struct EthDeps<B: BlockT, C, P, CT, CIDP> {
29	/// The client instance to use.
30	pub client: Arc<C>,
31	/// Transaction pool instance.
32	pub pool: Arc<P>,
33	/// Graph pool instance.
34	pub graph: Arc<P>,
35	/// Ethereum transaction converter.
36	pub converter: Option<CT>,
37	/// The Node authority flag
38	pub is_authority: bool,
39	/// Whether to enable dev signer
40	pub enable_dev_signer: bool,
41	/// Network service
42	pub network: Arc<dyn NetworkService>,
43	/// Chain syncing service
44	pub sync: Arc<SyncingService<B>>,
45	/// Frontier Backend.
46	pub frontier_backend: Arc<dyn fc_api::Backend<B>>,
47	/// Ethereum data access overrides.
48	pub storage_override: Arc<dyn StorageOverride<B>>,
49	/// Cache for Ethereum block data.
50	pub block_data_cache: Arc<EthBlockDataCacheTask<B>>,
51	/// EthFilterApi pool.
52	pub filter_pool: Option<FilterPool>,
53	/// Maximum number of logs in a query.
54	pub max_past_logs: u32,
55	/// Fee history cache.
56	pub fee_history_cache: FeeHistoryCache,
57	/// Maximum fee history cache size.
58	pub fee_history_cache_limit: FeeHistoryCacheLimit,
59	/// Maximum allowed gas limit will be ` block.gas_limit * execute_gas_limit_multiplier` when
60	/// using eth_call/eth_estimateGas.
61	pub execute_gas_limit_multiplier: u64,
62	/// Mandated parent hashes for a given block hash.
63	pub forced_parent_hashes: Option<BTreeMap<H256, H256>>,
64	/// Something that can create the inherent data providers for pending state
65	pub pending_create_inherent_data_providers: CIDP,
66}
67
68/// Instantiate Ethereum-compatible RPC extensions.
69pub fn create_eth<B, C, BE, P, CT, CIDP, EC>(
70	mut io: RpcModule<()>,
71	deps: EthDeps<B, C, P, CT, CIDP>,
72	subscription_task_executor: SubscriptionTaskExecutor,
73	pubsub_notification_sinks: Arc<
74		fc_mapping_sync::EthereumBlockNotificationSinks<
75			fc_mapping_sync::EthereumBlockNotification<B>,
76		>,
77	>,
78) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
79where
80	B: BlockT,
81	C: CallApiAt<B> + ProvideRuntimeApi<B>,
82	C::Api: AuraApi<B, AuraId>
83		+ BlockBuilderApi<B>
84		+ ConvertTransactionRuntimeApi<B>
85		+ EthereumRuntimeRPCApi<B>,
86	C: HeaderBackend<B> + HeaderMetadata<B, Error = BlockChainError>,
87	C: BlockchainEvents<B> + AuxStore + UsageProvider<B> + StorageProvider<B, BE> + 'static,
88	BE: Backend<B> + 'static,
89	P: TransactionPool<Block = B, Hash = B::Hash> + 'static,
90	CT: ConvertTransaction<<B as BlockT>::Extrinsic> + Send + Sync + 'static,
91	CIDP: CreateInherentDataProviders<B, ()> + Send + 'static,
92	EC: EthConfig<B, C>,
93{
94	use fc_rpc::{
95		pending::AuraConsensusDataProvider, Debug, DebugApiServer, Eth, EthApiServer, EthDevSigner,
96		EthFilter, EthFilterApiServer, EthPubSub, EthPubSubApiServer, EthSigner, Net, NetApiServer,
97		Web3, Web3ApiServer,
98	};
99	#[cfg(feature = "txpool")]
100	use fc_rpc::{TxPool, TxPoolApiServer};
101
102	let EthDeps {
103		client,
104		pool,
105		graph,
106		converter,
107		is_authority,
108		enable_dev_signer,
109		network,
110		sync,
111		frontier_backend,
112		storage_override,
113		block_data_cache,
114		filter_pool,
115		max_past_logs,
116		fee_history_cache,
117		fee_history_cache_limit,
118		execute_gas_limit_multiplier,
119		forced_parent_hashes,
120		pending_create_inherent_data_providers,
121	} = deps;
122
123	let mut signers = Vec::new();
124	if enable_dev_signer {
125		signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);
126	}
127
128	io.merge(
129		Eth::<B, C, P, CT, BE, CIDP, EC>::new(
130			client.clone(),
131			pool.clone(),
132			graph.clone(),
133			converter,
134			sync.clone(),
135			signers,
136			storage_override.clone(),
137			frontier_backend.clone(),
138			is_authority,
139			block_data_cache.clone(),
140			fee_history_cache,
141			fee_history_cache_limit,
142			execute_gas_limit_multiplier,
143			forced_parent_hashes,
144			pending_create_inherent_data_providers,
145			Some(Box::new(AuraConsensusDataProvider::new(client.clone()))),
146		)
147		.replace_config::<EC>()
148		.into_rpc(),
149	)?;
150
151	if let Some(filter_pool) = filter_pool {
152		io.merge(
153			EthFilter::new(
154				client.clone(),
155				frontier_backend.clone(),
156				graph.clone(),
157				filter_pool,
158				500_usize, // max stored filters
159				max_past_logs,
160				block_data_cache.clone(),
161			)
162			.into_rpc(),
163		)?;
164	}
165
166	io.merge(
167		EthPubSub::new(
168			pool,
169			client.clone(),
170			sync,
171			subscription_task_executor,
172			storage_override.clone(),
173			pubsub_notification_sinks,
174		)
175		.into_rpc(),
176	)?;
177
178	io.merge(
179		Net::new(
180			client.clone(),
181			network,
182			// Whether to format the `peer_count` response as Hex (default) or not.
183			true,
184		)
185		.into_rpc(),
186	)?;
187
188	io.merge(Web3::new(client.clone()).into_rpc())?;
189
190	io.merge(
191		Debug::new(
192			client.clone(),
193			frontier_backend,
194			storage_override,
195			block_data_cache,
196		)
197		.into_rpc(),
198	)?;
199
200	#[cfg(feature = "txpool")]
201	io.merge(TxPool::new(client, graph).into_rpc())?;
202
203	Ok(io)
204}