1use domain_service::rpc::FullDeps;
2use fc_mapping_sync::{EthereumBlockNotification, EthereumBlockNotificationSinks};
3use fc_rpc::{
4 Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub, EthPubSubApiServer,
5 EthSigner, Net, NetApiServer, Web3, Web3ApiServer,
6};
7pub use fc_rpc::{EthBlockDataCacheTask, EthConfig};
8pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool};
9use fc_storage::StorageOverride;
10use fp_rpc::{ConvertTransaction, ConvertTransactionRuntimeApi, EthereumRuntimeRPCApi};
11use jsonrpsee::RpcModule;
12use sc_client_api::backend::{Backend, StorageProvider};
13use sc_client_api::client::BlockchainEvents;
14use sc_network_sync::SyncingService;
15use sc_rpc::SubscriptionTaskExecutor;
16use sc_transaction_pool_api::TransactionPool;
17use sp_api::{CallApiAt, ProvideRuntimeApi};
18use sp_block_builder::BlockBuilder as BlockBuilderApi;
19use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
20use sp_core::H256;
21use sp_inherents::CreateInherentDataProviders;
22use sp_runtime::traits::Block as BlockT;
23use std::collections::BTreeMap;
24use std::sync::Arc;
25
26pub struct DefaultEthConfig<Client, Backend>(std::marker::PhantomData<(Client, Backend)>);
27
28impl<Block, Client, BE> EthConfig<Block, Client> for DefaultEthConfig<Client, BE>
29where
30 Block: BlockT,
31 Client: StorageProvider<Block, BE> + Sync + Send + 'static,
32 BE: Backend<Block> + 'static,
33{
34 type EstimateGasAdapter = ();
35 type RuntimeStorageOverride =
36 fc_rpc::frontier_backend_client::SystemAccountId20StorageOverride<Block, Client, BE>;
37}
38
39pub struct EthDeps<Client, TxPool, CT, Block: BlockT, BE, CIDP> {
41 pub full_deps: FullDeps<Block, Client, TxPool, BE, CIDP>,
43 pub converter: Option<CT>,
45 pub enable_dev_signer: bool,
47 pub sync: Arc<SyncingService<Block>>,
49 pub frontier_backend: Arc<fc_db::kv::Backend<Block, Client>>,
51 pub storage_override: Arc<dyn StorageOverride<Block>>,
53 pub block_data_cache: Arc<EthBlockDataCacheTask<Block>>,
55 pub filter_pool: Option<FilterPool>,
57 pub max_past_logs: u32,
59 pub fee_history_cache: FeeHistoryCache,
61 pub fee_history_cache_limit: FeeHistoryCacheLimit,
63 pub execute_gas_limit_multiplier: u64,
66 pub forced_parent_hashes: Option<BTreeMap<H256, H256>>,
68 pub pending_inherent_data_provider: CIDP,
70}
71
72impl<Client, TxPool, CT: Clone, Block: BlockT, BE, CIDP: Clone> Clone
73 for EthDeps<Client, TxPool, CT, Block, BE, CIDP>
74{
75 fn clone(&self) -> Self {
76 Self {
77 full_deps: self.full_deps.clone(),
78 converter: self.converter.clone(),
79 enable_dev_signer: self.enable_dev_signer,
80 sync: self.sync.clone(),
81 frontier_backend: self.frontier_backend.clone(),
82 storage_override: self.storage_override.clone(),
83 block_data_cache: self.block_data_cache.clone(),
84 filter_pool: self.filter_pool.clone(),
85 max_past_logs: self.max_past_logs,
86 fee_history_cache: self.fee_history_cache.clone(),
87 fee_history_cache_limit: self.fee_history_cache_limit,
88 execute_gas_limit_multiplier: self.execute_gas_limit_multiplier,
89 forced_parent_hashes: self.forced_parent_hashes.clone(),
90 pending_inherent_data_provider: self.pending_inherent_data_provider.clone(),
91 }
92 }
93}
94
95pub(crate) fn create_eth_rpc<Client, BE, TxPool, CT, Block, EC, CIDP>(
97 mut io: RpcModule<()>,
98 deps: EthDeps<Client, TxPool, CT, Block, BE, CIDP>,
99 subscription_task_executor: SubscriptionTaskExecutor,
100 pubsub_notification_sinks: Arc<
101 EthereumBlockNotificationSinks<EthereumBlockNotification<Block>>,
102 >,
103) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
104where
105 Block: BlockT<Hash = H256>,
106 Client: CallApiAt<Block> + ProvideRuntimeApi<Block>,
107 Client::Api:
108 BlockBuilderApi<Block> + EthereumRuntimeRPCApi<Block> + ConvertTransactionRuntimeApi<Block>,
109 Client: BlockchainEvents<Block> + 'static,
110 Client: HeaderBackend<Block>
111 + HeaderMetadata<Block, Error = BlockChainError>
112 + StorageProvider<Block, BE>,
113 BE: Backend<Block> + 'static,
114 TxPool: TransactionPool<Block = Block, Hash = H256> + 'static,
115 CT: ConvertTransaction<Block::Extrinsic> + Send + Sync + 'static,
116 EC: EthConfig<Block, Client>,
117 CIDP: CreateInherentDataProviders<Block, ()> + Send + 'static,
118{
119 let EthDeps {
120 full_deps,
121 converter,
122 enable_dev_signer,
123 sync: _,
124 frontier_backend,
125 storage_override,
126 block_data_cache,
127 filter_pool,
128 max_past_logs,
129 fee_history_cache,
130 fee_history_cache_limit,
131 execute_gas_limit_multiplier,
132 forced_parent_hashes,
133 pending_inherent_data_provider,
134 } = deps;
135
136 let FullDeps {
137 client,
138 pool,
139 network,
140 sync,
141 is_authority,
142 ..
143 } = full_deps;
144
145 let mut signers = Vec::<Box<dyn EthSigner>>::new();
146 if enable_dev_signer {
147 signers.push(Box::new(EthDevSigner::new()));
148 }
149
150 io.merge(
151 Eth::<Block, Client, TxPool, CT, BE, CIDP, EC>::new(
152 client.clone(),
153 pool.clone(),
154 pool.clone(),
155 converter,
156 sync.clone(),
157 signers,
158 storage_override.clone(),
159 frontier_backend.clone(),
160 is_authority,
161 block_data_cache.clone(),
162 fee_history_cache,
163 fee_history_cache_limit,
164 execute_gas_limit_multiplier,
165 forced_parent_hashes,
166 pending_inherent_data_provider,
167 None,
168 )
169 .replace_config::<EC>()
170 .into_rpc(),
171 )?;
172
173 if let Some(filter_pool) = filter_pool {
174 io.merge(
175 EthFilter::new(
176 client.clone(),
177 frontier_backend,
178 pool.clone(),
179 filter_pool,
180 500_usize, max_past_logs,
182 block_data_cache,
183 )
184 .into_rpc(),
185 )?;
186 }
187
188 io.merge(
189 EthPubSub::new(
190 pool,
191 client.clone(),
192 sync,
193 subscription_task_executor,
194 storage_override,
195 pubsub_notification_sinks,
196 )
197 .into_rpc(),
198 )?;
199
200 io.merge(
201 Net::new(
202 client.clone(),
203 network,
204 true,
206 )
207 .into_rpc(),
208 )?;
209
210 io.merge(Web3::new(client).into_rpc())?;
211
212 Ok(io)
213}